@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,226 @@
1
+ /**
2
+ * UI Store - UI state management for SolidJS
3
+ *
4
+ * This store manages UI-level concerns like notifications, terminal size,
5
+ * loading states, and modal dialogs.
6
+ *
7
+ * @see specs/SPEC-d27be71b/spec.md - OpenTUI migration spec
8
+ */
9
+
10
+ import { createRoot } from "solid-js";
11
+ import { createStore } from "solid-js/store";
12
+ import type {
13
+ Notification,
14
+ NotificationTone,
15
+ TerminalSize,
16
+ LoadingState,
17
+ } from "../core/types.js";
18
+
19
+ // ========================================
20
+ // Types
21
+ // ========================================
22
+
23
+ export interface UIStoreState {
24
+ /** Current notification */
25
+ notification: Notification | null;
26
+ /** Terminal dimensions */
27
+ terminalSize: TerminalSize;
28
+ /** Global loading state */
29
+ loading: LoadingState;
30
+ /** Is search mode active */
31
+ searchMode: boolean;
32
+ /** Is confirm dialog visible */
33
+ confirmDialogVisible: boolean;
34
+ /** Confirm dialog message */
35
+ confirmDialogMessage: string;
36
+ }
37
+
38
+ // ========================================
39
+ // Initial State
40
+ // ========================================
41
+
42
+ const initialState: UIStoreState = {
43
+ notification: null,
44
+ terminalSize: { width: 80, height: 24 },
45
+ loading: { isLoading: false },
46
+ searchMode: false,
47
+ confirmDialogVisible: false,
48
+ confirmDialogMessage: "",
49
+ };
50
+
51
+ // ========================================
52
+ // Store Creation
53
+ // ========================================
54
+
55
+ function createUIStore() {
56
+ const [state, setState] = createStore<UIStoreState>(initialState);
57
+
58
+ // Notification timeout handle
59
+ let notificationTimeout: ReturnType<typeof setTimeout> | null = null;
60
+
61
+ const actions = {
62
+ /**
63
+ * Show a notification
64
+ */
65
+ showNotification(
66
+ message: string,
67
+ tone: NotificationTone = "info",
68
+ duration = 3000,
69
+ ): void {
70
+ // Clear existing timeout
71
+ if (notificationTimeout) {
72
+ clearTimeout(notificationTimeout);
73
+ }
74
+
75
+ setState("notification", {
76
+ message,
77
+ tone,
78
+ timestamp: new Date(),
79
+ });
80
+
81
+ // Auto-hide after duration
82
+ if (duration > 0) {
83
+ notificationTimeout = setTimeout(() => {
84
+ setState("notification", null);
85
+ }, duration);
86
+ }
87
+ },
88
+
89
+ /**
90
+ * Show success notification
91
+ */
92
+ showSuccess(message: string, duration = 3000): void {
93
+ actions.showNotification(message, "success", duration);
94
+ },
95
+
96
+ /**
97
+ * Show error notification
98
+ */
99
+ showError(message: string, duration = 5000): void {
100
+ actions.showNotification(message, "error", duration);
101
+ },
102
+
103
+ /**
104
+ * Show warning notification
105
+ */
106
+ showWarning(message: string, duration = 4000): void {
107
+ actions.showNotification(message, "warning", duration);
108
+ },
109
+
110
+ /**
111
+ * Clear notification
112
+ */
113
+ clearNotification(): void {
114
+ if (notificationTimeout) {
115
+ clearTimeout(notificationTimeout);
116
+ notificationTimeout = null;
117
+ }
118
+ setState("notification", null);
119
+ },
120
+
121
+ /**
122
+ * Update terminal size
123
+ */
124
+ setTerminalSize(size: TerminalSize): void {
125
+ setState("terminalSize", size);
126
+ },
127
+
128
+ /**
129
+ * Set loading state
130
+ */
131
+ setLoading(isLoading: boolean, message?: string): void {
132
+ const loadingState: LoadingState = { isLoading };
133
+ if (message !== undefined) loadingState.message = message;
134
+ setState("loading", loadingState);
135
+ },
136
+
137
+ /**
138
+ * Set loading progress
139
+ */
140
+ setLoadingProgress(progress: number, message?: string): void {
141
+ const loadingState: LoadingState = { isLoading: true, progress };
142
+ if (message !== undefined) loadingState.message = message;
143
+ setState("loading", loadingState);
144
+ },
145
+
146
+ /**
147
+ * Clear loading state
148
+ */
149
+ clearLoading(): void {
150
+ setState("loading", { isLoading: false });
151
+ },
152
+
153
+ /**
154
+ * Enter search mode
155
+ */
156
+ enterSearchMode(): void {
157
+ setState("searchMode", true);
158
+ },
159
+
160
+ /**
161
+ * Exit search mode
162
+ */
163
+ exitSearchMode(): void {
164
+ setState("searchMode", false);
165
+ },
166
+
167
+ /**
168
+ * Toggle search mode
169
+ */
170
+ toggleSearchMode(): void {
171
+ setState("searchMode", (v) => !v);
172
+ },
173
+
174
+ /**
175
+ * Show confirm dialog
176
+ */
177
+ showConfirmDialog(message: string): void {
178
+ setState("confirmDialogVisible", true);
179
+ setState("confirmDialogMessage", message);
180
+ },
181
+
182
+ /**
183
+ * Hide confirm dialog
184
+ */
185
+ hideConfirmDialog(): void {
186
+ setState("confirmDialogVisible", false);
187
+ setState("confirmDialogMessage", "");
188
+ },
189
+ };
190
+
191
+ return {
192
+ state,
193
+ actions,
194
+ };
195
+ }
196
+
197
+ // ========================================
198
+ // Singleton Export
199
+ // ========================================
200
+
201
+ let _store: ReturnType<typeof createUIStore> | null = null;
202
+
203
+ export function getUIStore() {
204
+ if (!_store) {
205
+ createRoot(() => {
206
+ _store = createUIStore();
207
+ });
208
+ }
209
+ // Store is guaranteed to be initialized by createRoot
210
+ return _store as ReturnType<typeof createUIStore>;
211
+ }
212
+
213
+ // Convenience exports
214
+ export const uiStore = new Proxy({} as UIStoreState, {
215
+ get: (_, prop) => getUIStore().state[prop as keyof UIStoreState],
216
+ });
217
+
218
+ export const uiActions = new Proxy(
219
+ {} as ReturnType<typeof createUIStore>["actions"],
220
+ {
221
+ get: (_, prop) =>
222
+ getUIStore().actions[
223
+ prop as keyof ReturnType<typeof createUIStore>["actions"]
224
+ ],
225
+ },
226
+ );
@@ -162,6 +162,21 @@ export interface CleanupTarget {
162
162
  reasons?: CleanupReason[];
163
163
  }
164
164
 
165
+ export interface CleanupStatus {
166
+ branch: string;
167
+ worktreePath: string | null;
168
+ hasUncommittedChanges: boolean;
169
+ hasUnpushedCommits: boolean;
170
+ hasRemoteBranch: boolean;
171
+ hasUniqueCommits: boolean;
172
+ hasUpstream: boolean;
173
+ upstream?: string | null;
174
+ cleanupType: "worktree-and-branch" | "branch-only";
175
+ isAccessible?: boolean;
176
+ invalidReason?: string;
177
+ reasons: CleanupReason[];
178
+ }
179
+
165
180
  export interface GitHubPRAuthor {
166
181
  id?: string;
167
182
  is_bot?: boolean;
@@ -180,11 +195,11 @@ export interface GitHubPRResponse {
180
195
  }
181
196
 
182
197
  // ========================================
183
- // Ink.js UI Types (Phase 2+)
198
+ // CLI UI Types
184
199
  // ========================================
185
200
 
186
201
  /**
187
- * Screen types for Ink.js UI
202
+ * Screen types for CLI UI
188
203
  */
189
204
  export type ScreenType =
190
205
  | "branch-list"
@@ -239,8 +254,10 @@ export interface BranchItem extends BranchInfo {
239
254
  syncStatus?: SyncStatus;
240
255
  syncInfo?: string | undefined;
241
256
  remoteName?: string | undefined;
242
- // クリーンアップ判定で「未コミット/未プッシュなし かつマージ済み」と評価された場合に true
257
+ // クリーンアップ候補判定で安全と評価された場合に true
243
258
  safeToCleanup?: boolean;
259
+ // ベースブランチとの差分があり未マージと判定された場合に true
260
+ isUnmerged?: boolean;
244
261
  }
245
262
 
246
263
  /**
@@ -0,0 +1,180 @@
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
+ describe("branchFormatter", () => {
11
+ describe("buildLastToolUsageLabel with version", () => {
12
+ const baseBranch: BranchInfo = {
13
+ name: "feature/test",
14
+ type: "local",
15
+ isCurrent: false,
16
+ branchType: "feature",
17
+ hasRemoteCounterpart: false,
18
+ };
19
+
20
+ it("should format as 'ToolName@1.0.3 | 2024-01-08 12:00' with version", () => {
21
+ const branch: BranchInfo = {
22
+ ...baseBranch,
23
+ lastToolUsage: {
24
+ branch: "feature/test",
25
+ worktreePath: "/path/to/worktree",
26
+ toolId: "claude-code",
27
+ toolLabel: "Claude Code",
28
+ timestamp: new Date("2024-01-08T12:00:00").getTime(),
29
+ toolVersion: "1.0.3",
30
+ },
31
+ };
32
+
33
+ const item = formatBranchItem(branch);
34
+ expect(item.lastToolUsageLabel).toBe("Claude@1.0.3 | 2024-01-08 12:00");
35
+ });
36
+
37
+ it("should format as 'ToolName@latest | 2024-01-08 12:00' when version is null", () => {
38
+ const branch: BranchInfo = {
39
+ ...baseBranch,
40
+ lastToolUsage: {
41
+ branch: "feature/test",
42
+ worktreePath: "/path/to/worktree",
43
+ toolId: "claude-code",
44
+ toolLabel: "Claude Code",
45
+ timestamp: new Date("2024-01-08T12:00:00").getTime(),
46
+ toolVersion: null,
47
+ },
48
+ };
49
+
50
+ const item = formatBranchItem(branch);
51
+ expect(item.lastToolUsageLabel).toBe("Claude@latest | 2024-01-08 12:00");
52
+ });
53
+
54
+ it("should format as 'ToolName@latest | 2024-01-08 12:00' when version is undefined", () => {
55
+ const branch: BranchInfo = {
56
+ ...baseBranch,
57
+ lastToolUsage: {
58
+ branch: "feature/test",
59
+ worktreePath: "/path/to/worktree",
60
+ toolId: "claude-code",
61
+ toolLabel: "Claude Code",
62
+ timestamp: new Date("2024-01-08T12:00:00").getTime(),
63
+ },
64
+ };
65
+
66
+ const item = formatBranchItem(branch);
67
+ expect(item.lastToolUsageLabel).toBe("Claude@latest | 2024-01-08 12:00");
68
+ });
69
+
70
+ it("should format Codex with version", () => {
71
+ const branch: BranchInfo = {
72
+ ...baseBranch,
73
+ lastToolUsage: {
74
+ branch: "feature/test",
75
+ worktreePath: "/path/to/worktree",
76
+ toolId: "codex-cli",
77
+ toolLabel: "Codex CLI",
78
+ timestamp: new Date("2024-01-08T15:30:00").getTime(),
79
+ toolVersion: "2.1.0-beta.1",
80
+ },
81
+ };
82
+
83
+ const item = formatBranchItem(branch);
84
+ expect(item.lastToolUsageLabel).toBe(
85
+ "Codex@2.1.0-beta.1 | 2024-01-08 15:30",
86
+ );
87
+ });
88
+
89
+ it("should format Gemini with version", () => {
90
+ const branch: BranchInfo = {
91
+ ...baseBranch,
92
+ lastToolUsage: {
93
+ branch: "feature/test",
94
+ worktreePath: "/path/to/worktree",
95
+ toolId: "gemini-cli",
96
+ toolLabel: "Gemini CLI",
97
+ timestamp: new Date("2024-01-08T09:15:00").getTime(),
98
+ toolVersion: "0.5.0",
99
+ },
100
+ };
101
+
102
+ const item = formatBranchItem(branch);
103
+ expect(item.lastToolUsageLabel).toBe("Gemini@0.5.0 | 2024-01-08 09:15");
104
+ });
105
+
106
+ it("should format custom tool with version", () => {
107
+ const branch: BranchInfo = {
108
+ ...baseBranch,
109
+ lastToolUsage: {
110
+ branch: "feature/test",
111
+ worktreePath: "/path/to/worktree",
112
+ toolId: "custom-tool",
113
+ toolLabel: "MyTool",
114
+ timestamp: new Date("2024-01-08T10:00:00").getTime(),
115
+ toolVersion: "1.0.0",
116
+ },
117
+ };
118
+
119
+ const item = formatBranchItem(branch);
120
+ expect(item.lastToolUsageLabel).toBe("MyTool@1.0.0 | 2024-01-08 10:00");
121
+ });
122
+
123
+ it("should return null when lastToolUsage is undefined", () => {
124
+ const branch: BranchInfo = {
125
+ ...baseBranch,
126
+ lastToolUsage: undefined,
127
+ };
128
+
129
+ const item = formatBranchItem(branch);
130
+ expect(item.lastToolUsageLabel).toBeNull();
131
+ });
132
+
133
+ it("should return null when lastToolUsage is null", () => {
134
+ const branch: BranchInfo = {
135
+ ...baseBranch,
136
+ lastToolUsage: null,
137
+ };
138
+
139
+ const item = formatBranchItem(branch);
140
+ expect(item.lastToolUsageLabel).toBeNull();
141
+ });
142
+ });
143
+
144
+ describe("getLatestActivityTimestamp", () => {
145
+ it("should return git timestamp when tool usage is undefined", () => {
146
+ const branch: BranchInfo = {
147
+ name: "feature/test",
148
+ type: "local",
149
+ isCurrent: false,
150
+ branchType: "feature",
151
+ hasRemoteCounterpart: false,
152
+ latestCommitTimestamp: 1704700800, // 2024-01-08 12:00:00 UTC in seconds
153
+ };
154
+
155
+ const result = getLatestActivityTimestamp(branch);
156
+ expect(result).toBe(1704700800);
157
+ });
158
+
159
+ it("should return tool timestamp when it is newer than git timestamp", () => {
160
+ const branch: BranchInfo = {
161
+ name: "feature/test",
162
+ type: "local",
163
+ isCurrent: false,
164
+ branchType: "feature",
165
+ hasRemoteCounterpart: false,
166
+ latestCommitTimestamp: 1704700800, // 2024-01-08 12:00:00 UTC in seconds
167
+ lastToolUsage: {
168
+ branch: "feature/test",
169
+ worktreePath: "/path/to/worktree",
170
+ toolId: "claude-code",
171
+ toolLabel: "Claude Code",
172
+ timestamp: 1704704400000, // 2024-01-08 13:00:00 UTC in milliseconds
173
+ },
174
+ };
175
+
176
+ const result = getLatestActivityTimestamp(branch);
177
+ expect(result).toBe(1704704400); // converted to seconds
178
+ });
179
+ });
180
+ });
@@ -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;
@@ -117,8 +32,11 @@ function buildLastToolUsageLabel(
117
32
  ): string | null {
118
33
  if (!usage) return null;
119
34
  const toolText = mapToolLabel(usage.toolId, usage.toolLabel);
35
+ // バージョン情報を追加(存在しない場合は@latest)
36
+ const versionSuffix = usage.toolVersion ? `@${usage.toolVersion}` : "@latest";
37
+ const labelWithVersion = `${toolText}${versionSuffix}`;
120
38
  const timestamp = usage.timestamp ? formatTimestamp(usage.timestamp) : null;
121
- const parts = [toolText];
39
+ const parts = [labelWithVersion];
122
40
  if (timestamp) {
123
41
  parts.push(timestamp);
124
42
  }
@@ -146,106 +64,10 @@ export function formatBranchItem(
146
64
  options: FormatOptions = {},
147
65
  ): BranchItem {
148
66
  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;
67
+ let worktreeStatus: WorktreeStatus | undefined;
164
68
  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);
69
+ worktreeStatus =
70
+ branch.worktree.isAccessible === false ? "inaccessible" : "active";
249
71
  }
250
72
 
251
73
  // Build Local/Remote name for display
@@ -263,37 +85,8 @@ export function formatBranchItem(
263
85
  displayName = branch.name;
264
86
  }
265
87
 
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
88
+ const label = displayName;
271
89
  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
90
 
298
91
  // Determine sync status for BranchItem
299
92
  let syncStatus: BranchItem["syncStatus"];