@akiojin/gwt 4.9.1 → 4.11.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 (605) hide show
  1. package/README.ja.md +4 -4
  2. package/README.md +4 -4
  3. package/dist/claude.d.ts +1 -0
  4. package/dist/claude.d.ts.map +1 -1
  5. package/dist/claude.js +52 -49
  6. package/dist/claude.js.map +1 -1
  7. package/dist/cli/ui/App.solid.d.ts +29 -0
  8. package/dist/cli/ui/App.solid.d.ts.map +1 -0
  9. package/dist/cli/ui/App.solid.js +1197 -0
  10. package/dist/cli/ui/App.solid.js.map +1 -0
  11. package/dist/cli/ui/components/solid/Footer.d.ts +10 -0
  12. package/dist/cli/ui/components/solid/Footer.d.ts.map +1 -0
  13. package/dist/cli/ui/components/solid/Footer.js +10 -0
  14. package/dist/cli/ui/components/solid/Footer.js.map +1 -0
  15. package/dist/cli/ui/components/{parts → solid}/Header.d.ts +1 -6
  16. package/dist/cli/ui/components/solid/Header.d.ts.map +1 -0
  17. package/dist/cli/ui/components/solid/Header.js +13 -0
  18. package/dist/cli/ui/components/solid/Header.js.map +1 -0
  19. package/dist/cli/ui/components/solid/HelpOverlay.d.ts +8 -0
  20. package/dist/cli/ui/components/solid/HelpOverlay.d.ts.map +1 -0
  21. package/dist/cli/ui/components/solid/HelpOverlay.js +118 -0
  22. package/dist/cli/ui/components/solid/HelpOverlay.js.map +1 -0
  23. package/dist/cli/ui/components/solid/QuickStartStep.d.ts +17 -0
  24. package/dist/cli/ui/components/solid/QuickStartStep.d.ts.map +1 -0
  25. package/dist/cli/ui/components/solid/QuickStartStep.js +139 -0
  26. package/dist/cli/ui/components/solid/QuickStartStep.js.map +1 -0
  27. package/dist/cli/ui/components/solid/SelectInput.d.ts +22 -0
  28. package/dist/cli/ui/components/solid/SelectInput.d.ts.map +1 -0
  29. package/dist/cli/ui/components/solid/SelectInput.js +44 -0
  30. package/dist/cli/ui/components/solid/SelectInput.js.map +1 -0
  31. package/dist/cli/ui/components/solid/TextInput.d.ts +12 -0
  32. package/dist/cli/ui/components/solid/TextInput.d.ts.map +1 -0
  33. package/dist/cli/ui/components/solid/TextInput.js +9 -0
  34. package/dist/cli/ui/components/solid/TextInput.js.map +1 -0
  35. package/dist/cli/ui/components/solid/WizardController.d.ts +34 -0
  36. package/dist/cli/ui/components/solid/WizardController.d.ts.map +1 -0
  37. package/dist/cli/ui/components/solid/WizardController.js +215 -0
  38. package/dist/cli/ui/components/solid/WizardController.js.map +1 -0
  39. package/dist/cli/ui/components/solid/WizardPopup.d.ts +26 -0
  40. package/dist/cli/ui/components/solid/WizardPopup.d.ts.map +1 -0
  41. package/dist/cli/ui/components/solid/WizardPopup.js +68 -0
  42. package/dist/cli/ui/components/solid/WizardPopup.js.map +1 -0
  43. package/dist/cli/ui/components/solid/WizardSteps.d.ts +52 -0
  44. package/dist/cli/ui/components/solid/WizardSteps.d.ts.map +1 -0
  45. package/dist/cli/ui/components/solid/WizardSteps.js +462 -0
  46. package/dist/cli/ui/components/solid/WizardSteps.js.map +1 -0
  47. package/dist/cli/ui/core/index.d.ts +12 -0
  48. package/dist/cli/ui/core/index.d.ts.map +1 -0
  49. package/dist/cli/ui/core/index.js +15 -0
  50. package/dist/cli/ui/core/index.js.map +1 -0
  51. package/dist/cli/ui/core/keybindings.d.ts +106 -0
  52. package/dist/cli/ui/core/keybindings.d.ts.map +1 -0
  53. package/dist/cli/ui/core/keybindings.js +270 -0
  54. package/dist/cli/ui/core/keybindings.js.map +1 -0
  55. package/dist/cli/ui/core/theme.d.ts +114 -0
  56. package/dist/cli/ui/core/theme.d.ts.map +1 -0
  57. package/dist/cli/ui/core/theme.js +170 -0
  58. package/dist/cli/ui/core/theme.js.map +1 -0
  59. package/dist/cli/ui/core/types.d.ts +156 -0
  60. package/dist/cli/ui/core/types.d.ts.map +1 -0
  61. package/dist/cli/ui/core/types.js +10 -0
  62. package/dist/cli/ui/core/types.js.map +1 -0
  63. package/dist/cli/ui/hooks/solid/useScrollableList.d.ts +26 -0
  64. package/dist/cli/ui/hooks/solid/useScrollableList.d.ts.map +1 -0
  65. package/dist/cli/ui/hooks/solid/useScrollableList.js +89 -0
  66. package/dist/cli/ui/hooks/solid/useScrollableList.js.map +1 -0
  67. package/dist/cli/ui/hooks/solid/useTerminalSize.d.ts +10 -0
  68. package/dist/cli/ui/hooks/solid/useTerminalSize.d.ts.map +1 -0
  69. package/dist/cli/ui/hooks/solid/useTerminalSize.js +16 -0
  70. package/dist/cli/ui/hooks/solid/useTerminalSize.js.map +1 -0
  71. package/dist/cli/ui/index.solid.d.ts +5 -0
  72. package/dist/cli/ui/index.solid.d.ts.map +1 -0
  73. package/dist/cli/ui/index.solid.js +21 -0
  74. package/dist/cli/ui/index.solid.js.map +1 -0
  75. package/dist/cli/ui/{components/screens → screens/solid}/BranchListScreen.d.ts +8 -22
  76. package/dist/cli/ui/screens/solid/BranchListScreen.d.ts.map +1 -0
  77. package/dist/cli/ui/screens/solid/BranchListScreen.js +756 -0
  78. package/dist/cli/ui/screens/solid/BranchListScreen.js.map +1 -0
  79. package/dist/cli/ui/screens/solid/ConfirmScreen.d.ts +10 -0
  80. package/dist/cli/ui/screens/solid/ConfirmScreen.d.ts.map +1 -0
  81. package/dist/cli/ui/screens/solid/ConfirmScreen.js +37 -0
  82. package/dist/cli/ui/screens/solid/ConfirmScreen.js.map +1 -0
  83. package/dist/cli/ui/screens/solid/EnvironmentScreen.d.ts +14 -0
  84. package/dist/cli/ui/screens/solid/EnvironmentScreen.d.ts.map +1 -0
  85. package/dist/cli/ui/screens/solid/EnvironmentScreen.js +91 -0
  86. package/dist/cli/ui/screens/solid/EnvironmentScreen.js.map +1 -0
  87. package/dist/cli/ui/screens/solid/ErrorScreen.d.ts +8 -0
  88. package/dist/cli/ui/screens/solid/ErrorScreen.d.ts.map +1 -0
  89. package/dist/cli/ui/screens/solid/ErrorScreen.js +18 -0
  90. package/dist/cli/ui/screens/solid/ErrorScreen.js.map +1 -0
  91. package/dist/cli/ui/screens/solid/InputScreen.d.ts +13 -0
  92. package/dist/cli/ui/screens/solid/InputScreen.d.ts.map +1 -0
  93. package/dist/cli/ui/screens/solid/InputScreen.js +17 -0
  94. package/dist/cli/ui/screens/solid/InputScreen.js.map +1 -0
  95. package/dist/cli/ui/screens/solid/LoadingIndicator.d.ts +9 -0
  96. package/dist/cli/ui/screens/solid/LoadingIndicator.d.ts.map +1 -0
  97. package/dist/cli/ui/screens/solid/LoadingIndicator.js +43 -0
  98. package/dist/cli/ui/screens/solid/LoadingIndicator.js.map +1 -0
  99. package/dist/cli/ui/{components/screens → screens/solid}/LogDetailScreen.d.ts +2 -2
  100. package/dist/cli/ui/screens/solid/LogDetailScreen.d.ts.map +1 -0
  101. package/dist/cli/ui/screens/solid/LogDetailScreen.js +34 -0
  102. package/dist/cli/ui/screens/solid/LogDetailScreen.js.map +1 -0
  103. package/dist/cli/ui/{components/screens/LogListScreen.d.ts → screens/solid/LogScreen.d.ts} +4 -4
  104. package/dist/cli/ui/screens/solid/LogScreen.d.ts.map +1 -0
  105. package/dist/cli/ui/screens/solid/LogScreen.js +95 -0
  106. package/dist/cli/ui/screens/solid/LogScreen.js.map +1 -0
  107. package/dist/cli/ui/screens/solid/ProfileEnvScreen.d.ts +17 -0
  108. package/dist/cli/ui/screens/solid/ProfileEnvScreen.d.ts.map +1 -0
  109. package/dist/cli/ui/screens/solid/ProfileEnvScreen.js +112 -0
  110. package/dist/cli/ui/screens/solid/ProfileEnvScreen.js.map +1 -0
  111. package/dist/cli/ui/screens/solid/ProfileScreen.d.ts +17 -0
  112. package/dist/cli/ui/screens/solid/ProfileScreen.d.ts.map +1 -0
  113. package/dist/cli/ui/screens/solid/ProfileScreen.js +50 -0
  114. package/dist/cli/ui/screens/solid/ProfileScreen.js.map +1 -0
  115. package/dist/cli/ui/screens/solid/SelectorScreen.d.ts +20 -0
  116. package/dist/cli/ui/screens/solid/SelectorScreen.d.ts.map +1 -0
  117. package/dist/cli/ui/screens/solid/SelectorScreen.js +90 -0
  118. package/dist/cli/ui/screens/solid/SelectorScreen.js.map +1 -0
  119. package/dist/cli/ui/screens/solid/WorktreeCreateScreen.d.ts +13 -0
  120. package/dist/cli/ui/screens/solid/WorktreeCreateScreen.d.ts.map +1 -0
  121. package/dist/cli/ui/screens/solid/WorktreeCreateScreen.js +59 -0
  122. package/dist/cli/ui/screens/solid/WorktreeCreateScreen.js.map +1 -0
  123. package/dist/cli/ui/stores/appStore.d.ts +143 -0
  124. package/dist/cli/ui/stores/appStore.d.ts.map +1 -0
  125. package/dist/cli/ui/stores/appStore.js +158 -0
  126. package/dist/cli/ui/stores/appStore.js.map +1 -0
  127. package/dist/cli/ui/stores/branchStore.d.ts +159 -0
  128. package/dist/cli/ui/stores/branchStore.d.ts.map +1 -0
  129. package/dist/cli/ui/stores/branchStore.js +275 -0
  130. package/dist/cli/ui/stores/branchStore.js.map +1 -0
  131. package/dist/cli/ui/stores/index.d.ts +11 -0
  132. package/dist/cli/ui/stores/index.d.ts.map +1 -0
  133. package/dist/cli/ui/stores/index.js +14 -0
  134. package/dist/cli/ui/stores/index.js.map +1 -0
  135. package/dist/cli/ui/stores/uiStore.d.ts +146 -0
  136. package/dist/cli/ui/stores/uiStore.d.ts.map +1 -0
  137. package/dist/cli/ui/stores/uiStore.js +166 -0
  138. package/dist/cli/ui/stores/uiStore.js.map +1 -0
  139. package/dist/cli/ui/types.d.ts +16 -1
  140. package/dist/cli/ui/types.d.ts.map +1 -1
  141. package/dist/cli/ui/utils/branchFormatter.d.ts.map +1 -1
  142. package/dist/cli/ui/utils/branchFormatter.js +7 -210
  143. package/dist/cli/ui/utils/branchFormatter.js.map +1 -1
  144. package/dist/cli/ui/utils/continueSession.d.ts +4 -0
  145. package/dist/cli/ui/utils/continueSession.d.ts.map +1 -1
  146. package/dist/cli/ui/utils/continueSession.js +30 -0
  147. package/dist/cli/ui/utils/continueSession.js.map +1 -1
  148. package/dist/client/assets/{index-ChHC-Puh.css → index-BbfV7Wuj.css} +1 -1
  149. package/dist/client/assets/index-CoAyq5x1.js +78 -0
  150. package/dist/client/index.html +2 -2
  151. package/dist/codex.d.ts +1 -0
  152. package/dist/codex.d.ts.map +1 -1
  153. package/dist/codex.js +86 -45
  154. package/dist/codex.js.map +1 -1
  155. package/dist/config/builtin-coding-agents.d.ts +4 -0
  156. package/dist/config/builtin-coding-agents.d.ts.map +1 -1
  157. package/dist/config/builtin-coding-agents.js +18 -3
  158. package/dist/config/builtin-coding-agents.js.map +1 -1
  159. package/dist/config/index.d.ts +2 -0
  160. package/dist/config/index.d.ts.map +1 -1
  161. package/dist/config/index.js +2 -0
  162. package/dist/config/index.js.map +1 -1
  163. package/dist/config/tools.d.ts.map +1 -1
  164. package/dist/config/tools.js +11 -0
  165. package/dist/config/tools.js.map +1 -1
  166. package/dist/gemini.d.ts +1 -0
  167. package/dist/gemini.d.ts.map +1 -1
  168. package/dist/gemini.js +42 -37
  169. package/dist/gemini.js.map +1 -1
  170. package/dist/index.d.ts +1 -1
  171. package/dist/index.d.ts.map +1 -1
  172. package/dist/index.js +122 -102
  173. package/dist/index.js.map +1 -1
  174. package/dist/launcher.d.ts.map +1 -1
  175. package/dist/launcher.js +18 -3
  176. package/dist/launcher.js.map +1 -1
  177. package/dist/logging/logger.d.ts.map +1 -1
  178. package/dist/logging/logger.js +26 -9
  179. package/dist/logging/logger.js.map +1 -1
  180. package/dist/opentui/highlights-eq9cgrbb.scm +604 -0
  181. package/dist/opentui/highlights-ghv9g403.scm +205 -0
  182. package/dist/opentui/highlights-hk7bwhj4.scm +284 -0
  183. package/dist/opentui/highlights-r812a2qc.scm +150 -0
  184. package/dist/opentui/highlights-x6tmsnaa.scm +115 -0
  185. package/dist/opentui/index.solid.d.ts +2 -0
  186. package/dist/opentui/index.solid.d.ts.map +1 -0
  187. package/dist/opentui/index.solid.js +52034 -0
  188. package/dist/opentui/index.solid.js.map +1 -0
  189. package/dist/opentui/injections-73j83es3.scm +27 -0
  190. package/dist/opentui/tree-sitter-javascript-nd0q4pe9.wasm +0 -0
  191. package/dist/opentui/tree-sitter-markdown-411r6y9b.wasm +0 -0
  192. package/dist/opentui/tree-sitter-markdown_inline-j5349f42.wasm +0 -0
  193. package/dist/opentui/tree-sitter-typescript-zxjzwt75.wasm +0 -0
  194. package/dist/opentui/tree-sitter-zig-e78zbjpm.wasm +0 -0
  195. package/dist/repositories/worktree.repository.d.ts +1 -0
  196. package/dist/repositories/worktree.repository.d.ts.map +1 -1
  197. package/dist/repositories/worktree.repository.js +7 -0
  198. package/dist/repositories/worktree.repository.js.map +1 -1
  199. package/dist/services/codingAgentResolver.d.ts +2 -0
  200. package/dist/services/codingAgentResolver.d.ts.map +1 -1
  201. package/dist/services/codingAgentResolver.js +30 -4
  202. package/dist/services/codingAgentResolver.js.map +1 -1
  203. package/dist/services/dependency-installer.d.ts.map +1 -1
  204. package/dist/services/dependency-installer.js +0 -5
  205. package/dist/services/dependency-installer.js.map +1 -1
  206. package/dist/types/api.d.ts +3 -0
  207. package/dist/types/api.d.ts.map +1 -1
  208. package/dist/types/coding-agent.d.ts +62 -0
  209. package/dist/types/coding-agent.d.ts.map +1 -0
  210. package/dist/types/coding-agent.js +29 -0
  211. package/dist/types/coding-agent.js.map +1 -0
  212. package/dist/types/tools.d.ts +17 -0
  213. package/dist/types/tools.d.ts.map +1 -1
  214. package/dist/utils/coding-agent-colors.d.ts +88 -0
  215. package/dist/utils/coding-agent-colors.d.ts.map +1 -0
  216. package/dist/utils/coding-agent-colors.js +137 -0
  217. package/dist/utils/coding-agent-colors.js.map +1 -0
  218. package/dist/utils/command.d.ts +1 -1
  219. package/dist/utils/command.d.ts.map +1 -1
  220. package/dist/utils/command.js +10 -1
  221. package/dist/utils/command.js.map +1 -1
  222. package/dist/utils/error-utils.d.ts +27 -0
  223. package/dist/utils/error-utils.d.ts.map +1 -0
  224. package/dist/utils/error-utils.js +98 -0
  225. package/dist/utils/error-utils.js.map +1 -0
  226. package/dist/utils/npmRegistry.d.ts +61 -0
  227. package/dist/utils/npmRegistry.d.ts.map +1 -0
  228. package/dist/utils/npmRegistry.js +180 -0
  229. package/dist/utils/npmRegistry.js.map +1 -0
  230. package/dist/utils/prompt.d.ts +1 -1
  231. package/dist/utils/prompt.js +1 -1
  232. package/dist/utils/session/index.d.ts +5 -3
  233. package/dist/utils/session/index.d.ts.map +1 -1
  234. package/dist/utils/session/index.js +5 -2
  235. package/dist/utils/session/index.js.map +1 -1
  236. package/dist/utils/session/parsers/codex.d.ts.map +1 -1
  237. package/dist/utils/session/parsers/codex.js +8 -1
  238. package/dist/utils/session/parsers/codex.js.map +1 -1
  239. package/dist/utils/session/parsers/index.d.ts +1 -0
  240. package/dist/utils/session/parsers/index.d.ts.map +1 -1
  241. package/dist/utils/session/parsers/index.js +2 -0
  242. package/dist/utils/session/parsers/index.js.map +1 -1
  243. package/dist/utils/session/parsers/opencode.d.ts +23 -0
  244. package/dist/utils/session/parsers/opencode.d.ts.map +1 -0
  245. package/dist/utils/session/parsers/opencode.js +89 -0
  246. package/dist/utils/session/parsers/opencode.js.map +1 -0
  247. package/dist/utils/session/types.d.ts +4 -0
  248. package/dist/utils/session/types.d.ts.map +1 -1
  249. package/dist/utils/terminal.d.ts +1 -0
  250. package/dist/utils/terminal.d.ts.map +1 -1
  251. package/dist/utils/terminal.js +20 -0
  252. package/dist/utils/terminal.js.map +1 -1
  253. package/dist/utils.d.ts +9 -0
  254. package/dist/utils.d.ts.map +1 -1
  255. package/dist/utils.js +33 -2
  256. package/dist/utils.js.map +1 -1
  257. package/dist/web/client/src/components/CodingAgentLaunchModal.d.ts.map +1 -1
  258. package/dist/web/client/src/components/CodingAgentLaunchModal.js +7 -16
  259. package/dist/web/client/src/components/CodingAgentLaunchModal.js.map +1 -1
  260. package/dist/web/client/src/components/branch-detail/BranchInfoCards.d.ts.map +1 -1
  261. package/dist/web/client/src/components/branch-detail/BranchInfoCards.js +7 -2
  262. package/dist/web/client/src/components/branch-detail/BranchInfoCards.js.map +1 -1
  263. package/dist/web/client/src/components/branch-detail/SessionHistoryTable.d.ts.map +1 -1
  264. package/dist/web/client/src/components/branch-detail/SessionHistoryTable.js +2 -1
  265. package/dist/web/client/src/components/branch-detail/SessionHistoryTable.js.map +1 -1
  266. package/dist/web/client/src/components/branch-detail/ToolLauncher.d.ts +2 -2
  267. package/dist/web/client/src/components/branch-detail/ToolLauncher.d.ts.map +1 -1
  268. package/dist/web/client/src/components/branch-detail/ToolLauncher.js +5 -5
  269. package/dist/web/client/src/components/branch-detail/ToolLauncher.js.map +1 -1
  270. package/dist/web/client/src/lib/coding-agent-colors.d.ts +86 -0
  271. package/dist/web/client/src/lib/coding-agent-colors.d.ts.map +1 -0
  272. package/dist/web/client/src/lib/coding-agent-colors.js +135 -0
  273. package/dist/web/client/src/lib/coding-agent-colors.js.map +1 -0
  274. package/dist/web/client/src/pages/BranchDetailPage.js +10 -10
  275. package/dist/web/client/src/pages/BranchDetailPage.js.map +1 -1
  276. package/dist/web/server/pty/manager.d.ts +2 -0
  277. package/dist/web/server/pty/manager.d.ts.map +1 -1
  278. package/dist/web/server/pty/manager.js +104 -0
  279. package/dist/web/server/pty/manager.js.map +1 -1
  280. package/dist/web/server/routes/sessions.d.ts.map +1 -1
  281. package/dist/web/server/routes/sessions.js +5 -1
  282. package/dist/web/server/routes/sessions.js.map +1 -1
  283. package/dist/web/server/services/branches.d.ts.map +1 -1
  284. package/dist/web/server/services/branches.js +10 -8
  285. package/dist/web/server/services/branches.js.map +1 -1
  286. package/dist/web/server/services/worktrees.js +2 -2
  287. package/dist/web/server/services/worktrees.js.map +1 -1
  288. package/dist/worktree.d.ts +47 -1
  289. package/dist/worktree.d.ts.map +1 -1
  290. package/dist/worktree.js +280 -94
  291. package/dist/worktree.js.map +1 -1
  292. package/package.json +12 -14
  293. package/src/claude.ts +68 -70
  294. package/src/cli/ui/App.solid.tsx +1823 -0
  295. package/src/cli/ui/__tests__/solid/AppSolid.cleanup.test.tsx +255 -0
  296. package/src/cli/ui/__tests__/solid/BranchListScreen.test.tsx +243 -0
  297. package/src/cli/ui/__tests__/solid/components/QuickStartStep.test.tsx +237 -0
  298. package/src/cli/ui/__tests__/solid/components/WizardPopup.test.tsx +231 -0
  299. package/src/cli/ui/__tests__/solid/components/WizardSteps.test.tsx +238 -0
  300. package/src/cli/ui/__tests__/utils/branchFormatter.test.ts +7 -289
  301. package/src/cli/ui/__tests__/utils/clipboard.test.ts +3 -3
  302. package/src/cli/ui/__tests__/utils/statisticsCalculator.test.ts +1 -1
  303. package/src/cli/ui/components/solid/Footer.tsx +36 -0
  304. package/src/cli/ui/components/{parts → solid}/Header.tsx +17 -28
  305. package/src/cli/ui/components/solid/HelpOverlay.tsx +194 -0
  306. package/src/cli/ui/components/solid/QuickStartStep.tsx +197 -0
  307. package/src/cli/ui/components/{parts → solid}/ScrollableList.tsx +7 -8
  308. package/src/cli/ui/components/solid/SearchInput.tsx +42 -0
  309. package/src/cli/ui/components/solid/SelectInput.tsx +84 -0
  310. package/src/cli/ui/components/solid/Stats.tsx +92 -0
  311. package/src/cli/ui/components/solid/TextInput.tsx +49 -0
  312. package/src/cli/ui/components/solid/WizardController.tsx +384 -0
  313. package/src/cli/ui/components/solid/WizardPopup.tsx +135 -0
  314. package/src/cli/ui/components/solid/WizardSteps.tsx +793 -0
  315. package/src/cli/ui/core/index.ts +17 -0
  316. package/src/cli/ui/core/keybindings.ts +367 -0
  317. package/src/cli/ui/core/theme.ts +234 -0
  318. package/src/cli/ui/core/types.ts +235 -0
  319. package/src/cli/ui/hooks/solid/useAsyncOperation.ts +76 -0
  320. package/src/cli/ui/hooks/solid/useFilter.ts +86 -0
  321. package/src/cli/ui/hooks/solid/useGitOperations.ts +80 -0
  322. package/src/cli/ui/hooks/solid/useKeyHandler.ts +103 -0
  323. package/src/cli/ui/hooks/solid/useScrollableList.ts +149 -0
  324. package/src/cli/ui/hooks/solid/useSelection.ts +77 -0
  325. package/src/cli/ui/hooks/solid/useTerminalSize.ts +22 -0
  326. package/src/cli/ui/index.solid.ts +28 -0
  327. package/src/cli/ui/screens/solid/BranchListScreen.tsx +1050 -0
  328. package/src/cli/ui/screens/solid/ConfirmScreen.tsx +74 -0
  329. package/src/cli/ui/screens/solid/EnvironmentScreen.tsx +159 -0
  330. package/src/cli/ui/screens/solid/ErrorScreen.tsx +42 -0
  331. package/src/cli/ui/screens/solid/InputScreen.tsx +55 -0
  332. package/src/cli/ui/screens/solid/LoadingIndicator.tsx +77 -0
  333. package/src/cli/ui/screens/solid/LogDetailScreen.tsx +75 -0
  334. package/src/cli/ui/screens/solid/LogScreen.tsx +175 -0
  335. package/src/cli/ui/screens/solid/ProfileEnvScreen.tsx +192 -0
  336. package/src/cli/ui/screens/solid/ProfileScreen.tsx +98 -0
  337. package/src/cli/ui/screens/solid/SelectorScreen.tsx +170 -0
  338. package/src/cli/ui/screens/solid/SettingsScreen.tsx +50 -0
  339. package/src/cli/ui/screens/solid/WorktreeCreateScreen.tsx +136 -0
  340. package/src/cli/ui/screens/solid/WorktreeDeleteScreen.tsx +40 -0
  341. package/src/cli/ui/stores/appStore.ts +208 -0
  342. package/src/cli/ui/stores/branchStore.ts +357 -0
  343. package/src/cli/ui/stores/index.ts +31 -0
  344. package/src/cli/ui/stores/uiStore.ts +226 -0
  345. package/src/cli/ui/types.ts +20 -3
  346. package/src/cli/ui/utils/__tests__/branchFormatter.test.ts +180 -0
  347. package/src/cli/ui/utils/branchFormatter.ts +8 -215
  348. package/src/cli/ui/utils/continueSession.ts +44 -0
  349. package/src/cli/ui/utils/modelOptions.test.ts +1 -1
  350. package/src/codex.ts +100 -43
  351. package/src/config/__tests__/saveSession.test.ts +143 -0
  352. package/src/config/builtin-coding-agents.ts +19 -3
  353. package/src/config/index.ts +4 -0
  354. package/src/config/tools.ts +16 -0
  355. package/src/gemini.ts +58 -43
  356. package/src/index.test.ts +12 -12
  357. package/src/index.ts +164 -142
  358. package/src/launcher.ts +22 -3
  359. package/src/logging/logger.ts +32 -10
  360. package/src/opentui/index.solid.ts +1 -0
  361. package/src/repositories/worktree.repository.ts +8 -0
  362. package/src/services/__tests__/BatchMergeService.test.ts +62 -66
  363. package/src/services/__tests__/WorktreeOrchestrator.test.ts +8 -7
  364. package/src/services/codingAgentResolver.ts +30 -4
  365. package/src/services/dependency-installer.ts +0 -7
  366. package/src/types/api.ts +3 -0
  367. package/src/types/coding-agent.ts +85 -0
  368. package/src/types/tools.ts +19 -0
  369. package/src/utils/__tests__/npmRegistry.test.ts +250 -0
  370. package/src/utils/__tests__/prompt.test.ts +4 -5
  371. package/src/utils/coding-agent-colors.ts +165 -0
  372. package/src/utils/command.ts +10 -1
  373. package/src/utils/error-utils.ts +133 -0
  374. package/src/utils/npmRegistry.ts +249 -0
  375. package/src/utils/prompt.ts +1 -1
  376. package/src/utils/session/index.ts +10 -2
  377. package/src/utils/session/parsers/codex.ts +9 -1
  378. package/src/utils/session/parsers/index.ts +6 -0
  379. package/src/utils/session/parsers/opencode.ts +110 -0
  380. package/src/utils/session/types.ts +5 -0
  381. package/src/utils/terminal.ts +24 -0
  382. package/src/utils.test.ts +1 -1
  383. package/src/utils.ts +37 -4
  384. package/src/web/client/src/components/CodingAgentLaunchModal.tsx +12 -21
  385. package/src/web/client/src/components/branch-detail/BranchInfoCards.tsx +16 -1
  386. package/src/web/client/src/components/branch-detail/SessionHistoryTable.tsx +7 -1
  387. package/src/web/client/src/components/branch-detail/ToolLauncher.tsx +11 -6
  388. package/src/web/client/src/lib/coding-agent-colors.ts +149 -0
  389. package/src/web/client/src/pages/BranchDetailPage.tsx +11 -11
  390. package/src/web/server/pty/manager.ts +139 -0
  391. package/src/web/server/routes/sessions.ts +6 -0
  392. package/src/web/server/services/branches.ts +11 -8
  393. package/src/web/server/services/worktrees.ts +2 -2
  394. package/src/worktree.ts +366 -107
  395. package/dist/cli/ui/components/App.d.ts +0 -25
  396. package/dist/cli/ui/components/App.d.ts.map +0 -1
  397. package/dist/cli/ui/components/App.js +0 -988
  398. package/dist/cli/ui/components/App.js.map +0 -1
  399. package/dist/cli/ui/components/common/Confirm.d.ts +0 -13
  400. package/dist/cli/ui/components/common/Confirm.d.ts.map +0 -1
  401. package/dist/cli/ui/components/common/Confirm.js +0 -20
  402. package/dist/cli/ui/components/common/Confirm.js.map +0 -1
  403. package/dist/cli/ui/components/common/ErrorBoundary.d.ts +0 -23
  404. package/dist/cli/ui/components/common/ErrorBoundary.d.ts.map +0 -1
  405. package/dist/cli/ui/components/common/ErrorBoundary.js +0 -37
  406. package/dist/cli/ui/components/common/ErrorBoundary.js.map +0 -1
  407. package/dist/cli/ui/components/common/Input.d.ts +0 -19
  408. package/dist/cli/ui/components/common/Input.d.ts.map +0 -1
  409. package/dist/cli/ui/components/common/Input.js +0 -22
  410. package/dist/cli/ui/components/common/Input.js.map +0 -1
  411. package/dist/cli/ui/components/common/LoadingIndicator.d.ts +0 -19
  412. package/dist/cli/ui/components/common/LoadingIndicator.d.ts.map +0 -1
  413. package/dist/cli/ui/components/common/LoadingIndicator.js +0 -61
  414. package/dist/cli/ui/components/common/LoadingIndicator.js.map +0 -1
  415. package/dist/cli/ui/components/common/Select.d.ts +0 -38
  416. package/dist/cli/ui/components/common/Select.d.ts.map +0 -1
  417. package/dist/cli/ui/components/common/Select.js +0 -151
  418. package/dist/cli/ui/components/common/Select.js.map +0 -1
  419. package/dist/cli/ui/components/common/SpinnerIcon.d.ts +0 -20
  420. package/dist/cli/ui/components/common/SpinnerIcon.d.ts.map +0 -1
  421. package/dist/cli/ui/components/common/SpinnerIcon.js +0 -61
  422. package/dist/cli/ui/components/common/SpinnerIcon.js.map +0 -1
  423. package/dist/cli/ui/components/parts/Footer.d.ts +0 -15
  424. package/dist/cli/ui/components/parts/Footer.d.ts.map +0 -1
  425. package/dist/cli/ui/components/parts/Footer.js +0 -20
  426. package/dist/cli/ui/components/parts/Footer.js.map +0 -1
  427. package/dist/cli/ui/components/parts/Header.d.ts.map +0 -1
  428. package/dist/cli/ui/components/parts/Header.js +0 -24
  429. package/dist/cli/ui/components/parts/Header.js.map +0 -1
  430. package/dist/cli/ui/components/parts/MergeStatusList.d.ts +0 -13
  431. package/dist/cli/ui/components/parts/MergeStatusList.d.ts.map +0 -1
  432. package/dist/cli/ui/components/parts/MergeStatusList.js +0 -52
  433. package/dist/cli/ui/components/parts/MergeStatusList.js.map +0 -1
  434. package/dist/cli/ui/components/parts/ProgressBar.d.ts +0 -13
  435. package/dist/cli/ui/components/parts/ProgressBar.d.ts.map +0 -1
  436. package/dist/cli/ui/components/parts/ProgressBar.js +0 -53
  437. package/dist/cli/ui/components/parts/ProgressBar.js.map +0 -1
  438. package/dist/cli/ui/components/parts/ScrollableList.d.ts +0 -12
  439. package/dist/cli/ui/components/parts/ScrollableList.d.ts.map +0 -1
  440. package/dist/cli/ui/components/parts/ScrollableList.js +0 -11
  441. package/dist/cli/ui/components/parts/ScrollableList.js.map +0 -1
  442. package/dist/cli/ui/components/parts/Stats.d.ts +0 -10
  443. package/dist/cli/ui/components/parts/Stats.d.ts.map +0 -1
  444. package/dist/cli/ui/components/parts/Stats.js +0 -55
  445. package/dist/cli/ui/components/parts/Stats.js.map +0 -1
  446. package/dist/cli/ui/components/screens/BatchMergeProgressScreen.d.ts +0 -17
  447. package/dist/cli/ui/components/screens/BatchMergeProgressScreen.d.ts.map +0 -1
  448. package/dist/cli/ui/components/screens/BatchMergeProgressScreen.js +0 -42
  449. package/dist/cli/ui/components/screens/BatchMergeProgressScreen.js.map +0 -1
  450. package/dist/cli/ui/components/screens/BatchMergeResultScreen.d.ts +0 -17
  451. package/dist/cli/ui/components/screens/BatchMergeResultScreen.d.ts.map +0 -1
  452. package/dist/cli/ui/components/screens/BatchMergeResultScreen.js +0 -72
  453. package/dist/cli/ui/components/screens/BatchMergeResultScreen.js.map +0 -1
  454. package/dist/cli/ui/components/screens/BranchCreatorScreen.d.ts +0 -18
  455. package/dist/cli/ui/components/screens/BranchCreatorScreen.d.ts.map +0 -1
  456. package/dist/cli/ui/components/screens/BranchCreatorScreen.js +0 -151
  457. package/dist/cli/ui/components/screens/BranchCreatorScreen.js.map +0 -1
  458. package/dist/cli/ui/components/screens/BranchListScreen.d.ts.map +0 -1
  459. package/dist/cli/ui/components/screens/BranchListScreen.js +0 -476
  460. package/dist/cli/ui/components/screens/BranchListScreen.js.map +0 -1
  461. package/dist/cli/ui/components/screens/BranchQuickStartScreen.d.ts +0 -30
  462. package/dist/cli/ui/components/screens/BranchQuickStartScreen.d.ts.map +0 -1
  463. package/dist/cli/ui/components/screens/BranchQuickStartScreen.js +0 -145
  464. package/dist/cli/ui/components/screens/BranchQuickStartScreen.js.map +0 -1
  465. package/dist/cli/ui/components/screens/CodingAgentSelectorScreen.d.ts +0 -27
  466. package/dist/cli/ui/components/screens/CodingAgentSelectorScreen.d.ts.map +0 -1
  467. package/dist/cli/ui/components/screens/CodingAgentSelectorScreen.js +0 -93
  468. package/dist/cli/ui/components/screens/CodingAgentSelectorScreen.js.map +0 -1
  469. package/dist/cli/ui/components/screens/EnvironmentProfileScreen.d.ts +0 -19
  470. package/dist/cli/ui/components/screens/EnvironmentProfileScreen.d.ts.map +0 -1
  471. package/dist/cli/ui/components/screens/EnvironmentProfileScreen.js +0 -577
  472. package/dist/cli/ui/components/screens/EnvironmentProfileScreen.js.map +0 -1
  473. package/dist/cli/ui/components/screens/ExecutionModeSelectorScreen.d.ts +0 -45
  474. package/dist/cli/ui/components/screens/ExecutionModeSelectorScreen.d.ts.map +0 -1
  475. package/dist/cli/ui/components/screens/ExecutionModeSelectorScreen.js +0 -95
  476. package/dist/cli/ui/components/screens/ExecutionModeSelectorScreen.js.map +0 -1
  477. package/dist/cli/ui/components/screens/LogDatePickerScreen.d.ts +0 -10
  478. package/dist/cli/ui/components/screens/LogDatePickerScreen.d.ts.map +0 -1
  479. package/dist/cli/ui/components/screens/LogDatePickerScreen.js +0 -44
  480. package/dist/cli/ui/components/screens/LogDatePickerScreen.js.map +0 -1
  481. package/dist/cli/ui/components/screens/LogDetailScreen.d.ts.map +0 -1
  482. package/dist/cli/ui/components/screens/LogDetailScreen.js +0 -34
  483. package/dist/cli/ui/components/screens/LogDetailScreen.js.map +0 -1
  484. package/dist/cli/ui/components/screens/LogListScreen.d.ts.map +0 -1
  485. package/dist/cli/ui/components/screens/LogListScreen.js +0 -107
  486. package/dist/cli/ui/components/screens/LogListScreen.js.map +0 -1
  487. package/dist/cli/ui/components/screens/ModelSelectorScreen.d.ts +0 -24
  488. package/dist/cli/ui/components/screens/ModelSelectorScreen.d.ts.map +0 -1
  489. package/dist/cli/ui/components/screens/ModelSelectorScreen.js +0 -197
  490. package/dist/cli/ui/components/screens/ModelSelectorScreen.js.map +0 -1
  491. package/dist/cli/ui/components/screens/PRCleanupScreen.d.ts +0 -29
  492. package/dist/cli/ui/components/screens/PRCleanupScreen.d.ts.map +0 -1
  493. package/dist/cli/ui/components/screens/PRCleanupScreen.js +0 -92
  494. package/dist/cli/ui/components/screens/PRCleanupScreen.js.map +0 -1
  495. package/dist/cli/ui/components/screens/SessionSelectorScreen.d.ts +0 -31
  496. package/dist/cli/ui/components/screens/SessionSelectorScreen.d.ts.map +0 -1
  497. package/dist/cli/ui/components/screens/SessionSelectorScreen.js +0 -67
  498. package/dist/cli/ui/components/screens/SessionSelectorScreen.js.map +0 -1
  499. package/dist/cli/ui/hooks/useAppInput.d.ts +0 -21
  500. package/dist/cli/ui/hooks/useAppInput.d.ts.map +0 -1
  501. package/dist/cli/ui/hooks/useAppInput.js +0 -138
  502. package/dist/cli/ui/hooks/useAppInput.js.map +0 -1
  503. package/dist/cli/ui/hooks/useBatchMerge.d.ts +0 -17
  504. package/dist/cli/ui/hooks/useBatchMerge.d.ts.map +0 -1
  505. package/dist/cli/ui/hooks/useBatchMerge.js +0 -77
  506. package/dist/cli/ui/hooks/useBatchMerge.js.map +0 -1
  507. package/dist/cli/ui/hooks/useGitData.d.ts +0 -21
  508. package/dist/cli/ui/hooks/useGitData.d.ts.map +0 -1
  509. package/dist/cli/ui/hooks/useGitData.js +0 -229
  510. package/dist/cli/ui/hooks/useGitData.js.map +0 -1
  511. package/dist/cli/ui/hooks/useProfiles.d.ts +0 -41
  512. package/dist/cli/ui/hooks/useProfiles.d.ts.map +0 -1
  513. package/dist/cli/ui/hooks/useProfiles.js +0 -136
  514. package/dist/cli/ui/hooks/useProfiles.js.map +0 -1
  515. package/dist/cli/ui/hooks/useScreenState.d.ts +0 -12
  516. package/dist/cli/ui/hooks/useScreenState.d.ts.map +0 -1
  517. package/dist/cli/ui/hooks/useScreenState.js +0 -30
  518. package/dist/cli/ui/hooks/useScreenState.js.map +0 -1
  519. package/dist/cli/ui/hooks/useTerminalSize.d.ts +0 -9
  520. package/dist/cli/ui/hooks/useTerminalSize.d.ts.map +0 -1
  521. package/dist/cli/ui/hooks/useTerminalSize.js +0 -24
  522. package/dist/cli/ui/hooks/useTerminalSize.js.map +0 -1
  523. package/dist/cli/ui/hooks/useToolStatus.d.ts +0 -30
  524. package/dist/cli/ui/hooks/useToolStatus.d.ts.map +0 -1
  525. package/dist/cli/ui/hooks/useToolStatus.js +0 -49
  526. package/dist/cli/ui/hooks/useToolStatus.js.map +0 -1
  527. package/dist/cli/ui/screens/BranchActionSelectorScreen.d.ts +0 -24
  528. package/dist/cli/ui/screens/BranchActionSelectorScreen.d.ts.map +0 -1
  529. package/dist/cli/ui/screens/BranchActionSelectorScreen.js +0 -65
  530. package/dist/cli/ui/screens/BranchActionSelectorScreen.js.map +0 -1
  531. package/dist/client/assets/index-LNPtOrn3.js +0 -78
  532. package/src/cli/ui/__tests__/SKIPPED_TESTS.md +0 -119
  533. package/src/cli/ui/__tests__/acceptance/branchList.acceptance.test.tsx.skip +0 -239
  534. package/src/cli/ui/__tests__/acceptance/navigation.acceptance.test.tsx +0 -225
  535. package/src/cli/ui/__tests__/acceptance/realtimeUpdate.acceptance.test.tsx.skip +0 -219
  536. package/src/cli/ui/__tests__/components/App.protected-branch.test.tsx +0 -212
  537. package/src/cli/ui/__tests__/components/App.shortcuts.test.tsx +0 -440
  538. package/src/cli/ui/__tests__/components/App.test.tsx +0 -365
  539. package/src/cli/ui/__tests__/components/ModelSelectorScreen.initial.test.tsx +0 -91
  540. package/src/cli/ui/__tests__/components/common/Confirm.test.tsx +0 -80
  541. package/src/cli/ui/__tests__/components/common/ErrorBoundary.test.tsx +0 -104
  542. package/src/cli/ui/__tests__/components/common/Input.test.tsx +0 -100
  543. package/src/cli/ui/__tests__/components/common/LoadingIndicator.test.tsx +0 -148
  544. package/src/cli/ui/__tests__/components/common/Select.memo.test.tsx +0 -255
  545. package/src/cli/ui/__tests__/components/common/Select.test.tsx +0 -335
  546. package/src/cli/ui/__tests__/components/parts/Footer.test.tsx +0 -65
  547. package/src/cli/ui/__tests__/components/parts/Header.test.tsx +0 -55
  548. package/src/cli/ui/__tests__/components/parts/ScrollableList.test.tsx +0 -69
  549. package/src/cli/ui/__tests__/components/parts/Stats.test.tsx +0 -148
  550. package/src/cli/ui/__tests__/components/screens/BranchCreatorScreen.test.tsx +0 -253
  551. package/src/cli/ui/__tests__/components/screens/BranchListScreen.test.tsx +0 -1070
  552. package/src/cli/ui/__tests__/components/screens/BranchQuickStartScreen.test.tsx +0 -142
  553. package/src/cli/ui/__tests__/components/screens/CodingAgentSelectorScreen.test.tsx +0 -174
  554. package/src/cli/ui/__tests__/components/screens/ExecutionModeSelectorScreen.test.tsx +0 -182
  555. package/src/cli/ui/__tests__/components/screens/LogDetailScreen.test.tsx +0 -57
  556. package/src/cli/ui/__tests__/components/screens/LogListScreen.test.tsx +0 -102
  557. package/src/cli/ui/__tests__/components/screens/PRCleanupScreen.test.tsx +0 -216
  558. package/src/cli/ui/__tests__/components/screens/SessionSelectorScreen.test.tsx +0 -147
  559. package/src/cli/ui/__tests__/hooks/useGitData.nonblocking.test.tsx +0 -206
  560. package/src/cli/ui/__tests__/hooks/useGitData.test.ts +0 -197
  561. package/src/cli/ui/__tests__/hooks/useGitData.test.ts.skip +0 -228
  562. package/src/cli/ui/__tests__/hooks/useScreenState.test.ts +0 -147
  563. package/src/cli/ui/__tests__/hooks/useTerminalSize.test.ts +0 -99
  564. package/src/cli/ui/__tests__/integration/branchList.test.tsx.skip +0 -253
  565. package/src/cli/ui/__tests__/integration/edgeCases.test.tsx +0 -436
  566. package/src/cli/ui/__tests__/integration/navigation.test.tsx +0 -514
  567. package/src/cli/ui/__tests__/integration/realtimeUpdate.test.tsx +0 -509
  568. package/src/cli/ui/__tests__/integration/realtimeUpdate.test.tsx.skip +0 -216
  569. package/src/cli/ui/__tests__/performance/branchList.performance.test.tsx +0 -193
  570. package/src/cli/ui/__tests__/performance/useMemoOptimization.test.tsx +0 -234
  571. package/src/cli/ui/components/App.tsx +0 -1456
  572. package/src/cli/ui/components/common/Confirm.tsx +0 -44
  573. package/src/cli/ui/components/common/ErrorBoundary.tsx +0 -60
  574. package/src/cli/ui/components/common/Input.tsx +0 -58
  575. package/src/cli/ui/components/common/LoadingIndicator.tsx +0 -98
  576. package/src/cli/ui/components/common/Select.tsx +0 -247
  577. package/src/cli/ui/components/common/SpinnerIcon.tsx +0 -86
  578. package/src/cli/ui/components/parts/Footer.tsx +0 -41
  579. package/src/cli/ui/components/parts/Header.test.tsx +0 -75
  580. package/src/cli/ui/components/parts/MergeStatusList.tsx +0 -75
  581. package/src/cli/ui/components/parts/ProgressBar.tsx +0 -73
  582. package/src/cli/ui/components/parts/Stats.tsx +0 -88
  583. package/src/cli/ui/components/screens/BatchMergeProgressScreen.tsx +0 -74
  584. package/src/cli/ui/components/screens/BatchMergeResultScreen.tsx +0 -108
  585. package/src/cli/ui/components/screens/BranchCreatorScreen.tsx +0 -242
  586. package/src/cli/ui/components/screens/BranchListScreen.tsx +0 -744
  587. package/src/cli/ui/components/screens/BranchQuickStartScreen.tsx +0 -241
  588. package/src/cli/ui/components/screens/CodingAgentSelectorScreen.tsx +0 -159
  589. package/src/cli/ui/components/screens/EnvironmentProfileScreen.tsx +0 -928
  590. package/src/cli/ui/components/screens/ExecutionModeSelectorScreen.tsx +0 -176
  591. package/src/cli/ui/components/screens/LogDatePickerScreen.tsx +0 -83
  592. package/src/cli/ui/components/screens/LogDetailScreen.tsx +0 -67
  593. package/src/cli/ui/components/screens/LogListScreen.tsx +0 -192
  594. package/src/cli/ui/components/screens/ModelSelectorScreen.tsx +0 -320
  595. package/src/cli/ui/components/screens/PRCleanupScreen.tsx +0 -171
  596. package/src/cli/ui/components/screens/SessionSelectorScreen.tsx +0 -135
  597. package/src/cli/ui/hooks/useAppInput.ts +0 -172
  598. package/src/cli/ui/hooks/useBatchMerge.ts +0 -96
  599. package/src/cli/ui/hooks/useGitData.ts +0 -347
  600. package/src/cli/ui/hooks/useProfiles.ts +0 -211
  601. package/src/cli/ui/hooks/useScreenState.ts +0 -44
  602. package/src/cli/ui/hooks/useTerminalSize.ts +0 -33
  603. package/src/cli/ui/hooks/useToolStatus.ts +0 -68
  604. package/src/cli/ui/screens/BranchActionSelectorScreen.tsx +0 -111
  605. package/src/cli/ui/screens/__tests__/BranchActionSelectorScreen.test.tsx +0 -264
@@ -0,0 +1,249 @@
1
+ /**
2
+ * npm Registry API utilities for fetching package versions
3
+ */
4
+
5
+ export interface VersionInfo {
6
+ version: string;
7
+ isPrerelease: boolean;
8
+ publishedAt?: string;
9
+ }
10
+
11
+ export type VersionSelection = "installed" | "latest" | string;
12
+
13
+ interface NpmRegistryResponse {
14
+ "dist-tags"?: Record<string, string>;
15
+ time?: Record<string, string>;
16
+ versions?: Record<string, unknown>;
17
+ }
18
+
19
+ const DEFAULT_TIMEOUT_MS = 3000;
20
+ const DEFAULT_LIMIT = 10;
21
+
22
+ /**
23
+ * Check if a version string is a prerelease version
24
+ */
25
+ function isPrerelease(version: string): boolean {
26
+ // Prerelease versions contain - followed by alpha, beta, rc, canary, next, etc.
27
+ return /-(alpha|beta|rc|canary|next|dev|pre)\b/i.test(version);
28
+ }
29
+
30
+ /**
31
+ * Fetch package versions from npm registry
32
+ * Returns the latest N versions sorted by publish date (newest first)
33
+ */
34
+ export async function fetchPackageVersions(
35
+ packageName: string,
36
+ limit: number = DEFAULT_LIMIT,
37
+ timeoutMs: number = DEFAULT_TIMEOUT_MS,
38
+ ): Promise<VersionInfo[]> {
39
+ try {
40
+ const controller = new AbortController();
41
+ const timeoutId = setTimeout(() => controller.abort(), timeoutMs);
42
+
43
+ const response = await fetch(
44
+ `https://registry.npmjs.org/${encodeURIComponent(packageName)}`,
45
+ {
46
+ signal: controller.signal,
47
+ headers: {
48
+ Accept: "application/json",
49
+ },
50
+ },
51
+ );
52
+
53
+ clearTimeout(timeoutId);
54
+
55
+ if (!response.ok) {
56
+ return [];
57
+ }
58
+
59
+ const data = (await response.json()) as NpmRegistryResponse;
60
+
61
+ if (!data.versions || !data.time) {
62
+ return [];
63
+ }
64
+
65
+ // Get all versions with their publish times
66
+ const versionsWithTime: Array<{
67
+ version: string;
68
+ publishedAt: string;
69
+ }> = [];
70
+
71
+ for (const version of Object.keys(data.versions)) {
72
+ const publishedAt = data.time[version];
73
+ if (publishedAt) {
74
+ versionsWithTime.push({ version, publishedAt });
75
+ }
76
+ }
77
+
78
+ // Sort by publish date (newest first)
79
+ versionsWithTime.sort((a, b) => {
80
+ const dateA = new Date(a.publishedAt).getTime();
81
+ const dateB = new Date(b.publishedAt).getTime();
82
+ return dateB - dateA;
83
+ });
84
+
85
+ // Take the top N versions
86
+ const topVersions = versionsWithTime.slice(0, limit);
87
+
88
+ // Convert to VersionInfo
89
+ return topVersions.map((v) => ({
90
+ version: v.version,
91
+ isPrerelease: isPrerelease(v.version),
92
+ publishedAt: v.publishedAt,
93
+ }));
94
+ } catch {
95
+ // Return empty array on any error (network, timeout, parse error, etc.)
96
+ return [];
97
+ }
98
+ }
99
+
100
+ /**
101
+ * Parse a package command to extract package name and version
102
+ * Examples:
103
+ * "@anthropic-ai/claude-code" -> { packageName: "@anthropic-ai/claude-code", version: null }
104
+ * "@anthropic-ai/claude-code@latest" -> { packageName: "@anthropic-ai/claude-code", version: "latest" }
105
+ * "@anthropic-ai/claude-code@1.0.3" -> { packageName: "@anthropic-ai/claude-code", version: "1.0.3" }
106
+ * "opencode-ai@latest" -> { packageName: "opencode-ai", version: "latest" }
107
+ */
108
+ export function parsePackageCommand(command: string): {
109
+ packageName: string;
110
+ version: string | null;
111
+ } {
112
+ // Handle scoped packages (@scope/name@version)
113
+ if (command.startsWith("@")) {
114
+ // Find the second @ which separates version
115
+ const firstSlash = command.indexOf("/");
116
+ if (firstSlash === -1) {
117
+ // Invalid scoped package format
118
+ return { packageName: command, version: null };
119
+ }
120
+ const afterScope = command.substring(firstSlash + 1);
121
+ const atIndex = afterScope.indexOf("@");
122
+ if (atIndex === -1) {
123
+ return { packageName: command, version: null };
124
+ }
125
+ const packageName = command.substring(0, firstSlash + 1 + atIndex);
126
+ const version = afterScope.substring(atIndex + 1);
127
+ return { packageName, version };
128
+ }
129
+
130
+ // Handle non-scoped packages (name@version)
131
+ const atIndex = command.indexOf("@");
132
+ if (atIndex === -1) {
133
+ return { packageName: command, version: null };
134
+ }
135
+ const packageName = command.substring(0, atIndex);
136
+ const version = command.substring(atIndex + 1);
137
+ return { packageName, version };
138
+ }
139
+
140
+ /**
141
+ * Resolve version selection to a bunx-compatible suffix
142
+ * Examples:
143
+ * "installed" -> "" (use bunx default/cached version)
144
+ * "latest" -> "@latest"
145
+ * "1.0.3" -> "@1.0.3"
146
+ * undefined -> "" (use bunx default/cached version)
147
+ */
148
+ export function resolveVersionSuffix(version?: VersionSelection): string {
149
+ if (!version || version === "installed") {
150
+ return "";
151
+ }
152
+ return `@${version}`;
153
+ }
154
+
155
+ export interface GlobalPackageInfo {
156
+ name: string;
157
+ version: string;
158
+ }
159
+
160
+ export interface GlobalPackagesResult {
161
+ path: string | null;
162
+ packages: GlobalPackageInfo[];
163
+ }
164
+
165
+ /**
166
+ * Parse the output of `bun pm ls -g` command
167
+ * Example output:
168
+ * /root/.bun/install/global node_modules (17)
169
+ * ├── @anthropic-ai/claude-code@2.0.76
170
+ * └── @openai/codex@0.77.0
171
+ */
172
+ export function parseGlobalPackagesOutput(
173
+ output: string,
174
+ ): GlobalPackagesResult {
175
+ const lines = output.trim().split("\n");
176
+ if (lines.length === 0 || !lines[0]) {
177
+ return { path: null, packages: [] };
178
+ }
179
+
180
+ // Parse the first line to get the path
181
+ // Format: "/path/to/global node_modules (N)"
182
+ const firstLine = lines[0];
183
+ const pathMatch = firstLine.match(/^(.+?)\s+node_modules\s+\(\d+\)$/);
184
+ const path = pathMatch?.[1] ?? null;
185
+
186
+ // Parse package lines
187
+ const packages: GlobalPackageInfo[] = [];
188
+ for (let i = 1; i < lines.length; i++) {
189
+ const line = lines[i];
190
+ if (!line) continue;
191
+
192
+ // Remove tree characters (├── └── │)
193
+ const cleaned = line.replace(/^[├└│─\s]+/, "").trim();
194
+ if (!cleaned) continue;
195
+
196
+ // Parse package@version format
197
+ // Handle scoped packages like @anthropic-ai/claude-code@2.0.76
198
+ const lastAtIndex = cleaned.lastIndexOf("@");
199
+ if (lastAtIndex <= 0) continue; // No version or invalid format
200
+
201
+ const name = cleaned.substring(0, lastAtIndex);
202
+ const version = cleaned.substring(lastAtIndex + 1);
203
+
204
+ if (name && version) {
205
+ packages.push({ name, version });
206
+ }
207
+ }
208
+
209
+ return { path, packages };
210
+ }
211
+
212
+ export interface InstalledPackageInfo {
213
+ version: string;
214
+ path: string;
215
+ }
216
+
217
+ /**
218
+ * Get information about a globally installed package
219
+ * Returns null if the package is not installed
220
+ */
221
+ export async function getInstalledPackageInfo(
222
+ packageName: string,
223
+ ): Promise<InstalledPackageInfo | null> {
224
+ try {
225
+ const { execa } = await import("execa");
226
+ const result = await execa("bun", ["pm", "ls", "-g"], {
227
+ timeout: 5000,
228
+ reject: false,
229
+ });
230
+
231
+ if (result.exitCode !== 0 || !result.stdout) {
232
+ return null;
233
+ }
234
+
235
+ const parsed = parseGlobalPackagesOutput(result.stdout);
236
+ const pkg = parsed.packages.find((p) => p.name === packageName);
237
+
238
+ if (!pkg || !parsed.path) {
239
+ return null;
240
+ }
241
+
242
+ return {
243
+ version: pkg.version,
244
+ path: `${parsed.path}/node_modules/${packageName}`,
245
+ };
246
+ } catch {
247
+ return null;
248
+ }
249
+ }
@@ -95,7 +95,7 @@ async function runReadlinePrompt<T>(
95
95
  }
96
96
 
97
97
  /**
98
- * Wait for Enter using the same terminal streams as Ink.
98
+ * Wait for Enter using the same terminal streams as the CLI UI.
99
99
  * Falls back to no-op on non-interactive stdin to avoid blocking pipelines.
100
100
  */
101
101
  export async function waitForEnter(promptMessage: string): Promise<void> {
@@ -1,10 +1,11 @@
1
1
  /**
2
- * Session module - unified session management for AI tools
2
+ * Session module - unified session management for coding agents
3
3
  *
4
- * This module provides session detection and management for various AI CLI tools:
4
+ * This module provides session detection and management for various coding agents:
5
5
  * - Claude Code
6
6
  * - Codex CLI
7
7
  * - Gemini CLI
8
+ * - OpenCode
8
9
  */
9
10
 
10
11
  // Type exports
@@ -14,6 +15,7 @@ export type {
14
15
  ClaudeSessionInfo,
15
16
  CodexSessionInfo,
16
17
  GeminiSessionInfo,
18
+ OpenCodeSessionInfo,
17
19
  } from "./types.js";
18
20
 
19
21
  // Common utilities
@@ -40,3 +42,9 @@ export {
40
42
  findLatestGeminiSession,
41
43
  findLatestGeminiSessionId,
42
44
  } from "./parsers/gemini.js";
45
+
46
+ // OpenCode parser
47
+ export {
48
+ findLatestOpenCodeSession,
49
+ findLatestOpenCodeSessionId,
50
+ } from "./parsers/opencode.js";
@@ -63,6 +63,8 @@ export async function findLatestCodexSession(
63
63
  return b.mtime - a.mtime;
64
64
  });
65
65
 
66
+ let fallbackMissingCwd: CodexSessionInfo | null = null;
67
+
66
68
  for (const file of ordered) {
67
69
  // Priority 1: Extract session ID from filename (most reliable for Codex)
68
70
  const filenameMatch = path.basename(file.fullPath).match(UUID_REGEX);
@@ -74,6 +76,9 @@ export async function findLatestCodexSession(
74
76
  if (matchesCwd(info.cwd, options.cwd)) {
75
77
  return { id: sessionId, mtime: file.mtime };
76
78
  }
79
+ if (!info.cwd && !fallbackMissingCwd) {
80
+ fallbackMissingCwd = { id: sessionId, mtime: file.mtime };
81
+ }
77
82
  continue; // cwd doesn't match, try next file
78
83
  }
79
84
  return { id: sessionId, mtime: file.mtime };
@@ -86,12 +91,15 @@ export async function findLatestCodexSession(
86
91
  if (matchesCwd(info.cwd, options.cwd)) {
87
92
  return { id: info.id, mtime: file.mtime };
88
93
  }
94
+ if (!info.cwd && !fallbackMissingCwd) {
95
+ fallbackMissingCwd = { id: info.id, mtime: file.mtime };
96
+ }
89
97
  continue;
90
98
  }
91
99
  return { id: info.id, mtime: file.mtime };
92
100
  }
93
101
 
94
- return null;
102
+ return fallbackMissingCwd;
95
103
  }
96
104
 
97
105
  /**
@@ -23,3 +23,9 @@ export {
23
23
  findLatestGeminiSession,
24
24
  findLatestGeminiSessionId,
25
25
  } from "./gemini.js";
26
+
27
+ // OpenCode
28
+ export {
29
+ findLatestOpenCodeSession,
30
+ findLatestOpenCodeSessionId,
31
+ } from "./opencode.js";
@@ -0,0 +1,110 @@
1
+ /**
2
+ * OpenCode session parser
3
+ *
4
+ * Handles session detection for OpenCode.
5
+ * Session files are stored in ~/.local/share/opencode/storage/session/[projectID]/[sessionID].json
6
+ * Session JSON contains: id, projectID, directory (cwd), title, created, updated, etc.
7
+ */
8
+
9
+ import path from "node:path";
10
+ import { homedir } from "node:os";
11
+
12
+ import type { OpenCodeSessionInfo, SessionSearchOptions } from "../types.js";
13
+ import {
14
+ collectFilesIterative,
15
+ matchesCwd,
16
+ readSessionInfoFromFile,
17
+ } from "../common.js";
18
+
19
+ /**
20
+ * Returns the OpenCode session directory
21
+ * OpenCode stores sessions in: ~/.local/share/opencode/storage/session/[projectID]/[sessionID].json
22
+ */
23
+ function getOpenCodeSessionDir(): string {
24
+ return path.join(
25
+ homedir(),
26
+ ".local",
27
+ "share",
28
+ "opencode",
29
+ "storage",
30
+ "session",
31
+ );
32
+ }
33
+
34
+ /**
35
+ * Finds the latest OpenCode session with optional time filtering and cwd matching.
36
+ *
37
+ * @param options - Search options including time filters and cwd matching
38
+ * @returns Session info with ID and modification time, or null if not found
39
+ */
40
+ export async function findLatestOpenCodeSession(
41
+ options: SessionSearchOptions = {},
42
+ ): Promise<OpenCodeSessionInfo | null> {
43
+ // OpenCode stores sessions under ~/.local/share/opencode/storage/session/[projectID]/
44
+ const baseDir = getOpenCodeSessionDir();
45
+ const files = await collectFilesIterative(
46
+ baseDir,
47
+ (name) => name.endsWith(".json") || name.endsWith(".jsonl"),
48
+ );
49
+ if (!files.length) return null;
50
+
51
+ // Apply time filters
52
+ let pool = files;
53
+ const sinceVal = options.since;
54
+ if (sinceVal !== undefined) {
55
+ pool = pool.filter((f) => f.mtime >= sinceVal);
56
+ }
57
+ const untilVal = options.until;
58
+ if (untilVal !== undefined) {
59
+ pool = pool.filter((f) => f.mtime <= untilVal);
60
+ }
61
+ if (!pool.length) return null;
62
+
63
+ // Sort by preference or mtime
64
+ const ref = options.preferClosestTo;
65
+ const window = options.windowMs ?? 30 * 60 * 1000;
66
+ pool = pool.slice().sort((a, b) => {
67
+ if (typeof ref === "number") {
68
+ const da = Math.abs(a.mtime - ref);
69
+ const db = Math.abs(b.mtime - ref);
70
+ if (da === db) return b.mtime - a.mtime;
71
+ if (da <= window || db <= window) return da - db;
72
+ }
73
+ return b.mtime - a.mtime;
74
+ });
75
+
76
+ for (const file of pool) {
77
+ const info = await readSessionInfoFromFile(file.fullPath);
78
+ if (!info.id) continue;
79
+ if (options.cwd) {
80
+ if (matchesCwd(info.cwd, options.cwd)) {
81
+ return { id: info.id, mtime: file.mtime };
82
+ }
83
+ continue;
84
+ }
85
+ return { id: info.id, mtime: file.mtime };
86
+ }
87
+
88
+ return null;
89
+ }
90
+
91
+ /**
92
+ * Finds the latest OpenCode session ID.
93
+ * @param cwd - The working directory to find sessions for (used as fallback if options.cwd not set)
94
+ * @param options - Search options including time filters and cwd matching
95
+ * @returns Session ID string or null if not found
96
+ */
97
+ export async function findLatestOpenCodeSessionId(
98
+ cwd: string,
99
+ options: SessionSearchOptions = {},
100
+ ): Promise<string | null> {
101
+ const searchOptions: SessionSearchOptions = { cwd: options.cwd ?? cwd };
102
+ if (options.since !== undefined) searchOptions.since = options.since;
103
+ if (options.until !== undefined) searchOptions.until = options.until;
104
+ if (options.preferClosestTo !== undefined)
105
+ searchOptions.preferClosestTo = options.preferClosestTo;
106
+ if (options.windowMs !== undefined) searchOptions.windowMs = options.windowMs;
107
+
108
+ const found = await findLatestOpenCodeSession(searchOptions);
109
+ return found?.id ?? null;
110
+ }
@@ -40,3 +40,8 @@ export type CodexSessionInfo = SessionInfo;
40
40
  * Gemini CLI session info
41
41
  */
42
42
  export type GeminiSessionInfo = SessionInfo;
43
+
44
+ /**
45
+ * OpenCode session info
46
+ */
47
+ export type OpenCodeSessionInfo = SessionInfo;
@@ -214,6 +214,30 @@ export function resetTerminalModes(
214
214
  }
215
215
  }
216
216
 
217
+ export function writeTerminalLine(
218
+ message: string,
219
+ stream: "stdout" | "stderr" = "stdout",
220
+ ): void {
221
+ const terminal = getTerminalStreams();
222
+ const target = stream === "stderr" ? terminal.stderr : terminal.stdout;
223
+ const payload = message.endsWith("\n") ? message : `${message}\n`;
224
+
225
+ if (target && typeof target.write === "function") {
226
+ try {
227
+ target.write(payload);
228
+ return;
229
+ } catch {
230
+ // Ignore write errors and fall back to console.
231
+ }
232
+ }
233
+
234
+ if (stream === "stderr") {
235
+ console.error(message);
236
+ } else {
237
+ console.log(message);
238
+ }
239
+ }
240
+
217
241
  /**
218
242
  * Creates stdio settings for launching a child process.
219
243
  *
package/src/utils.test.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { describe, it, expect, beforeEach, afterEach } from "vitest";
1
+ import { describe, it, expect } from "bun:test";
2
2
  import { getPackageVersion } from "./utils";
3
3
  import { readFile } from "fs/promises";
4
4
  import path from "node:path";
package/src/utils.ts CHANGED
@@ -1,7 +1,6 @@
1
1
  import path from "node:path";
2
2
  import { fileURLToPath } from "node:url";
3
- import { access, readFile } from "fs/promises";
4
- import { existsSync } from "fs";
3
+ import { readFile } from "fs/promises";
5
4
  export function getCurrentDirname(): string {
6
5
  return path.dirname(fileURLToPath(import.meta.url));
7
6
  }
@@ -16,17 +15,51 @@ export class AppError extends Error {
16
15
  }
17
16
  }
18
17
 
18
+ /**
19
+ * Global cleanup callback for terminal restoration.
20
+ * This is called before exit to restore terminal state.
21
+ */
22
+ let cleanupCallback: (() => void) | null = null;
23
+
24
+ /**
25
+ * Registers a cleanup callback to be called on exit.
26
+ * Used for terminal state restoration.
27
+ */
28
+ export function registerExitCleanup(callback: () => void): void {
29
+ cleanupCallback = callback;
30
+ }
31
+
32
+ /**
33
+ * Clears the registered cleanup callback.
34
+ */
35
+ export function clearExitCleanup(): void {
36
+ cleanupCallback = null;
37
+ }
38
+
39
+ /**
40
+ * Performs cleanup and exits the process.
41
+ * Ensures terminal is restored before exiting.
42
+ */
43
+ function performCleanupAndExit(exitCode: number): void {
44
+ try {
45
+ cleanupCallback?.();
46
+ } catch {
47
+ // Ignore cleanup errors to ensure exit completes
48
+ }
49
+ process.exit(exitCode);
50
+ }
51
+
19
52
  export function setupExitHandlers(): void {
20
53
  // Handle Ctrl+C gracefully
21
54
  process.on("SIGINT", () => {
22
55
  console.log("\n\n👋 Goodbye!");
23
- process.exit(0);
56
+ performCleanupAndExit(0);
24
57
  });
25
58
 
26
59
  // Handle other termination signals
27
60
  process.on("SIGTERM", () => {
28
61
  console.log("\n\n👋 Goodbye!");
29
- process.exit(0);
62
+ performCleanupAndExit(0);
30
63
  });
31
64
  }
32
65
 
@@ -21,6 +21,7 @@ import { useStartSession } from "../hooks/useSessions";
21
21
  import { useCreateWorktree } from "../hooks/useWorktrees";
22
22
  import { useSyncBranch } from "../hooks/useBranches";
23
23
  import { ApiError } from "../lib/api";
24
+ import { getAgentTailwindClass } from "@/lib/coding-agent-colors";
24
25
 
25
26
  const BUILTIN_AGENT_SUMMARIES: Record<string, AgentSummary> = {
26
27
  "claude-code": {
@@ -166,7 +167,7 @@ export function CodingAgentLaunchModal({
166
167
  branch.name.replace(/^origin\//, ""),
167
168
  );
168
169
  const divergenceInfo = branch.divergence ?? null;
169
- const hasBlockingDivergence = Boolean(
170
+ const hasConflictingDivergence = Boolean(
170
171
  divergenceInfo && divergenceInfo.ahead > 0 && divergenceInfo.behind > 0,
171
172
  );
172
173
  const needsRemoteSync = Boolean(
@@ -174,7 +175,7 @@ export function CodingAgentLaunchModal({
174
175
  divergenceInfo &&
175
176
  divergenceInfo.behind > 0 &&
176
177
  divergenceInfo.ahead === 0 &&
177
- !hasBlockingDivergence,
178
+ !hasConflictingDivergence,
178
179
  );
179
180
 
180
181
  useEffect(() => {
@@ -270,15 +271,6 @@ export function CodingAgentLaunchModal({
270
271
  });
271
272
  return;
272
273
  }
273
- if (hasBlockingDivergence) {
274
- setBanner({
275
- type: "error",
276
- message:
277
- "Both remote and local have diverged. Resolve differences before launching.",
278
- });
279
- return;
280
- }
281
-
282
274
  if (
283
275
  skipPermissions &&
284
276
  !window.confirm("Skip permission checks? This is risky.")
@@ -408,11 +400,11 @@ export function CodingAgentLaunchModal({
408
400
  </Alert>
409
401
  )}
410
402
 
411
- {hasBlockingDivergence && (
403
+ {hasConflictingDivergence && (
412
404
  <Alert variant="warning">
413
405
  <AlertDescription>
414
- Both remote and local have unresolved differences. Rebase/merge
415
- before launching.
406
+ Both remote and local have unresolved differences. You can
407
+ launch, but resolving differences is recommended.
416
408
  </AlertDescription>
417
409
  </Alert>
418
410
  )}
@@ -430,7 +422,11 @@ export function CodingAgentLaunchModal({
430
422
  </SelectTrigger>
431
423
  <SelectContent>
432
424
  {availableAgents.map((agent) => (
433
- <SelectItem key={agent.id} value={agent.id}>
425
+ <SelectItem
426
+ key={agent.id}
427
+ value={agent.id}
428
+ className={getAgentTailwindClass(agent.id)}
429
+ >
434
430
  {agent.label}
435
431
  </SelectItem>
436
432
  ))}
@@ -479,12 +475,7 @@ export function CodingAgentLaunchModal({
479
475
  <div className="flex flex-wrap gap-2">
480
476
  <Button
481
477
  onClick={handleStartSession}
482
- disabled={
483
- isStartingSession ||
484
- !selectedAgent ||
485
- hasBlockingDivergence ||
486
- needsRemoteSync
487
- }
478
+ disabled={isStartingSession || !selectedAgent || needsRemoteSync}
488
479
  >
489
480
  {isStartingSession ? "Launching..." : "Launch coding agent"}
490
481
  </Button>
@@ -2,6 +2,10 @@ import React from "react";
2
2
  import { Card, CardHeader, CardContent } from "@/components/ui/card";
3
3
  import { Badge } from "@/components/ui/badge";
4
4
  import type { Branch, LastToolUsage } from "../../../../../types/api.js";
5
+ import {
6
+ getAgentTailwindClass,
7
+ getAgentBgTailwindClass,
8
+ } from "@/lib/coding-agent-colors";
5
9
 
6
10
  interface BranchInfoCardsProps {
7
11
  branch: Branch;
@@ -158,7 +162,10 @@ export function BranchInfoCards({
158
162
  </CardHeader>
159
163
  <CardContent>
160
164
  <div className="flex flex-wrap items-center gap-2 text-sm">
161
- <Badge variant="outline">
165
+ <Badge
166
+ variant="outline"
167
+ className={`${getAgentTailwindClass(latestToolUsage.toolId)} ${getAgentBgTailwindClass(latestToolUsage.toolId)}`}
168
+ >
162
169
  {renderToolUsage(latestToolUsage)}
163
170
  </Badge>
164
171
  <span className="text-muted-foreground">
@@ -169,6 +176,14 @@ export function BranchInfoCards({
169
176
  @ {latestToolUsage.worktreePath}
170
177
  </span>
171
178
  )}
179
+ {latestToolUsage.sessionId && (
180
+ <span className="text-xs text-muted-foreground">
181
+ Session ID:{" "}
182
+ <code className="rounded bg-muted px-1.5 py-0.5 font-mono">
183
+ {latestToolUsage.sessionId}
184
+ </code>
185
+ </span>
186
+ )}
172
187
  </div>
173
188
  </CardContent>
174
189
  </Card>