@akiojin/gwt 4.10.0 → 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 (579) 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.js +4 -4
  156. package/dist/config/builtin-coding-agents.js.map +1 -1
  157. package/dist/config/index.d.ts +2 -0
  158. package/dist/config/index.d.ts.map +1 -1
  159. package/dist/config/index.js +2 -0
  160. package/dist/config/index.js.map +1 -1
  161. package/dist/gemini.d.ts +1 -0
  162. package/dist/gemini.d.ts.map +1 -1
  163. package/dist/gemini.js +42 -37
  164. package/dist/gemini.js.map +1 -1
  165. package/dist/index.d.ts +1 -1
  166. package/dist/index.d.ts.map +1 -1
  167. package/dist/index.js +122 -102
  168. package/dist/index.js.map +1 -1
  169. package/dist/launcher.d.ts.map +1 -1
  170. package/dist/launcher.js +18 -3
  171. package/dist/launcher.js.map +1 -1
  172. package/dist/logging/logger.d.ts.map +1 -1
  173. package/dist/logging/logger.js +26 -9
  174. package/dist/logging/logger.js.map +1 -1
  175. package/dist/opentui/highlights-eq9cgrbb.scm +604 -0
  176. package/dist/opentui/highlights-ghv9g403.scm +205 -0
  177. package/dist/opentui/highlights-hk7bwhj4.scm +284 -0
  178. package/dist/opentui/highlights-r812a2qc.scm +150 -0
  179. package/dist/opentui/highlights-x6tmsnaa.scm +115 -0
  180. package/dist/opentui/index.solid.d.ts +2 -0
  181. package/dist/opentui/index.solid.d.ts.map +1 -0
  182. package/dist/opentui/index.solid.js +52034 -0
  183. package/dist/opentui/index.solid.js.map +1 -0
  184. package/dist/opentui/injections-73j83es3.scm +27 -0
  185. package/dist/opentui/tree-sitter-javascript-nd0q4pe9.wasm +0 -0
  186. package/dist/opentui/tree-sitter-markdown-411r6y9b.wasm +0 -0
  187. package/dist/opentui/tree-sitter-markdown_inline-j5349f42.wasm +0 -0
  188. package/dist/opentui/tree-sitter-typescript-zxjzwt75.wasm +0 -0
  189. package/dist/opentui/tree-sitter-zig-e78zbjpm.wasm +0 -0
  190. package/dist/repositories/worktree.repository.d.ts +1 -0
  191. package/dist/repositories/worktree.repository.d.ts.map +1 -1
  192. package/dist/repositories/worktree.repository.js +7 -0
  193. package/dist/repositories/worktree.repository.js.map +1 -1
  194. package/dist/services/codingAgentResolver.d.ts +2 -0
  195. package/dist/services/codingAgentResolver.d.ts.map +1 -1
  196. package/dist/services/codingAgentResolver.js +30 -4
  197. package/dist/services/codingAgentResolver.js.map +1 -1
  198. package/dist/services/dependency-installer.d.ts.map +1 -1
  199. package/dist/services/dependency-installer.js +0 -5
  200. package/dist/services/dependency-installer.js.map +1 -1
  201. package/dist/types/api.d.ts +3 -0
  202. package/dist/types/api.d.ts.map +1 -1
  203. package/dist/types/coding-agent.d.ts +62 -0
  204. package/dist/types/coding-agent.d.ts.map +1 -0
  205. package/dist/types/coding-agent.js +29 -0
  206. package/dist/types/coding-agent.js.map +1 -0
  207. package/dist/types/tools.d.ts +17 -0
  208. package/dist/types/tools.d.ts.map +1 -1
  209. package/dist/utils/coding-agent-colors.d.ts +88 -0
  210. package/dist/utils/coding-agent-colors.d.ts.map +1 -0
  211. package/dist/utils/coding-agent-colors.js +137 -0
  212. package/dist/utils/coding-agent-colors.js.map +1 -0
  213. package/dist/utils/command.d.ts +1 -1
  214. package/dist/utils/command.js +1 -1
  215. package/dist/utils/error-utils.d.ts +27 -0
  216. package/dist/utils/error-utils.d.ts.map +1 -0
  217. package/dist/utils/error-utils.js +98 -0
  218. package/dist/utils/error-utils.js.map +1 -0
  219. package/dist/utils/npmRegistry.d.ts +61 -0
  220. package/dist/utils/npmRegistry.d.ts.map +1 -0
  221. package/dist/utils/npmRegistry.js +180 -0
  222. package/dist/utils/npmRegistry.js.map +1 -0
  223. package/dist/utils/prompt.d.ts +1 -1
  224. package/dist/utils/prompt.js +1 -1
  225. package/dist/utils/session/parsers/codex.d.ts.map +1 -1
  226. package/dist/utils/session/parsers/codex.js +8 -1
  227. package/dist/utils/session/parsers/codex.js.map +1 -1
  228. package/dist/utils/terminal.d.ts +1 -0
  229. package/dist/utils/terminal.d.ts.map +1 -1
  230. package/dist/utils/terminal.js +20 -0
  231. package/dist/utils/terminal.js.map +1 -1
  232. package/dist/utils.d.ts +9 -0
  233. package/dist/utils.d.ts.map +1 -1
  234. package/dist/utils.js +33 -2
  235. package/dist/utils.js.map +1 -1
  236. package/dist/web/client/src/components/CodingAgentLaunchModal.d.ts.map +1 -1
  237. package/dist/web/client/src/components/CodingAgentLaunchModal.js +7 -16
  238. package/dist/web/client/src/components/CodingAgentLaunchModal.js.map +1 -1
  239. package/dist/web/client/src/components/branch-detail/BranchInfoCards.d.ts.map +1 -1
  240. package/dist/web/client/src/components/branch-detail/BranchInfoCards.js +7 -2
  241. package/dist/web/client/src/components/branch-detail/BranchInfoCards.js.map +1 -1
  242. package/dist/web/client/src/components/branch-detail/SessionHistoryTable.d.ts.map +1 -1
  243. package/dist/web/client/src/components/branch-detail/SessionHistoryTable.js +2 -1
  244. package/dist/web/client/src/components/branch-detail/SessionHistoryTable.js.map +1 -1
  245. package/dist/web/client/src/components/branch-detail/ToolLauncher.d.ts +2 -2
  246. package/dist/web/client/src/components/branch-detail/ToolLauncher.d.ts.map +1 -1
  247. package/dist/web/client/src/components/branch-detail/ToolLauncher.js +5 -5
  248. package/dist/web/client/src/components/branch-detail/ToolLauncher.js.map +1 -1
  249. package/dist/web/client/src/lib/coding-agent-colors.d.ts +86 -0
  250. package/dist/web/client/src/lib/coding-agent-colors.d.ts.map +1 -0
  251. package/dist/web/client/src/lib/coding-agent-colors.js +135 -0
  252. package/dist/web/client/src/lib/coding-agent-colors.js.map +1 -0
  253. package/dist/web/client/src/pages/BranchDetailPage.js +10 -10
  254. package/dist/web/client/src/pages/BranchDetailPage.js.map +1 -1
  255. package/dist/web/server/pty/manager.d.ts +2 -0
  256. package/dist/web/server/pty/manager.d.ts.map +1 -1
  257. package/dist/web/server/pty/manager.js +104 -0
  258. package/dist/web/server/pty/manager.js.map +1 -1
  259. package/dist/web/server/routes/sessions.d.ts.map +1 -1
  260. package/dist/web/server/routes/sessions.js +5 -1
  261. package/dist/web/server/routes/sessions.js.map +1 -1
  262. package/dist/web/server/services/branches.d.ts.map +1 -1
  263. package/dist/web/server/services/branches.js +10 -8
  264. package/dist/web/server/services/branches.js.map +1 -1
  265. package/dist/web/server/services/worktrees.js +2 -2
  266. package/dist/web/server/services/worktrees.js.map +1 -1
  267. package/dist/worktree.d.ts +47 -1
  268. package/dist/worktree.d.ts.map +1 -1
  269. package/dist/worktree.js +280 -94
  270. package/dist/worktree.js.map +1 -1
  271. package/package.json +12 -14
  272. package/src/claude.ts +68 -70
  273. package/src/cli/ui/App.solid.tsx +1823 -0
  274. package/src/cli/ui/__tests__/solid/AppSolid.cleanup.test.tsx +255 -0
  275. package/src/cli/ui/__tests__/solid/BranchListScreen.test.tsx +243 -0
  276. package/src/cli/ui/__tests__/solid/components/QuickStartStep.test.tsx +237 -0
  277. package/src/cli/ui/__tests__/solid/components/WizardPopup.test.tsx +231 -0
  278. package/src/cli/ui/__tests__/solid/components/WizardSteps.test.tsx +238 -0
  279. package/src/cli/ui/__tests__/utils/branchFormatter.test.ts +7 -289
  280. package/src/cli/ui/__tests__/utils/clipboard.test.ts +3 -3
  281. package/src/cli/ui/__tests__/utils/statisticsCalculator.test.ts +1 -1
  282. package/src/cli/ui/components/solid/Footer.tsx +36 -0
  283. package/src/cli/ui/components/{parts → solid}/Header.tsx +17 -28
  284. package/src/cli/ui/components/solid/HelpOverlay.tsx +194 -0
  285. package/src/cli/ui/components/solid/QuickStartStep.tsx +197 -0
  286. package/src/cli/ui/components/{parts → solid}/ScrollableList.tsx +7 -8
  287. package/src/cli/ui/components/solid/SearchInput.tsx +42 -0
  288. package/src/cli/ui/components/solid/SelectInput.tsx +84 -0
  289. package/src/cli/ui/components/solid/Stats.tsx +92 -0
  290. package/src/cli/ui/components/solid/TextInput.tsx +49 -0
  291. package/src/cli/ui/components/solid/WizardController.tsx +384 -0
  292. package/src/cli/ui/components/solid/WizardPopup.tsx +135 -0
  293. package/src/cli/ui/components/solid/WizardSteps.tsx +793 -0
  294. package/src/cli/ui/core/index.ts +17 -0
  295. package/src/cli/ui/core/keybindings.ts +367 -0
  296. package/src/cli/ui/core/theme.ts +234 -0
  297. package/src/cli/ui/core/types.ts +235 -0
  298. package/src/cli/ui/hooks/solid/useAsyncOperation.ts +76 -0
  299. package/src/cli/ui/hooks/solid/useFilter.ts +86 -0
  300. package/src/cli/ui/hooks/solid/useGitOperations.ts +80 -0
  301. package/src/cli/ui/hooks/solid/useKeyHandler.ts +103 -0
  302. package/src/cli/ui/hooks/solid/useScrollableList.ts +149 -0
  303. package/src/cli/ui/hooks/solid/useSelection.ts +77 -0
  304. package/src/cli/ui/hooks/solid/useTerminalSize.ts +22 -0
  305. package/src/cli/ui/index.solid.ts +28 -0
  306. package/src/cli/ui/screens/solid/BranchListScreen.tsx +1050 -0
  307. package/src/cli/ui/screens/solid/ConfirmScreen.tsx +74 -0
  308. package/src/cli/ui/screens/solid/EnvironmentScreen.tsx +159 -0
  309. package/src/cli/ui/screens/solid/ErrorScreen.tsx +42 -0
  310. package/src/cli/ui/screens/solid/InputScreen.tsx +55 -0
  311. package/src/cli/ui/screens/solid/LoadingIndicator.tsx +77 -0
  312. package/src/cli/ui/screens/solid/LogDetailScreen.tsx +75 -0
  313. package/src/cli/ui/screens/solid/LogScreen.tsx +175 -0
  314. package/src/cli/ui/screens/solid/ProfileEnvScreen.tsx +192 -0
  315. package/src/cli/ui/screens/solid/ProfileScreen.tsx +98 -0
  316. package/src/cli/ui/screens/solid/SelectorScreen.tsx +170 -0
  317. package/src/cli/ui/screens/solid/SettingsScreen.tsx +50 -0
  318. package/src/cli/ui/screens/solid/WorktreeCreateScreen.tsx +136 -0
  319. package/src/cli/ui/screens/solid/WorktreeDeleteScreen.tsx +40 -0
  320. package/src/cli/ui/stores/appStore.ts +208 -0
  321. package/src/cli/ui/stores/branchStore.ts +357 -0
  322. package/src/cli/ui/stores/index.ts +31 -0
  323. package/src/cli/ui/stores/uiStore.ts +226 -0
  324. package/src/cli/ui/types.ts +20 -3
  325. package/src/cli/ui/utils/__tests__/branchFormatter.test.ts +180 -0
  326. package/src/cli/ui/utils/branchFormatter.ts +8 -215
  327. package/src/cli/ui/utils/continueSession.ts +44 -0
  328. package/src/cli/ui/utils/modelOptions.test.ts +1 -1
  329. package/src/codex.ts +100 -43
  330. package/src/config/__tests__/saveSession.test.ts +143 -0
  331. package/src/config/builtin-coding-agents.ts +4 -4
  332. package/src/config/index.ts +4 -0
  333. package/src/gemini.ts +58 -43
  334. package/src/index.test.ts +12 -12
  335. package/src/index.ts +164 -142
  336. package/src/launcher.ts +22 -3
  337. package/src/logging/logger.ts +32 -10
  338. package/src/opentui/index.solid.ts +1 -0
  339. package/src/repositories/worktree.repository.ts +8 -0
  340. package/src/services/__tests__/BatchMergeService.test.ts +62 -66
  341. package/src/services/__tests__/WorktreeOrchestrator.test.ts +8 -7
  342. package/src/services/codingAgentResolver.ts +30 -4
  343. package/src/services/dependency-installer.ts +0 -7
  344. package/src/types/api.ts +3 -0
  345. package/src/types/coding-agent.ts +85 -0
  346. package/src/types/tools.ts +19 -0
  347. package/src/utils/__tests__/npmRegistry.test.ts +250 -0
  348. package/src/utils/__tests__/prompt.test.ts +4 -5
  349. package/src/utils/coding-agent-colors.ts +165 -0
  350. package/src/utils/command.ts +1 -1
  351. package/src/utils/error-utils.ts +133 -0
  352. package/src/utils/npmRegistry.ts +249 -0
  353. package/src/utils/prompt.ts +1 -1
  354. package/src/utils/session/parsers/codex.ts +9 -1
  355. package/src/utils/terminal.ts +24 -0
  356. package/src/utils.test.ts +1 -1
  357. package/src/utils.ts +37 -4
  358. package/src/web/client/src/components/CodingAgentLaunchModal.tsx +12 -21
  359. package/src/web/client/src/components/branch-detail/BranchInfoCards.tsx +16 -1
  360. package/src/web/client/src/components/branch-detail/SessionHistoryTable.tsx +7 -1
  361. package/src/web/client/src/components/branch-detail/ToolLauncher.tsx +11 -6
  362. package/src/web/client/src/lib/coding-agent-colors.ts +149 -0
  363. package/src/web/client/src/pages/BranchDetailPage.tsx +11 -11
  364. package/src/web/server/pty/manager.ts +139 -0
  365. package/src/web/server/routes/sessions.ts +6 -0
  366. package/src/web/server/services/branches.ts +11 -8
  367. package/src/web/server/services/worktrees.ts +2 -2
  368. package/src/worktree.ts +366 -107
  369. package/dist/cli/ui/components/App.d.ts +0 -25
  370. package/dist/cli/ui/components/App.d.ts.map +0 -1
  371. package/dist/cli/ui/components/App.js +0 -1006
  372. package/dist/cli/ui/components/App.js.map +0 -1
  373. package/dist/cli/ui/components/common/Confirm.d.ts +0 -13
  374. package/dist/cli/ui/components/common/Confirm.d.ts.map +0 -1
  375. package/dist/cli/ui/components/common/Confirm.js +0 -20
  376. package/dist/cli/ui/components/common/Confirm.js.map +0 -1
  377. package/dist/cli/ui/components/common/ErrorBoundary.d.ts +0 -23
  378. package/dist/cli/ui/components/common/ErrorBoundary.d.ts.map +0 -1
  379. package/dist/cli/ui/components/common/ErrorBoundary.js +0 -37
  380. package/dist/cli/ui/components/common/ErrorBoundary.js.map +0 -1
  381. package/dist/cli/ui/components/common/Input.d.ts +0 -19
  382. package/dist/cli/ui/components/common/Input.d.ts.map +0 -1
  383. package/dist/cli/ui/components/common/Input.js +0 -22
  384. package/dist/cli/ui/components/common/Input.js.map +0 -1
  385. package/dist/cli/ui/components/common/LoadingIndicator.d.ts +0 -19
  386. package/dist/cli/ui/components/common/LoadingIndicator.d.ts.map +0 -1
  387. package/dist/cli/ui/components/common/LoadingIndicator.js +0 -61
  388. package/dist/cli/ui/components/common/LoadingIndicator.js.map +0 -1
  389. package/dist/cli/ui/components/common/Select.d.ts +0 -38
  390. package/dist/cli/ui/components/common/Select.d.ts.map +0 -1
  391. package/dist/cli/ui/components/common/Select.js +0 -151
  392. package/dist/cli/ui/components/common/Select.js.map +0 -1
  393. package/dist/cli/ui/components/common/SpinnerIcon.d.ts +0 -20
  394. package/dist/cli/ui/components/common/SpinnerIcon.d.ts.map +0 -1
  395. package/dist/cli/ui/components/common/SpinnerIcon.js +0 -61
  396. package/dist/cli/ui/components/common/SpinnerIcon.js.map +0 -1
  397. package/dist/cli/ui/components/parts/Footer.d.ts +0 -15
  398. package/dist/cli/ui/components/parts/Footer.d.ts.map +0 -1
  399. package/dist/cli/ui/components/parts/Footer.js +0 -20
  400. package/dist/cli/ui/components/parts/Footer.js.map +0 -1
  401. package/dist/cli/ui/components/parts/Header.d.ts.map +0 -1
  402. package/dist/cli/ui/components/parts/Header.js +0 -24
  403. package/dist/cli/ui/components/parts/Header.js.map +0 -1
  404. package/dist/cli/ui/components/parts/MergeStatusList.d.ts +0 -13
  405. package/dist/cli/ui/components/parts/MergeStatusList.d.ts.map +0 -1
  406. package/dist/cli/ui/components/parts/MergeStatusList.js +0 -52
  407. package/dist/cli/ui/components/parts/MergeStatusList.js.map +0 -1
  408. package/dist/cli/ui/components/parts/ProgressBar.d.ts +0 -13
  409. package/dist/cli/ui/components/parts/ProgressBar.d.ts.map +0 -1
  410. package/dist/cli/ui/components/parts/ProgressBar.js +0 -53
  411. package/dist/cli/ui/components/parts/ProgressBar.js.map +0 -1
  412. package/dist/cli/ui/components/parts/ScrollableList.d.ts +0 -12
  413. package/dist/cli/ui/components/parts/ScrollableList.d.ts.map +0 -1
  414. package/dist/cli/ui/components/parts/ScrollableList.js +0 -11
  415. package/dist/cli/ui/components/parts/ScrollableList.js.map +0 -1
  416. package/dist/cli/ui/components/parts/Stats.d.ts +0 -10
  417. package/dist/cli/ui/components/parts/Stats.d.ts.map +0 -1
  418. package/dist/cli/ui/components/parts/Stats.js +0 -55
  419. package/dist/cli/ui/components/parts/Stats.js.map +0 -1
  420. package/dist/cli/ui/components/screens/BatchMergeProgressScreen.d.ts +0 -17
  421. package/dist/cli/ui/components/screens/BatchMergeProgressScreen.d.ts.map +0 -1
  422. package/dist/cli/ui/components/screens/BatchMergeProgressScreen.js +0 -42
  423. package/dist/cli/ui/components/screens/BatchMergeProgressScreen.js.map +0 -1
  424. package/dist/cli/ui/components/screens/BatchMergeResultScreen.d.ts +0 -17
  425. package/dist/cli/ui/components/screens/BatchMergeResultScreen.d.ts.map +0 -1
  426. package/dist/cli/ui/components/screens/BatchMergeResultScreen.js +0 -72
  427. package/dist/cli/ui/components/screens/BatchMergeResultScreen.js.map +0 -1
  428. package/dist/cli/ui/components/screens/BranchCreatorScreen.d.ts +0 -18
  429. package/dist/cli/ui/components/screens/BranchCreatorScreen.d.ts.map +0 -1
  430. package/dist/cli/ui/components/screens/BranchCreatorScreen.js +0 -151
  431. package/dist/cli/ui/components/screens/BranchCreatorScreen.js.map +0 -1
  432. package/dist/cli/ui/components/screens/BranchListScreen.d.ts.map +0 -1
  433. package/dist/cli/ui/components/screens/BranchListScreen.js +0 -476
  434. package/dist/cli/ui/components/screens/BranchListScreen.js.map +0 -1
  435. package/dist/cli/ui/components/screens/BranchQuickStartScreen.d.ts +0 -30
  436. package/dist/cli/ui/components/screens/BranchQuickStartScreen.d.ts.map +0 -1
  437. package/dist/cli/ui/components/screens/BranchQuickStartScreen.js +0 -148
  438. package/dist/cli/ui/components/screens/BranchQuickStartScreen.js.map +0 -1
  439. package/dist/cli/ui/components/screens/CodingAgentSelectorScreen.d.ts +0 -27
  440. package/dist/cli/ui/components/screens/CodingAgentSelectorScreen.d.ts.map +0 -1
  441. package/dist/cli/ui/components/screens/CodingAgentSelectorScreen.js +0 -93
  442. package/dist/cli/ui/components/screens/CodingAgentSelectorScreen.js.map +0 -1
  443. package/dist/cli/ui/components/screens/EnvironmentProfileScreen.d.ts +0 -19
  444. package/dist/cli/ui/components/screens/EnvironmentProfileScreen.d.ts.map +0 -1
  445. package/dist/cli/ui/components/screens/EnvironmentProfileScreen.js +0 -577
  446. package/dist/cli/ui/components/screens/EnvironmentProfileScreen.js.map +0 -1
  447. package/dist/cli/ui/components/screens/ExecutionModeSelectorScreen.d.ts +0 -45
  448. package/dist/cli/ui/components/screens/ExecutionModeSelectorScreen.d.ts.map +0 -1
  449. package/dist/cli/ui/components/screens/ExecutionModeSelectorScreen.js +0 -95
  450. package/dist/cli/ui/components/screens/ExecutionModeSelectorScreen.js.map +0 -1
  451. package/dist/cli/ui/components/screens/LogDatePickerScreen.d.ts +0 -10
  452. package/dist/cli/ui/components/screens/LogDatePickerScreen.d.ts.map +0 -1
  453. package/dist/cli/ui/components/screens/LogDatePickerScreen.js +0 -44
  454. package/dist/cli/ui/components/screens/LogDatePickerScreen.js.map +0 -1
  455. package/dist/cli/ui/components/screens/LogDetailScreen.d.ts.map +0 -1
  456. package/dist/cli/ui/components/screens/LogDetailScreen.js +0 -34
  457. package/dist/cli/ui/components/screens/LogDetailScreen.js.map +0 -1
  458. package/dist/cli/ui/components/screens/LogListScreen.d.ts.map +0 -1
  459. package/dist/cli/ui/components/screens/LogListScreen.js +0 -107
  460. package/dist/cli/ui/components/screens/LogListScreen.js.map +0 -1
  461. package/dist/cli/ui/components/screens/ModelSelectorScreen.d.ts +0 -24
  462. package/dist/cli/ui/components/screens/ModelSelectorScreen.d.ts.map +0 -1
  463. package/dist/cli/ui/components/screens/ModelSelectorScreen.js +0 -197
  464. package/dist/cli/ui/components/screens/ModelSelectorScreen.js.map +0 -1
  465. package/dist/cli/ui/components/screens/PRCleanupScreen.d.ts +0 -29
  466. package/dist/cli/ui/components/screens/PRCleanupScreen.d.ts.map +0 -1
  467. package/dist/cli/ui/components/screens/PRCleanupScreen.js +0 -92
  468. package/dist/cli/ui/components/screens/PRCleanupScreen.js.map +0 -1
  469. package/dist/cli/ui/components/screens/SessionSelectorScreen.d.ts +0 -31
  470. package/dist/cli/ui/components/screens/SessionSelectorScreen.d.ts.map +0 -1
  471. package/dist/cli/ui/components/screens/SessionSelectorScreen.js +0 -67
  472. package/dist/cli/ui/components/screens/SessionSelectorScreen.js.map +0 -1
  473. package/dist/cli/ui/hooks/useAppInput.d.ts +0 -21
  474. package/dist/cli/ui/hooks/useAppInput.d.ts.map +0 -1
  475. package/dist/cli/ui/hooks/useAppInput.js +0 -138
  476. package/dist/cli/ui/hooks/useAppInput.js.map +0 -1
  477. package/dist/cli/ui/hooks/useBatchMerge.d.ts +0 -17
  478. package/dist/cli/ui/hooks/useBatchMerge.d.ts.map +0 -1
  479. package/dist/cli/ui/hooks/useBatchMerge.js +0 -77
  480. package/dist/cli/ui/hooks/useBatchMerge.js.map +0 -1
  481. package/dist/cli/ui/hooks/useGitData.d.ts +0 -21
  482. package/dist/cli/ui/hooks/useGitData.d.ts.map +0 -1
  483. package/dist/cli/ui/hooks/useGitData.js +0 -229
  484. package/dist/cli/ui/hooks/useGitData.js.map +0 -1
  485. package/dist/cli/ui/hooks/useProfiles.d.ts +0 -41
  486. package/dist/cli/ui/hooks/useProfiles.d.ts.map +0 -1
  487. package/dist/cli/ui/hooks/useProfiles.js +0 -136
  488. package/dist/cli/ui/hooks/useProfiles.js.map +0 -1
  489. package/dist/cli/ui/hooks/useScreenState.d.ts +0 -12
  490. package/dist/cli/ui/hooks/useScreenState.d.ts.map +0 -1
  491. package/dist/cli/ui/hooks/useScreenState.js +0 -30
  492. package/dist/cli/ui/hooks/useScreenState.js.map +0 -1
  493. package/dist/cli/ui/hooks/useTerminalSize.d.ts +0 -9
  494. package/dist/cli/ui/hooks/useTerminalSize.d.ts.map +0 -1
  495. package/dist/cli/ui/hooks/useTerminalSize.js +0 -24
  496. package/dist/cli/ui/hooks/useTerminalSize.js.map +0 -1
  497. package/dist/cli/ui/hooks/useToolStatus.d.ts +0 -30
  498. package/dist/cli/ui/hooks/useToolStatus.d.ts.map +0 -1
  499. package/dist/cli/ui/hooks/useToolStatus.js +0 -49
  500. package/dist/cli/ui/hooks/useToolStatus.js.map +0 -1
  501. package/dist/cli/ui/screens/BranchActionSelectorScreen.d.ts +0 -24
  502. package/dist/cli/ui/screens/BranchActionSelectorScreen.d.ts.map +0 -1
  503. package/dist/cli/ui/screens/BranchActionSelectorScreen.js +0 -65
  504. package/dist/cli/ui/screens/BranchActionSelectorScreen.js.map +0 -1
  505. package/dist/client/assets/index-LNPtOrn3.js +0 -78
  506. package/src/cli/ui/__tests__/SKIPPED_TESTS.md +0 -119
  507. package/src/cli/ui/__tests__/acceptance/branchList.acceptance.test.tsx.skip +0 -239
  508. package/src/cli/ui/__tests__/acceptance/navigation.acceptance.test.tsx +0 -225
  509. package/src/cli/ui/__tests__/acceptance/realtimeUpdate.acceptance.test.tsx.skip +0 -219
  510. package/src/cli/ui/__tests__/components/App.protected-branch.test.tsx +0 -212
  511. package/src/cli/ui/__tests__/components/App.shortcuts.test.tsx +0 -440
  512. package/src/cli/ui/__tests__/components/App.test.tsx +0 -365
  513. package/src/cli/ui/__tests__/components/ModelSelectorScreen.initial.test.tsx +0 -91
  514. package/src/cli/ui/__tests__/components/common/Confirm.test.tsx +0 -80
  515. package/src/cli/ui/__tests__/components/common/ErrorBoundary.test.tsx +0 -104
  516. package/src/cli/ui/__tests__/components/common/Input.test.tsx +0 -100
  517. package/src/cli/ui/__tests__/components/common/LoadingIndicator.test.tsx +0 -148
  518. package/src/cli/ui/__tests__/components/common/Select.memo.test.tsx +0 -255
  519. package/src/cli/ui/__tests__/components/common/Select.test.tsx +0 -335
  520. package/src/cli/ui/__tests__/components/parts/Footer.test.tsx +0 -65
  521. package/src/cli/ui/__tests__/components/parts/Header.test.tsx +0 -55
  522. package/src/cli/ui/__tests__/components/parts/ScrollableList.test.tsx +0 -69
  523. package/src/cli/ui/__tests__/components/parts/Stats.test.tsx +0 -148
  524. package/src/cli/ui/__tests__/components/screens/BranchCreatorScreen.test.tsx +0 -253
  525. package/src/cli/ui/__tests__/components/screens/BranchListScreen.test.tsx +0 -1070
  526. package/src/cli/ui/__tests__/components/screens/BranchQuickStartScreen.test.tsx +0 -142
  527. package/src/cli/ui/__tests__/components/screens/CodingAgentSelectorScreen.test.tsx +0 -174
  528. package/src/cli/ui/__tests__/components/screens/ExecutionModeSelectorScreen.test.tsx +0 -182
  529. package/src/cli/ui/__tests__/components/screens/LogDetailScreen.test.tsx +0 -57
  530. package/src/cli/ui/__tests__/components/screens/LogListScreen.test.tsx +0 -102
  531. package/src/cli/ui/__tests__/components/screens/PRCleanupScreen.test.tsx +0 -216
  532. package/src/cli/ui/__tests__/components/screens/SessionSelectorScreen.test.tsx +0 -147
  533. package/src/cli/ui/__tests__/hooks/useGitData.nonblocking.test.tsx +0 -206
  534. package/src/cli/ui/__tests__/hooks/useGitData.test.ts +0 -197
  535. package/src/cli/ui/__tests__/hooks/useGitData.test.ts.skip +0 -228
  536. package/src/cli/ui/__tests__/hooks/useScreenState.test.ts +0 -147
  537. package/src/cli/ui/__tests__/hooks/useTerminalSize.test.ts +0 -99
  538. package/src/cli/ui/__tests__/integration/branchList.test.tsx.skip +0 -253
  539. package/src/cli/ui/__tests__/integration/edgeCases.test.tsx +0 -436
  540. package/src/cli/ui/__tests__/integration/navigation.test.tsx +0 -514
  541. package/src/cli/ui/__tests__/integration/realtimeUpdate.test.tsx +0 -509
  542. package/src/cli/ui/__tests__/integration/realtimeUpdate.test.tsx.skip +0 -216
  543. package/src/cli/ui/__tests__/performance/branchList.performance.test.tsx +0 -193
  544. package/src/cli/ui/__tests__/performance/useMemoOptimization.test.tsx +0 -234
  545. package/src/cli/ui/components/App.tsx +0 -1478
  546. package/src/cli/ui/components/common/Confirm.tsx +0 -44
  547. package/src/cli/ui/components/common/ErrorBoundary.tsx +0 -60
  548. package/src/cli/ui/components/common/Input.tsx +0 -58
  549. package/src/cli/ui/components/common/LoadingIndicator.tsx +0 -98
  550. package/src/cli/ui/components/common/Select.tsx +0 -247
  551. package/src/cli/ui/components/common/SpinnerIcon.tsx +0 -86
  552. package/src/cli/ui/components/parts/Footer.tsx +0 -41
  553. package/src/cli/ui/components/parts/Header.test.tsx +0 -75
  554. package/src/cli/ui/components/parts/MergeStatusList.tsx +0 -75
  555. package/src/cli/ui/components/parts/ProgressBar.tsx +0 -73
  556. package/src/cli/ui/components/parts/Stats.tsx +0 -88
  557. package/src/cli/ui/components/screens/BatchMergeProgressScreen.tsx +0 -74
  558. package/src/cli/ui/components/screens/BatchMergeResultScreen.tsx +0 -108
  559. package/src/cli/ui/components/screens/BranchCreatorScreen.tsx +0 -242
  560. package/src/cli/ui/components/screens/BranchListScreen.tsx +0 -744
  561. package/src/cli/ui/components/screens/BranchQuickStartScreen.tsx +0 -244
  562. package/src/cli/ui/components/screens/CodingAgentSelectorScreen.tsx +0 -159
  563. package/src/cli/ui/components/screens/EnvironmentProfileScreen.tsx +0 -928
  564. package/src/cli/ui/components/screens/ExecutionModeSelectorScreen.tsx +0 -176
  565. package/src/cli/ui/components/screens/LogDatePickerScreen.tsx +0 -83
  566. package/src/cli/ui/components/screens/LogDetailScreen.tsx +0 -67
  567. package/src/cli/ui/components/screens/LogListScreen.tsx +0 -192
  568. package/src/cli/ui/components/screens/ModelSelectorScreen.tsx +0 -320
  569. package/src/cli/ui/components/screens/PRCleanupScreen.tsx +0 -171
  570. package/src/cli/ui/components/screens/SessionSelectorScreen.tsx +0 -135
  571. package/src/cli/ui/hooks/useAppInput.ts +0 -172
  572. package/src/cli/ui/hooks/useBatchMerge.ts +0 -96
  573. package/src/cli/ui/hooks/useGitData.ts +0 -347
  574. package/src/cli/ui/hooks/useProfiles.ts +0 -211
  575. package/src/cli/ui/hooks/useScreenState.ts +0 -44
  576. package/src/cli/ui/hooks/useTerminalSize.ts +0 -33
  577. package/src/cli/ui/hooks/useToolStatus.ts +0 -68
  578. package/src/cli/ui/screens/BranchActionSelectorScreen.tsx +0 -111
  579. 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> {
@@ -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
  /**
@@ -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>
@@ -10,6 +10,10 @@ import {
10
10
  TableHead,
11
11
  TableCell,
12
12
  } from "@/components/ui/table";
13
+ import {
14
+ getAgentTailwindClass,
15
+ normalizeAgentToToolId,
16
+ } from "@/lib/coding-agent-colors";
13
17
 
14
18
  interface SessionInfo {
15
19
  sessionId: string;
@@ -131,7 +135,9 @@ export function SessionHistoryTable({
131
135
  {SESSION_STATUS_LABEL[session.status]}
132
136
  </Badge>
133
137
  </TableCell>
134
- <TableCell className="font-medium">
138
+ <TableCell
139
+ className={`font-medium ${getAgentTailwindClass(normalizeAgentToToolId(session.agentType))}`}
140
+ >
135
141
  {agentLabel(session.agentType, session.agentName)}
136
142
  </TableCell>
137
143
  <TableCell>
@@ -13,6 +13,7 @@ import {
13
13
  SelectValue,
14
14
  } from "@/components/ui/select";
15
15
  import { cn } from "@/lib/utils";
16
+ import { getAgentTailwindClass } from "@/lib/coding-agent-colors";
16
17
  import type { ApiCodingAgent, Branch } from "../../../../../types/api.js";
17
18
 
18
19
  type ToolMode = "normal" | "continue" | "resume";
@@ -45,7 +46,7 @@ interface ToolLauncherProps {
45
46
  isStartingSession: boolean;
46
47
  isSyncingBranch: boolean;
47
48
  needsRemoteSync: boolean;
48
- hasBlockingDivergence: boolean;
49
+ hasConflictingDivergence: boolean;
49
50
  onToolChange: (toolId: string) => void;
50
51
  onModeChange: (mode: ToolMode) => void;
51
52
  onSkipPermissionsChange: (skip: boolean) => void;
@@ -88,7 +89,7 @@ export function ToolLauncher({
88
89
  isStartingSession,
89
90
  isSyncingBranch,
90
91
  needsRemoteSync,
91
- hasBlockingDivergence,
92
+ hasConflictingDivergence,
92
93
  onToolChange,
93
94
  onModeChange,
94
95
  onSkipPermissionsChange,
@@ -170,7 +171,11 @@ export function ToolLauncher({
170
171
  </SelectTrigger>
171
172
  <SelectContent>
172
173
  {availableTools.map((tool) => (
173
- <SelectItem key={tool.id} value={tool.id}>
174
+ <SelectItem
175
+ key={tool.id}
176
+ value={tool.id}
177
+ className={getAgentTailwindClass(tool.id)}
178
+ >
174
179
  {tool.label}
175
180
  </SelectItem>
176
181
  ))}
@@ -243,11 +248,12 @@ export function ToolLauncher({
243
248
  </Alert>
244
249
  )}
245
250
 
246
- {hasBlockingDivergence && (
251
+ {hasConflictingDivergence && (
247
252
  <Alert variant="warning" data-testid="divergence-warning">
248
253
  <AlertDescription>
249
254
  <p>
250
- リモートとローカルの両方に未解決の差分があるため、起動をブロックしています。
255
+ リモートとローカルの両方に未解決の差分があります。起動は可能ですが、
256
+ 衝突を避けるために差分の解消を推奨します。
251
257
  </p>
252
258
  <ul className="mt-2 list-inside list-disc text-xs text-muted-foreground">
253
259
  <li>
@@ -266,7 +272,6 @@ export function ToolLauncher({
266
272
  disabled={
267
273
  isStartingSession ||
268
274
  !selectedTool ||
269
- hasBlockingDivergence ||
270
275
  needsRemoteSync ||
271
276
  isSyncingBranch
272
277
  }