@wrongstack/cli 0.295.0 → 0.296.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (471) hide show
  1. package/data/providers.json +0 -24
  2. package/dist/acp-A5OSIU2P.js +824 -0
  3. package/dist/acp-A5OSIU2P.js.map +7 -0
  4. package/dist/acp-server-agent.d.ts.map +1 -1
  5. package/dist/arg-parser.d.ts.map +1 -1
  6. package/dist/audit-2ZSFGNIF.js +102 -0
  7. package/dist/audit-2ZSFGNIF.js.map +7 -0
  8. package/dist/auth-CJWQJVRH.js +504 -0
  9. package/dist/auth-CJWQJVRH.js.map +7 -0
  10. package/dist/auth-menu/auth-menu-audit.d.ts +1 -5
  11. package/dist/auth-menu/auth-menu-audit.d.ts.map +1 -1
  12. package/dist/auth-menu/local.d.ts +1 -1
  13. package/dist/auth-menu/local.d.ts.map +1 -1
  14. package/dist/auth-menu/shared.d.ts +1 -1
  15. package/dist/auth-menu/shared.d.ts.map +1 -1
  16. package/dist/bench-7ZDWSNEF.js +278 -0
  17. package/dist/bench-7ZDWSNEF.js.map +7 -0
  18. package/dist/boot/brain-decision-log.d.ts +7 -5
  19. package/dist/boot/brain-decision-log.d.ts.map +1 -1
  20. package/dist/boot/dispatch-webui.d.ts +4 -8
  21. package/dist/boot/dispatch-webui.d.ts.map +1 -1
  22. package/dist/boot/launch-menu.d.ts +1 -1
  23. package/dist/boot/launch-menu.d.ts.map +1 -1
  24. package/dist/boot/system-prompt-builder.d.ts +4 -1
  25. package/dist/boot/system-prompt-builder.d.ts.map +1 -1
  26. package/dist/boot/tui-coordinator-callbacks.d.ts +45 -0
  27. package/dist/boot/tui-coordinator-callbacks.d.ts.map +1 -0
  28. package/dist/boot/tui-coordinator-setup.d.ts +2 -2
  29. package/dist/boot/tui-coordinator-setup.d.ts.map +1 -1
  30. package/dist/boot/tui-project-picker-callback.d.ts +1 -1
  31. package/dist/boot/tui-project-picker-callback.d.ts.map +1 -1
  32. package/dist/boot/tui-project-switch.d.ts +3 -4
  33. package/dist/boot/tui-project-switch.d.ts.map +1 -1
  34. package/dist/boot/tui-runtime-state.d.ts +5 -6
  35. package/dist/boot/tui-runtime-state.d.ts.map +1 -1
  36. package/dist/boot/tui-session-resume.d.ts.map +1 -1
  37. package/dist/boot/tui-settings-adapter.d.ts +2 -3
  38. package/dist/boot/tui-settings-adapter.d.ts.map +1 -1
  39. package/dist/boot-config.d.ts +2 -2
  40. package/dist/boot-config.d.ts.map +1 -1
  41. package/dist/boot.d.ts +1 -1
  42. package/dist/boot.d.ts.map +1 -1
  43. package/dist/brain-menu/panel-service.d.ts.map +1 -1
  44. package/dist/chimera-review-task.d.ts +6 -0
  45. package/dist/chimera-review-task.d.ts.map +1 -0
  46. package/dist/chimera-reviewer-policy.d.ts +34 -0
  47. package/dist/chimera-reviewer-policy.d.ts.map +1 -0
  48. package/dist/chronicle-QQEQFSSE.js +256 -0
  49. package/dist/chronicle-QQEQFSSE.js.map +7 -0
  50. package/dist/chunk-5N34EWJR.js +418 -0
  51. package/dist/chunk-5N34EWJR.js.map +7 -0
  52. package/dist/chunk-66T43Q4Y.js +90 -0
  53. package/dist/chunk-66T43Q4Y.js.map +7 -0
  54. package/dist/chunk-7OCVIDC7.js +11 -0
  55. package/dist/chunk-7OCVIDC7.js.map +7 -0
  56. package/dist/chunk-ABXK4VVY.js +84 -0
  57. package/dist/chunk-ABXK4VVY.js.map +7 -0
  58. package/dist/chunk-AXVZMEWG.js +306 -0
  59. package/dist/chunk-AXVZMEWG.js.map +7 -0
  60. package/dist/chunk-AZESNNIC.js +216 -0
  61. package/dist/chunk-AZESNNIC.js.map +7 -0
  62. package/dist/chunk-BGFM3PD7.js +41 -0
  63. package/dist/chunk-BGFM3PD7.js.map +7 -0
  64. package/dist/chunk-DPJZQCVP.js +13 -0
  65. package/dist/chunk-DPJZQCVP.js.map +7 -0
  66. package/dist/chunk-F4PEGAJZ.js +176 -0
  67. package/dist/chunk-F4PEGAJZ.js.map +7 -0
  68. package/dist/chunk-IHBYBYGA.js +443 -0
  69. package/dist/chunk-IHBYBYGA.js.map +7 -0
  70. package/dist/chunk-IN4GXGYW.js +425 -0
  71. package/dist/chunk-IN4GXGYW.js.map +7 -0
  72. package/dist/chunk-JBSQ7ONN.js +1023 -0
  73. package/dist/chunk-JBSQ7ONN.js.map +7 -0
  74. package/dist/chunk-JBTFWWKV.js +1325 -0
  75. package/dist/chunk-JBTFWWKV.js.map +7 -0
  76. package/dist/chunk-JUHRI6OV.js +100 -0
  77. package/dist/chunk-JUHRI6OV.js.map +7 -0
  78. package/dist/chunk-OP47B3IX.js +142 -0
  79. package/dist/chunk-OP47B3IX.js.map +7 -0
  80. package/dist/chunk-PJHET45A.js +158 -0
  81. package/dist/chunk-PJHET45A.js.map +7 -0
  82. package/dist/chunk-Q5GTM25S.js +17 -0
  83. package/dist/chunk-Q5GTM25S.js.map +7 -0
  84. package/dist/chunk-QD544J2B.js +19 -0
  85. package/dist/chunk-QD544J2B.js.map +7 -0
  86. package/dist/chunk-QUNHS6O3.js +258 -0
  87. package/dist/chunk-QUNHS6O3.js.map +7 -0
  88. package/dist/chunk-TADVX644.js +480 -0
  89. package/dist/chunk-TADVX644.js.map +7 -0
  90. package/dist/chunk-TGDHN4LM.js +81 -0
  91. package/dist/chunk-TGDHN4LM.js.map +7 -0
  92. package/dist/chunk-TYO2OVAD.js +50 -0
  93. package/dist/chunk-TYO2OVAD.js.map +7 -0
  94. package/dist/chunk-VCYZ3WZV.js +14 -0
  95. package/dist/chunk-VCYZ3WZV.js.map +7 -0
  96. package/dist/chunk-VJUEZZYB.js +29 -0
  97. package/dist/chunk-VJUEZZYB.js.map +7 -0
  98. package/dist/chunk-WHOIR577.js +1 -0
  99. package/dist/chunk-WHOIR577.js.map +7 -0
  100. package/dist/chunk-WY7KKOUK.js +460 -0
  101. package/dist/chunk-WY7KKOUK.js.map +7 -0
  102. package/dist/chunk-X5DQTPXT.js +3059 -0
  103. package/dist/chunk-X5DQTPXT.js.map +7 -0
  104. package/dist/chunk-XJXDOF63.js +28 -0
  105. package/dist/chunk-XJXDOF63.js.map +7 -0
  106. package/dist/chunk-XWEGWYDU.js +560 -0
  107. package/dist/chunk-XWEGWYDU.js.map +7 -0
  108. package/dist/chunk-YWUPHRGB.js +346 -0
  109. package/dist/chunk-YWUPHRGB.js.map +7 -0
  110. package/dist/chunk-Z7YGASQP.js +313 -0
  111. package/dist/chunk-Z7YGASQP.js.map +7 -0
  112. package/dist/cli-entry-main.d.ts +2 -0
  113. package/dist/cli-entry-main.d.ts.map +1 -0
  114. package/dist/cli-entry-point.d.ts +3 -3
  115. package/dist/cli-entry-point.d.ts.map +1 -1
  116. package/dist/cli-eternal-flag.d.ts +2 -2
  117. package/dist/cli-eternal-flag.d.ts.map +1 -1
  118. package/dist/cli-main-6AU6E4XZ.js +29126 -0
  119. package/dist/cli-main-6AU6E4XZ.js.map +7 -0
  120. package/dist/cli-main-helpers.d.ts +21 -0
  121. package/dist/cli-main-helpers.d.ts.map +1 -0
  122. package/dist/cli-main.d.ts +25 -1
  123. package/dist/cli-main.d.ts.map +1 -1
  124. package/dist/context-limit.d.ts +48 -0
  125. package/dist/context-limit.d.ts.map +1 -1
  126. package/dist/diag-doctor-OQ3AA63O.js +170 -0
  127. package/dist/diag-doctor-OQ3AA63O.js.map +7 -0
  128. package/dist/execute-deps.d.ts +10 -12
  129. package/dist/execute-deps.d.ts.map +1 -1
  130. package/dist/execution-V26SE52F.js +4656 -0
  131. package/dist/execution-V26SE52F.js.map +7 -0
  132. package/dist/execution-chimera-ask.d.ts +10 -0
  133. package/dist/execution-chimera-ask.d.ts.map +1 -0
  134. package/dist/execution-chimera-cascade.d.ts +15 -0
  135. package/dist/execution-chimera-cascade.d.ts.map +1 -0
  136. package/dist/execution-cleanup.d.ts +23 -0
  137. package/dist/execution-cleanup.d.ts.map +1 -0
  138. package/dist/execution-kanban-dispatch.d.ts +10 -0
  139. package/dist/execution-kanban-dispatch.d.ts.map +1 -0
  140. package/dist/execution-repl-fleet-callbacks.d.ts +11 -0
  141. package/dist/execution-repl-fleet-callbacks.d.ts.map +1 -0
  142. package/dist/execution-storage-observability.d.ts +3 -0
  143. package/dist/execution-storage-observability.d.ts.map +1 -0
  144. package/dist/execution-tui-next-step-callbacks.d.ts +20 -0
  145. package/dist/execution-tui-next-step-callbacks.d.ts.map +1 -0
  146. package/dist/execution.d.ts +2 -139
  147. package/dist/execution.d.ts.map +1 -1
  148. package/dist/export-TPORYVRZ.js +64 -0
  149. package/dist/export-TPORYVRZ.js.map +7 -0
  150. package/dist/fleet/host-acp-runner-cache.d.ts +9 -0
  151. package/dist/fleet/host-acp-runner-cache.d.ts.map +1 -0
  152. package/dist/fleet/host-acp.d.ts +3 -0
  153. package/dist/fleet/host-acp.d.ts.map +1 -0
  154. package/dist/fleet/host-concurrency.d.ts +2 -0
  155. package/dist/fleet/host-concurrency.d.ts.map +1 -0
  156. package/dist/fleet/host-context.d.ts +5 -0
  157. package/dist/fleet/host-context.d.ts.map +1 -0
  158. package/dist/fleet/host-director-builder.d.ts +24 -0
  159. package/dist/fleet/host-director-builder.d.ts.map +1 -0
  160. package/dist/fleet/host-director-event-bridges.d.ts +37 -0
  161. package/dist/fleet/host-director-event-bridges.d.ts.map +1 -0
  162. package/dist/fleet/host-director-services.d.ts +20 -0
  163. package/dist/fleet/host-director-services.d.ts.map +1 -0
  164. package/dist/fleet/host-event-bridge.d.ts +17 -0
  165. package/dist/fleet/host-event-bridge.d.ts.map +1 -0
  166. package/dist/fleet/host-helpers.d.ts +22 -0
  167. package/dist/fleet/host-helpers.d.ts.map +1 -0
  168. package/dist/fleet/host-learning-tracker.d.ts +11 -0
  169. package/dist/fleet/host-learning-tracker.d.ts.map +1 -0
  170. package/dist/fleet/host-learning.d.ts +4 -0
  171. package/dist/fleet/host-learning.d.ts.map +1 -0
  172. package/dist/fleet/host-lifecycle-events.d.ts +4 -0
  173. package/dist/fleet/host-lifecycle-events.d.ts.map +1 -0
  174. package/dist/fleet/host-paths.d.ts +3 -0
  175. package/dist/fleet/host-paths.d.ts.map +1 -0
  176. package/dist/fleet/host-provider.d.ts +22 -0
  177. package/dist/fleet/host-provider.d.ts.map +1 -0
  178. package/dist/fleet/host-session-writer.d.ts +3 -0
  179. package/dist/fleet/host-session-writer.d.ts.map +1 -0
  180. package/dist/fleet/host-shadow-pass.d.ts +21 -0
  181. package/dist/fleet/host-shadow-pass.d.ts.map +1 -0
  182. package/dist/fleet/host-spawn-types.d.ts +25 -0
  183. package/dist/fleet/host-spawn-types.d.ts.map +1 -0
  184. package/dist/fleet/host-status.d.ts +48 -0
  185. package/dist/fleet/host-status.d.ts.map +1 -0
  186. package/dist/fleet/host-subagent-factory.d.ts +16 -0
  187. package/dist/fleet/host-subagent-factory.d.ts.map +1 -0
  188. package/dist/fleet/host-supervisor.d.ts +16 -0
  189. package/dist/fleet/host-supervisor.d.ts.map +1 -0
  190. package/dist/fleet/host-task-result-report.d.ts +11 -0
  191. package/dist/fleet/host-task-result-report.d.ts.map +1 -0
  192. package/dist/fleet/host-types.d.ts +89 -0
  193. package/dist/fleet/host-types.d.ts.map +1 -0
  194. package/dist/fleet/host.d.ts +10 -357
  195. package/dist/fleet/host.d.ts.map +1 -1
  196. package/dist/fleet/routing.d.ts +1 -1
  197. package/dist/fleet/routing.d.ts.map +1 -1
  198. package/dist/fleet/status-broadcast.d.ts.map +1 -1
  199. package/dist/goal-host.d.ts +2 -2
  200. package/dist/goal-host.d.ts.map +1 -1
  201. package/dist/hq-BECGICEZ.js +547 -0
  202. package/dist/hq-BECGICEZ.js.map +7 -0
  203. package/dist/hq-command-controller.d.ts +2 -2
  204. package/dist/hq-command-controller.d.ts.map +1 -1
  205. package/dist/hq-publisher.d.ts +2 -2
  206. package/dist/hq-publisher.d.ts.map +1 -1
  207. package/dist/hq-server/auth-state.d.ts +1 -1
  208. package/dist/hq-server/auth-state.d.ts.map +1 -1
  209. package/dist/hq-server/project-root.d.ts +5 -0
  210. package/dist/hq-server/project-root.d.ts.map +1 -0
  211. package/dist/hq-server/routes/auth-handlers.d.ts +32 -0
  212. package/dist/hq-server/routes/auth-handlers.d.ts.map +1 -0
  213. package/dist/hq-server/routes/session-handlers.d.ts +8 -0
  214. package/dist/hq-server/routes/session-handlers.d.ts.map +1 -0
  215. package/dist/hq-server/routes/system-handlers.d.ts +16 -0
  216. package/dist/hq-server/routes/system-handlers.d.ts.map +1 -0
  217. package/dist/hq-server/routes.d.ts +6 -6
  218. package/dist/hq-server/routes.d.ts.map +1 -1
  219. package/dist/hq-server/ws.d.ts +1 -1
  220. package/dist/hq-server/ws.d.ts.map +1 -1
  221. package/dist/hq-server-FJOVOERO.js +39 -0
  222. package/dist/hq-server-FJOVOERO.js.map +7 -0
  223. package/dist/hq-server.d.ts.map +1 -1
  224. package/dist/hq-ttl-U2FAYFAT.js +8 -0
  225. package/dist/hq-ttl-U2FAYFAT.js.map +7 -0
  226. package/dist/hq-tunnel-YZLRONPV.js +111 -0
  227. package/dist/hq-tunnel-YZLRONPV.js.map +7 -0
  228. package/dist/index.d.ts +2 -1
  229. package/dist/index.d.ts.map +1 -1
  230. package/dist/index.js +2507 -52632
  231. package/dist/index.js.map +4 -4
  232. package/dist/init-E2NDDOHI.js +27 -0
  233. package/dist/init-E2NDDOHI.js.map +7 -0
  234. package/dist/input-reader.d.ts +1 -1
  235. package/dist/input-reader.d.ts.map +1 -1
  236. package/dist/kanban-dispatch-route.d.ts +14 -0
  237. package/dist/kanban-dispatch-route.d.ts.map +1 -0
  238. package/dist/kanban-hq-sync.d.ts +2 -0
  239. package/dist/kanban-hq-sync.d.ts.map +1 -1
  240. package/dist/kanban-run-mirror-EKVNGXWW.js +12 -0
  241. package/dist/kanban-run-mirror-EKVNGXWW.js.map +7 -0
  242. package/dist/live-settings-input.d.ts +69 -0
  243. package/dist/live-settings-input.d.ts.map +1 -0
  244. package/dist/mailbox-serve-2UWHEN3M.js +302 -0
  245. package/dist/mailbox-serve-2UWHEN3M.js.map +7 -0
  246. package/dist/mcp-CYLPUEHC.js +413 -0
  247. package/dist/mcp-CYLPUEHC.js.map +7 -0
  248. package/dist/mcp-serve.d.ts +1 -1
  249. package/dist/mcp-serve.d.ts.map +1 -1
  250. package/dist/modeldiag-HENYJ4N7.js +1290 -0
  251. package/dist/modeldiag-HENYJ4N7.js.map +7 -0
  252. package/dist/next-task-predictor.d.ts +1 -1
  253. package/dist/next-task-predictor.d.ts.map +1 -1
  254. package/dist/permissions-FNYLZIL4.js +115 -0
  255. package/dist/permissions-FNYLZIL4.js.map +7 -0
  256. package/dist/picker-key-state.d.ts +7 -0
  257. package/dist/picker-key-state.d.ts.map +1 -0
  258. package/dist/picker-model-picker.d.ts +6 -0
  259. package/dist/picker-model-picker.d.ts.map +1 -0
  260. package/dist/picker-ui.d.ts +17 -0
  261. package/dist/picker-ui.d.ts.map +1 -0
  262. package/dist/picker.d.ts +4 -37
  263. package/dist/picker.d.ts.map +1 -1
  264. package/dist/plugin-management.d.ts +1 -1
  265. package/dist/plugin-management.d.ts.map +1 -1
  266. package/dist/plugin-usage-OU6X6LM3.js +40 -0
  267. package/dist/plugin-usage-OU6X6LM3.js.map +7 -0
  268. package/dist/plugins-4LJ5IUBI.js +24 -0
  269. package/dist/plugins-4LJ5IUBI.js.map +7 -0
  270. package/dist/pre-launch.d.ts +0 -1
  271. package/dist/pre-launch.d.ts.map +1 -1
  272. package/dist/project-BLQ3ALVL.js +76 -0
  273. package/dist/project-BLQ3ALVL.js.map +7 -0
  274. package/dist/project-manifest-GE25PW4S.js +18 -0
  275. package/dist/project-manifest-GE25PW4S.js.map +7 -0
  276. package/dist/project-picker-BOCWHBXP.js +17 -0
  277. package/dist/project-picker-BOCWHBXP.js.map +7 -0
  278. package/dist/projects-XE76NFNZ.js +38 -0
  279. package/dist/projects-XE76NFNZ.js.map +7 -0
  280. package/dist/provider-helpers.d.ts +22 -6
  281. package/dist/provider-helpers.d.ts.map +1 -1
  282. package/dist/providers-models-GDELBHZK.js +589 -0
  283. package/dist/providers-models-GDELBHZK.js.map +7 -0
  284. package/dist/quick-VIO2BEHS.js +10 -0
  285. package/dist/quick-VIO2BEHS.js.map +7 -0
  286. package/dist/repl-auto-proceed.d.ts +19 -0
  287. package/dist/repl-auto-proceed.d.ts.map +1 -0
  288. package/dist/repl-client-registration.d.ts +7 -0
  289. package/dist/repl-client-registration.d.ts.map +1 -0
  290. package/dist/repl-input.d.ts +11 -0
  291. package/dist/repl-input.d.ts.map +1 -0
  292. package/dist/repl-options.d.ts +54 -0
  293. package/dist/repl-options.d.ts.map +1 -0
  294. package/dist/repl-rendering.d.ts +4 -0
  295. package/dist/repl-rendering.d.ts.map +1 -0
  296. package/dist/repl-suggestions.d.ts +21 -0
  297. package/dist/repl-suggestions.d.ts.map +1 -0
  298. package/dist/repl.d.ts +3 -162
  299. package/dist/repl.d.ts.map +1 -1
  300. package/dist/replay-KCTXNMZQ.js +75 -0
  301. package/dist/replay-KCTXNMZQ.js.map +7 -0
  302. package/dist/rewind-EJMVFVLS.js +185 -0
  303. package/dist/rewind-EJMVFVLS.js.map +7 -0
  304. package/dist/sdd-runtime-IKPROVV2.js +54 -0
  305. package/dist/sdd-runtime-IKPROVV2.js.map +7 -0
  306. package/dist/services/dispatch-classifier.d.ts +1 -1
  307. package/dist/services/dispatch-classifier.d.ts.map +1 -1
  308. package/dist/services/project-facts.d.ts.map +1 -1
  309. package/dist/services/sdd/project-context.d.ts +1 -1
  310. package/dist/services/sdd/project-context.d.ts.map +1 -1
  311. package/dist/services/sdd/task-manager.d.ts +1 -1
  312. package/dist/services/sdd/task-manager.d.ts.map +1 -1
  313. package/dist/services/statusline-config.d.ts +1 -1
  314. package/dist/services/statusline-config.d.ts.map +1 -1
  315. package/dist/session-event-wiring.d.ts +5 -2
  316. package/dist/session-event-wiring.d.ts.map +1 -1
  317. package/dist/sessions-config-NLCMK3BY.js +409 -0
  318. package/dist/sessions-config-NLCMK3BY.js.map +7 -0
  319. package/dist/settings-menu.d.ts +4 -19
  320. package/dist/settings-menu.d.ts.map +1 -1
  321. package/dist/simpleui-dist-JIFGUJO7.js +93 -0
  322. package/dist/simpleui-dist-JIFGUJO7.js.map +7 -0
  323. package/dist/slash-commands/agent-improve.d.ts +6 -5
  324. package/dist/slash-commands/agent-improve.d.ts.map +1 -1
  325. package/dist/slash-commands/brain.d.ts.map +1 -1
  326. package/dist/slash-commands/btw.d.ts +1 -1
  327. package/dist/slash-commands/btw.d.ts.map +1 -1
  328. package/dist/slash-commands/clear.d.ts +1 -1
  329. package/dist/slash-commands/clear.d.ts.map +1 -1
  330. package/dist/slash-commands/fallback.d.ts.map +1 -1
  331. package/dist/slash-commands/goal-refiner.d.ts +2 -2
  332. package/dist/slash-commands/goal-refiner.d.ts.map +1 -1
  333. package/dist/slash-commands/interrupt.d.ts +1 -1
  334. package/dist/slash-commands/interrupt.d.ts.map +1 -1
  335. package/dist/slash-commands/kanban-agent-helpers.d.ts +18 -0
  336. package/dist/slash-commands/kanban-agent-helpers.d.ts.map +1 -0
  337. package/dist/slash-commands/kanban-format.d.ts +16 -0
  338. package/dist/slash-commands/kanban-format.d.ts.map +1 -0
  339. package/dist/slash-commands/kanban-help.d.ts +2 -0
  340. package/dist/slash-commands/kanban-help.d.ts.map +1 -0
  341. package/dist/slash-commands/kanban.d.ts +1 -1
  342. package/dist/slash-commands/kanban.d.ts.map +1 -1
  343. package/dist/slash-commands/mailbox-demo.d.ts.map +1 -1
  344. package/dist/slash-commands/mailbox.d.ts +3 -2
  345. package/dist/slash-commands/mailbox.d.ts.map +1 -1
  346. package/dist/slash-commands/memory-compact.d.ts +5 -0
  347. package/dist/slash-commands/memory-compact.d.ts.map +1 -0
  348. package/dist/slash-commands/memory-flags.d.ts +36 -0
  349. package/dist/slash-commands/memory-flags.d.ts.map +1 -0
  350. package/dist/slash-commands/memory-formatters.d.ts +16 -0
  351. package/dist/slash-commands/memory-formatters.d.ts.map +1 -0
  352. package/dist/slash-commands/memory.d.ts.map +1 -1
  353. package/dist/slash-commands/mouse.d.ts +2 -2
  354. package/dist/slash-commands/refiner.d.ts +1 -1
  355. package/dist/slash-commands/refiner.d.ts.map +1 -1
  356. package/dist/slash-commands/review.d.ts.map +1 -1
  357. package/dist/slash-commands/sdd-command-helpers.d.ts +23 -0
  358. package/dist/slash-commands/sdd-command-helpers.d.ts.map +1 -0
  359. package/dist/slash-commands/sdd-format.d.ts +32 -0
  360. package/dist/slash-commands/sdd-format.d.ts.map +1 -0
  361. package/dist/slash-commands/sdd.d.ts +1 -1
  362. package/dist/slash-commands/sdd.d.ts.map +1 -1
  363. package/dist/slash-commands/tool.d.ts +1 -1
  364. package/dist/slash-commands/tool.d.ts.map +1 -1
  365. package/dist/slash-commands/working-dir.d.ts +1 -1
  366. package/dist/slash-commands/working-dir.d.ts.map +1 -1
  367. package/dist/subcommands/handlers/chronicle.d.ts.map +1 -1
  368. package/dist/subcommands/handlers/mailbox-serve.d.ts.map +1 -1
  369. package/dist/subcommands/handlers/model-smoke-test.d.ts +51 -0
  370. package/dist/subcommands/handlers/model-smoke-test.d.ts.map +1 -0
  371. package/dist/subcommands/handlers/modeldiag-profiles.d.ts +64 -0
  372. package/dist/subcommands/handlers/modeldiag-profiles.d.ts.map +1 -0
  373. package/dist/subcommands/handlers/modeldiag.d.ts.map +1 -1
  374. package/dist/subcommands/handlers/per-subcommand-deep-help-table.d.ts +3 -0
  375. package/dist/subcommands/handlers/per-subcommand-deep-help-table.d.ts.map +1 -0
  376. package/dist/subcommands/handlers/per-subcommand-help-data.d.ts +3 -0
  377. package/dist/subcommands/handlers/per-subcommand-help-data.d.ts.map +1 -0
  378. package/dist/subcommands/handlers/per-subcommand-help-table.d.ts +36 -0
  379. package/dist/subcommands/handlers/per-subcommand-help-table.d.ts.map +1 -0
  380. package/dist/subcommands/handlers/per-subcommand-help-types.d.ts +18 -0
  381. package/dist/subcommands/handlers/per-subcommand-help-types.d.ts.map +1 -0
  382. package/dist/subcommands/handlers/per-subcommand-help.d.ts +2 -80
  383. package/dist/subcommands/handlers/per-subcommand-help.d.ts.map +1 -1
  384. package/dist/subcommands/handlers/rewind.d.ts.map +1 -1
  385. package/dist/subcommands/index.d.ts +7 -0
  386. package/dist/subcommands/index.d.ts.map +1 -1
  387. package/dist/tools-skills-UNKLOB7M.js +29 -0
  388. package/dist/tools-skills-UNKLOB7M.js.map +7 -0
  389. package/dist/update-YC4TYW2Y.js +16 -0
  390. package/dist/update-YC4TYW2Y.js.map +7 -0
  391. package/dist/update-check-UMYTOH7Z.js +18 -0
  392. package/dist/update-check-UMYTOH7Z.js.map +7 -0
  393. package/dist/version-help-DROHZRW6.js +11 -0
  394. package/dist/version-help-DROHZRW6.js.map +7 -0
  395. package/dist/webui-server/connection-handler.d.ts +2 -1
  396. package/dist/webui-server/connection-handler.d.ts.map +1 -1
  397. package/dist/webui-server/kanban-host-adapter.d.ts +9 -5
  398. package/dist/webui-server/kanban-host-adapter.d.ts.map +1 -1
  399. package/dist/webui-server/listen-helpers.d.ts +18 -0
  400. package/dist/webui-server/listen-helpers.d.ts.map +1 -0
  401. package/dist/webui-server/node-pty-loader.d.ts +6 -0
  402. package/dist/webui-server/node-pty-loader.d.ts.map +1 -0
  403. package/dist/webui-server/prefs-seeding.d.ts.map +1 -1
  404. package/dist/webui-server/terminal-log-view.d.ts +30 -0
  405. package/dist/webui-server/terminal-log-view.d.ts.map +1 -0
  406. package/dist/webui-server-G3TISUIY.js +1459 -0
  407. package/dist/webui-server-G3TISUIY.js.map +7 -0
  408. package/dist/webui-server-options.d.ts +189 -0
  409. package/dist/webui-server-options.d.ts.map +1 -0
  410. package/dist/webui-server.d.ts +2 -178
  411. package/dist/webui-server.d.ts.map +1 -1
  412. package/dist/wiring/brain-and-orchestration.d.ts +2 -2
  413. package/dist/wiring/brain-and-orchestration.d.ts.map +1 -1
  414. package/dist/wiring/codebase-index.d.ts.map +1 -1
  415. package/dist/wiring/command-host-adapters.d.ts +2 -2
  416. package/dist/wiring/command-host-adapters.d.ts.map +1 -1
  417. package/dist/wiring/command-host-state.d.ts +7 -7
  418. package/dist/wiring/command-host-state.d.ts.map +1 -1
  419. package/dist/wiring/dep-watcher-bridge.d.ts +23 -0
  420. package/dist/wiring/dep-watcher-bridge.d.ts.map +1 -0
  421. package/dist/wiring/dep-watcher.d.ts +1 -1
  422. package/dist/wiring/dep-watcher.d.ts.map +1 -1
  423. package/dist/wiring/director-setup.d.ts +4 -4
  424. package/dist/wiring/director-setup.d.ts.map +1 -1
  425. package/dist/wiring/eternal-command-handlers.d.ts +5 -5
  426. package/dist/wiring/eternal-command-handlers.d.ts.map +1 -1
  427. package/dist/wiring/fleet-command-handlers.d.ts +2 -2
  428. package/dist/wiring/fleet-command-handlers.d.ts.map +1 -1
  429. package/dist/wiring/hq-telemetry.d.ts +5 -5
  430. package/dist/wiring/hq-telemetry.d.ts.map +1 -1
  431. package/dist/wiring/lifecycle-plugins.d.ts +9 -8
  432. package/dist/wiring/lifecycle-plugins.d.ts.map +1 -1
  433. package/dist/wiring/mailbox-bridge-bootstrap.d.ts +1 -1
  434. package/dist/wiring/management-tools.d.ts +15 -0
  435. package/dist/wiring/management-tools.d.ts.map +1 -0
  436. package/dist/wiring/pipeline.d.ts +4 -3
  437. package/dist/wiring/pipeline.d.ts.map +1 -1
  438. package/dist/wiring/plugins.d.ts +1 -1
  439. package/dist/wiring/plugins.d.ts.map +1 -1
  440. package/dist/wiring/provider-runtime-setup.d.ts +18 -5
  441. package/dist/wiring/provider-runtime-setup.d.ts.map +1 -1
  442. package/dist/wiring/provider-status.d.ts +3 -3
  443. package/dist/wiring/provider-status.d.ts.map +1 -1
  444. package/dist/wiring/provider-utility-tools.d.ts +4 -4
  445. package/dist/wiring/provider-utility-tools.d.ts.map +1 -1
  446. package/dist/wiring/provider.d.ts.map +1 -1
  447. package/dist/wiring/replay.d.ts +2 -2
  448. package/dist/wiring/replay.d.ts.map +1 -1
  449. package/dist/wiring/runtime-controller-deps.d.ts +4 -4
  450. package/dist/wiring/runtime-controller-deps.d.ts.map +1 -1
  451. package/dist/wiring/runtime-dispatch-state.d.ts +5 -5
  452. package/dist/wiring/runtime-dispatch-state.d.ts.map +1 -1
  453. package/dist/wiring/runtime-picker-deps.d.ts +3 -3
  454. package/dist/wiring/runtime-picker-deps.d.ts.map +1 -1
  455. package/dist/wiring/sage.d.ts.map +1 -1
  456. package/dist/wiring/sdd-handlers.d.ts.map +1 -1
  457. package/dist/wiring/session-command-handlers.d.ts +5 -5
  458. package/dist/wiring/session-command-handlers.d.ts.map +1 -1
  459. package/dist/wiring/session-registry.d.ts +38 -0
  460. package/dist/wiring/session-registry.d.ts.map +1 -0
  461. package/dist/wiring/session.d.ts +7 -5
  462. package/dist/wiring/session.d.ts.map +1 -1
  463. package/dist/wiring/tools.d.ts +2 -2
  464. package/dist/wiring/tools.d.ts.map +1 -1
  465. package/package.json +22 -22
  466. package/dist/cli-recovery-prompt.d.ts +0 -19
  467. package/dist/cli-recovery-prompt.d.ts.map +0 -1
  468. package/dist/first-run-auth-gate.d.ts +0 -20
  469. package/dist/first-run-auth-gate.d.ts.map +0 -1
  470. package/dist/pre-launch/indexing-question.d.ts +0 -28
  471. package/dist/pre-launch/indexing-question.d.ts.map +0 -1
@@ -0,0 +1,418 @@
1
+ import {
2
+ loadManifest
3
+ } from "./chunk-JUHRI6OV.js";
4
+
5
+ // src/project-picker.ts
6
+ import { color } from "@wrongstack/core/utils";
7
+ var CSI = "\x1B[";
8
+ var CURSOR_HIDE = `${CSI}?25l`;
9
+ var CURSOR_SHOW = `${CSI}?25h`;
10
+ var CLEAR_SCREEN = `${CSI}2J`;
11
+ var CURSOR_HOME = `${CSI}H`;
12
+ var ARROW_UP = "\x1B[A";
13
+ var ARROW_DOWN = "\x1B[B";
14
+ var ARROW_UP_ALT = "\x1BOA";
15
+ var ARROW_DOWN_ALT = "\x1BOB";
16
+ var PAGE_UP = "\x1B[5~";
17
+ var PAGE_DOWN = "\x1B[6~";
18
+ var ENTER = "\r";
19
+ var CTRL_C = "";
20
+ var ESC = "\x1B";
21
+ var BS = "\x7F";
22
+ function fmtLastSeen(iso) {
23
+ if (!iso) return "never";
24
+ const diff = Date.now() - new Date(iso).getTime();
25
+ const min = Math.floor(diff / 6e4);
26
+ if (min < 1) return "just now";
27
+ if (min < 60) return `${min}m ago`;
28
+ const hours = Math.floor(min / 60);
29
+ if (hours < 24) return `${hours}h ago`;
30
+ const days = Math.floor(hours / 24);
31
+ if (days === 1) return "yesterday";
32
+ if (days < 30) return `${days}d ago`;
33
+ if (days < 365) return `${Math.floor(days / 30)}mo ago`;
34
+ return `${Math.floor(days / 365)}y ago`;
35
+ }
36
+ function terminalHeight() {
37
+ return process.stdout.rows || 24;
38
+ }
39
+ async function buildPickerItems(opts) {
40
+ const manifest = await loadManifest(opts.globalConfigPath);
41
+ const sorted = [...manifest.projects].sort((a, b) => {
42
+ if (a.lastSeen && b.lastSeen) {
43
+ const cmp = b.lastSeen.localeCompare(a.lastSeen);
44
+ return cmp !== 0 ? cmp : a.name.localeCompare(b.name);
45
+ }
46
+ if (a.lastSeen) return -1;
47
+ if (b.lastSeen) return 1;
48
+ return a.name.localeCompare(b.name);
49
+ });
50
+ const items = [];
51
+ for (const p of sorted) {
52
+ const isCurrent = p.root === opts.currentProjectRoot;
53
+ const marker = isCurrent ? "\u25CF" : " ";
54
+ items.push({
55
+ key: p.slug,
56
+ label: `${marker} ${p.name}`,
57
+ subtitle: p.root,
58
+ meta: fmtLastSeen(p.lastSeen),
59
+ kind: "project"
60
+ });
61
+ }
62
+ items.push(
63
+ { key: "__divider__", label: "\u2500".repeat(32), kind: "action" },
64
+ { key: "new-session", label: "+ Start new session", kind: "action", meta: "current project" },
65
+ { key: "prev-sessions", label: "\u23F1 Previous sessions", kind: "action", meta: "resume" },
66
+ { key: "quit", label: "q Quit", kind: "action" }
67
+ );
68
+ return items;
69
+ }
70
+ function renderPickerFrame(items, selectedIdx, scrollOffset, visibleHeight, title, filter, out) {
71
+ const width = out.columns || 80;
72
+ const pad = " ".repeat(2);
73
+ out.write(CLEAR_SCREEN);
74
+ out.write(CURSOR_HOME);
75
+ out.write(`
76
+ ${pad}${color.bold(color.amber(title))}
77
+ `);
78
+ if (filter.length > 0) {
79
+ out.write(`${pad}${color.cyan("Filter:")} ${filter}${color.dim("\u2588")}
80
+ `);
81
+ const divider = color.dim("\u2500".repeat(Math.min(width - 4, 60)));
82
+ out.write(`${pad}${divider}
83
+ `);
84
+ } else {
85
+ const divider = color.dim("\u2500".repeat(Math.min(width - 4, 60)));
86
+ out.write(`${pad}${divider}
87
+ `);
88
+ }
89
+ if (items.length === 0) {
90
+ if (filter.length > 0) {
91
+ out.write(`
92
+ ${pad}${color.dim("No projects match your filter.")}
93
+ `);
94
+ out.write(`${pad}${color.dim("Press ESC to clear filter, or backspace to refine.")}
95
+ `);
96
+ } else {
97
+ out.write(`
98
+ ${pad}${color.dim("No projects registered.")}
99
+ `);
100
+ out.write(`${pad}${color.dim("Use /project add <path> to register one.")}
101
+ `);
102
+ }
103
+ return;
104
+ }
105
+ const filterOverhead = filter.length > 0 ? 2 : 0;
106
+ const effectiveVisible = Math.max(3, visibleHeight - filterOverhead);
107
+ const maxIdx = Math.min(items.length, scrollOffset + effectiveVisible);
108
+ for (let i = scrollOffset; i < maxIdx; i++) {
109
+ const item = items[i];
110
+ if (!item) continue;
111
+ const isSelected = i === selectedIdx;
112
+ const prefix = isSelected ? color.bold(color.cyan(" \u25B8 ")) : " ";
113
+ if (item.key === "__divider__") {
114
+ out.write(`
115
+ ${pad}${color.dim(item.label)}
116
+ `);
117
+ continue;
118
+ }
119
+ const labelText = isSelected ? color.bold(item.label) : item.label;
120
+ const metaText = item.meta ? color.dim(` ${item.meta}`) : "";
121
+ let sub = "";
122
+ if (item.subtitle) {
123
+ const maxSub = width - 10;
124
+ const truncated = item.subtitle.length > maxSub ? `\u2026${item.subtitle.slice(item.subtitle.length - maxSub + 1)}` : item.subtitle;
125
+ sub = `
126
+ ${pad} ${color.dim(truncated)}`;
127
+ }
128
+ const line = `${prefix} ${labelText}${metaText}`;
129
+ out.write(`${line}${sub}
130
+ `);
131
+ }
132
+ if (items.length > effectiveVisible) {
133
+ const pct = Math.round(scrollOffset / Math.max(1, items.length - effectiveVisible) * 100);
134
+ out.write(
135
+ `
136
+ ${pad}${color.dim(`\u2191 ${scrollOffset + 1}-${Math.min(scrollOffset + effectiveVisible, items.length)} of ${items.length} (${pct}%) \u2193`)}
137
+ `
138
+ );
139
+ }
140
+ if (filter.length > 0) {
141
+ out.write(
142
+ `
143
+ ${pad}${color.dim("type to filter \u2191\u2193 navigate \u21B5 select ESC clear Ctrl+C quit")}
144
+ `
145
+ );
146
+ } else {
147
+ out.write(
148
+ `
149
+ ${pad}${color.dim("type to filter \u2191\u2193 navigate PgUp PgDn page \u21B5 select q quit")}
150
+ `
151
+ );
152
+ }
153
+ }
154
+ function filterItems(allItems, filter) {
155
+ if (filter.length === 0) return allItems;
156
+ const lower = filter.toLowerCase();
157
+ const projectItems = allItems.filter((item) => {
158
+ if (item.kind !== "project") return true;
159
+ const labelMatch = item.label.toLowerCase().includes(lower);
160
+ const subMatch = item.subtitle?.toLowerCase().includes(lower);
161
+ return labelMatch || subMatch;
162
+ });
163
+ return projectItems;
164
+ }
165
+ function effectiveVisibleHeight(baseVisibleHeight, filter) {
166
+ const overhead = filter.length > 0 ? 2 : 0;
167
+ return Math.max(3, baseVisibleHeight - overhead);
168
+ }
169
+ function skipDivider(items, idx, direction) {
170
+ let i = idx;
171
+ while (i >= 0 && i < items.length && items[i]?.key === "__divider__") {
172
+ i += direction;
173
+ }
174
+ return Math.max(0, Math.min(items.length - 1, i));
175
+ }
176
+ async function runProjectPicker(opts) {
177
+ const stdin = process.stdin;
178
+ const out = process.stdout;
179
+ if (!stdin.isTTY || !out.isTTY) {
180
+ return void 0;
181
+ }
182
+ const allItems = await buildPickerItems(opts);
183
+ if (allItems.length === 0) return void 0;
184
+ const title = "Project Switch";
185
+ const reservedTop = 4;
186
+ const reservedBottom = 3;
187
+ const headerHeight = reservedTop + reservedBottom;
188
+ const baseVisibleHeight = Math.max(5, terminalHeight() - headerHeight);
189
+ return new Promise((resolve) => {
190
+ const wasRaw = stdin.isRaw;
191
+ const wasPaused = stdin.isPaused();
192
+ let filter = "";
193
+ let displayItems = allItems;
194
+ let selectedIdx = 0;
195
+ let scrollOffset = 0;
196
+ let buf = "";
197
+ const visibleHeight = () => effectiveVisibleHeight(baseVisibleHeight, filter);
198
+ const render = () => {
199
+ renderPickerFrame(
200
+ displayItems,
201
+ selectedIdx,
202
+ scrollOffset,
203
+ visibleHeight(),
204
+ title,
205
+ filter,
206
+ out
207
+ );
208
+ };
209
+ const applyFilter = (newFilter) => {
210
+ filter = newFilter;
211
+ displayItems = filterItems(allItems, filter);
212
+ selectedIdx = 0;
213
+ scrollOffset = 0;
214
+ if (displayItems[0]?.key === "__divider__") {
215
+ selectedIdx = skipDivider(displayItems, selectedIdx, 1);
216
+ }
217
+ };
218
+ const navigateDown = () => {
219
+ if (selectedIdx < displayItems.length - 1) {
220
+ selectedIdx = skipDivider(displayItems, selectedIdx + 1, 1);
221
+ }
222
+ const vh = visibleHeight();
223
+ if (selectedIdx >= scrollOffset + vh) {
224
+ scrollOffset = selectedIdx - vh + 1;
225
+ }
226
+ };
227
+ const navigateUp = () => {
228
+ if (selectedIdx > 0) {
229
+ selectedIdx = skipDivider(displayItems, selectedIdx - 1, -1);
230
+ }
231
+ if (selectedIdx < scrollOffset) {
232
+ scrollOffset = selectedIdx;
233
+ }
234
+ };
235
+ const pageUp = () => {
236
+ const pageSize = Math.max(1, visibleHeight() - 1);
237
+ const target = selectedIdx - pageSize;
238
+ selectedIdx = Math.max(0, target);
239
+ selectedIdx = skipDivider(displayItems, selectedIdx, -1);
240
+ if (selectedIdx < scrollOffset) {
241
+ scrollOffset = Math.max(0, selectedIdx - 1);
242
+ }
243
+ };
244
+ const pageDown = () => {
245
+ const pageSize = Math.max(1, visibleHeight() - 1);
246
+ const target = selectedIdx + pageSize;
247
+ selectedIdx = Math.min(displayItems.length - 1, target);
248
+ selectedIdx = skipDivider(displayItems, selectedIdx, 1);
249
+ const vh = visibleHeight();
250
+ if (selectedIdx >= scrollOffset + vh) {
251
+ scrollOffset = Math.min(displayItems.length - vh, selectedIdx - vh + 1);
252
+ if (scrollOffset < 0) scrollOffset = 0;
253
+ }
254
+ };
255
+ const cleanup = () => {
256
+ stdin.off("data", onData);
257
+ if (wasRaw) {
258
+ try {
259
+ stdin.setRawMode(wasRaw);
260
+ } catch {
261
+ }
262
+ }
263
+ if (wasPaused) stdin.pause();
264
+ out.write(CURSOR_SHOW);
265
+ };
266
+ const isPrintable = (ch) => {
267
+ if (ch.length !== 1) return false;
268
+ const code = ch.charCodeAt(0);
269
+ return code >= 32 && code < 127;
270
+ };
271
+ const onData = (chunk) => {
272
+ const str = chunk.toString();
273
+ buf += str;
274
+ if (buf.startsWith(ESC) && buf.length >= 3) {
275
+ if (buf.length >= 4) {
276
+ if (buf === PAGE_UP) {
277
+ buf = "";
278
+ pageUp();
279
+ render();
280
+ return;
281
+ }
282
+ if (buf === PAGE_DOWN) {
283
+ buf = "";
284
+ pageDown();
285
+ render();
286
+ return;
287
+ }
288
+ }
289
+ if (buf.length === 3) {
290
+ if (buf === ARROW_UP || buf === ARROW_UP_ALT) {
291
+ buf = "";
292
+ navigateUp();
293
+ render();
294
+ return;
295
+ }
296
+ if (buf === ARROW_DOWN || buf === ARROW_DOWN_ALT) {
297
+ buf = "";
298
+ navigateDown();
299
+ render();
300
+ return;
301
+ }
302
+ }
303
+ if (buf.length < 4) return;
304
+ buf = "";
305
+ return;
306
+ }
307
+ if (buf.length === 1) {
308
+ const ch = buf;
309
+ if (ch === CTRL_C) {
310
+ cleanup();
311
+ out.write(CURSOR_SHOW);
312
+ out.write("\n");
313
+ resolve(void 0);
314
+ return;
315
+ }
316
+ if (ch === ESC) {
317
+ if (filter.length > 0) {
318
+ applyFilter("");
319
+ buf = "";
320
+ render();
321
+ return;
322
+ }
323
+ cleanup();
324
+ out.write(CURSOR_SHOW);
325
+ out.write("\n");
326
+ resolve(void 0);
327
+ return;
328
+ }
329
+ if (ch === BS || ch === "\b") {
330
+ if (filter.length > 0) {
331
+ applyFilter(filter.slice(0, -1));
332
+ }
333
+ buf = "";
334
+ render();
335
+ return;
336
+ }
337
+ if (ch === ENTER) {
338
+ const item = displayItems[selectedIdx];
339
+ cleanup();
340
+ out.write(CURSOR_SHOW);
341
+ out.write("\n");
342
+ if (!item || item.key === "__divider__") {
343
+ resolve(void 0);
344
+ return;
345
+ }
346
+ if (item.key === "quit") {
347
+ resolve(void 0);
348
+ return;
349
+ }
350
+ if (item.key === "new-session") {
351
+ resolve({ kind: "action", key: "new-session", action: "new-session" });
352
+ return;
353
+ }
354
+ if (item.key === "prev-sessions") {
355
+ resolve({ kind: "action", key: "prev-sessions", action: "prev-sessions" });
356
+ return;
357
+ }
358
+ resolve({ kind: "project", key: item.key });
359
+ return;
360
+ }
361
+ if (filter.length === 0) {
362
+ if (ch === "q" || ch === "Q") {
363
+ cleanup();
364
+ out.write(CURSOR_SHOW);
365
+ out.write("\n");
366
+ resolve(void 0);
367
+ return;
368
+ }
369
+ if (ch === "j") {
370
+ buf = "";
371
+ navigateDown();
372
+ render();
373
+ return;
374
+ }
375
+ if (ch === "k") {
376
+ buf = "";
377
+ navigateUp();
378
+ render();
379
+ return;
380
+ }
381
+ }
382
+ if (isPrintable(ch)) {
383
+ applyFilter(filter + ch);
384
+ buf = "";
385
+ render();
386
+ return;
387
+ }
388
+ buf = "";
389
+ return;
390
+ }
391
+ };
392
+ try {
393
+ stdin.setRawMode(true);
394
+ } catch {
395
+ resolve(void 0);
396
+ return;
397
+ }
398
+ stdin.resume();
399
+ out.write(CURSOR_HIDE);
400
+ selectedIdx = skipDivider(displayItems, 0, 1);
401
+ render();
402
+ stdin.on("data", onData);
403
+ stdin.once("close", () => {
404
+ cleanup();
405
+ out.write(CURSOR_SHOW);
406
+ resolve(void 0);
407
+ });
408
+ });
409
+ }
410
+
411
+ export {
412
+ buildPickerItems,
413
+ filterItems,
414
+ effectiveVisibleHeight,
415
+ skipDivider,
416
+ runProjectPicker
417
+ };
418
+ //# sourceMappingURL=chunk-5N34EWJR.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/project-picker.ts"],
4
+ "sourcesContent": ["/**\n * Interactive project picker for the CLI.\n *\n * Renders an arrow-navigable, scrollable menu listing known projects,\n * plus actions like \"Start new session\" and \"Previous sessions\".\n * Uses raw terminal input to capture arrow keys and Enter.\n *\n * @module project-picker\n */\nimport { color } from '@wrongstack/core/utils';\nimport type { ProjectEntry } from './services/project-manifest.js';\nimport { loadManifest } from './services/project-manifest.js';\n\n// \u2500\u2500 ANSI constants \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nconst CSI = '\\x1b[';\nconst CURSOR_HIDE = `${CSI}?25l`;\nconst CURSOR_SHOW = `${CSI}?25h`;\nconst CLEAR_SCREEN = `${CSI}2J`;\nconst CURSOR_HOME = `${CSI}H`;\n\nconst ARROW_UP = '\\x1b[A';\nconst ARROW_DOWN = '\\x1b[B';\nconst ARROW_UP_ALT = '\\x1bOA';\nconst ARROW_DOWN_ALT = '\\x1bOB';\nconst PAGE_UP = '\\x1b[5~';\nconst PAGE_DOWN = '\\x1b[6~';\nconst ENTER = '\\r';\nconst CTRL_C = '\\x03';\nconst ESC = '\\x1b';\nconst BS = '\\x7f';\n\n// \u2500\u2500 Types \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport interface PickerItem {\n key: string; // unique identifier\n label: string; // primary display line\n subtitle?: string | undefined; // secondary dim line (e.g. path)\n meta?: string | undefined; // right-aligned info (e.g. \"yesterday\")\n kind: 'project' | 'action';\n}\n\nexport interface PickerConfig {\n title: string;\n items: PickerItem[];\n globalConfigPath?: string | undefined;\n}\n\nexport interface PickerResult {\n kind: 'project' | 'action';\n key: string;\n /** Resolved project entry (only set when kind === 'project') */\n project?: ProjectEntry | undefined;\n /** Action identifier: 'new-session', 'prev-sessions', 'quit' */\n action?: 'new-session' | 'prev-sessions' | 'quit' | undefined;\n}\n\n// \u2500\u2500 Helpers \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nfunction fmtLastSeen(iso: string | undefined): string {\n if (!iso) return 'never';\n const diff = Date.now() - new Date(iso).getTime();\n const min = Math.floor(diff / 60000);\n if (min < 1) return 'just now';\n if (min < 60) return `${min}m ago`;\n const hours = Math.floor(min / 60);\n if (hours < 24) return `${hours}h ago`;\n const days = Math.floor(hours / 24);\n if (days === 1) return 'yesterday';\n if (days < 30) return `${days}d ago`;\n if (days < 365) return `${Math.floor(days / 30)}mo ago`;\n return `${Math.floor(days / 365)}y ago`;\n}\n\n/**\n * Get the terminal height, defaulting to 24 if it can't be determined.\n */\nfunction terminalHeight(): number {\n return process.stdout.rows || 24;\n}\n\n/**\n * Build the picker items from the projects manifest plus built-in actions.\n */\nexport async function buildPickerItems(opts: {\n globalConfigPath?: string | undefined;\n currentProjectRoot?: string | undefined;\n}): Promise<PickerItem[]> {\n const manifest = await loadManifest(opts.globalConfigPath);\n const sorted = [...manifest.projects].sort((a, b) => {\n if (a.lastSeen && b.lastSeen) {\n const cmp = b.lastSeen.localeCompare(a.lastSeen);\n return cmp !== 0 ? cmp : a.name.localeCompare(b.name);\n }\n if (a.lastSeen) return -1;\n if (b.lastSeen) return 1;\n return a.name.localeCompare(b.name);\n });\n\n const items: PickerItem[] = [];\n\n for (const p of sorted) {\n const isCurrent = p.root === opts.currentProjectRoot;\n const marker = isCurrent ? '\u25CF' : ' ';\n items.push({\n key: p.slug,\n label: `${marker} ${p.name}`,\n subtitle: p.root,\n meta: fmtLastSeen(p.lastSeen),\n kind: 'project',\n });\n }\n\n // Divider + action items\n items.push(\n { key: '__divider__', label: '\u2500'.repeat(32), kind: 'action' },\n { key: 'new-session', label: '+ Start new session', kind: 'action', meta: 'current project' },\n { key: 'prev-sessions', label: '\u23F1 Previous sessions', kind: 'action', meta: 'resume' },\n { key: 'quit', label: 'q Quit', kind: 'action' },\n );\n\n return items;\n}\n\n// \u2500\u2500 Rendering \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nfunction renderPickerFrame(\n items: PickerItem[],\n selectedIdx: number,\n scrollOffset: number,\n visibleHeight: number,\n title: string,\n filter: string,\n out: NodeJS.WriteStream,\n): void {\n const width = out.columns || 80;\n const pad = ' '.repeat(2);\n\n // Clear screen and move home\n out.write(CLEAR_SCREEN);\n out.write(CURSOR_HOME);\n\n // Title\n out.write(`\\n${pad}${color.bold(color.amber(title))}\\n`);\n\n // Search/filter bar \u2014 always visible when filter is non-empty\n if (filter.length > 0) {\n out.write(`${pad}${color.cyan('Filter:')} ${filter}${color.dim('\u2588')}\\n`);\n // Divider after filter bar\n const divider = color.dim('\u2500'.repeat(Math.min(width - 4, 60)));\n out.write(`${pad}${divider}\\n`);\n } else {\n // Normal divider\n const divider = color.dim('\u2500'.repeat(Math.min(width - 4, 60)));\n out.write(`${pad}${divider}\\n`);\n }\n\n // Empty state\n if (items.length === 0) {\n if (filter.length > 0) {\n out.write(`\\n${pad}${color.dim('No projects match your filter.')}\\n`);\n out.write(`${pad}${color.dim('Press ESC to clear filter, or backspace to refine.')}\\n`);\n } else {\n out.write(`\\n${pad}${color.dim('No projects registered.')}\\n`);\n out.write(`${pad}${color.dim('Use /project add <path> to register one.')}\\n`);\n }\n return;\n }\n\n // Adjust visible height: filter bar adds 2 lines (filter line + divider)\n const filterOverhead = filter.length > 0 ? 2 : 0;\n const effectiveVisible = Math.max(3, visibleHeight - filterOverhead);\n const maxIdx = Math.min(items.length, scrollOffset + effectiveVisible);\n\n for (let i = scrollOffset; i < maxIdx; i++) {\n const item = items[i];\n if (!item) continue;\n\n const isSelected = i === selectedIdx;\n const prefix = isSelected ? color.bold(color.cyan(' \u25B8 ')) : ' ';\n\n if (item.key === '__divider__') {\n out.write(`\\n${pad}${color.dim(item.label)}\\n`);\n continue;\n }\n\n // Build the line: [marker] label \u2026 meta\n const labelText = isSelected ? color.bold(item.label) : item.label;\n const metaText = item.meta ? color.dim(` ${item.meta}`) : '';\n\n // Truncate subtitle if too long\n let sub = '';\n if (item.subtitle) {\n const maxSub = width - 10;\n const truncated =\n item.subtitle.length > maxSub\n ? `\u2026${item.subtitle.slice(item.subtitle.length - maxSub + 1)}`\n : item.subtitle;\n sub = `\\n${pad} ${color.dim(truncated)}`;\n }\n\n const line = `${prefix} ${labelText}${metaText}`;\n out.write(`${line}${sub}\\n`);\n }\n\n // Scroll indicator\n if (items.length > effectiveVisible) {\n const pct = Math.round((scrollOffset / Math.max(1, items.length - effectiveVisible)) * 100);\n out.write(\n `\\n${pad}${color.dim(`\u2191 ${scrollOffset + 1}-${Math.min(scrollOffset + effectiveVisible, items.length)} of ${items.length} (${pct}%) \u2193`)}\\n`,\n );\n }\n\n // Footer hint \u2014 context-sensitive\n if (filter.length > 0) {\n out.write(\n `\\n${pad}${color.dim('type to filter \u2191\u2193 navigate \u21B5 select ESC clear Ctrl+C quit')}\\n`,\n );\n } else {\n out.write(\n `\\n${pad}${color.dim('type to filter \u2191\u2193 navigate PgUp PgDn page \u21B5 select q quit')}\\n`,\n );\n }\n}\n\n/**\n * Filter items by a case-insensitive substring match against label and subtitle.\n * Only project items are filtered; action items and dividers always appear.\n *\n * @public \u2014 exported for testing\n */\nexport function filterItems(allItems: PickerItem[], filter: string): PickerItem[] {\n if (filter.length === 0) return allItems;\n\n const lower = filter.toLowerCase();\n const projectItems = allItems.filter((item) => {\n if (item.kind !== 'project') return true; // actions/dividers pass through\n const labelMatch = item.label.toLowerCase().includes(lower);\n const subMatch = item.subtitle?.toLowerCase().includes(lower);\n return labelMatch || subMatch;\n });\n\n // If filter yields no project results, still show action items + divider\n // So the user can ESC clear or quit\n return projectItems;\n}\n\n/**\n * Compute the effective visible height accounting for the filter bar overhead.\n *\n * @public \u2014 exported for testing\n */\nexport function effectiveVisibleHeight(baseVisibleHeight: number, filter: string): number {\n const overhead = filter.length > 0 ? 2 : 0; // filter bar + its divider\n return Math.max(3, baseVisibleHeight - overhead);\n}\n\n/**\n * Skip divider items at the given index, moving forward or backward.\n * Returns the adjusted index, clamped to bounds.\n *\n * @public \u2014 exported for testing\n */\nexport function skipDivider(items: PickerItem[], idx: number, direction: -1 | 1): number {\n let i = idx;\n while (i >= 0 && i < items.length && items[i]?.key === '__divider__') {\n i += direction;\n }\n return Math.max(0, Math.min(items.length - 1, i));\n}\n\n/**\n * Run the interactive project picker. Returns the selection or undefined on cancel.\n */\nexport async function runProjectPicker(opts: {\n globalConfigPath?: string | undefined;\n currentProjectRoot?: string | undefined;\n}): Promise<PickerResult | undefined> {\n const stdin = process.stdin;\n const out = process.stdout;\n\n if (!stdin.isTTY || !out.isTTY) {\n // Non-TTY fallback: return undefined (caller should provide a usable message)\n return undefined;\n }\n\n const allItems = await buildPickerItems(opts);\n if (allItems.length === 0) return undefined;\n\n const title = 'Project Switch';\n const reservedTop = 4; // title + divider + padding\n const reservedBottom = 3; // scroll indicator + footer\n const headerHeight = reservedTop + reservedBottom;\n const baseVisibleHeight = Math.max(5, terminalHeight() - headerHeight);\n\n return new Promise<PickerResult | undefined>((resolve) => {\n const wasRaw = stdin.isRaw;\n const wasPaused = stdin.isPaused();\n let filter = '';\n let displayItems = allItems;\n let selectedIdx = 0;\n let scrollOffset = 0;\n let buf = '';\n\n const visibleHeight = () => effectiveVisibleHeight(baseVisibleHeight, filter);\n\n const render = () => {\n renderPickerFrame(\n displayItems,\n selectedIdx,\n scrollOffset,\n visibleHeight(),\n title,\n filter,\n out,\n );\n };\n\n const applyFilter = (newFilter: string) => {\n filter = newFilter;\n displayItems = filterItems(allItems, filter);\n // Reset position to top\n selectedIdx = 0;\n scrollOffset = 0;\n // Skip divider at position 0\n if (displayItems[0]?.key === '__divider__') {\n selectedIdx = skipDivider(displayItems, selectedIdx, 1);\n }\n };\n\n const navigateDown = () => {\n if (selectedIdx < displayItems.length - 1) {\n selectedIdx = skipDivider(displayItems, selectedIdx + 1, 1);\n }\n const vh = visibleHeight();\n if (selectedIdx >= scrollOffset + vh) {\n scrollOffset = selectedIdx - vh + 1;\n }\n };\n\n const navigateUp = () => {\n if (selectedIdx > 0) {\n selectedIdx = skipDivider(displayItems, selectedIdx - 1, -1);\n }\n if (selectedIdx < scrollOffset) {\n scrollOffset = selectedIdx;\n }\n };\n\n const pageUp = () => {\n const pageSize = Math.max(1, visibleHeight() - 1);\n const target = selectedIdx - pageSize;\n selectedIdx = Math.max(0, target);\n selectedIdx = skipDivider(displayItems, selectedIdx, -1);\n if (selectedIdx < scrollOffset) {\n scrollOffset = Math.max(0, selectedIdx - 1);\n }\n };\n\n const pageDown = () => {\n const pageSize = Math.max(1, visibleHeight() - 1);\n const target = selectedIdx + pageSize;\n selectedIdx = Math.min(displayItems.length - 1, target);\n selectedIdx = skipDivider(displayItems, selectedIdx, 1);\n const vh = visibleHeight();\n if (selectedIdx >= scrollOffset + vh) {\n scrollOffset = Math.min(displayItems.length - vh, selectedIdx - vh + 1);\n if (scrollOffset < 0) scrollOffset = 0;\n }\n };\n\n const cleanup = () => {\n stdin.off('data', onData);\n if (wasRaw) {\n try {\n stdin.setRawMode(wasRaw);\n } catch {\n /* ignore */\n }\n }\n if (wasPaused) stdin.pause();\n out.write(CURSOR_SHOW);\n };\n\n /**\n * Check if a single character is printable (should be added to filter).\n * Excludes control characters (0x00-0x1F) and DEL (0x7F).\n */\n const isPrintable = (ch: string): boolean => {\n if (ch.length !== 1) return false;\n const code = ch.charCodeAt(0);\n return code >= 0x20 && code < 0x7f;\n };\n\n const onData = (chunk: Buffer) => {\n const str = chunk.toString();\n buf += str;\n\n // Escape sequences (ESC + [...])\n if (buf.startsWith(ESC) && buf.length >= 3) {\n // \u2500\u2500 4-byte sequences (PageUp/Down: ESC [ 5/6 ~) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n if (buf.length >= 4) {\n if (buf === PAGE_UP) {\n buf = '';\n pageUp();\n render();\n return;\n }\n if (buf === PAGE_DOWN) {\n buf = '';\n pageDown();\n render();\n return;\n }\n }\n\n // \u2500\u2500 3-byte sequences (arrows: ESC [ A / B / O A / O B) \u2500\u2500\n if (buf.length === 3) {\n if (buf === ARROW_UP || buf === ARROW_UP_ALT) {\n buf = '';\n navigateUp();\n render();\n return;\n }\n if (buf === ARROW_DOWN || buf === ARROW_DOWN_ALT) {\n buf = '';\n navigateDown();\n render();\n return;\n }\n }\n\n // Known lengths but unknown sequence \u2014 let it buffer more\n if (buf.length < 4) return;\n\n // Unknown escape sequence \u2014 clear buffer\n buf = '';\n return;\n }\n\n // Single-byte inputs\n if (buf.length === 1) {\n const ch = buf;\n\n // Ctrl+C \u2014 always quit\n if (ch === CTRL_C) {\n cleanup();\n out.write(CURSOR_SHOW);\n out.write('\\n');\n resolve(undefined);\n return;\n }\n\n // Escape\n if (ch === ESC) {\n if (filter.length > 0) {\n // First ESC clears the filter\n applyFilter('');\n buf = '';\n render();\n return;\n }\n // No filter active \u2014 quit\n cleanup();\n out.write(CURSOR_SHOW);\n out.write('\\n');\n resolve(undefined);\n return;\n }\n\n // Backspace \u2014 remove last char from filter\n if (ch === BS || ch === '\\b') {\n if (filter.length > 0) {\n applyFilter(filter.slice(0, -1));\n }\n buf = '';\n render();\n return;\n }\n\n // Enter/Return\n if (ch === ENTER) {\n const item = displayItems[selectedIdx];\n cleanup();\n out.write(CURSOR_SHOW);\n out.write('\\n');\n\n if (!item || item.key === '__divider__') {\n resolve(undefined);\n return;\n }\n\n if (item.key === 'quit') {\n resolve(undefined);\n return;\n }\n\n if (item.key === 'new-session') {\n resolve({ kind: 'action', key: 'new-session', action: 'new-session' });\n return;\n }\n\n if (item.key === 'prev-sessions') {\n resolve({ kind: 'action', key: 'prev-sessions', action: 'prev-sessions' });\n return;\n }\n\n // Project item\n resolve({ kind: 'project', key: item.key });\n return;\n }\n\n // Special single-char navigation (only when filter is empty)\n if (filter.length === 0) {\n if (ch === 'q' || ch === 'Q') {\n cleanup();\n out.write(CURSOR_SHOW);\n out.write('\\n');\n resolve(undefined);\n return;\n }\n if (ch === 'j') {\n buf = '';\n navigateDown();\n render();\n return;\n }\n if (ch === 'k') {\n buf = '';\n navigateUp();\n render();\n return;\n }\n }\n\n // Printable character \u2192 add to filter\n if (isPrintable(ch)) {\n applyFilter(filter + ch);\n buf = '';\n render();\n return;\n }\n\n buf = '';\n return;\n }\n };\n\n // Setup raw mode\n try {\n stdin.setRawMode(true);\n } catch {\n // Can't set raw mode \u2014 fallback\n resolve(undefined);\n return;\n }\n stdin.resume();\n out.write(CURSOR_HIDE);\n\n // Skip divider items to start on a valid entry\n selectedIdx = skipDivider(displayItems, 0, 1);\n\n // Initial render\n render();\n\n stdin.on('data', onData);\n\n // Handle stdin close (pipe broken, etc.)\n stdin.once('close', () => {\n cleanup();\n out.write(CURSOR_SHOW);\n resolve(undefined);\n });\n });\n}\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -0,0 +1,90 @@
1
+
2
+ // src/provider-helpers.ts
3
+ function uniqueModelIds(primary, fallback) {
4
+ const seen = /* @__PURE__ */ new Set();
5
+ const out = [];
6
+ for (const id of [...primary, ...fallback]) {
7
+ const trimmed = id.trim();
8
+ if (!trimmed || seen.has(trimmed)) continue;
9
+ seen.add(trimmed);
10
+ out.push(trimmed);
11
+ }
12
+ return out;
13
+ }
14
+ function visibleModelIds(providerId, config, catalogModelIds, cfg) {
15
+ const entry = cfg ?? config.providers?.[providerId];
16
+ if (entry?.models === void 0) return [...catalogModelIds];
17
+ return uniqueModelIds(entry.models, catalogModelIds);
18
+ }
19
+ function isLoopbackUrl(apiBase) {
20
+ if (!apiBase) return false;
21
+ let host;
22
+ try {
23
+ host = new URL(apiBase).hostname.toLowerCase();
24
+ } catch {
25
+ return false;
26
+ }
27
+ host = host.replace(/^\[|\]$/g, "");
28
+ if (host === "localhost" || host === "::1" || host === "0.0.0.0") return true;
29
+ return /^127\.\d{1,3}\.\d{1,3}\.\d{1,3}$/.test(host);
30
+ }
31
+ function isKeylessLocalProvider(provider) {
32
+ if (provider.envVars && provider.envVars.length > 0) return false;
33
+ return isLoopbackUrl(provider.apiBase);
34
+ }
35
+ function hasApiKey(provider, config) {
36
+ if (provider.envVars.some((v) => !!process.env[v])) return true;
37
+ const entry = config?.providers?.[provider.id];
38
+ if (!entry) return false;
39
+ if (typeof entry.apiKey === "string" && entry.apiKey.length > 0) return true;
40
+ if (Array.isArray(entry.apiKeys) && entry.apiKeys.some((k) => k?.apiKey)) return true;
41
+ return false;
42
+ }
43
+ async function buildPickableProviders(modelsRegistry, config) {
44
+ const overlay = config.providers ?? {};
45
+ let catalog = [];
46
+ try {
47
+ catalog = await modelsRegistry.listProviders();
48
+ } catch {
49
+ }
50
+ const catalogById = new Map(catalog.map((p) => [p.id, p]));
51
+ const isSelectable = (id) => {
52
+ const entry = overlay[id];
53
+ const catalogEntry = catalogById.get(id);
54
+ const envHit = catalogEntry?.envVars.some((v) => !!process.env[v]);
55
+ if (envHit) return true;
56
+ if (typeof entry?.apiKey === "string" && entry.apiKey.length > 0) return true;
57
+ if (Array.isArray(entry?.apiKeys) && entry.apiKeys.some((k) => k?.apiKey)) return true;
58
+ return isKeylessLocalProvider({
59
+ apiBase: entry?.baseUrl ?? catalogEntry?.apiBase,
60
+ envVars: entry?.envVars ?? catalogEntry?.envVars
61
+ });
62
+ };
63
+ const seen = /* @__PURE__ */ new Set();
64
+ const out = [];
65
+ for (const [id, cfg] of Object.entries(overlay)) {
66
+ if (!isSelectable(id)) continue;
67
+ seen.add(id);
68
+ const catalogType = cfg.type && cfg.type !== id ? cfg.type : id;
69
+ const inherited = catalogById.get(catalogType);
70
+ const family = cfg.family ?? inherited?.family ?? "unsupported";
71
+ if (family === "unsupported") continue;
72
+ const models = visibleModelIds(id, config, (inherited?.models ?? []).map((m) => m.id), cfg);
73
+ out.push({ id, family, models });
74
+ }
75
+ for (const p of catalog) {
76
+ if (seen.has(p.id)) continue;
77
+ if (p.family === "unsupported") continue;
78
+ if (!isSelectable(p.id)) continue;
79
+ out.push({ id: p.id, family: p.family, models: p.models.map((m) => m.id) });
80
+ }
81
+ return out;
82
+ }
83
+
84
+ export {
85
+ visibleModelIds,
86
+ isKeylessLocalProvider,
87
+ hasApiKey,
88
+ buildPickableProviders
89
+ };
90
+ //# sourceMappingURL=chunk-66T43Q4Y.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/provider-helpers.ts"],
4
+ "sourcesContent": ["/**\n * Shared provider-config helpers used by the picker, main boot sequence,\n * and subcommands. Keeps provider key detection and alias resolution in\n * one place so the logic doesn't drift between call sites.\n */\nimport type { Config, ModelsRegistry, ProviderConfig, ResolvedProvider } from '@wrongstack/core/types';\n\n// (Removed) CATALOG_REFRESHABLE_MODEL_PROVIDERS \u2014 a four-entry hand-list that\n// decided whose models were allowed to come from models.dev. See visibleModelIds.\n\nfunction uniqueModelIds(primary: readonly string[], fallback: readonly string[]): string[] {\n const seen = new Set<string>();\n const out: string[] = [];\n for (const id of [...primary, ...fallback]) {\n const trimmed = id.trim();\n if (!trimmed || seen.has(trimmed)) continue;\n seen.add(trimmed);\n out.push(trimmed);\n }\n return out;\n}\n\n/** Return the provider's visible model ids: models.dev plus anything the saved\n * config names that the catalog does not carry.\n *\n * `cfg.models` is ADDITIVE, never subtractive. It used to be a strict allowlist\n * for every provider except a four-entry hand-list (chatgpt/openai/codex/\n * openai-codex), which had two failure modes that showed up in real configs:\n *\n * - A saved `models: []` \u2014 written by an auth flow that had nothing to cache\n * yet \u2014 pinned the provider to ZERO selectable models forever. A configured\n * GitHub Copilot listed nothing at all.\n * - A preset's hand-maintained list went stale against the catalog and hid\n * real models on the user's own plan: `kimi-for-coding` offered 2 of the 4\n * models models.dev publishes for it, hiding `k3` (131_072 output) behind\n * `kimi-for-coding` (32_768). `alibaba-token-plan` hid 11 of 22.\n *\n * models.dev publishes a dedicated provider entry per subscription plan, so the\n * catalog already describes exactly what a plan includes \u2014 a second,\n * hand-curated copy could only ever drift below it. Narrowing what the user\n * sees is `favoriteModels`' job, not this list's.\n *\n * A model the credential cannot actually serve now surfaces as an error at\n * request time rather than being silently unselectable, which is the better\n * failure: visible and actionable. */\nexport function visibleModelIds(\n providerId: string,\n config: Config,\n catalogModelIds: string[],\n cfg?: ProviderConfig | undefined,\n): string[] {\n const entry = cfg ?? config.providers?.[providerId];\n if (entry?.models === undefined) return [...catalogModelIds];\n return uniqueModelIds(entry.models, catalogModelIds);\n}\n\n/**\n * Is `apiBase` a loopback URL (localhost / 127.0.0.0-8 / ::1 / 0.0.0.0)?\n * Such a host is a server running on the same machine, never a remote API.\n */\nfunction isLoopbackUrl(apiBase: string | undefined): boolean {\n if (!apiBase) return false;\n let host: string;\n try {\n host = new URL(apiBase).hostname.toLowerCase();\n } catch {\n return false;\n }\n // URL keeps the brackets around IPv6 hosts (e.g. \"[::1]\") \u2014 strip them.\n host = host.replace(/^\\[|\\]$/g, '');\n if (host === 'localhost' || host === '::1' || host === '0.0.0.0') return true;\n return /^127\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}$/.test(host);\n}\n\n/**\n * Is this a keyless local gateway \u2014 a server on a loopback address that\n * declares no API-key env vars (omniroute, LiteLLM/vLLM/LM Studio/Ollama\n * running locally, \u2026)? These need no credential, so they belong in the\n * picker even though `hasApiKey` returns false for them. Accepts the\n * minimal shape both call sites can supply.\n */\nexport function isKeylessLocalProvider(provider: {\n apiBase?: string | undefined;\n envVars?: string[] | undefined;\n}): boolean {\n if (provider.envVars && provider.envVars.length > 0) return false;\n return isLoopbackUrl(provider.apiBase);\n}\n\n/**\n * Does this provider have an API key available \u2014 either in the\n * environment (via one of its known env vars) or stored in config\n * (encrypted or plaintext)? Used to filter the picker to providers\n * the user can actually use right now.\n */\nexport function hasApiKey(provider: ResolvedProvider, config?: Config): boolean {\n if (provider.envVars.some((v) => !!process.env[v])) return true;\n const entry = config?.providers?.[provider.id];\n if (!entry) return false;\n if (typeof entry.apiKey === 'string' && entry.apiKey.length > 0) return true;\n if (Array.isArray(entry.apiKeys) && entry.apiKeys.some((k) => k?.apiKey)) return true;\n return false;\n}\n\n/**\n * Build the list of providers the user can switch to mid-session.\n * Only includes providers that have an API key available (env var or\n * stored config). Falls back to the full catalog when no keys are found.\n *\n * Models are inlined from the catalog (or from `cfg.models` for custom\n * entries) so the picker can show a real selection.\n */\nexport async function buildPickableProviders(\n modelsRegistry: ModelsRegistry,\n config: Config,\n): Promise<Array<{ id: string; family: string; models: string[] }>> {\n const overlay = config.providers ?? {};\n let catalog: Awaited<ReturnType<typeof modelsRegistry.listProviders>> = [];\n try {\n catalog = await modelsRegistry.listProviders();\n } catch {\n // catalog unavailable \u2014 keyed-by-config-only path still works\n }\n const catalogById = new Map(catalog.map((p) => [p.id, p]));\n // Selectable when the provider has a usable key OR is a keyless local\n // gateway (omniroute/LiteLLM/\u2026 on a loopback address, which needs no\n // credential). Mirrors `runPicker`'s filter so the `/model` switch and\n // the startup picker agree on what's offered.\n const isSelectable = (id: string): boolean => {\n const entry = overlay[id];\n const catalogEntry = catalogById.get(id);\n const envHit = catalogEntry?.envVars.some((v) => !!process.env[v]);\n if (envHit) return true;\n if (typeof entry?.apiKey === 'string' && entry.apiKey.length > 0) return true;\n if (Array.isArray(entry?.apiKeys) && entry.apiKeys.some((k) => k?.apiKey)) return true;\n return isKeylessLocalProvider({\n apiBase: entry?.baseUrl ?? catalogEntry?.apiBase,\n envVars: entry?.envVars ?? catalogEntry?.envVars,\n });\n };\n const seen = new Set<string>();\n const out: Array<{ id: string; family: string; models: string[] }> = [];\n for (const [id, cfg] of Object.entries(overlay)) {\n if (!isSelectable(id)) continue;\n seen.add(id);\n const catalogType = cfg.type && cfg.type !== id ? cfg.type : id;\n const inherited = catalogById.get(catalogType);\n const family = cfg.family ?? inherited?.family ?? 'unsupported';\n if (family === 'unsupported') continue;\n const models = visibleModelIds(id, config, (inherited?.models ?? []).map((m) => m.id), cfg);\n out.push({ id, family, models });\n }\n for (const p of catalog) {\n if (seen.has(p.id)) continue;\n if (p.family === 'unsupported') continue;\n if (!isSelectable(p.id)) continue;\n out.push({ id: p.id, family: p.family, models: p.models.map((m) => m.id) });\n }\n return out;\n}\n\n/**\n * Resolve a provider id that may be an alias. When the user has\n * `providers[id].type` pointing at a different catalog entry, return\n * the catalog id so downstream lookups still work. Returns the\n * original id unchanged when it's a direct catalog match.\n */\nexport function resolveProviderAlias(providerId: string, config: Config): string {\n const savedAlias = config.providers?.[providerId];\n if (savedAlias?.type && savedAlias.type !== providerId) {\n return savedAlias.type;\n }\n return providerId;\n}\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -0,0 +1,11 @@
1
+ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
2
+ get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
3
+ }) : x)(function(x) {
4
+ if (typeof require !== "undefined") return require.apply(this, arguments);
5
+ throw Error('Dynamic require of "' + x + '" is not supported');
6
+ });
7
+
8
+ export {
9
+ __require
10
+ };
11
+ //# sourceMappingURL=chunk-7OCVIDC7.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": [],
4
+ "sourcesContent": [],
5
+ "mappings": "",
6
+ "names": []
7
+ }