@akiojin/gwt 4.10.0 → 4.12.0

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 (630) hide show
  1. package/README.ja.md +4 -4
  2. package/README.md +4 -4
  3. package/bin/gwt.js +1 -1
  4. package/dist/claude.d.ts +2 -0
  5. package/dist/claude.d.ts.map +1 -1
  6. package/dist/claude.js +97 -68
  7. package/dist/claude.js.map +1 -1
  8. package/dist/cli/ui/App.solid.d.ts +29 -0
  9. package/dist/cli/ui/App.solid.d.ts.map +1 -0
  10. package/dist/cli/ui/App.solid.js +1395 -0
  11. package/dist/cli/ui/App.solid.js.map +1 -0
  12. package/dist/cli/ui/components/solid/Footer.d.ts +10 -0
  13. package/dist/cli/ui/components/solid/Footer.d.ts.map +1 -0
  14. package/dist/cli/ui/components/solid/Footer.js +10 -0
  15. package/dist/cli/ui/components/solid/Footer.js.map +1 -0
  16. package/dist/cli/ui/components/{parts → solid}/Header.d.ts +1 -6
  17. package/dist/cli/ui/components/solid/Header.d.ts.map +1 -0
  18. package/dist/cli/ui/components/solid/Header.js +13 -0
  19. package/dist/cli/ui/components/solid/Header.js.map +1 -0
  20. package/dist/cli/ui/components/solid/HelpOverlay.d.ts +8 -0
  21. package/dist/cli/ui/components/solid/HelpOverlay.d.ts.map +1 -0
  22. package/dist/cli/ui/components/solid/HelpOverlay.js +118 -0
  23. package/dist/cli/ui/components/solid/HelpOverlay.js.map +1 -0
  24. package/dist/cli/ui/components/solid/QuickStartStep.d.ts +17 -0
  25. package/dist/cli/ui/components/solid/QuickStartStep.d.ts.map +1 -0
  26. package/dist/cli/ui/components/solid/QuickStartStep.js +152 -0
  27. package/dist/cli/ui/components/solid/QuickStartStep.js.map +1 -0
  28. package/dist/cli/ui/components/solid/SelectInput.d.ts +22 -0
  29. package/dist/cli/ui/components/solid/SelectInput.d.ts.map +1 -0
  30. package/dist/cli/ui/components/solid/SelectInput.js +45 -0
  31. package/dist/cli/ui/components/solid/SelectInput.js.map +1 -0
  32. package/dist/cli/ui/components/solid/TextInput.d.ts +12 -0
  33. package/dist/cli/ui/components/solid/TextInput.d.ts.map +1 -0
  34. package/dist/cli/ui/components/solid/TextInput.js +9 -0
  35. package/dist/cli/ui/components/solid/TextInput.js.map +1 -0
  36. package/dist/cli/ui/components/solid/WizardController.d.ts +34 -0
  37. package/dist/cli/ui/components/solid/WizardController.d.ts.map +1 -0
  38. package/dist/cli/ui/components/solid/WizardController.js +223 -0
  39. package/dist/cli/ui/components/solid/WizardController.js.map +1 -0
  40. package/dist/cli/ui/components/solid/WizardPopup.d.ts +26 -0
  41. package/dist/cli/ui/components/solid/WizardPopup.d.ts.map +1 -0
  42. package/dist/cli/ui/components/solid/WizardPopup.js +68 -0
  43. package/dist/cli/ui/components/solid/WizardPopup.js.map +1 -0
  44. package/dist/cli/ui/components/solid/WizardSteps.d.ts +52 -0
  45. package/dist/cli/ui/components/solid/WizardSteps.d.ts.map +1 -0
  46. package/dist/cli/ui/components/solid/WizardSteps.js +419 -0
  47. package/dist/cli/ui/components/solid/WizardSteps.js.map +1 -0
  48. package/dist/cli/ui/core/index.d.ts +12 -0
  49. package/dist/cli/ui/core/index.d.ts.map +1 -0
  50. package/dist/cli/ui/core/index.js +15 -0
  51. package/dist/cli/ui/core/index.js.map +1 -0
  52. package/dist/cli/ui/core/keybindings.d.ts +106 -0
  53. package/dist/cli/ui/core/keybindings.d.ts.map +1 -0
  54. package/dist/cli/ui/core/keybindings.js +270 -0
  55. package/dist/cli/ui/core/keybindings.js.map +1 -0
  56. package/dist/cli/ui/core/theme.d.ts +123 -0
  57. package/dist/cli/ui/core/theme.d.ts.map +1 -0
  58. package/dist/cli/ui/core/theme.js +191 -0
  59. package/dist/cli/ui/core/theme.js.map +1 -0
  60. package/dist/cli/ui/core/types.d.ts +156 -0
  61. package/dist/cli/ui/core/types.d.ts.map +1 -0
  62. package/dist/cli/ui/core/types.js +10 -0
  63. package/dist/cli/ui/core/types.js.map +1 -0
  64. package/dist/cli/ui/hooks/solid/useScrollableList.d.ts +26 -0
  65. package/dist/cli/ui/hooks/solid/useScrollableList.d.ts.map +1 -0
  66. package/dist/cli/ui/hooks/solid/useScrollableList.js +89 -0
  67. package/dist/cli/ui/hooks/solid/useScrollableList.js.map +1 -0
  68. package/dist/cli/ui/hooks/solid/useTerminalSize.d.ts +10 -0
  69. package/dist/cli/ui/hooks/solid/useTerminalSize.d.ts.map +1 -0
  70. package/dist/cli/ui/hooks/solid/useTerminalSize.js +16 -0
  71. package/dist/cli/ui/hooks/solid/useTerminalSize.js.map +1 -0
  72. package/dist/cli/ui/index.solid.d.ts +5 -0
  73. package/dist/cli/ui/index.solid.d.ts.map +1 -0
  74. package/dist/cli/ui/index.solid.js +21 -0
  75. package/dist/cli/ui/index.solid.js.map +1 -0
  76. package/dist/cli/ui/screens/solid/BranchListScreen.d.ts +53 -0
  77. package/dist/cli/ui/screens/solid/BranchListScreen.d.ts.map +1 -0
  78. package/dist/cli/ui/screens/solid/BranchListScreen.js +829 -0
  79. package/dist/cli/ui/screens/solid/BranchListScreen.js.map +1 -0
  80. package/dist/cli/ui/screens/solid/ConfirmScreen.d.ts +11 -0
  81. package/dist/cli/ui/screens/solid/ConfirmScreen.d.ts.map +1 -0
  82. package/dist/cli/ui/screens/solid/ConfirmScreen.js +45 -0
  83. package/dist/cli/ui/screens/solid/ConfirmScreen.js.map +1 -0
  84. package/dist/cli/ui/screens/solid/EnvironmentScreen.d.ts +14 -0
  85. package/dist/cli/ui/screens/solid/EnvironmentScreen.d.ts.map +1 -0
  86. package/dist/cli/ui/screens/solid/EnvironmentScreen.js +90 -0
  87. package/dist/cli/ui/screens/solid/EnvironmentScreen.js.map +1 -0
  88. package/dist/cli/ui/screens/solid/ErrorScreen.d.ts +8 -0
  89. package/dist/cli/ui/screens/solid/ErrorScreen.d.ts.map +1 -0
  90. package/dist/cli/ui/screens/solid/ErrorScreen.js +18 -0
  91. package/dist/cli/ui/screens/solid/ErrorScreen.js.map +1 -0
  92. package/dist/cli/ui/screens/solid/InputScreen.d.ts +13 -0
  93. package/dist/cli/ui/screens/solid/InputScreen.d.ts.map +1 -0
  94. package/dist/cli/ui/screens/solid/InputScreen.js +17 -0
  95. package/dist/cli/ui/screens/solid/InputScreen.js.map +1 -0
  96. package/dist/cli/ui/screens/solid/LoadingIndicator.d.ts +9 -0
  97. package/dist/cli/ui/screens/solid/LoadingIndicator.d.ts.map +1 -0
  98. package/dist/cli/ui/screens/solid/LoadingIndicator.js +43 -0
  99. package/dist/cli/ui/screens/solid/LoadingIndicator.js.map +1 -0
  100. package/dist/cli/ui/{components/screens → screens/solid}/LogDetailScreen.d.ts +2 -2
  101. package/dist/cli/ui/screens/solid/LogDetailScreen.d.ts.map +1 -0
  102. package/dist/cli/ui/screens/solid/LogDetailScreen.js +34 -0
  103. package/dist/cli/ui/screens/solid/LogDetailScreen.js.map +1 -0
  104. package/dist/cli/ui/{components/screens/LogListScreen.d.ts → screens/solid/LogScreen.d.ts} +10 -4
  105. package/dist/cli/ui/screens/solid/LogScreen.d.ts.map +1 -0
  106. package/dist/cli/ui/screens/solid/LogScreen.js +333 -0
  107. package/dist/cli/ui/screens/solid/LogScreen.js.map +1 -0
  108. package/dist/cli/ui/screens/solid/ProfileEnvScreen.d.ts +17 -0
  109. package/dist/cli/ui/screens/solid/ProfileEnvScreen.d.ts.map +1 -0
  110. package/dist/cli/ui/screens/solid/ProfileEnvScreen.js +115 -0
  111. package/dist/cli/ui/screens/solid/ProfileEnvScreen.js.map +1 -0
  112. package/dist/cli/ui/screens/solid/ProfileScreen.d.ts +17 -0
  113. package/dist/cli/ui/screens/solid/ProfileScreen.d.ts.map +1 -0
  114. package/dist/cli/ui/screens/solid/ProfileScreen.js +50 -0
  115. package/dist/cli/ui/screens/solid/ProfileScreen.js.map +1 -0
  116. package/dist/cli/ui/screens/solid/SelectorScreen.d.ts +20 -0
  117. package/dist/cli/ui/screens/solid/SelectorScreen.d.ts.map +1 -0
  118. package/dist/cli/ui/screens/solid/SelectorScreen.js +98 -0
  119. package/dist/cli/ui/screens/solid/SelectorScreen.js.map +1 -0
  120. package/dist/cli/ui/screens/solid/WorktreeCreateScreen.d.ts +13 -0
  121. package/dist/cli/ui/screens/solid/WorktreeCreateScreen.d.ts.map +1 -0
  122. package/dist/cli/ui/screens/solid/WorktreeCreateScreen.js +59 -0
  123. package/dist/cli/ui/screens/solid/WorktreeCreateScreen.js.map +1 -0
  124. package/dist/cli/ui/stores/appStore.d.ts +143 -0
  125. package/dist/cli/ui/stores/appStore.d.ts.map +1 -0
  126. package/dist/cli/ui/stores/appStore.js +158 -0
  127. package/dist/cli/ui/stores/appStore.js.map +1 -0
  128. package/dist/cli/ui/stores/branchStore.d.ts +159 -0
  129. package/dist/cli/ui/stores/branchStore.d.ts.map +1 -0
  130. package/dist/cli/ui/stores/branchStore.js +275 -0
  131. package/dist/cli/ui/stores/branchStore.js.map +1 -0
  132. package/dist/cli/ui/stores/index.d.ts +11 -0
  133. package/dist/cli/ui/stores/index.d.ts.map +1 -0
  134. package/dist/cli/ui/stores/index.js +14 -0
  135. package/dist/cli/ui/stores/index.js.map +1 -0
  136. package/dist/cli/ui/stores/uiStore.d.ts +146 -0
  137. package/dist/cli/ui/stores/uiStore.d.ts.map +1 -0
  138. package/dist/cli/ui/stores/uiStore.js +166 -0
  139. package/dist/cli/ui/stores/uiStore.js.map +1 -0
  140. package/dist/cli/ui/types.d.ts +17 -1
  141. package/dist/cli/ui/types.d.ts.map +1 -1
  142. package/dist/cli/ui/utils/branchFormatter.d.ts +1 -0
  143. package/dist/cli/ui/utils/branchFormatter.d.ts.map +1 -1
  144. package/dist/cli/ui/utils/branchFormatter.js +36 -217
  145. package/dist/cli/ui/utils/branchFormatter.js.map +1 -1
  146. package/dist/cli/ui/utils/continueSession.d.ts +18 -0
  147. package/dist/cli/ui/utils/continueSession.d.ts.map +1 -1
  148. package/dist/cli/ui/utils/continueSession.js +90 -2
  149. package/dist/cli/ui/utils/continueSession.js.map +1 -1
  150. package/dist/cli/ui/utils/versionCache.d.ts +37 -0
  151. package/dist/cli/ui/utils/versionCache.d.ts.map +1 -0
  152. package/dist/cli/ui/utils/versionCache.js +70 -0
  153. package/dist/cli/ui/utils/versionCache.js.map +1 -0
  154. package/dist/cli/ui/utils/versionFetcher.d.ts +41 -0
  155. package/dist/cli/ui/utils/versionFetcher.d.ts.map +1 -0
  156. package/dist/cli/ui/utils/versionFetcher.js +89 -0
  157. package/dist/cli/ui/utils/versionFetcher.js.map +1 -0
  158. package/dist/client/assets/{index-ChHC-Puh.css → index-BbfV7Wuj.css} +1 -1
  159. package/dist/client/assets/index-CoAyq5x1.js +78 -0
  160. package/dist/client/index.html +2 -2
  161. package/dist/codex.d.ts +2 -0
  162. package/dist/codex.d.ts.map +1 -1
  163. package/dist/codex.js +109 -39
  164. package/dist/codex.js.map +1 -1
  165. package/dist/config/builtin-coding-agents.js +4 -4
  166. package/dist/config/builtin-coding-agents.js.map +1 -1
  167. package/dist/config/index.d.ts +2 -0
  168. package/dist/config/index.d.ts.map +1 -1
  169. package/dist/config/index.js +11 -0
  170. package/dist/config/index.js.map +1 -1
  171. package/dist/gemini.d.ts +2 -0
  172. package/dist/gemini.d.ts.map +1 -1
  173. package/dist/gemini.js +77 -39
  174. package/dist/gemini.js.map +1 -1
  175. package/dist/index.d.ts +1 -1
  176. package/dist/index.d.ts.map +1 -1
  177. package/dist/index.js +153 -103
  178. package/dist/index.js.map +1 -1
  179. package/dist/launcher.d.ts.map +1 -1
  180. package/dist/launcher.js +56 -6
  181. package/dist/launcher.js.map +1 -1
  182. package/dist/logging/agentOutput.d.ts +21 -0
  183. package/dist/logging/agentOutput.d.ts.map +1 -0
  184. package/dist/logging/agentOutput.js +164 -0
  185. package/dist/logging/agentOutput.js.map +1 -0
  186. package/dist/logging/formatter.d.ts.map +1 -1
  187. package/dist/logging/formatter.js +18 -4
  188. package/dist/logging/formatter.js.map +1 -1
  189. package/dist/logging/logger.d.ts.map +1 -1
  190. package/dist/logging/logger.js +28 -9
  191. package/dist/logging/logger.js.map +1 -1
  192. package/dist/logging/reader.d.ts +21 -0
  193. package/dist/logging/reader.d.ts.map +1 -1
  194. package/dist/logging/reader.js +79 -0
  195. package/dist/logging/reader.js.map +1 -1
  196. package/dist/opentui/highlights-eq9cgrbb.scm +604 -0
  197. package/dist/opentui/highlights-ghv9g403.scm +205 -0
  198. package/dist/opentui/highlights-hk7bwhj4.scm +284 -0
  199. package/dist/opentui/highlights-r812a2qc.scm +150 -0
  200. package/dist/opentui/highlights-x6tmsnaa.scm +115 -0
  201. package/dist/opentui/index.solid.d.ts +2 -0
  202. package/dist/opentui/index.solid.d.ts.map +1 -0
  203. package/dist/opentui/index.solid.js +53687 -0
  204. package/dist/opentui/index.solid.js.map +1 -0
  205. package/dist/opentui/injections-73j83es3.scm +27 -0
  206. package/dist/opentui/tree-sitter-javascript-nd0q4pe9.wasm +0 -0
  207. package/dist/opentui/tree-sitter-markdown-411r6y9b.wasm +0 -0
  208. package/dist/opentui/tree-sitter-markdown_inline-j5349f42.wasm +0 -0
  209. package/dist/opentui/tree-sitter-typescript-zxjzwt75.wasm +0 -0
  210. package/dist/opentui/tree-sitter-zig-e78zbjpm.wasm +0 -0
  211. package/dist/repositories/worktree.repository.d.ts +1 -0
  212. package/dist/repositories/worktree.repository.d.ts.map +1 -1
  213. package/dist/repositories/worktree.repository.js +7 -0
  214. package/dist/repositories/worktree.repository.js.map +1 -1
  215. package/dist/services/codingAgentResolver.d.ts +2 -0
  216. package/dist/services/codingAgentResolver.d.ts.map +1 -1
  217. package/dist/services/codingAgentResolver.js +30 -4
  218. package/dist/services/codingAgentResolver.js.map +1 -1
  219. package/dist/services/dependency-installer.d.ts.map +1 -1
  220. package/dist/services/dependency-installer.js +2 -7
  221. package/dist/services/dependency-installer.js.map +1 -1
  222. package/dist/types/api.d.ts +3 -0
  223. package/dist/types/api.d.ts.map +1 -1
  224. package/dist/types/coding-agent.d.ts +62 -0
  225. package/dist/types/coding-agent.d.ts.map +1 -0
  226. package/dist/types/coding-agent.js +29 -0
  227. package/dist/types/coding-agent.js.map +1 -0
  228. package/dist/types/tools.d.ts +17 -0
  229. package/dist/types/tools.d.ts.map +1 -1
  230. package/dist/utils/coding-agent-colors.d.ts +88 -0
  231. package/dist/utils/coding-agent-colors.d.ts.map +1 -0
  232. package/dist/utils/coding-agent-colors.js +137 -0
  233. package/dist/utils/coding-agent-colors.js.map +1 -0
  234. package/dist/utils/command.d.ts +1 -1
  235. package/dist/utils/command.js +1 -1
  236. package/dist/utils/error-utils.d.ts +27 -0
  237. package/dist/utils/error-utils.d.ts.map +1 -0
  238. package/dist/utils/error-utils.js +98 -0
  239. package/dist/utils/error-utils.js.map +1 -0
  240. package/dist/utils/npmRegistry.d.ts +61 -0
  241. package/dist/utils/npmRegistry.d.ts.map +1 -0
  242. package/dist/utils/npmRegistry.js +180 -0
  243. package/dist/utils/npmRegistry.js.map +1 -0
  244. package/dist/utils/prompt.d.ts +1 -1
  245. package/dist/utils/prompt.js +1 -1
  246. package/dist/utils/session/common.d.ts +8 -0
  247. package/dist/utils/session/common.d.ts.map +1 -1
  248. package/dist/utils/session/common.js +22 -0
  249. package/dist/utils/session/common.js.map +1 -1
  250. package/dist/utils/session/parsers/claude.d.ts +10 -4
  251. package/dist/utils/session/parsers/claude.d.ts.map +1 -1
  252. package/dist/utils/session/parsers/claude.js +64 -18
  253. package/dist/utils/session/parsers/claude.js.map +1 -1
  254. package/dist/utils/session/parsers/codex.d.ts.map +1 -1
  255. package/dist/utils/session/parsers/codex.js +47 -20
  256. package/dist/utils/session/parsers/codex.js.map +1 -1
  257. package/dist/utils/session/parsers/gemini.d.ts.map +1 -1
  258. package/dist/utils/session/parsers/gemini.js +43 -6
  259. package/dist/utils/session/parsers/gemini.js.map +1 -1
  260. package/dist/utils/session/parsers/opencode.d.ts.map +1 -1
  261. package/dist/utils/session/parsers/opencode.js +43 -6
  262. package/dist/utils/session/parsers/opencode.js.map +1 -1
  263. package/dist/utils/session/types.d.ts +7 -0
  264. package/dist/utils/session/types.d.ts.map +1 -1
  265. package/dist/utils/terminal.d.ts +1 -0
  266. package/dist/utils/terminal.d.ts.map +1 -1
  267. package/dist/utils/terminal.js +20 -0
  268. package/dist/utils/terminal.js.map +1 -1
  269. package/dist/utils.d.ts +9 -0
  270. package/dist/utils.d.ts.map +1 -1
  271. package/dist/utils.js +33 -2
  272. package/dist/utils.js.map +1 -1
  273. package/dist/web/client/src/components/CodingAgentLaunchModal.d.ts.map +1 -1
  274. package/dist/web/client/src/components/CodingAgentLaunchModal.js +7 -16
  275. package/dist/web/client/src/components/CodingAgentLaunchModal.js.map +1 -1
  276. package/dist/web/client/src/components/branch-detail/BranchInfoCards.d.ts.map +1 -1
  277. package/dist/web/client/src/components/branch-detail/BranchInfoCards.js +7 -2
  278. package/dist/web/client/src/components/branch-detail/BranchInfoCards.js.map +1 -1
  279. package/dist/web/client/src/components/branch-detail/SessionHistoryTable.d.ts.map +1 -1
  280. package/dist/web/client/src/components/branch-detail/SessionHistoryTable.js +2 -1
  281. package/dist/web/client/src/components/branch-detail/SessionHistoryTable.js.map +1 -1
  282. package/dist/web/client/src/components/branch-detail/ToolLauncher.d.ts +2 -2
  283. package/dist/web/client/src/components/branch-detail/ToolLauncher.d.ts.map +1 -1
  284. package/dist/web/client/src/components/branch-detail/ToolLauncher.js +5 -5
  285. package/dist/web/client/src/components/branch-detail/ToolLauncher.js.map +1 -1
  286. package/dist/web/client/src/components/ui/alert.d.ts +1 -1
  287. package/dist/web/client/src/lib/coding-agent-colors.d.ts +86 -0
  288. package/dist/web/client/src/lib/coding-agent-colors.d.ts.map +1 -0
  289. package/dist/web/client/src/lib/coding-agent-colors.js +135 -0
  290. package/dist/web/client/src/lib/coding-agent-colors.js.map +1 -0
  291. package/dist/web/client/src/pages/BranchDetailPage.js +10 -10
  292. package/dist/web/client/src/pages/BranchDetailPage.js.map +1 -1
  293. package/dist/web/server/pty/manager.d.ts +2 -0
  294. package/dist/web/server/pty/manager.d.ts.map +1 -1
  295. package/dist/web/server/pty/manager.js +104 -0
  296. package/dist/web/server/pty/manager.js.map +1 -1
  297. package/dist/web/server/routes/sessions.d.ts.map +1 -1
  298. package/dist/web/server/routes/sessions.js +5 -1
  299. package/dist/web/server/routes/sessions.js.map +1 -1
  300. package/dist/web/server/services/branches.d.ts.map +1 -1
  301. package/dist/web/server/services/branches.js +10 -8
  302. package/dist/web/server/services/branches.js.map +1 -1
  303. package/dist/web/server/services/worktrees.js +2 -2
  304. package/dist/web/server/services/worktrees.js.map +1 -1
  305. package/dist/worktree.d.ts +50 -1
  306. package/dist/worktree.d.ts.map +1 -1
  307. package/dist/worktree.js +292 -100
  308. package/dist/worktree.js.map +1 -1
  309. package/package.json +13 -14
  310. package/src/claude.ts +129 -95
  311. package/src/cli/ui/App.solid.tsx +2096 -0
  312. package/src/cli/ui/__tests__/solid/AppSolid.cleanup.test.tsx +1084 -0
  313. package/src/cli/ui/__tests__/solid/BranchListScreen.test.tsx +343 -0
  314. package/src/cli/ui/__tests__/solid/ConfirmScreen.test.tsx +77 -0
  315. package/src/cli/ui/__tests__/solid/LogScreen.test.tsx +351 -0
  316. package/src/cli/ui/__tests__/solid/components/QuickStartStep.test.tsx +308 -0
  317. package/src/cli/ui/__tests__/solid/components/WizardPopup.test.tsx +231 -0
  318. package/src/cli/ui/__tests__/solid/components/WizardSteps.test.tsx +241 -0
  319. package/src/cli/ui/__tests__/utils/branchFormatter.test.ts +79 -334
  320. package/src/cli/ui/__tests__/utils/clipboard.test.ts +3 -3
  321. package/src/cli/ui/__tests__/utils/statisticsCalculator.test.ts +1 -1
  322. package/src/cli/ui/components/solid/Footer.tsx +36 -0
  323. package/src/cli/ui/components/{parts → solid}/Header.tsx +17 -28
  324. package/src/cli/ui/components/solid/HelpOverlay.tsx +194 -0
  325. package/src/cli/ui/components/solid/QuickStartStep.tsx +209 -0
  326. package/src/cli/ui/components/{parts → solid}/ScrollableList.tsx +7 -8
  327. package/src/cli/ui/components/solid/SearchInput.tsx +42 -0
  328. package/src/cli/ui/components/solid/SelectInput.tsx +88 -0
  329. package/src/cli/ui/components/solid/Stats.tsx +92 -0
  330. package/src/cli/ui/components/solid/TextInput.tsx +49 -0
  331. package/src/cli/ui/components/solid/WizardController.tsx +393 -0
  332. package/src/cli/ui/components/solid/WizardPopup.tsx +135 -0
  333. package/src/cli/ui/components/solid/WizardSteps.tsx +736 -0
  334. package/src/cli/ui/core/index.ts +17 -0
  335. package/src/cli/ui/core/keybindings.ts +367 -0
  336. package/src/cli/ui/core/theme.ts +266 -0
  337. package/src/cli/ui/core/types.ts +235 -0
  338. package/src/cli/ui/hooks/solid/useAsyncOperation.ts +78 -0
  339. package/src/cli/ui/hooks/solid/useFilter.ts +86 -0
  340. package/src/cli/ui/hooks/solid/useGitOperations.ts +81 -0
  341. package/src/cli/ui/hooks/solid/useKeyHandler.ts +103 -0
  342. package/src/cli/ui/hooks/solid/useScrollableList.ts +149 -0
  343. package/src/cli/ui/hooks/solid/useSelection.ts +77 -0
  344. package/src/cli/ui/hooks/solid/useTerminalSize.ts +22 -0
  345. package/src/cli/ui/index.solid.ts +28 -0
  346. package/src/cli/ui/screens/solid/BranchListScreen.tsx +1153 -0
  347. package/src/cli/ui/screens/solid/ConfirmScreen.tsx +86 -0
  348. package/src/cli/ui/screens/solid/EnvironmentScreen.tsx +161 -0
  349. package/src/cli/ui/screens/solid/ErrorScreen.tsx +42 -0
  350. package/src/cli/ui/screens/solid/InputScreen.tsx +55 -0
  351. package/src/cli/ui/screens/solid/LoadingIndicator.tsx +77 -0
  352. package/src/cli/ui/screens/solid/LogDetailScreen.tsx +75 -0
  353. package/src/cli/ui/screens/solid/LogScreen.tsx +504 -0
  354. package/src/cli/ui/screens/solid/ProfileEnvScreen.tsx +196 -0
  355. package/src/cli/ui/screens/solid/ProfileScreen.tsx +98 -0
  356. package/src/cli/ui/screens/solid/SelectorScreen.tsx +181 -0
  357. package/src/cli/ui/screens/solid/SettingsScreen.tsx +52 -0
  358. package/src/cli/ui/screens/solid/WorktreeCreateScreen.tsx +136 -0
  359. package/src/cli/ui/screens/solid/WorktreeDeleteScreen.tsx +40 -0
  360. package/src/cli/ui/stores/appStore.ts +208 -0
  361. package/src/cli/ui/stores/branchStore.ts +357 -0
  362. package/src/cli/ui/stores/index.ts +31 -0
  363. package/src/cli/ui/stores/uiStore.ts +226 -0
  364. package/src/cli/ui/types.ts +21 -3
  365. package/src/cli/ui/utils/__tests__/branchFormatter.test.ts +227 -0
  366. package/src/cli/ui/utils/branchFormatter.ts +43 -222
  367. package/src/cli/ui/utils/continueSession.ts +133 -2
  368. package/src/cli/ui/utils/modelOptions.test.ts +1 -1
  369. package/src/cli/ui/utils/versionCache.ts +93 -0
  370. package/src/cli/ui/utils/versionFetcher.ts +120 -0
  371. package/src/codex.ts +138 -39
  372. package/src/config/__tests__/saveSession.test.ts +143 -0
  373. package/src/config/builtin-coding-agents.ts +4 -4
  374. package/src/config/index.ts +14 -0
  375. package/src/gemini.ts +107 -46
  376. package/src/index.test.ts +25 -19
  377. package/src/index.ts +202 -143
  378. package/src/launcher.ts +66 -6
  379. package/src/logging/agentOutput.ts +216 -0
  380. package/src/logging/formatter.ts +23 -4
  381. package/src/logging/logger.ts +34 -10
  382. package/src/logging/reader.ts +117 -0
  383. package/src/opentui/index.solid.ts +1 -0
  384. package/src/repositories/worktree.repository.ts +8 -0
  385. package/src/services/__tests__/BatchMergeService.test.ts +83 -67
  386. package/src/services/__tests__/WorktreeOrchestrator.test.ts +8 -7
  387. package/src/services/codingAgentResolver.ts +30 -4
  388. package/src/services/dependency-installer.ts +2 -9
  389. package/src/types/api.ts +3 -0
  390. package/src/types/coding-agent.ts +85 -0
  391. package/src/types/tools.ts +19 -0
  392. package/src/utils/__tests__/npmRegistry.test.ts +250 -0
  393. package/src/utils/__tests__/prompt.test.ts +4 -5
  394. package/src/utils/coding-agent-colors.ts +165 -0
  395. package/src/utils/command.ts +1 -1
  396. package/src/utils/error-utils.ts +133 -0
  397. package/src/utils/npmRegistry.ts +249 -0
  398. package/src/utils/prompt.ts +1 -1
  399. package/src/utils/session/common.ts +28 -0
  400. package/src/utils/session/parsers/claude.ts +79 -29
  401. package/src/utils/session/parsers/codex.ts +50 -18
  402. package/src/utils/session/parsers/gemini.ts +46 -5
  403. package/src/utils/session/parsers/opencode.ts +46 -5
  404. package/src/utils/session/types.ts +4 -0
  405. package/src/utils/terminal.ts +24 -0
  406. package/src/utils.test.ts +1 -1
  407. package/src/utils.ts +37 -4
  408. package/src/web/client/src/components/CodingAgentLaunchModal.tsx +12 -21
  409. package/src/web/client/src/components/branch-detail/BranchInfoCards.tsx +16 -1
  410. package/src/web/client/src/components/branch-detail/SessionHistoryTable.tsx +7 -1
  411. package/src/web/client/src/components/branch-detail/ToolLauncher.tsx +11 -6
  412. package/src/web/client/src/lib/coding-agent-colors.ts +149 -0
  413. package/src/web/client/src/pages/BranchDetailPage.tsx +11 -11
  414. package/src/web/server/pty/manager.ts +139 -0
  415. package/src/web/server/routes/sessions.ts +6 -0
  416. package/src/web/server/services/branches.ts +11 -8
  417. package/src/web/server/services/worktrees.ts +2 -2
  418. package/src/worktree.ts +386 -114
  419. package/dist/cli/ui/components/App.d.ts +0 -25
  420. package/dist/cli/ui/components/App.d.ts.map +0 -1
  421. package/dist/cli/ui/components/App.js +0 -1006
  422. package/dist/cli/ui/components/App.js.map +0 -1
  423. package/dist/cli/ui/components/common/Confirm.d.ts +0 -13
  424. package/dist/cli/ui/components/common/Confirm.d.ts.map +0 -1
  425. package/dist/cli/ui/components/common/Confirm.js +0 -20
  426. package/dist/cli/ui/components/common/Confirm.js.map +0 -1
  427. package/dist/cli/ui/components/common/ErrorBoundary.d.ts +0 -23
  428. package/dist/cli/ui/components/common/ErrorBoundary.d.ts.map +0 -1
  429. package/dist/cli/ui/components/common/ErrorBoundary.js +0 -37
  430. package/dist/cli/ui/components/common/ErrorBoundary.js.map +0 -1
  431. package/dist/cli/ui/components/common/Input.d.ts +0 -19
  432. package/dist/cli/ui/components/common/Input.d.ts.map +0 -1
  433. package/dist/cli/ui/components/common/Input.js +0 -22
  434. package/dist/cli/ui/components/common/Input.js.map +0 -1
  435. package/dist/cli/ui/components/common/LoadingIndicator.d.ts +0 -19
  436. package/dist/cli/ui/components/common/LoadingIndicator.d.ts.map +0 -1
  437. package/dist/cli/ui/components/common/LoadingIndicator.js +0 -61
  438. package/dist/cli/ui/components/common/LoadingIndicator.js.map +0 -1
  439. package/dist/cli/ui/components/common/Select.d.ts +0 -38
  440. package/dist/cli/ui/components/common/Select.d.ts.map +0 -1
  441. package/dist/cli/ui/components/common/Select.js +0 -151
  442. package/dist/cli/ui/components/common/Select.js.map +0 -1
  443. package/dist/cli/ui/components/common/SpinnerIcon.d.ts +0 -20
  444. package/dist/cli/ui/components/common/SpinnerIcon.d.ts.map +0 -1
  445. package/dist/cli/ui/components/common/SpinnerIcon.js +0 -61
  446. package/dist/cli/ui/components/common/SpinnerIcon.js.map +0 -1
  447. package/dist/cli/ui/components/parts/Footer.d.ts +0 -15
  448. package/dist/cli/ui/components/parts/Footer.d.ts.map +0 -1
  449. package/dist/cli/ui/components/parts/Footer.js +0 -20
  450. package/dist/cli/ui/components/parts/Footer.js.map +0 -1
  451. package/dist/cli/ui/components/parts/Header.d.ts.map +0 -1
  452. package/dist/cli/ui/components/parts/Header.js +0 -24
  453. package/dist/cli/ui/components/parts/Header.js.map +0 -1
  454. package/dist/cli/ui/components/parts/MergeStatusList.d.ts +0 -13
  455. package/dist/cli/ui/components/parts/MergeStatusList.d.ts.map +0 -1
  456. package/dist/cli/ui/components/parts/MergeStatusList.js +0 -52
  457. package/dist/cli/ui/components/parts/MergeStatusList.js.map +0 -1
  458. package/dist/cli/ui/components/parts/ProgressBar.d.ts +0 -13
  459. package/dist/cli/ui/components/parts/ProgressBar.d.ts.map +0 -1
  460. package/dist/cli/ui/components/parts/ProgressBar.js +0 -53
  461. package/dist/cli/ui/components/parts/ProgressBar.js.map +0 -1
  462. package/dist/cli/ui/components/parts/ScrollableList.d.ts +0 -12
  463. package/dist/cli/ui/components/parts/ScrollableList.d.ts.map +0 -1
  464. package/dist/cli/ui/components/parts/ScrollableList.js +0 -11
  465. package/dist/cli/ui/components/parts/ScrollableList.js.map +0 -1
  466. package/dist/cli/ui/components/parts/Stats.d.ts +0 -10
  467. package/dist/cli/ui/components/parts/Stats.d.ts.map +0 -1
  468. package/dist/cli/ui/components/parts/Stats.js +0 -55
  469. package/dist/cli/ui/components/parts/Stats.js.map +0 -1
  470. package/dist/cli/ui/components/screens/BatchMergeProgressScreen.d.ts +0 -17
  471. package/dist/cli/ui/components/screens/BatchMergeProgressScreen.d.ts.map +0 -1
  472. package/dist/cli/ui/components/screens/BatchMergeProgressScreen.js +0 -42
  473. package/dist/cli/ui/components/screens/BatchMergeProgressScreen.js.map +0 -1
  474. package/dist/cli/ui/components/screens/BatchMergeResultScreen.d.ts +0 -17
  475. package/dist/cli/ui/components/screens/BatchMergeResultScreen.d.ts.map +0 -1
  476. package/dist/cli/ui/components/screens/BatchMergeResultScreen.js +0 -72
  477. package/dist/cli/ui/components/screens/BatchMergeResultScreen.js.map +0 -1
  478. package/dist/cli/ui/components/screens/BranchCreatorScreen.d.ts +0 -18
  479. package/dist/cli/ui/components/screens/BranchCreatorScreen.d.ts.map +0 -1
  480. package/dist/cli/ui/components/screens/BranchCreatorScreen.js +0 -151
  481. package/dist/cli/ui/components/screens/BranchCreatorScreen.js.map +0 -1
  482. package/dist/cli/ui/components/screens/BranchListScreen.d.ts +0 -60
  483. package/dist/cli/ui/components/screens/BranchListScreen.d.ts.map +0 -1
  484. package/dist/cli/ui/components/screens/BranchListScreen.js +0 -476
  485. package/dist/cli/ui/components/screens/BranchListScreen.js.map +0 -1
  486. package/dist/cli/ui/components/screens/BranchQuickStartScreen.d.ts +0 -30
  487. package/dist/cli/ui/components/screens/BranchQuickStartScreen.d.ts.map +0 -1
  488. package/dist/cli/ui/components/screens/BranchQuickStartScreen.js +0 -148
  489. package/dist/cli/ui/components/screens/BranchQuickStartScreen.js.map +0 -1
  490. package/dist/cli/ui/components/screens/CodingAgentSelectorScreen.d.ts +0 -27
  491. package/dist/cli/ui/components/screens/CodingAgentSelectorScreen.d.ts.map +0 -1
  492. package/dist/cli/ui/components/screens/CodingAgentSelectorScreen.js +0 -93
  493. package/dist/cli/ui/components/screens/CodingAgentSelectorScreen.js.map +0 -1
  494. package/dist/cli/ui/components/screens/EnvironmentProfileScreen.d.ts +0 -19
  495. package/dist/cli/ui/components/screens/EnvironmentProfileScreen.d.ts.map +0 -1
  496. package/dist/cli/ui/components/screens/EnvironmentProfileScreen.js +0 -577
  497. package/dist/cli/ui/components/screens/EnvironmentProfileScreen.js.map +0 -1
  498. package/dist/cli/ui/components/screens/ExecutionModeSelectorScreen.d.ts +0 -45
  499. package/dist/cli/ui/components/screens/ExecutionModeSelectorScreen.d.ts.map +0 -1
  500. package/dist/cli/ui/components/screens/ExecutionModeSelectorScreen.js +0 -95
  501. package/dist/cli/ui/components/screens/ExecutionModeSelectorScreen.js.map +0 -1
  502. package/dist/cli/ui/components/screens/LogDatePickerScreen.d.ts +0 -10
  503. package/dist/cli/ui/components/screens/LogDatePickerScreen.d.ts.map +0 -1
  504. package/dist/cli/ui/components/screens/LogDatePickerScreen.js +0 -44
  505. package/dist/cli/ui/components/screens/LogDatePickerScreen.js.map +0 -1
  506. package/dist/cli/ui/components/screens/LogDetailScreen.d.ts.map +0 -1
  507. package/dist/cli/ui/components/screens/LogDetailScreen.js +0 -34
  508. package/dist/cli/ui/components/screens/LogDetailScreen.js.map +0 -1
  509. package/dist/cli/ui/components/screens/LogListScreen.d.ts.map +0 -1
  510. package/dist/cli/ui/components/screens/LogListScreen.js +0 -107
  511. package/dist/cli/ui/components/screens/LogListScreen.js.map +0 -1
  512. package/dist/cli/ui/components/screens/ModelSelectorScreen.d.ts +0 -24
  513. package/dist/cli/ui/components/screens/ModelSelectorScreen.d.ts.map +0 -1
  514. package/dist/cli/ui/components/screens/ModelSelectorScreen.js +0 -197
  515. package/dist/cli/ui/components/screens/ModelSelectorScreen.js.map +0 -1
  516. package/dist/cli/ui/components/screens/PRCleanupScreen.d.ts +0 -29
  517. package/dist/cli/ui/components/screens/PRCleanupScreen.d.ts.map +0 -1
  518. package/dist/cli/ui/components/screens/PRCleanupScreen.js +0 -92
  519. package/dist/cli/ui/components/screens/PRCleanupScreen.js.map +0 -1
  520. package/dist/cli/ui/components/screens/SessionSelectorScreen.d.ts +0 -31
  521. package/dist/cli/ui/components/screens/SessionSelectorScreen.d.ts.map +0 -1
  522. package/dist/cli/ui/components/screens/SessionSelectorScreen.js +0 -67
  523. package/dist/cli/ui/components/screens/SessionSelectorScreen.js.map +0 -1
  524. package/dist/cli/ui/hooks/useAppInput.d.ts +0 -21
  525. package/dist/cli/ui/hooks/useAppInput.d.ts.map +0 -1
  526. package/dist/cli/ui/hooks/useAppInput.js +0 -138
  527. package/dist/cli/ui/hooks/useAppInput.js.map +0 -1
  528. package/dist/cli/ui/hooks/useBatchMerge.d.ts +0 -17
  529. package/dist/cli/ui/hooks/useBatchMerge.d.ts.map +0 -1
  530. package/dist/cli/ui/hooks/useBatchMerge.js +0 -77
  531. package/dist/cli/ui/hooks/useBatchMerge.js.map +0 -1
  532. package/dist/cli/ui/hooks/useGitData.d.ts +0 -21
  533. package/dist/cli/ui/hooks/useGitData.d.ts.map +0 -1
  534. package/dist/cli/ui/hooks/useGitData.js +0 -229
  535. package/dist/cli/ui/hooks/useGitData.js.map +0 -1
  536. package/dist/cli/ui/hooks/useProfiles.d.ts +0 -41
  537. package/dist/cli/ui/hooks/useProfiles.d.ts.map +0 -1
  538. package/dist/cli/ui/hooks/useProfiles.js +0 -136
  539. package/dist/cli/ui/hooks/useProfiles.js.map +0 -1
  540. package/dist/cli/ui/hooks/useScreenState.d.ts +0 -12
  541. package/dist/cli/ui/hooks/useScreenState.d.ts.map +0 -1
  542. package/dist/cli/ui/hooks/useScreenState.js +0 -30
  543. package/dist/cli/ui/hooks/useScreenState.js.map +0 -1
  544. package/dist/cli/ui/hooks/useTerminalSize.d.ts +0 -9
  545. package/dist/cli/ui/hooks/useTerminalSize.d.ts.map +0 -1
  546. package/dist/cli/ui/hooks/useTerminalSize.js +0 -24
  547. package/dist/cli/ui/hooks/useTerminalSize.js.map +0 -1
  548. package/dist/cli/ui/hooks/useToolStatus.d.ts +0 -30
  549. package/dist/cli/ui/hooks/useToolStatus.d.ts.map +0 -1
  550. package/dist/cli/ui/hooks/useToolStatus.js +0 -49
  551. package/dist/cli/ui/hooks/useToolStatus.js.map +0 -1
  552. package/dist/cli/ui/screens/BranchActionSelectorScreen.d.ts +0 -24
  553. package/dist/cli/ui/screens/BranchActionSelectorScreen.d.ts.map +0 -1
  554. package/dist/cli/ui/screens/BranchActionSelectorScreen.js +0 -65
  555. package/dist/cli/ui/screens/BranchActionSelectorScreen.js.map +0 -1
  556. package/dist/client/assets/index-LNPtOrn3.js +0 -78
  557. package/src/cli/ui/__tests__/SKIPPED_TESTS.md +0 -119
  558. package/src/cli/ui/__tests__/acceptance/branchList.acceptance.test.tsx.skip +0 -239
  559. package/src/cli/ui/__tests__/acceptance/navigation.acceptance.test.tsx +0 -225
  560. package/src/cli/ui/__tests__/acceptance/realtimeUpdate.acceptance.test.tsx.skip +0 -219
  561. package/src/cli/ui/__tests__/components/App.protected-branch.test.tsx +0 -212
  562. package/src/cli/ui/__tests__/components/App.shortcuts.test.tsx +0 -440
  563. package/src/cli/ui/__tests__/components/App.test.tsx +0 -365
  564. package/src/cli/ui/__tests__/components/ModelSelectorScreen.initial.test.tsx +0 -91
  565. package/src/cli/ui/__tests__/components/common/Confirm.test.tsx +0 -80
  566. package/src/cli/ui/__tests__/components/common/ErrorBoundary.test.tsx +0 -104
  567. package/src/cli/ui/__tests__/components/common/Input.test.tsx +0 -100
  568. package/src/cli/ui/__tests__/components/common/LoadingIndicator.test.tsx +0 -148
  569. package/src/cli/ui/__tests__/components/common/Select.memo.test.tsx +0 -255
  570. package/src/cli/ui/__tests__/components/common/Select.test.tsx +0 -335
  571. package/src/cli/ui/__tests__/components/parts/Footer.test.tsx +0 -65
  572. package/src/cli/ui/__tests__/components/parts/Header.test.tsx +0 -55
  573. package/src/cli/ui/__tests__/components/parts/ScrollableList.test.tsx +0 -69
  574. package/src/cli/ui/__tests__/components/parts/Stats.test.tsx +0 -148
  575. package/src/cli/ui/__tests__/components/screens/BranchCreatorScreen.test.tsx +0 -253
  576. package/src/cli/ui/__tests__/components/screens/BranchListScreen.test.tsx +0 -1070
  577. package/src/cli/ui/__tests__/components/screens/BranchQuickStartScreen.test.tsx +0 -142
  578. package/src/cli/ui/__tests__/components/screens/CodingAgentSelectorScreen.test.tsx +0 -174
  579. package/src/cli/ui/__tests__/components/screens/ExecutionModeSelectorScreen.test.tsx +0 -182
  580. package/src/cli/ui/__tests__/components/screens/LogDetailScreen.test.tsx +0 -57
  581. package/src/cli/ui/__tests__/components/screens/LogListScreen.test.tsx +0 -102
  582. package/src/cli/ui/__tests__/components/screens/PRCleanupScreen.test.tsx +0 -216
  583. package/src/cli/ui/__tests__/components/screens/SessionSelectorScreen.test.tsx +0 -147
  584. package/src/cli/ui/__tests__/hooks/useGitData.nonblocking.test.tsx +0 -206
  585. package/src/cli/ui/__tests__/hooks/useGitData.test.ts +0 -197
  586. package/src/cli/ui/__tests__/hooks/useGitData.test.ts.skip +0 -228
  587. package/src/cli/ui/__tests__/hooks/useScreenState.test.ts +0 -147
  588. package/src/cli/ui/__tests__/hooks/useTerminalSize.test.ts +0 -99
  589. package/src/cli/ui/__tests__/integration/branchList.test.tsx.skip +0 -253
  590. package/src/cli/ui/__tests__/integration/edgeCases.test.tsx +0 -436
  591. package/src/cli/ui/__tests__/integration/navigation.test.tsx +0 -514
  592. package/src/cli/ui/__tests__/integration/realtimeUpdate.test.tsx +0 -509
  593. package/src/cli/ui/__tests__/integration/realtimeUpdate.test.tsx.skip +0 -216
  594. package/src/cli/ui/__tests__/performance/branchList.performance.test.tsx +0 -193
  595. package/src/cli/ui/__tests__/performance/useMemoOptimization.test.tsx +0 -234
  596. package/src/cli/ui/components/App.tsx +0 -1478
  597. package/src/cli/ui/components/common/Confirm.tsx +0 -44
  598. package/src/cli/ui/components/common/ErrorBoundary.tsx +0 -60
  599. package/src/cli/ui/components/common/Input.tsx +0 -58
  600. package/src/cli/ui/components/common/LoadingIndicator.tsx +0 -98
  601. package/src/cli/ui/components/common/Select.tsx +0 -247
  602. package/src/cli/ui/components/common/SpinnerIcon.tsx +0 -86
  603. package/src/cli/ui/components/parts/Footer.tsx +0 -41
  604. package/src/cli/ui/components/parts/Header.test.tsx +0 -75
  605. package/src/cli/ui/components/parts/MergeStatusList.tsx +0 -75
  606. package/src/cli/ui/components/parts/ProgressBar.tsx +0 -73
  607. package/src/cli/ui/components/parts/Stats.tsx +0 -88
  608. package/src/cli/ui/components/screens/BatchMergeProgressScreen.tsx +0 -74
  609. package/src/cli/ui/components/screens/BatchMergeResultScreen.tsx +0 -108
  610. package/src/cli/ui/components/screens/BranchCreatorScreen.tsx +0 -242
  611. package/src/cli/ui/components/screens/BranchListScreen.tsx +0 -744
  612. package/src/cli/ui/components/screens/BranchQuickStartScreen.tsx +0 -244
  613. package/src/cli/ui/components/screens/CodingAgentSelectorScreen.tsx +0 -159
  614. package/src/cli/ui/components/screens/EnvironmentProfileScreen.tsx +0 -928
  615. package/src/cli/ui/components/screens/ExecutionModeSelectorScreen.tsx +0 -176
  616. package/src/cli/ui/components/screens/LogDatePickerScreen.tsx +0 -83
  617. package/src/cli/ui/components/screens/LogDetailScreen.tsx +0 -67
  618. package/src/cli/ui/components/screens/LogListScreen.tsx +0 -192
  619. package/src/cli/ui/components/screens/ModelSelectorScreen.tsx +0 -320
  620. package/src/cli/ui/components/screens/PRCleanupScreen.tsx +0 -171
  621. package/src/cli/ui/components/screens/SessionSelectorScreen.tsx +0 -135
  622. package/src/cli/ui/hooks/useAppInput.ts +0 -172
  623. package/src/cli/ui/hooks/useBatchMerge.ts +0 -96
  624. package/src/cli/ui/hooks/useGitData.ts +0 -347
  625. package/src/cli/ui/hooks/useProfiles.ts +0 -211
  626. package/src/cli/ui/hooks/useScreenState.ts +0 -44
  627. package/src/cli/ui/hooks/useTerminalSize.ts +0 -33
  628. package/src/cli/ui/hooks/useToolStatus.ts +0 -68
  629. package/src/cli/ui/screens/BranchActionSelectorScreen.tsx +0 -111
  630. package/src/cli/ui/screens/__tests__/BranchActionSelectorScreen.test.tsx +0 -264
@@ -0,0 +1,227 @@
1
+ import { describe, expect, it } from "bun:test";
2
+ import {
3
+ formatBranchItem,
4
+ getLatestActivityTimestamp,
5
+ } from "../branchFormatter.js";
6
+ import type { BranchInfo } from "../../types.js";
7
+
8
+ // TDD: テストを先に書き、実装は後から行う
9
+
10
+ const LOCAL_DATE_TIME_FORMATTER = new Intl.DateTimeFormat(undefined, {
11
+ year: "numeric",
12
+ month: "2-digit",
13
+ day: "2-digit",
14
+ hour: "2-digit",
15
+ minute: "2-digit",
16
+ hour12: false,
17
+ });
18
+
19
+ const formatLocalDateTime = (timestampMs: number): string => {
20
+ const date = new Date(timestampMs);
21
+ const parts = LOCAL_DATE_TIME_FORMATTER.formatToParts(date);
22
+ const get = (type: Intl.DateTimeFormatPartTypes) =>
23
+ parts.find((part) => part.type === type)?.value;
24
+ const year = get("year");
25
+ const month = get("month");
26
+ const day = get("day");
27
+ const hour = get("hour");
28
+ const minute = get("minute");
29
+ if (!year || !month || !day || !hour || !minute) {
30
+ return LOCAL_DATE_TIME_FORMATTER.format(date);
31
+ }
32
+ return `${year}-${month}-${day} ${hour}:${minute}`;
33
+ };
34
+
35
+ describe("branchFormatter", () => {
36
+ describe("buildLastToolUsageLabel with version", () => {
37
+ const baseBranch: BranchInfo = {
38
+ name: "feature/test",
39
+ type: "local",
40
+ isCurrent: false,
41
+ branchType: "feature",
42
+ hasRemoteCounterpart: false,
43
+ };
44
+
45
+ it("should format as 'ToolName@1.0.3 | 2024-01-08 12:00' with version", () => {
46
+ const branch: BranchInfo = {
47
+ ...baseBranch,
48
+ lastToolUsage: {
49
+ branch: "feature/test",
50
+ worktreePath: "/path/to/worktree",
51
+ toolId: "claude-code",
52
+ toolLabel: "Claude Code",
53
+ timestamp: new Date("2024-01-08T12:00:00").getTime(),
54
+ toolVersion: "1.0.3",
55
+ },
56
+ };
57
+
58
+ const item = formatBranchItem(branch);
59
+ expect(item.lastToolUsageLabel).toBe(
60
+ `Claude@1.0.3 | ${formatLocalDateTime(
61
+ new Date("2024-01-08T12:00:00").getTime(),
62
+ )}`,
63
+ );
64
+ });
65
+
66
+ it("should format as 'ToolName@latest | 2024-01-08 12:00' when version is null", () => {
67
+ const branch: BranchInfo = {
68
+ ...baseBranch,
69
+ lastToolUsage: {
70
+ branch: "feature/test",
71
+ worktreePath: "/path/to/worktree",
72
+ toolId: "claude-code",
73
+ toolLabel: "Claude Code",
74
+ timestamp: new Date("2024-01-08T12:00:00").getTime(),
75
+ toolVersion: null,
76
+ },
77
+ };
78
+
79
+ const item = formatBranchItem(branch);
80
+ expect(item.lastToolUsageLabel).toBe(
81
+ `Claude@latest | ${formatLocalDateTime(
82
+ new Date("2024-01-08T12:00:00").getTime(),
83
+ )}`,
84
+ );
85
+ });
86
+
87
+ it("should format as 'ToolName@latest | 2024-01-08 12:00' when version is undefined", () => {
88
+ const branch: BranchInfo = {
89
+ ...baseBranch,
90
+ lastToolUsage: {
91
+ branch: "feature/test",
92
+ worktreePath: "/path/to/worktree",
93
+ toolId: "claude-code",
94
+ toolLabel: "Claude Code",
95
+ timestamp: new Date("2024-01-08T12:00:00").getTime(),
96
+ },
97
+ };
98
+
99
+ const item = formatBranchItem(branch);
100
+ expect(item.lastToolUsageLabel).toBe(
101
+ `Claude@latest | ${formatLocalDateTime(
102
+ new Date("2024-01-08T12:00:00").getTime(),
103
+ )}`,
104
+ );
105
+ });
106
+
107
+ it("should format Codex with version", () => {
108
+ const branch: BranchInfo = {
109
+ ...baseBranch,
110
+ lastToolUsage: {
111
+ branch: "feature/test",
112
+ worktreePath: "/path/to/worktree",
113
+ toolId: "codex-cli",
114
+ toolLabel: "Codex CLI",
115
+ timestamp: new Date("2024-01-08T15:30:00").getTime(),
116
+ toolVersion: "2.1.0-beta.1",
117
+ },
118
+ };
119
+
120
+ const item = formatBranchItem(branch);
121
+ expect(item.lastToolUsageLabel).toBe(
122
+ `Codex@2.1.0-beta.1 | ${formatLocalDateTime(
123
+ new Date("2024-01-08T15:30:00").getTime(),
124
+ )}`,
125
+ );
126
+ });
127
+
128
+ it("should format Gemini with version", () => {
129
+ const branch: BranchInfo = {
130
+ ...baseBranch,
131
+ lastToolUsage: {
132
+ branch: "feature/test",
133
+ worktreePath: "/path/to/worktree",
134
+ toolId: "gemini-cli",
135
+ toolLabel: "Gemini CLI",
136
+ timestamp: new Date("2024-01-08T09:15:00").getTime(),
137
+ toolVersion: "0.5.0",
138
+ },
139
+ };
140
+
141
+ const item = formatBranchItem(branch);
142
+ expect(item.lastToolUsageLabel).toBe(
143
+ `Gemini@0.5.0 | ${formatLocalDateTime(
144
+ new Date("2024-01-08T09:15:00").getTime(),
145
+ )}`,
146
+ );
147
+ });
148
+
149
+ it("should format custom tool with version", () => {
150
+ const branch: BranchInfo = {
151
+ ...baseBranch,
152
+ lastToolUsage: {
153
+ branch: "feature/test",
154
+ worktreePath: "/path/to/worktree",
155
+ toolId: "custom-tool",
156
+ toolLabel: "MyTool",
157
+ timestamp: new Date("2024-01-08T10:00:00").getTime(),
158
+ toolVersion: "1.0.0",
159
+ },
160
+ };
161
+
162
+ const item = formatBranchItem(branch);
163
+ expect(item.lastToolUsageLabel).toBe(
164
+ `MyTool@1.0.0 | ${formatLocalDateTime(
165
+ new Date("2024-01-08T10:00:00").getTime(),
166
+ )}`,
167
+ );
168
+ });
169
+
170
+ it("should return null when lastToolUsage is undefined", () => {
171
+ const branch: BranchInfo = {
172
+ ...baseBranch,
173
+ lastToolUsage: undefined,
174
+ };
175
+
176
+ const item = formatBranchItem(branch);
177
+ expect(item.lastToolUsageLabel).toBeNull();
178
+ });
179
+
180
+ it("should return null when lastToolUsage is null", () => {
181
+ const branch: BranchInfo = {
182
+ ...baseBranch,
183
+ lastToolUsage: null,
184
+ };
185
+
186
+ const item = formatBranchItem(branch);
187
+ expect(item.lastToolUsageLabel).toBeNull();
188
+ });
189
+ });
190
+
191
+ describe("getLatestActivityTimestamp", () => {
192
+ it("should return git timestamp when tool usage is undefined", () => {
193
+ const branch: BranchInfo = {
194
+ name: "feature/test",
195
+ type: "local",
196
+ isCurrent: false,
197
+ branchType: "feature",
198
+ hasRemoteCounterpart: false,
199
+ latestCommitTimestamp: 1704700800, // 2024-01-08 12:00:00 UTC in seconds
200
+ };
201
+
202
+ const result = getLatestActivityTimestamp(branch);
203
+ expect(result).toBe(1704700800);
204
+ });
205
+
206
+ it("should return tool timestamp when it is newer than git timestamp", () => {
207
+ const branch: BranchInfo = {
208
+ name: "feature/test",
209
+ type: "local",
210
+ isCurrent: false,
211
+ branchType: "feature",
212
+ hasRemoteCounterpart: false,
213
+ latestCommitTimestamp: 1704700800, // 2024-01-08 12:00:00 UTC in seconds
214
+ lastToolUsage: {
215
+ branch: "feature/test",
216
+ worktreePath: "/path/to/worktree",
217
+ toolId: "claude-code",
218
+ toolLabel: "Claude Code",
219
+ timestamp: 1704704400000, // 2024-01-08 13:00:00 UTC in milliseconds
220
+ },
221
+ };
222
+
223
+ const result = getLatestActivityTimestamp(branch);
224
+ expect(result).toBe(1704704400); // converted to seconds
225
+ });
226
+ });
227
+ });
@@ -1,94 +1,9 @@
1
1
  import type {
2
2
  BranchInfo,
3
3
  BranchItem,
4
- BranchType,
5
4
  WorktreeStatus,
6
5
  WorktreeInfo,
7
6
  } from "../types.js";
8
- import stringWidth from "string-width";
9
-
10
- // Icon mappings
11
- const branchIcons: Record<BranchType, string> = {
12
- main: "⚡",
13
- develop: "⚡",
14
- feature: "✨",
15
- bugfix: "🐛",
16
- hotfix: "🔥",
17
- release: "🚀",
18
- other: "📌",
19
- };
20
-
21
- const worktreeIcons: Record<Exclude<WorktreeStatus, undefined>, string> = {
22
- active: "🟢",
23
- inaccessible: "🔴",
24
- };
25
-
26
- const changeIcons = {
27
- current: "👉",
28
- hasChanges: "💾",
29
- unpushed: "📤",
30
- openPR: "🔃",
31
- mergedPR: "✅",
32
- warning: "⚠️",
33
- };
34
-
35
- const remoteIcon = "☁";
36
-
37
- // Sync status icons
38
- const syncIcons = {
39
- upToDate: "✓",
40
- ahead: "↑",
41
- behind: "↓",
42
- diverged: "↕",
43
- none: "-",
44
- remoteOnly: "☁",
45
- };
46
-
47
- // Remote column markers
48
- const remoteMarkers = {
49
- tracked: "🔗", // ローカル+同名リモートあり
50
- localOnly: "💻", // ローカルのみ(リモートなし)
51
- remoteOnly: "☁️", // リモートのみ(ローカルなし)
52
- };
53
-
54
- // Emoji width varies by terminal. Provide explicit minimum widths so we never
55
- // underestimate and accidentally push the row past the terminal columns.
56
- const iconWidthOverrides: Record<string, number> = {
57
- // Remote icon
58
- [remoteIcon]: 1,
59
- // Branch type icons
60
- "⚡": 1,
61
- "✨": 1,
62
- "🐛": 1,
63
- "🔥": 1,
64
- "🚀": 1,
65
- "📌": 1,
66
- // Worktree status icons
67
- "🟢": 2,
68
- "⚪": 2,
69
- "🔴": 2,
70
- // Change status icons
71
- "👉": 1,
72
- "💾": 1,
73
- "📤": 1,
74
- "🔃": 1,
75
- "✅": 1,
76
- "⚠️": 2,
77
- "⚠": 1,
78
- "🛡": 2,
79
- "☑": 2,
80
- "☐": 2,
81
- // Remote markers
82
- "🔗": 1,
83
- "💻": 1,
84
- "☁️": 1,
85
- };
86
-
87
- const getIconWidth = (icon: string): number => {
88
- const baseWidth = stringWidth(icon);
89
- const override = iconWidthOverrides[icon];
90
- return override !== undefined ? Math.max(baseWidth, override) : baseWidth;
91
- };
92
7
 
93
8
  export interface FormatOptions {
94
9
  hasChanges?: boolean;
@@ -102,14 +17,42 @@ function mapToolLabel(toolId: string, toolLabel?: string): string {
102
17
  return "Custom";
103
18
  }
104
19
 
20
+ const LOCAL_DATE_TIME_FORMATTER = new Intl.DateTimeFormat(undefined, {
21
+ year: "numeric",
22
+ month: "2-digit",
23
+ day: "2-digit",
24
+ hour: "2-digit",
25
+ minute: "2-digit",
26
+ hour12: false,
27
+ });
28
+
29
+ const formatLocalDateTimeParts = (date: Date): string => {
30
+ const parts = LOCAL_DATE_TIME_FORMATTER.formatToParts(date);
31
+ const get = (type: Intl.DateTimeFormatPartTypes) =>
32
+ parts.find((part) => part.type === type)?.value;
33
+ const year = get("year");
34
+ const month = get("month");
35
+ const day = get("day");
36
+ const hour = get("hour");
37
+ const minute = get("minute");
38
+
39
+ if (!year || !month || !day || !hour || !minute) {
40
+ return LOCAL_DATE_TIME_FORMATTER.format(date);
41
+ }
42
+
43
+ return `${year}-${month}-${day} ${hour}:${minute}`;
44
+ };
45
+
46
+ export function formatLocalDateTime(timestampMs: number): string {
47
+ const date = new Date(timestampMs);
48
+ if (Number.isNaN(date.getTime())) {
49
+ return "";
50
+ }
51
+ return formatLocalDateTimeParts(date);
52
+ }
53
+
105
54
  function formatTimestamp(ts: number): string {
106
- const date = new Date(ts);
107
- const year = date.getFullYear();
108
- const month = String(date.getMonth() + 1).padStart(2, "0");
109
- const day = String(date.getDate()).padStart(2, "0");
110
- const hours = String(date.getHours()).padStart(2, "0");
111
- const minutes = String(date.getMinutes()).padStart(2, "0");
112
- return `${year}-${month}-${day} ${hours}:${minutes}`;
55
+ return formatLocalDateTime(ts);
113
56
  }
114
57
 
115
58
  function buildLastToolUsageLabel(
@@ -117,8 +60,11 @@ function buildLastToolUsageLabel(
117
60
  ): string | null {
118
61
  if (!usage) return null;
119
62
  const toolText = mapToolLabel(usage.toolId, usage.toolLabel);
63
+ // バージョン情報を追加(存在しない場合は@latest)
64
+ const versionSuffix = usage.toolVersion ? `@${usage.toolVersion}` : "@latest";
65
+ const labelWithVersion = `${toolText}${versionSuffix}`;
120
66
  const timestamp = usage.timestamp ? formatTimestamp(usage.timestamp) : null;
121
- const parts = [toolText];
67
+ const parts = [labelWithVersion];
122
68
  if (timestamp) {
123
69
  parts.push(timestamp);
124
70
  }
@@ -146,106 +92,10 @@ export function formatBranchItem(
146
92
  options: FormatOptions = {},
147
93
  ): BranchItem {
148
94
  const hasChanges = options.hasChanges ?? false;
149
- const COLUMN_WIDTH = 2; // Fixed width for each icon column
150
-
151
- // Helper to pad icon to fixed width
152
- const padIcon = (icon: string): string => {
153
- const width = getIconWidth(icon);
154
- const padding = Math.max(0, COLUMN_WIDTH - width);
155
- return icon + " ".repeat(padding);
156
- };
157
-
158
- // Column 1: Branch type icon (always present)
159
- const branchTypeIcon = padIcon(branchIcons[branch.branchType]);
160
-
161
- // Column 2: Worktree status icon
162
- let worktreeStatus: WorktreeStatus;
163
- let worktreeIcon: string;
95
+ let worktreeStatus: WorktreeStatus | undefined;
164
96
  if (branch.worktree) {
165
- if (branch.worktree.isAccessible === false) {
166
- worktreeStatus = "inaccessible";
167
- worktreeIcon = padIcon(worktreeIcons.inaccessible);
168
- } else {
169
- worktreeStatus = "active";
170
- worktreeIcon = padIcon(worktreeIcons.active);
171
- }
172
- } else {
173
- worktreeIcon = " ".repeat(COLUMN_WIDTH);
174
- }
175
-
176
- // Column 3: Change status icon (priority: ✏️ > ⬆️ > 🔀 > ✅ > ⚠️ > ⭐)
177
- let changesIcon: string;
178
- if (hasChanges) {
179
- changesIcon = padIcon(changeIcons.hasChanges);
180
- } else if (branch.hasUnpushedCommits) {
181
- changesIcon = padIcon(changeIcons.unpushed);
182
- } else if (branch.openPR) {
183
- changesIcon = padIcon(changeIcons.openPR);
184
- } else if (branch.mergedPR) {
185
- changesIcon = padIcon(changeIcons.mergedPR);
186
- } else if (branch.worktree?.isAccessible === false) {
187
- changesIcon = padIcon(changeIcons.warning);
188
- } else if (branch.isCurrent) {
189
- changesIcon = padIcon(changeIcons.current);
190
- } else {
191
- changesIcon = " ".repeat(COLUMN_WIDTH);
192
- }
193
-
194
- // Column 4: Remote status (✓ for tracked, L for local-only, R for remote-only)
195
- let remoteStatusStr: string;
196
- if (branch.type === "remote") {
197
- // リモートのみのブランチ
198
- remoteStatusStr = padIcon(remoteMarkers.remoteOnly);
199
- } else if (branch.hasRemoteCounterpart) {
200
- // ローカルブランチで同名リモートあり
201
- remoteStatusStr = padIcon(remoteMarkers.tracked);
202
- } else {
203
- // ローカルブランチでリモートなし
204
- remoteStatusStr = padIcon(remoteMarkers.localOnly);
205
- }
206
-
207
- // Column 5: Sync status (=, ↑N, ↓N, ↕, -)
208
- // 5文字固定幅(アイコン1文字 + 数字最大4桁)、9999超は「9999+」表示
209
- const SYNC_COLUMN_WIDTH = 6; // アイコン1 + 数字4 + スペース1
210
-
211
- // 数字を4桁以内にフォーマット(9999超は9999+)
212
- const formatSyncNumber = (n: number): string => {
213
- if (n > 9999) return "9999+";
214
- return String(n);
215
- };
216
-
217
- // Sync列を固定幅でパディング
218
- const padSyncColumn = (content: string): string => {
219
- const width = stringWidth(content);
220
- const padding = Math.max(0, SYNC_COLUMN_WIDTH - width);
221
- return content + " ".repeat(padding);
222
- };
223
-
224
- let syncStatusStr: string;
225
- if (branch.type === "remote") {
226
- // リモートのみ → 比較不可
227
- syncStatusStr = padSyncColumn(syncIcons.none);
228
- } else if (branch.divergence) {
229
- const { ahead, behind, upToDate } = branch.divergence;
230
- if (upToDate) {
231
- syncStatusStr = padSyncColumn(syncIcons.upToDate);
232
- } else if (ahead > 0 && behind > 0) {
233
- // diverged: ↕ のみ表示(詳細は別途表示可能)
234
- syncStatusStr = padSyncColumn(syncIcons.diverged);
235
- } else if (ahead > 0) {
236
- // ahead: ↑N の形式
237
- syncStatusStr = padSyncColumn(
238
- `${syncIcons.ahead}${formatSyncNumber(ahead)}`,
239
- );
240
- } else {
241
- // behind: ↓N の形式
242
- syncStatusStr = padSyncColumn(
243
- `${syncIcons.behind}${formatSyncNumber(behind)}`,
244
- );
245
- }
246
- } else {
247
- // divergence情報なし
248
- syncStatusStr = padSyncColumn(syncIcons.none);
97
+ worktreeStatus =
98
+ branch.worktree.isAccessible === false ? "inaccessible" : "active";
249
99
  }
250
100
 
251
101
  // Build Local/Remote name for display
@@ -263,37 +113,8 @@ export function formatBranchItem(
263
113
  displayName = branch.name;
264
114
  }
265
115
 
266
- // Build label with fixed-width columns
267
- // Format: [Type][Worktree][Changes][Remote][Sync] DisplayName
268
- const label = `${branchTypeIcon}${worktreeIcon}${changesIcon}${remoteStatusStr}${syncStatusStr}${displayName}`;
269
-
270
- // Collect icons for compatibility
116
+ const label = displayName;
271
117
  const icons: string[] = [];
272
- icons.push(branchIcons[branch.branchType]);
273
- if (worktreeStatus) {
274
- icons.push(
275
- worktreeStatus === "active"
276
- ? worktreeIcons.active
277
- : worktreeIcons.inaccessible,
278
- );
279
- }
280
- // Add change icon based on priority
281
- if (hasChanges) {
282
- icons.push(changeIcons.hasChanges);
283
- } else if (branch.hasUnpushedCommits) {
284
- icons.push(changeIcons.unpushed);
285
- } else if (branch.openPR) {
286
- icons.push(changeIcons.openPR);
287
- } else if (branch.mergedPR) {
288
- icons.push(changeIcons.mergedPR);
289
- } else if (branch.worktree?.isAccessible === false) {
290
- icons.push(changeIcons.warning);
291
- } else if (branch.isCurrent) {
292
- icons.push(changeIcons.current);
293
- }
294
- if (branch.type === "remote") {
295
- icons.push(remoteIcon);
296
- }
297
118
 
298
119
  // Determine sync status for BranchItem
299
120
  let syncStatus: BranchItem["syncStatus"];
@@ -1,4 +1,15 @@
1
1
  import type { SessionData, ToolSessionEntry } from "../../../config/index.js";
2
+ import type { SessionSearchOptions } from "../../../utils/session/index.js";
3
+ import {
4
+ findLatestClaudeSession,
5
+ findLatestClaudeSessionId,
6
+ findLatestCodexSession,
7
+ findLatestCodexSessionId,
8
+ findLatestGeminiSession,
9
+ findLatestGeminiSessionId,
10
+ findLatestOpenCodeSession,
11
+ } from "../../../utils/session/index.js";
12
+ import { listAllWorktrees } from "../../../worktree.js";
2
13
 
3
14
  export interface ContinueSessionContext {
4
15
  history: ToolSessionEntry[];
@@ -6,6 +17,10 @@ export interface ContinueSessionContext {
6
17
  branch: string;
7
18
  toolId: string;
8
19
  repoRoot: string | null;
20
+ lookupLatestSessionId?: (params: {
21
+ toolId: string;
22
+ worktreePath: string;
23
+ }) => Promise<string | null>;
9
24
  }
10
25
 
11
26
  /**
@@ -41,6 +56,41 @@ export async function resolveContinueSessionId(
41
56
  return sessionData.lastSessionId;
42
57
  }
43
58
 
59
+ const latestEntry = findLatestBranchSession(history, branch, toolId);
60
+ const worktreePath = latestEntry?.worktreePath ?? null;
61
+ if (!worktreePath) {
62
+ return null;
63
+ }
64
+
65
+ if (context.lookupLatestSessionId) {
66
+ const lookupResult = await context.lookupLatestSessionId({
67
+ toolId,
68
+ worktreePath,
69
+ });
70
+ return lookupResult ?? null;
71
+ }
72
+
73
+ return lookupLatestSessionIdForTool(toolId, worktreePath);
74
+ }
75
+
76
+ async function lookupLatestSessionIdForTool(
77
+ toolId: string,
78
+ worktreePath: string,
79
+ ): Promise<string | null> {
80
+ try {
81
+ if (toolId === "claude-code") {
82
+ return await findLatestClaudeSessionId(worktreePath);
83
+ }
84
+ if (toolId === "codex-cli") {
85
+ return await findLatestCodexSessionId({ cwd: worktreePath });
86
+ }
87
+ if (toolId === "gemini-cli") {
88
+ return await findLatestGeminiSessionId(worktreePath);
89
+ }
90
+ } catch {
91
+ return null;
92
+ }
93
+
44
94
  return null;
45
95
  }
46
96
 
@@ -78,10 +128,10 @@ export function findLatestBranchSessionsByTool(
78
128
  const byBranch = history.filter((entry) => entry && entry.branch === branch);
79
129
  if (!byBranch.length) return [];
80
130
 
81
- const scoped = worktreePath
131
+ const source = worktreePath
82
132
  ? byBranch.filter((entry) => entry.worktreePath === worktreePath)
83
133
  : byBranch;
84
- const source = scoped.length ? scoped : byBranch;
134
+ if (!source.length) return [];
85
135
 
86
136
  const latestByTool = new Map<string, ToolSessionEntry>();
87
137
  for (const entry of source) {
@@ -98,3 +148,84 @@ export function findLatestBranchSessionsByTool(
98
148
  (a, b) => (b.timestamp ?? 0) - (a.timestamp ?? 0),
99
149
  );
100
150
  }
151
+
152
+ export interface QuickStartRefreshContext {
153
+ branch: string;
154
+ worktreePath?: string | null;
155
+ }
156
+
157
+ export interface QuickStartSessionLookups {
158
+ findLatestCodexSession?: typeof findLatestCodexSession;
159
+ findLatestClaudeSession?: typeof findLatestClaudeSession;
160
+ findLatestGeminiSession?: typeof findLatestGeminiSession;
161
+ findLatestOpenCodeSession?: typeof findLatestOpenCodeSession;
162
+ listAllWorktrees?: typeof listAllWorktrees;
163
+ }
164
+
165
+ export async function refreshQuickStartEntries(
166
+ entries: ToolSessionEntry[],
167
+ context: QuickStartRefreshContext,
168
+ lookups: QuickStartSessionLookups = {},
169
+ ): Promise<ToolSessionEntry[]> {
170
+ if (!entries.length) return entries;
171
+ const worktreePath = context.worktreePath ?? null;
172
+ if (!worktreePath) return entries;
173
+
174
+ const lookupWorktrees = lookups.listAllWorktrees ?? listAllWorktrees;
175
+ let resolvedWorktrees: { path: string; branch: string }[] | null = null;
176
+ try {
177
+ const allWorktrees = await lookupWorktrees();
178
+ resolvedWorktrees = allWorktrees
179
+ .filter((entry) => entry?.path && entry?.branch)
180
+ .map((entry) => ({ path: entry.path, branch: entry.branch }));
181
+ } catch {
182
+ resolvedWorktrees = null;
183
+ }
184
+
185
+ const searchOptions: SessionSearchOptions = {
186
+ branch: context.branch,
187
+ ...(resolvedWorktrees && resolvedWorktrees.length > 0
188
+ ? { worktrees: resolvedWorktrees }
189
+ : {}),
190
+ };
191
+
192
+ const lookupCodex = lookups.findLatestCodexSession ?? findLatestCodexSession;
193
+ const lookupClaude =
194
+ lookups.findLatestClaudeSession ?? findLatestClaudeSession;
195
+ const lookupGemini =
196
+ lookups.findLatestGeminiSession ?? findLatestGeminiSession;
197
+ const lookupOpenCode =
198
+ lookups.findLatestOpenCodeSession ?? findLatestOpenCodeSession;
199
+
200
+ const updated = await Promise.all(
201
+ entries.map(async (entry) => {
202
+ let latest: { id: string; mtime: number } | null = null;
203
+ switch (entry.toolId) {
204
+ case "codex-cli":
205
+ latest = await lookupCodex(searchOptions);
206
+ break;
207
+ case "claude-code":
208
+ latest = await lookupClaude(worktreePath, searchOptions);
209
+ break;
210
+ case "gemini-cli":
211
+ latest = await lookupGemini(searchOptions);
212
+ break;
213
+ case "opencode":
214
+ latest = await lookupOpenCode(searchOptions);
215
+ break;
216
+ default:
217
+ return entry;
218
+ }
219
+
220
+ if (!latest?.id) return entry;
221
+ const updatedTimestamp = Math.max(entry.timestamp ?? 0, latest.mtime);
222
+ return {
223
+ ...entry,
224
+ sessionId: latest.id,
225
+ timestamp: updatedTimestamp,
226
+ };
227
+ }),
228
+ );
229
+
230
+ return updated.sort((a, b) => (b.timestamp ?? 0) - (a.timestamp ?? 0));
231
+ }
@@ -1,4 +1,4 @@
1
- import { describe, it, expect } from "vitest";
1
+ import { describe, it, expect } from "bun:test";
2
2
  import {
3
3
  getModelOptions,
4
4
  getDefaultInferenceForModel,