@akiojin/gwt 4.9.1 → 4.11.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (605) hide show
  1. package/README.ja.md +4 -4
  2. package/README.md +4 -4
  3. package/dist/claude.d.ts +1 -0
  4. package/dist/claude.d.ts.map +1 -1
  5. package/dist/claude.js +52 -49
  6. package/dist/claude.js.map +1 -1
  7. package/dist/cli/ui/App.solid.d.ts +29 -0
  8. package/dist/cli/ui/App.solid.d.ts.map +1 -0
  9. package/dist/cli/ui/App.solid.js +1197 -0
  10. package/dist/cli/ui/App.solid.js.map +1 -0
  11. package/dist/cli/ui/components/solid/Footer.d.ts +10 -0
  12. package/dist/cli/ui/components/solid/Footer.d.ts.map +1 -0
  13. package/dist/cli/ui/components/solid/Footer.js +10 -0
  14. package/dist/cli/ui/components/solid/Footer.js.map +1 -0
  15. package/dist/cli/ui/components/{parts → solid}/Header.d.ts +1 -6
  16. package/dist/cli/ui/components/solid/Header.d.ts.map +1 -0
  17. package/dist/cli/ui/components/solid/Header.js +13 -0
  18. package/dist/cli/ui/components/solid/Header.js.map +1 -0
  19. package/dist/cli/ui/components/solid/HelpOverlay.d.ts +8 -0
  20. package/dist/cli/ui/components/solid/HelpOverlay.d.ts.map +1 -0
  21. package/dist/cli/ui/components/solid/HelpOverlay.js +118 -0
  22. package/dist/cli/ui/components/solid/HelpOverlay.js.map +1 -0
  23. package/dist/cli/ui/components/solid/QuickStartStep.d.ts +17 -0
  24. package/dist/cli/ui/components/solid/QuickStartStep.d.ts.map +1 -0
  25. package/dist/cli/ui/components/solid/QuickStartStep.js +139 -0
  26. package/dist/cli/ui/components/solid/QuickStartStep.js.map +1 -0
  27. package/dist/cli/ui/components/solid/SelectInput.d.ts +22 -0
  28. package/dist/cli/ui/components/solid/SelectInput.d.ts.map +1 -0
  29. package/dist/cli/ui/components/solid/SelectInput.js +44 -0
  30. package/dist/cli/ui/components/solid/SelectInput.js.map +1 -0
  31. package/dist/cli/ui/components/solid/TextInput.d.ts +12 -0
  32. package/dist/cli/ui/components/solid/TextInput.d.ts.map +1 -0
  33. package/dist/cli/ui/components/solid/TextInput.js +9 -0
  34. package/dist/cli/ui/components/solid/TextInput.js.map +1 -0
  35. package/dist/cli/ui/components/solid/WizardController.d.ts +34 -0
  36. package/dist/cli/ui/components/solid/WizardController.d.ts.map +1 -0
  37. package/dist/cli/ui/components/solid/WizardController.js +215 -0
  38. package/dist/cli/ui/components/solid/WizardController.js.map +1 -0
  39. package/dist/cli/ui/components/solid/WizardPopup.d.ts +26 -0
  40. package/dist/cli/ui/components/solid/WizardPopup.d.ts.map +1 -0
  41. package/dist/cli/ui/components/solid/WizardPopup.js +68 -0
  42. package/dist/cli/ui/components/solid/WizardPopup.js.map +1 -0
  43. package/dist/cli/ui/components/solid/WizardSteps.d.ts +52 -0
  44. package/dist/cli/ui/components/solid/WizardSteps.d.ts.map +1 -0
  45. package/dist/cli/ui/components/solid/WizardSteps.js +462 -0
  46. package/dist/cli/ui/components/solid/WizardSteps.js.map +1 -0
  47. package/dist/cli/ui/core/index.d.ts +12 -0
  48. package/dist/cli/ui/core/index.d.ts.map +1 -0
  49. package/dist/cli/ui/core/index.js +15 -0
  50. package/dist/cli/ui/core/index.js.map +1 -0
  51. package/dist/cli/ui/core/keybindings.d.ts +106 -0
  52. package/dist/cli/ui/core/keybindings.d.ts.map +1 -0
  53. package/dist/cli/ui/core/keybindings.js +270 -0
  54. package/dist/cli/ui/core/keybindings.js.map +1 -0
  55. package/dist/cli/ui/core/theme.d.ts +114 -0
  56. package/dist/cli/ui/core/theme.d.ts.map +1 -0
  57. package/dist/cli/ui/core/theme.js +170 -0
  58. package/dist/cli/ui/core/theme.js.map +1 -0
  59. package/dist/cli/ui/core/types.d.ts +156 -0
  60. package/dist/cli/ui/core/types.d.ts.map +1 -0
  61. package/dist/cli/ui/core/types.js +10 -0
  62. package/dist/cli/ui/core/types.js.map +1 -0
  63. package/dist/cli/ui/hooks/solid/useScrollableList.d.ts +26 -0
  64. package/dist/cli/ui/hooks/solid/useScrollableList.d.ts.map +1 -0
  65. package/dist/cli/ui/hooks/solid/useScrollableList.js +89 -0
  66. package/dist/cli/ui/hooks/solid/useScrollableList.js.map +1 -0
  67. package/dist/cli/ui/hooks/solid/useTerminalSize.d.ts +10 -0
  68. package/dist/cli/ui/hooks/solid/useTerminalSize.d.ts.map +1 -0
  69. package/dist/cli/ui/hooks/solid/useTerminalSize.js +16 -0
  70. package/dist/cli/ui/hooks/solid/useTerminalSize.js.map +1 -0
  71. package/dist/cli/ui/index.solid.d.ts +5 -0
  72. package/dist/cli/ui/index.solid.d.ts.map +1 -0
  73. package/dist/cli/ui/index.solid.js +21 -0
  74. package/dist/cli/ui/index.solid.js.map +1 -0
  75. package/dist/cli/ui/{components/screens → screens/solid}/BranchListScreen.d.ts +8 -22
  76. package/dist/cli/ui/screens/solid/BranchListScreen.d.ts.map +1 -0
  77. package/dist/cli/ui/screens/solid/BranchListScreen.js +756 -0
  78. package/dist/cli/ui/screens/solid/BranchListScreen.js.map +1 -0
  79. package/dist/cli/ui/screens/solid/ConfirmScreen.d.ts +10 -0
  80. package/dist/cli/ui/screens/solid/ConfirmScreen.d.ts.map +1 -0
  81. package/dist/cli/ui/screens/solid/ConfirmScreen.js +37 -0
  82. package/dist/cli/ui/screens/solid/ConfirmScreen.js.map +1 -0
  83. package/dist/cli/ui/screens/solid/EnvironmentScreen.d.ts +14 -0
  84. package/dist/cli/ui/screens/solid/EnvironmentScreen.d.ts.map +1 -0
  85. package/dist/cli/ui/screens/solid/EnvironmentScreen.js +91 -0
  86. package/dist/cli/ui/screens/solid/EnvironmentScreen.js.map +1 -0
  87. package/dist/cli/ui/screens/solid/ErrorScreen.d.ts +8 -0
  88. package/dist/cli/ui/screens/solid/ErrorScreen.d.ts.map +1 -0
  89. package/dist/cli/ui/screens/solid/ErrorScreen.js +18 -0
  90. package/dist/cli/ui/screens/solid/ErrorScreen.js.map +1 -0
  91. package/dist/cli/ui/screens/solid/InputScreen.d.ts +13 -0
  92. package/dist/cli/ui/screens/solid/InputScreen.d.ts.map +1 -0
  93. package/dist/cli/ui/screens/solid/InputScreen.js +17 -0
  94. package/dist/cli/ui/screens/solid/InputScreen.js.map +1 -0
  95. package/dist/cli/ui/screens/solid/LoadingIndicator.d.ts +9 -0
  96. package/dist/cli/ui/screens/solid/LoadingIndicator.d.ts.map +1 -0
  97. package/dist/cli/ui/screens/solid/LoadingIndicator.js +43 -0
  98. package/dist/cli/ui/screens/solid/LoadingIndicator.js.map +1 -0
  99. package/dist/cli/ui/{components/screens → screens/solid}/LogDetailScreen.d.ts +2 -2
  100. package/dist/cli/ui/screens/solid/LogDetailScreen.d.ts.map +1 -0
  101. package/dist/cli/ui/screens/solid/LogDetailScreen.js +34 -0
  102. package/dist/cli/ui/screens/solid/LogDetailScreen.js.map +1 -0
  103. package/dist/cli/ui/{components/screens/LogListScreen.d.ts → screens/solid/LogScreen.d.ts} +4 -4
  104. package/dist/cli/ui/screens/solid/LogScreen.d.ts.map +1 -0
  105. package/dist/cli/ui/screens/solid/LogScreen.js +95 -0
  106. package/dist/cli/ui/screens/solid/LogScreen.js.map +1 -0
  107. package/dist/cli/ui/screens/solid/ProfileEnvScreen.d.ts +17 -0
  108. package/dist/cli/ui/screens/solid/ProfileEnvScreen.d.ts.map +1 -0
  109. package/dist/cli/ui/screens/solid/ProfileEnvScreen.js +112 -0
  110. package/dist/cli/ui/screens/solid/ProfileEnvScreen.js.map +1 -0
  111. package/dist/cli/ui/screens/solid/ProfileScreen.d.ts +17 -0
  112. package/dist/cli/ui/screens/solid/ProfileScreen.d.ts.map +1 -0
  113. package/dist/cli/ui/screens/solid/ProfileScreen.js +50 -0
  114. package/dist/cli/ui/screens/solid/ProfileScreen.js.map +1 -0
  115. package/dist/cli/ui/screens/solid/SelectorScreen.d.ts +20 -0
  116. package/dist/cli/ui/screens/solid/SelectorScreen.d.ts.map +1 -0
  117. package/dist/cli/ui/screens/solid/SelectorScreen.js +90 -0
  118. package/dist/cli/ui/screens/solid/SelectorScreen.js.map +1 -0
  119. package/dist/cli/ui/screens/solid/WorktreeCreateScreen.d.ts +13 -0
  120. package/dist/cli/ui/screens/solid/WorktreeCreateScreen.d.ts.map +1 -0
  121. package/dist/cli/ui/screens/solid/WorktreeCreateScreen.js +59 -0
  122. package/dist/cli/ui/screens/solid/WorktreeCreateScreen.js.map +1 -0
  123. package/dist/cli/ui/stores/appStore.d.ts +143 -0
  124. package/dist/cli/ui/stores/appStore.d.ts.map +1 -0
  125. package/dist/cli/ui/stores/appStore.js +158 -0
  126. package/dist/cli/ui/stores/appStore.js.map +1 -0
  127. package/dist/cli/ui/stores/branchStore.d.ts +159 -0
  128. package/dist/cli/ui/stores/branchStore.d.ts.map +1 -0
  129. package/dist/cli/ui/stores/branchStore.js +275 -0
  130. package/dist/cli/ui/stores/branchStore.js.map +1 -0
  131. package/dist/cli/ui/stores/index.d.ts +11 -0
  132. package/dist/cli/ui/stores/index.d.ts.map +1 -0
  133. package/dist/cli/ui/stores/index.js +14 -0
  134. package/dist/cli/ui/stores/index.js.map +1 -0
  135. package/dist/cli/ui/stores/uiStore.d.ts +146 -0
  136. package/dist/cli/ui/stores/uiStore.d.ts.map +1 -0
  137. package/dist/cli/ui/stores/uiStore.js +166 -0
  138. package/dist/cli/ui/stores/uiStore.js.map +1 -0
  139. package/dist/cli/ui/types.d.ts +16 -1
  140. package/dist/cli/ui/types.d.ts.map +1 -1
  141. package/dist/cli/ui/utils/branchFormatter.d.ts.map +1 -1
  142. package/dist/cli/ui/utils/branchFormatter.js +7 -210
  143. package/dist/cli/ui/utils/branchFormatter.js.map +1 -1
  144. package/dist/cli/ui/utils/continueSession.d.ts +4 -0
  145. package/dist/cli/ui/utils/continueSession.d.ts.map +1 -1
  146. package/dist/cli/ui/utils/continueSession.js +30 -0
  147. package/dist/cli/ui/utils/continueSession.js.map +1 -1
  148. package/dist/client/assets/{index-ChHC-Puh.css → index-BbfV7Wuj.css} +1 -1
  149. package/dist/client/assets/index-CoAyq5x1.js +78 -0
  150. package/dist/client/index.html +2 -2
  151. package/dist/codex.d.ts +1 -0
  152. package/dist/codex.d.ts.map +1 -1
  153. package/dist/codex.js +86 -45
  154. package/dist/codex.js.map +1 -1
  155. package/dist/config/builtin-coding-agents.d.ts +4 -0
  156. package/dist/config/builtin-coding-agents.d.ts.map +1 -1
  157. package/dist/config/builtin-coding-agents.js +18 -3
  158. package/dist/config/builtin-coding-agents.js.map +1 -1
  159. package/dist/config/index.d.ts +2 -0
  160. package/dist/config/index.d.ts.map +1 -1
  161. package/dist/config/index.js +2 -0
  162. package/dist/config/index.js.map +1 -1
  163. package/dist/config/tools.d.ts.map +1 -1
  164. package/dist/config/tools.js +11 -0
  165. package/dist/config/tools.js.map +1 -1
  166. package/dist/gemini.d.ts +1 -0
  167. package/dist/gemini.d.ts.map +1 -1
  168. package/dist/gemini.js +42 -37
  169. package/dist/gemini.js.map +1 -1
  170. package/dist/index.d.ts +1 -1
  171. package/dist/index.d.ts.map +1 -1
  172. package/dist/index.js +122 -102
  173. package/dist/index.js.map +1 -1
  174. package/dist/launcher.d.ts.map +1 -1
  175. package/dist/launcher.js +18 -3
  176. package/dist/launcher.js.map +1 -1
  177. package/dist/logging/logger.d.ts.map +1 -1
  178. package/dist/logging/logger.js +26 -9
  179. package/dist/logging/logger.js.map +1 -1
  180. package/dist/opentui/highlights-eq9cgrbb.scm +604 -0
  181. package/dist/opentui/highlights-ghv9g403.scm +205 -0
  182. package/dist/opentui/highlights-hk7bwhj4.scm +284 -0
  183. package/dist/opentui/highlights-r812a2qc.scm +150 -0
  184. package/dist/opentui/highlights-x6tmsnaa.scm +115 -0
  185. package/dist/opentui/index.solid.d.ts +2 -0
  186. package/dist/opentui/index.solid.d.ts.map +1 -0
  187. package/dist/opentui/index.solid.js +52034 -0
  188. package/dist/opentui/index.solid.js.map +1 -0
  189. package/dist/opentui/injections-73j83es3.scm +27 -0
  190. package/dist/opentui/tree-sitter-javascript-nd0q4pe9.wasm +0 -0
  191. package/dist/opentui/tree-sitter-markdown-411r6y9b.wasm +0 -0
  192. package/dist/opentui/tree-sitter-markdown_inline-j5349f42.wasm +0 -0
  193. package/dist/opentui/tree-sitter-typescript-zxjzwt75.wasm +0 -0
  194. package/dist/opentui/tree-sitter-zig-e78zbjpm.wasm +0 -0
  195. package/dist/repositories/worktree.repository.d.ts +1 -0
  196. package/dist/repositories/worktree.repository.d.ts.map +1 -1
  197. package/dist/repositories/worktree.repository.js +7 -0
  198. package/dist/repositories/worktree.repository.js.map +1 -1
  199. package/dist/services/codingAgentResolver.d.ts +2 -0
  200. package/dist/services/codingAgentResolver.d.ts.map +1 -1
  201. package/dist/services/codingAgentResolver.js +30 -4
  202. package/dist/services/codingAgentResolver.js.map +1 -1
  203. package/dist/services/dependency-installer.d.ts.map +1 -1
  204. package/dist/services/dependency-installer.js +0 -5
  205. package/dist/services/dependency-installer.js.map +1 -1
  206. package/dist/types/api.d.ts +3 -0
  207. package/dist/types/api.d.ts.map +1 -1
  208. package/dist/types/coding-agent.d.ts +62 -0
  209. package/dist/types/coding-agent.d.ts.map +1 -0
  210. package/dist/types/coding-agent.js +29 -0
  211. package/dist/types/coding-agent.js.map +1 -0
  212. package/dist/types/tools.d.ts +17 -0
  213. package/dist/types/tools.d.ts.map +1 -1
  214. package/dist/utils/coding-agent-colors.d.ts +88 -0
  215. package/dist/utils/coding-agent-colors.d.ts.map +1 -0
  216. package/dist/utils/coding-agent-colors.js +137 -0
  217. package/dist/utils/coding-agent-colors.js.map +1 -0
  218. package/dist/utils/command.d.ts +1 -1
  219. package/dist/utils/command.d.ts.map +1 -1
  220. package/dist/utils/command.js +10 -1
  221. package/dist/utils/command.js.map +1 -1
  222. package/dist/utils/error-utils.d.ts +27 -0
  223. package/dist/utils/error-utils.d.ts.map +1 -0
  224. package/dist/utils/error-utils.js +98 -0
  225. package/dist/utils/error-utils.js.map +1 -0
  226. package/dist/utils/npmRegistry.d.ts +61 -0
  227. package/dist/utils/npmRegistry.d.ts.map +1 -0
  228. package/dist/utils/npmRegistry.js +180 -0
  229. package/dist/utils/npmRegistry.js.map +1 -0
  230. package/dist/utils/prompt.d.ts +1 -1
  231. package/dist/utils/prompt.js +1 -1
  232. package/dist/utils/session/index.d.ts +5 -3
  233. package/dist/utils/session/index.d.ts.map +1 -1
  234. package/dist/utils/session/index.js +5 -2
  235. package/dist/utils/session/index.js.map +1 -1
  236. package/dist/utils/session/parsers/codex.d.ts.map +1 -1
  237. package/dist/utils/session/parsers/codex.js +8 -1
  238. package/dist/utils/session/parsers/codex.js.map +1 -1
  239. package/dist/utils/session/parsers/index.d.ts +1 -0
  240. package/dist/utils/session/parsers/index.d.ts.map +1 -1
  241. package/dist/utils/session/parsers/index.js +2 -0
  242. package/dist/utils/session/parsers/index.js.map +1 -1
  243. package/dist/utils/session/parsers/opencode.d.ts +23 -0
  244. package/dist/utils/session/parsers/opencode.d.ts.map +1 -0
  245. package/dist/utils/session/parsers/opencode.js +89 -0
  246. package/dist/utils/session/parsers/opencode.js.map +1 -0
  247. package/dist/utils/session/types.d.ts +4 -0
  248. package/dist/utils/session/types.d.ts.map +1 -1
  249. package/dist/utils/terminal.d.ts +1 -0
  250. package/dist/utils/terminal.d.ts.map +1 -1
  251. package/dist/utils/terminal.js +20 -0
  252. package/dist/utils/terminal.js.map +1 -1
  253. package/dist/utils.d.ts +9 -0
  254. package/dist/utils.d.ts.map +1 -1
  255. package/dist/utils.js +33 -2
  256. package/dist/utils.js.map +1 -1
  257. package/dist/web/client/src/components/CodingAgentLaunchModal.d.ts.map +1 -1
  258. package/dist/web/client/src/components/CodingAgentLaunchModal.js +7 -16
  259. package/dist/web/client/src/components/CodingAgentLaunchModal.js.map +1 -1
  260. package/dist/web/client/src/components/branch-detail/BranchInfoCards.d.ts.map +1 -1
  261. package/dist/web/client/src/components/branch-detail/BranchInfoCards.js +7 -2
  262. package/dist/web/client/src/components/branch-detail/BranchInfoCards.js.map +1 -1
  263. package/dist/web/client/src/components/branch-detail/SessionHistoryTable.d.ts.map +1 -1
  264. package/dist/web/client/src/components/branch-detail/SessionHistoryTable.js +2 -1
  265. package/dist/web/client/src/components/branch-detail/SessionHistoryTable.js.map +1 -1
  266. package/dist/web/client/src/components/branch-detail/ToolLauncher.d.ts +2 -2
  267. package/dist/web/client/src/components/branch-detail/ToolLauncher.d.ts.map +1 -1
  268. package/dist/web/client/src/components/branch-detail/ToolLauncher.js +5 -5
  269. package/dist/web/client/src/components/branch-detail/ToolLauncher.js.map +1 -1
  270. package/dist/web/client/src/lib/coding-agent-colors.d.ts +86 -0
  271. package/dist/web/client/src/lib/coding-agent-colors.d.ts.map +1 -0
  272. package/dist/web/client/src/lib/coding-agent-colors.js +135 -0
  273. package/dist/web/client/src/lib/coding-agent-colors.js.map +1 -0
  274. package/dist/web/client/src/pages/BranchDetailPage.js +10 -10
  275. package/dist/web/client/src/pages/BranchDetailPage.js.map +1 -1
  276. package/dist/web/server/pty/manager.d.ts +2 -0
  277. package/dist/web/server/pty/manager.d.ts.map +1 -1
  278. package/dist/web/server/pty/manager.js +104 -0
  279. package/dist/web/server/pty/manager.js.map +1 -1
  280. package/dist/web/server/routes/sessions.d.ts.map +1 -1
  281. package/dist/web/server/routes/sessions.js +5 -1
  282. package/dist/web/server/routes/sessions.js.map +1 -1
  283. package/dist/web/server/services/branches.d.ts.map +1 -1
  284. package/dist/web/server/services/branches.js +10 -8
  285. package/dist/web/server/services/branches.js.map +1 -1
  286. package/dist/web/server/services/worktrees.js +2 -2
  287. package/dist/web/server/services/worktrees.js.map +1 -1
  288. package/dist/worktree.d.ts +47 -1
  289. package/dist/worktree.d.ts.map +1 -1
  290. package/dist/worktree.js +280 -94
  291. package/dist/worktree.js.map +1 -1
  292. package/package.json +12 -14
  293. package/src/claude.ts +68 -70
  294. package/src/cli/ui/App.solid.tsx +1823 -0
  295. package/src/cli/ui/__tests__/solid/AppSolid.cleanup.test.tsx +255 -0
  296. package/src/cli/ui/__tests__/solid/BranchListScreen.test.tsx +243 -0
  297. package/src/cli/ui/__tests__/solid/components/QuickStartStep.test.tsx +237 -0
  298. package/src/cli/ui/__tests__/solid/components/WizardPopup.test.tsx +231 -0
  299. package/src/cli/ui/__tests__/solid/components/WizardSteps.test.tsx +238 -0
  300. package/src/cli/ui/__tests__/utils/branchFormatter.test.ts +7 -289
  301. package/src/cli/ui/__tests__/utils/clipboard.test.ts +3 -3
  302. package/src/cli/ui/__tests__/utils/statisticsCalculator.test.ts +1 -1
  303. package/src/cli/ui/components/solid/Footer.tsx +36 -0
  304. package/src/cli/ui/components/{parts → solid}/Header.tsx +17 -28
  305. package/src/cli/ui/components/solid/HelpOverlay.tsx +194 -0
  306. package/src/cli/ui/components/solid/QuickStartStep.tsx +197 -0
  307. package/src/cli/ui/components/{parts → solid}/ScrollableList.tsx +7 -8
  308. package/src/cli/ui/components/solid/SearchInput.tsx +42 -0
  309. package/src/cli/ui/components/solid/SelectInput.tsx +84 -0
  310. package/src/cli/ui/components/solid/Stats.tsx +92 -0
  311. package/src/cli/ui/components/solid/TextInput.tsx +49 -0
  312. package/src/cli/ui/components/solid/WizardController.tsx +384 -0
  313. package/src/cli/ui/components/solid/WizardPopup.tsx +135 -0
  314. package/src/cli/ui/components/solid/WizardSteps.tsx +793 -0
  315. package/src/cli/ui/core/index.ts +17 -0
  316. package/src/cli/ui/core/keybindings.ts +367 -0
  317. package/src/cli/ui/core/theme.ts +234 -0
  318. package/src/cli/ui/core/types.ts +235 -0
  319. package/src/cli/ui/hooks/solid/useAsyncOperation.ts +76 -0
  320. package/src/cli/ui/hooks/solid/useFilter.ts +86 -0
  321. package/src/cli/ui/hooks/solid/useGitOperations.ts +80 -0
  322. package/src/cli/ui/hooks/solid/useKeyHandler.ts +103 -0
  323. package/src/cli/ui/hooks/solid/useScrollableList.ts +149 -0
  324. package/src/cli/ui/hooks/solid/useSelection.ts +77 -0
  325. package/src/cli/ui/hooks/solid/useTerminalSize.ts +22 -0
  326. package/src/cli/ui/index.solid.ts +28 -0
  327. package/src/cli/ui/screens/solid/BranchListScreen.tsx +1050 -0
  328. package/src/cli/ui/screens/solid/ConfirmScreen.tsx +74 -0
  329. package/src/cli/ui/screens/solid/EnvironmentScreen.tsx +159 -0
  330. package/src/cli/ui/screens/solid/ErrorScreen.tsx +42 -0
  331. package/src/cli/ui/screens/solid/InputScreen.tsx +55 -0
  332. package/src/cli/ui/screens/solid/LoadingIndicator.tsx +77 -0
  333. package/src/cli/ui/screens/solid/LogDetailScreen.tsx +75 -0
  334. package/src/cli/ui/screens/solid/LogScreen.tsx +175 -0
  335. package/src/cli/ui/screens/solid/ProfileEnvScreen.tsx +192 -0
  336. package/src/cli/ui/screens/solid/ProfileScreen.tsx +98 -0
  337. package/src/cli/ui/screens/solid/SelectorScreen.tsx +170 -0
  338. package/src/cli/ui/screens/solid/SettingsScreen.tsx +50 -0
  339. package/src/cli/ui/screens/solid/WorktreeCreateScreen.tsx +136 -0
  340. package/src/cli/ui/screens/solid/WorktreeDeleteScreen.tsx +40 -0
  341. package/src/cli/ui/stores/appStore.ts +208 -0
  342. package/src/cli/ui/stores/branchStore.ts +357 -0
  343. package/src/cli/ui/stores/index.ts +31 -0
  344. package/src/cli/ui/stores/uiStore.ts +226 -0
  345. package/src/cli/ui/types.ts +20 -3
  346. package/src/cli/ui/utils/__tests__/branchFormatter.test.ts +180 -0
  347. package/src/cli/ui/utils/branchFormatter.ts +8 -215
  348. package/src/cli/ui/utils/continueSession.ts +44 -0
  349. package/src/cli/ui/utils/modelOptions.test.ts +1 -1
  350. package/src/codex.ts +100 -43
  351. package/src/config/__tests__/saveSession.test.ts +143 -0
  352. package/src/config/builtin-coding-agents.ts +19 -3
  353. package/src/config/index.ts +4 -0
  354. package/src/config/tools.ts +16 -0
  355. package/src/gemini.ts +58 -43
  356. package/src/index.test.ts +12 -12
  357. package/src/index.ts +164 -142
  358. package/src/launcher.ts +22 -3
  359. package/src/logging/logger.ts +32 -10
  360. package/src/opentui/index.solid.ts +1 -0
  361. package/src/repositories/worktree.repository.ts +8 -0
  362. package/src/services/__tests__/BatchMergeService.test.ts +62 -66
  363. package/src/services/__tests__/WorktreeOrchestrator.test.ts +8 -7
  364. package/src/services/codingAgentResolver.ts +30 -4
  365. package/src/services/dependency-installer.ts +0 -7
  366. package/src/types/api.ts +3 -0
  367. package/src/types/coding-agent.ts +85 -0
  368. package/src/types/tools.ts +19 -0
  369. package/src/utils/__tests__/npmRegistry.test.ts +250 -0
  370. package/src/utils/__tests__/prompt.test.ts +4 -5
  371. package/src/utils/coding-agent-colors.ts +165 -0
  372. package/src/utils/command.ts +10 -1
  373. package/src/utils/error-utils.ts +133 -0
  374. package/src/utils/npmRegistry.ts +249 -0
  375. package/src/utils/prompt.ts +1 -1
  376. package/src/utils/session/index.ts +10 -2
  377. package/src/utils/session/parsers/codex.ts +9 -1
  378. package/src/utils/session/parsers/index.ts +6 -0
  379. package/src/utils/session/parsers/opencode.ts +110 -0
  380. package/src/utils/session/types.ts +5 -0
  381. package/src/utils/terminal.ts +24 -0
  382. package/src/utils.test.ts +1 -1
  383. package/src/utils.ts +37 -4
  384. package/src/web/client/src/components/CodingAgentLaunchModal.tsx +12 -21
  385. package/src/web/client/src/components/branch-detail/BranchInfoCards.tsx +16 -1
  386. package/src/web/client/src/components/branch-detail/SessionHistoryTable.tsx +7 -1
  387. package/src/web/client/src/components/branch-detail/ToolLauncher.tsx +11 -6
  388. package/src/web/client/src/lib/coding-agent-colors.ts +149 -0
  389. package/src/web/client/src/pages/BranchDetailPage.tsx +11 -11
  390. package/src/web/server/pty/manager.ts +139 -0
  391. package/src/web/server/routes/sessions.ts +6 -0
  392. package/src/web/server/services/branches.ts +11 -8
  393. package/src/web/server/services/worktrees.ts +2 -2
  394. package/src/worktree.ts +366 -107
  395. package/dist/cli/ui/components/App.d.ts +0 -25
  396. package/dist/cli/ui/components/App.d.ts.map +0 -1
  397. package/dist/cli/ui/components/App.js +0 -988
  398. package/dist/cli/ui/components/App.js.map +0 -1
  399. package/dist/cli/ui/components/common/Confirm.d.ts +0 -13
  400. package/dist/cli/ui/components/common/Confirm.d.ts.map +0 -1
  401. package/dist/cli/ui/components/common/Confirm.js +0 -20
  402. package/dist/cli/ui/components/common/Confirm.js.map +0 -1
  403. package/dist/cli/ui/components/common/ErrorBoundary.d.ts +0 -23
  404. package/dist/cli/ui/components/common/ErrorBoundary.d.ts.map +0 -1
  405. package/dist/cli/ui/components/common/ErrorBoundary.js +0 -37
  406. package/dist/cli/ui/components/common/ErrorBoundary.js.map +0 -1
  407. package/dist/cli/ui/components/common/Input.d.ts +0 -19
  408. package/dist/cli/ui/components/common/Input.d.ts.map +0 -1
  409. package/dist/cli/ui/components/common/Input.js +0 -22
  410. package/dist/cli/ui/components/common/Input.js.map +0 -1
  411. package/dist/cli/ui/components/common/LoadingIndicator.d.ts +0 -19
  412. package/dist/cli/ui/components/common/LoadingIndicator.d.ts.map +0 -1
  413. package/dist/cli/ui/components/common/LoadingIndicator.js +0 -61
  414. package/dist/cli/ui/components/common/LoadingIndicator.js.map +0 -1
  415. package/dist/cli/ui/components/common/Select.d.ts +0 -38
  416. package/dist/cli/ui/components/common/Select.d.ts.map +0 -1
  417. package/dist/cli/ui/components/common/Select.js +0 -151
  418. package/dist/cli/ui/components/common/Select.js.map +0 -1
  419. package/dist/cli/ui/components/common/SpinnerIcon.d.ts +0 -20
  420. package/dist/cli/ui/components/common/SpinnerIcon.d.ts.map +0 -1
  421. package/dist/cli/ui/components/common/SpinnerIcon.js +0 -61
  422. package/dist/cli/ui/components/common/SpinnerIcon.js.map +0 -1
  423. package/dist/cli/ui/components/parts/Footer.d.ts +0 -15
  424. package/dist/cli/ui/components/parts/Footer.d.ts.map +0 -1
  425. package/dist/cli/ui/components/parts/Footer.js +0 -20
  426. package/dist/cli/ui/components/parts/Footer.js.map +0 -1
  427. package/dist/cli/ui/components/parts/Header.d.ts.map +0 -1
  428. package/dist/cli/ui/components/parts/Header.js +0 -24
  429. package/dist/cli/ui/components/parts/Header.js.map +0 -1
  430. package/dist/cli/ui/components/parts/MergeStatusList.d.ts +0 -13
  431. package/dist/cli/ui/components/parts/MergeStatusList.d.ts.map +0 -1
  432. package/dist/cli/ui/components/parts/MergeStatusList.js +0 -52
  433. package/dist/cli/ui/components/parts/MergeStatusList.js.map +0 -1
  434. package/dist/cli/ui/components/parts/ProgressBar.d.ts +0 -13
  435. package/dist/cli/ui/components/parts/ProgressBar.d.ts.map +0 -1
  436. package/dist/cli/ui/components/parts/ProgressBar.js +0 -53
  437. package/dist/cli/ui/components/parts/ProgressBar.js.map +0 -1
  438. package/dist/cli/ui/components/parts/ScrollableList.d.ts +0 -12
  439. package/dist/cli/ui/components/parts/ScrollableList.d.ts.map +0 -1
  440. package/dist/cli/ui/components/parts/ScrollableList.js +0 -11
  441. package/dist/cli/ui/components/parts/ScrollableList.js.map +0 -1
  442. package/dist/cli/ui/components/parts/Stats.d.ts +0 -10
  443. package/dist/cli/ui/components/parts/Stats.d.ts.map +0 -1
  444. package/dist/cli/ui/components/parts/Stats.js +0 -55
  445. package/dist/cli/ui/components/parts/Stats.js.map +0 -1
  446. package/dist/cli/ui/components/screens/BatchMergeProgressScreen.d.ts +0 -17
  447. package/dist/cli/ui/components/screens/BatchMergeProgressScreen.d.ts.map +0 -1
  448. package/dist/cli/ui/components/screens/BatchMergeProgressScreen.js +0 -42
  449. package/dist/cli/ui/components/screens/BatchMergeProgressScreen.js.map +0 -1
  450. package/dist/cli/ui/components/screens/BatchMergeResultScreen.d.ts +0 -17
  451. package/dist/cli/ui/components/screens/BatchMergeResultScreen.d.ts.map +0 -1
  452. package/dist/cli/ui/components/screens/BatchMergeResultScreen.js +0 -72
  453. package/dist/cli/ui/components/screens/BatchMergeResultScreen.js.map +0 -1
  454. package/dist/cli/ui/components/screens/BranchCreatorScreen.d.ts +0 -18
  455. package/dist/cli/ui/components/screens/BranchCreatorScreen.d.ts.map +0 -1
  456. package/dist/cli/ui/components/screens/BranchCreatorScreen.js +0 -151
  457. package/dist/cli/ui/components/screens/BranchCreatorScreen.js.map +0 -1
  458. package/dist/cli/ui/components/screens/BranchListScreen.d.ts.map +0 -1
  459. package/dist/cli/ui/components/screens/BranchListScreen.js +0 -476
  460. package/dist/cli/ui/components/screens/BranchListScreen.js.map +0 -1
  461. package/dist/cli/ui/components/screens/BranchQuickStartScreen.d.ts +0 -30
  462. package/dist/cli/ui/components/screens/BranchQuickStartScreen.d.ts.map +0 -1
  463. package/dist/cli/ui/components/screens/BranchQuickStartScreen.js +0 -145
  464. package/dist/cli/ui/components/screens/BranchQuickStartScreen.js.map +0 -1
  465. package/dist/cli/ui/components/screens/CodingAgentSelectorScreen.d.ts +0 -27
  466. package/dist/cli/ui/components/screens/CodingAgentSelectorScreen.d.ts.map +0 -1
  467. package/dist/cli/ui/components/screens/CodingAgentSelectorScreen.js +0 -93
  468. package/dist/cli/ui/components/screens/CodingAgentSelectorScreen.js.map +0 -1
  469. package/dist/cli/ui/components/screens/EnvironmentProfileScreen.d.ts +0 -19
  470. package/dist/cli/ui/components/screens/EnvironmentProfileScreen.d.ts.map +0 -1
  471. package/dist/cli/ui/components/screens/EnvironmentProfileScreen.js +0 -577
  472. package/dist/cli/ui/components/screens/EnvironmentProfileScreen.js.map +0 -1
  473. package/dist/cli/ui/components/screens/ExecutionModeSelectorScreen.d.ts +0 -45
  474. package/dist/cli/ui/components/screens/ExecutionModeSelectorScreen.d.ts.map +0 -1
  475. package/dist/cli/ui/components/screens/ExecutionModeSelectorScreen.js +0 -95
  476. package/dist/cli/ui/components/screens/ExecutionModeSelectorScreen.js.map +0 -1
  477. package/dist/cli/ui/components/screens/LogDatePickerScreen.d.ts +0 -10
  478. package/dist/cli/ui/components/screens/LogDatePickerScreen.d.ts.map +0 -1
  479. package/dist/cli/ui/components/screens/LogDatePickerScreen.js +0 -44
  480. package/dist/cli/ui/components/screens/LogDatePickerScreen.js.map +0 -1
  481. package/dist/cli/ui/components/screens/LogDetailScreen.d.ts.map +0 -1
  482. package/dist/cli/ui/components/screens/LogDetailScreen.js +0 -34
  483. package/dist/cli/ui/components/screens/LogDetailScreen.js.map +0 -1
  484. package/dist/cli/ui/components/screens/LogListScreen.d.ts.map +0 -1
  485. package/dist/cli/ui/components/screens/LogListScreen.js +0 -107
  486. package/dist/cli/ui/components/screens/LogListScreen.js.map +0 -1
  487. package/dist/cli/ui/components/screens/ModelSelectorScreen.d.ts +0 -24
  488. package/dist/cli/ui/components/screens/ModelSelectorScreen.d.ts.map +0 -1
  489. package/dist/cli/ui/components/screens/ModelSelectorScreen.js +0 -197
  490. package/dist/cli/ui/components/screens/ModelSelectorScreen.js.map +0 -1
  491. package/dist/cli/ui/components/screens/PRCleanupScreen.d.ts +0 -29
  492. package/dist/cli/ui/components/screens/PRCleanupScreen.d.ts.map +0 -1
  493. package/dist/cli/ui/components/screens/PRCleanupScreen.js +0 -92
  494. package/dist/cli/ui/components/screens/PRCleanupScreen.js.map +0 -1
  495. package/dist/cli/ui/components/screens/SessionSelectorScreen.d.ts +0 -31
  496. package/dist/cli/ui/components/screens/SessionSelectorScreen.d.ts.map +0 -1
  497. package/dist/cli/ui/components/screens/SessionSelectorScreen.js +0 -67
  498. package/dist/cli/ui/components/screens/SessionSelectorScreen.js.map +0 -1
  499. package/dist/cli/ui/hooks/useAppInput.d.ts +0 -21
  500. package/dist/cli/ui/hooks/useAppInput.d.ts.map +0 -1
  501. package/dist/cli/ui/hooks/useAppInput.js +0 -138
  502. package/dist/cli/ui/hooks/useAppInput.js.map +0 -1
  503. package/dist/cli/ui/hooks/useBatchMerge.d.ts +0 -17
  504. package/dist/cli/ui/hooks/useBatchMerge.d.ts.map +0 -1
  505. package/dist/cli/ui/hooks/useBatchMerge.js +0 -77
  506. package/dist/cli/ui/hooks/useBatchMerge.js.map +0 -1
  507. package/dist/cli/ui/hooks/useGitData.d.ts +0 -21
  508. package/dist/cli/ui/hooks/useGitData.d.ts.map +0 -1
  509. package/dist/cli/ui/hooks/useGitData.js +0 -229
  510. package/dist/cli/ui/hooks/useGitData.js.map +0 -1
  511. package/dist/cli/ui/hooks/useProfiles.d.ts +0 -41
  512. package/dist/cli/ui/hooks/useProfiles.d.ts.map +0 -1
  513. package/dist/cli/ui/hooks/useProfiles.js +0 -136
  514. package/dist/cli/ui/hooks/useProfiles.js.map +0 -1
  515. package/dist/cli/ui/hooks/useScreenState.d.ts +0 -12
  516. package/dist/cli/ui/hooks/useScreenState.d.ts.map +0 -1
  517. package/dist/cli/ui/hooks/useScreenState.js +0 -30
  518. package/dist/cli/ui/hooks/useScreenState.js.map +0 -1
  519. package/dist/cli/ui/hooks/useTerminalSize.d.ts +0 -9
  520. package/dist/cli/ui/hooks/useTerminalSize.d.ts.map +0 -1
  521. package/dist/cli/ui/hooks/useTerminalSize.js +0 -24
  522. package/dist/cli/ui/hooks/useTerminalSize.js.map +0 -1
  523. package/dist/cli/ui/hooks/useToolStatus.d.ts +0 -30
  524. package/dist/cli/ui/hooks/useToolStatus.d.ts.map +0 -1
  525. package/dist/cli/ui/hooks/useToolStatus.js +0 -49
  526. package/dist/cli/ui/hooks/useToolStatus.js.map +0 -1
  527. package/dist/cli/ui/screens/BranchActionSelectorScreen.d.ts +0 -24
  528. package/dist/cli/ui/screens/BranchActionSelectorScreen.d.ts.map +0 -1
  529. package/dist/cli/ui/screens/BranchActionSelectorScreen.js +0 -65
  530. package/dist/cli/ui/screens/BranchActionSelectorScreen.js.map +0 -1
  531. package/dist/client/assets/index-LNPtOrn3.js +0 -78
  532. package/src/cli/ui/__tests__/SKIPPED_TESTS.md +0 -119
  533. package/src/cli/ui/__tests__/acceptance/branchList.acceptance.test.tsx.skip +0 -239
  534. package/src/cli/ui/__tests__/acceptance/navigation.acceptance.test.tsx +0 -225
  535. package/src/cli/ui/__tests__/acceptance/realtimeUpdate.acceptance.test.tsx.skip +0 -219
  536. package/src/cli/ui/__tests__/components/App.protected-branch.test.tsx +0 -212
  537. package/src/cli/ui/__tests__/components/App.shortcuts.test.tsx +0 -440
  538. package/src/cli/ui/__tests__/components/App.test.tsx +0 -365
  539. package/src/cli/ui/__tests__/components/ModelSelectorScreen.initial.test.tsx +0 -91
  540. package/src/cli/ui/__tests__/components/common/Confirm.test.tsx +0 -80
  541. package/src/cli/ui/__tests__/components/common/ErrorBoundary.test.tsx +0 -104
  542. package/src/cli/ui/__tests__/components/common/Input.test.tsx +0 -100
  543. package/src/cli/ui/__tests__/components/common/LoadingIndicator.test.tsx +0 -148
  544. package/src/cli/ui/__tests__/components/common/Select.memo.test.tsx +0 -255
  545. package/src/cli/ui/__tests__/components/common/Select.test.tsx +0 -335
  546. package/src/cli/ui/__tests__/components/parts/Footer.test.tsx +0 -65
  547. package/src/cli/ui/__tests__/components/parts/Header.test.tsx +0 -55
  548. package/src/cli/ui/__tests__/components/parts/ScrollableList.test.tsx +0 -69
  549. package/src/cli/ui/__tests__/components/parts/Stats.test.tsx +0 -148
  550. package/src/cli/ui/__tests__/components/screens/BranchCreatorScreen.test.tsx +0 -253
  551. package/src/cli/ui/__tests__/components/screens/BranchListScreen.test.tsx +0 -1070
  552. package/src/cli/ui/__tests__/components/screens/BranchQuickStartScreen.test.tsx +0 -142
  553. package/src/cli/ui/__tests__/components/screens/CodingAgentSelectorScreen.test.tsx +0 -174
  554. package/src/cli/ui/__tests__/components/screens/ExecutionModeSelectorScreen.test.tsx +0 -182
  555. package/src/cli/ui/__tests__/components/screens/LogDetailScreen.test.tsx +0 -57
  556. package/src/cli/ui/__tests__/components/screens/LogListScreen.test.tsx +0 -102
  557. package/src/cli/ui/__tests__/components/screens/PRCleanupScreen.test.tsx +0 -216
  558. package/src/cli/ui/__tests__/components/screens/SessionSelectorScreen.test.tsx +0 -147
  559. package/src/cli/ui/__tests__/hooks/useGitData.nonblocking.test.tsx +0 -206
  560. package/src/cli/ui/__tests__/hooks/useGitData.test.ts +0 -197
  561. package/src/cli/ui/__tests__/hooks/useGitData.test.ts.skip +0 -228
  562. package/src/cli/ui/__tests__/hooks/useScreenState.test.ts +0 -147
  563. package/src/cli/ui/__tests__/hooks/useTerminalSize.test.ts +0 -99
  564. package/src/cli/ui/__tests__/integration/branchList.test.tsx.skip +0 -253
  565. package/src/cli/ui/__tests__/integration/edgeCases.test.tsx +0 -436
  566. package/src/cli/ui/__tests__/integration/navigation.test.tsx +0 -514
  567. package/src/cli/ui/__tests__/integration/realtimeUpdate.test.tsx +0 -509
  568. package/src/cli/ui/__tests__/integration/realtimeUpdate.test.tsx.skip +0 -216
  569. package/src/cli/ui/__tests__/performance/branchList.performance.test.tsx +0 -193
  570. package/src/cli/ui/__tests__/performance/useMemoOptimization.test.tsx +0 -234
  571. package/src/cli/ui/components/App.tsx +0 -1456
  572. package/src/cli/ui/components/common/Confirm.tsx +0 -44
  573. package/src/cli/ui/components/common/ErrorBoundary.tsx +0 -60
  574. package/src/cli/ui/components/common/Input.tsx +0 -58
  575. package/src/cli/ui/components/common/LoadingIndicator.tsx +0 -98
  576. package/src/cli/ui/components/common/Select.tsx +0 -247
  577. package/src/cli/ui/components/common/SpinnerIcon.tsx +0 -86
  578. package/src/cli/ui/components/parts/Footer.tsx +0 -41
  579. package/src/cli/ui/components/parts/Header.test.tsx +0 -75
  580. package/src/cli/ui/components/parts/MergeStatusList.tsx +0 -75
  581. package/src/cli/ui/components/parts/ProgressBar.tsx +0 -73
  582. package/src/cli/ui/components/parts/Stats.tsx +0 -88
  583. package/src/cli/ui/components/screens/BatchMergeProgressScreen.tsx +0 -74
  584. package/src/cli/ui/components/screens/BatchMergeResultScreen.tsx +0 -108
  585. package/src/cli/ui/components/screens/BranchCreatorScreen.tsx +0 -242
  586. package/src/cli/ui/components/screens/BranchListScreen.tsx +0 -744
  587. package/src/cli/ui/components/screens/BranchQuickStartScreen.tsx +0 -241
  588. package/src/cli/ui/components/screens/CodingAgentSelectorScreen.tsx +0 -159
  589. package/src/cli/ui/components/screens/EnvironmentProfileScreen.tsx +0 -928
  590. package/src/cli/ui/components/screens/ExecutionModeSelectorScreen.tsx +0 -176
  591. package/src/cli/ui/components/screens/LogDatePickerScreen.tsx +0 -83
  592. package/src/cli/ui/components/screens/LogDetailScreen.tsx +0 -67
  593. package/src/cli/ui/components/screens/LogListScreen.tsx +0 -192
  594. package/src/cli/ui/components/screens/ModelSelectorScreen.tsx +0 -320
  595. package/src/cli/ui/components/screens/PRCleanupScreen.tsx +0 -171
  596. package/src/cli/ui/components/screens/SessionSelectorScreen.tsx +0 -135
  597. package/src/cli/ui/hooks/useAppInput.ts +0 -172
  598. package/src/cli/ui/hooks/useBatchMerge.ts +0 -96
  599. package/src/cli/ui/hooks/useGitData.ts +0 -347
  600. package/src/cli/ui/hooks/useProfiles.ts +0 -211
  601. package/src/cli/ui/hooks/useScreenState.ts +0 -44
  602. package/src/cli/ui/hooks/useTerminalSize.ts +0 -33
  603. package/src/cli/ui/hooks/useToolStatus.ts +0 -68
  604. package/src/cli/ui/screens/BranchActionSelectorScreen.tsx +0 -111
  605. package/src/cli/ui/screens/__tests__/BranchActionSelectorScreen.test.tsx +0 -264
@@ -1,988 +0,0 @@
1
- import React, { useCallback, useEffect, useMemo, useRef, useState, } from "react";
2
- import { useApp } from "ink";
3
- import { ErrorBoundary } from "./common/ErrorBoundary.js";
4
- import { BranchListScreen, } from "./screens/BranchListScreen.js";
5
- import { LogListScreen } from "./screens/LogListScreen.js";
6
- import { LogDetailScreen } from "./screens/LogDetailScreen.js";
7
- import { LogDatePickerScreen } from "./screens/LogDatePickerScreen.js";
8
- import { BranchCreatorScreen } from "./screens/BranchCreatorScreen.js";
9
- import { BranchActionSelectorScreen } from "../screens/BranchActionSelectorScreen.js";
10
- import { CodingAgentSelectorScreen } from "./screens/CodingAgentSelectorScreen.js";
11
- import { ExecutionModeSelectorScreen } from "./screens/ExecutionModeSelectorScreen.js";
12
- import { BranchQuickStartScreen } from "./screens/BranchQuickStartScreen.js";
13
- import { ModelSelectorScreen, } from "./screens/ModelSelectorScreen.js";
14
- import { EnvironmentProfileScreen } from "./screens/EnvironmentProfileScreen.js";
15
- import { useGitData } from "../hooks/useGitData.js";
16
- import { useProfiles } from "../hooks/useProfiles.js";
17
- import { useScreenState } from "../hooks/useScreenState.js";
18
- import { useToolStatus } from "../hooks/useToolStatus.js";
19
- import { formatBranchItems } from "../utils/branchFormatter.js";
20
- import { calculateStatistics } from "../utils/statisticsCalculator.js";
21
- import { copyToClipboard } from "../utils/clipboard.js";
22
- import { parseLogLines, } from "../../../logging/formatter.js";
23
- import { buildLogFilePath, getTodayLogDate, listRecentLogFiles, readLogFileLines, resolveLogDir, } from "../../../logging/reader.js";
24
- import { getRepositoryRoot, deleteBranch } from "../../../git.js";
25
- import { loadSession } from "../../../config/index.js";
26
- import { createWorktree, generateWorktreePath, isProtectedBranchName, removeWorktree, switchToProtectedBranch, } from "../../../worktree.js";
27
- import { getPackageVersion } from "../../../utils.js";
28
- import { resolveBaseBranchLabel, resolveBaseBranchRef, } from "../utils/baseBranch.js";
29
- import { getDefaultInferenceForModel, getDefaultModelOption, normalizeModelId, } from "../utils/modelOptions.js";
30
- import { resolveContinueSessionId, findLatestBranchSessionsByTool, } from "../utils/continueSession.js";
31
- import { findLatestCodexSession, findLatestCodexSessionId, findLatestClaudeSession, findLatestGeminiSession, } from "../../../utils/session.js";
32
- const COMPLETION_HOLD_DURATION_MS = 3000;
33
- const PROTECTED_BRANCH_WARNING = "Root branches operate directly in the repository root. Create a new branch if you need a dedicated worktree.";
34
- /**
35
- * App - Top-level component for Ink.js UI
36
- * Integrates ErrorBoundary, data fetching, screen navigation, and all screens
37
- */
38
- export function App({ onExit, loadingIndicatorDelay = 300 }) {
39
- const { exit } = useApp();
40
- // 起動ディレクトリの取得
41
- const workingDirectory = process.cwd();
42
- const { branches, worktrees, loading, error, refresh, lastUpdated } = useGitData({
43
- enableAutoRefresh: false, // Manual refresh with 'r' key
44
- });
45
- const { currentScreen, navigateTo, goBack } = useScreenState();
46
- // Profile state
47
- const { activeProfileName, refresh: refreshProfiles } = useProfiles();
48
- // Tool status state (FR-017: 起動時に検出してキャッシュ)
49
- const { tools: toolStatuses } = useToolStatus();
50
- // Version state
51
- const [version, setVersion] = useState(null);
52
- const [repoRoot, setRepoRoot] = useState(null);
53
- const [continueSessionId, setContinueSessionId] = useState(null);
54
- const [branchQuickStart, setBranchQuickStart] = useState([]);
55
- const [branchQuickStartLoading, setBranchQuickStartLoading] = useState(false);
56
- // Log viewer state
57
- const logDir = useMemo(() => resolveLogDir(workingDirectory), [workingDirectory]);
58
- const [logEntries, setLogEntries] = useState([]);
59
- const [logLoading, setLogLoading] = useState(false);
60
- const [logError, setLogError] = useState(null);
61
- const [logSelectedDate, setLogSelectedDate] = useState(getTodayLogDate());
62
- const [logDates, setLogDates] = useState([]);
63
- const [logSelectedEntry, setLogSelectedEntry] = useState(null);
64
- const [logNotification, setLogNotification] = useState(null);
65
- const logNotificationTimerRef = useRef(null);
66
- // Selection state (for branch → tool → mode flow)
67
- const [selectedBranch, setSelectedBranch] = useState(null);
68
- const [creationSourceBranch, setCreationSourceBranch] = useState(null);
69
- const [selectedTool, setSelectedTool] = useState(null);
70
- const [selectedModel, setSelectedModel] = useState(null);
71
- const [lastModelByTool, setLastModelByTool] = useState({});
72
- const [preferredToolId, setPreferredToolId] = useState(null);
73
- // PR cleanup feedback
74
- const [cleanupIndicators, setCleanupIndicators] = useState({});
75
- const [_cleanupProcessingBranch, setCleanupProcessingBranch] = useState(null);
76
- const [cleanupInputLocked, setCleanupInputLocked] = useState(false);
77
- const [cleanupFooterMessage, setCleanupFooterMessage] = useState(null);
78
- const [hiddenBranches, setHiddenBranches] = useState([]);
79
- const [selectedBranches, setSelectedBranches] = useState([]);
80
- const completionTimerRef = useRef(null);
81
- // Fetch version on mount
82
- useEffect(() => {
83
- getPackageVersion()
84
- .then(setVersion)
85
- .catch(() => setVersion(null));
86
- }, []);
87
- // Fetch repository root once for session lookups
88
- useEffect(() => {
89
- getRepositoryRoot()
90
- .then(setRepoRoot)
91
- .catch(() => setRepoRoot(null));
92
- }, []);
93
- const showLogNotification = useCallback((message, tone = "success") => {
94
- setLogNotification({ message, tone });
95
- if (logNotificationTimerRef.current) {
96
- clearTimeout(logNotificationTimerRef.current);
97
- }
98
- logNotificationTimerRef.current = setTimeout(() => {
99
- setLogNotification(null);
100
- }, 2000);
101
- }, []);
102
- useEffect(() => {
103
- return () => {
104
- if (logNotificationTimerRef.current) {
105
- clearTimeout(logNotificationTimerRef.current);
106
- }
107
- };
108
- }, []);
109
- const loadLogEntries = useCallback(async (date) => {
110
- const targetDate = date ?? getTodayLogDate();
111
- setLogLoading(true);
112
- setLogError(null);
113
- try {
114
- const filePath = buildLogFilePath(logDir, targetDate);
115
- const lines = await readLogFileLines(filePath);
116
- const parsed = parseLogLines(lines, { limit: 100 });
117
- setLogEntries(parsed);
118
- }
119
- catch (error) {
120
- setLogEntries([]);
121
- setLogError(error instanceof Error ? error.message : "Failed to load logs");
122
- }
123
- finally {
124
- setLogLoading(false);
125
- }
126
- }, [logDir]);
127
- const loadLogDates = useCallback(async () => {
128
- try {
129
- const files = await listRecentLogFiles(logDir, 7);
130
- setLogDates(files);
131
- }
132
- catch {
133
- setLogDates([]);
134
- }
135
- }, [logDir]);
136
- useEffect(() => {
137
- if (currentScreen === "log-list") {
138
- void loadLogEntries(logSelectedDate);
139
- }
140
- }, [currentScreen, loadLogEntries, logSelectedDate]);
141
- useEffect(() => {
142
- if (currentScreen === "log-date-picker") {
143
- void loadLogDates();
144
- }
145
- }, [currentScreen, loadLogDates]);
146
- useEffect(() => {
147
- if (!hiddenBranches.length) {
148
- return;
149
- }
150
- const existing = new Set(branches.map((branch) => branch.name));
151
- const filtered = hiddenBranches.filter((name) => existing.has(name));
152
- if (filtered.length !== hiddenBranches.length) {
153
- setHiddenBranches(filtered);
154
- }
155
- }, [branches, hiddenBranches]);
156
- // Remove selections that no longer exist (hidden or disappeared)
157
- useEffect(() => {
158
- setSelectedBranches((prev) => prev.filter((name) => branches.some((b) => b.name === name) &&
159
- !hiddenBranches.includes(name)));
160
- }, [branches, hiddenBranches]);
161
- // Load quick start options for selected branch (latest per tool)
162
- useEffect(() => {
163
- if (!selectedBranch) {
164
- setBranchQuickStart([]);
165
- return;
166
- }
167
- let cancelled = false;
168
- setBranchQuickStartLoading(true);
169
- (async () => {
170
- try {
171
- const root = repoRoot ?? (await getRepositoryRoot());
172
- if (!repoRoot && root) {
173
- setRepoRoot(root);
174
- }
175
- if (!root) {
176
- if (!cancelled)
177
- setBranchQuickStart([]);
178
- return;
179
- }
180
- const sessionData = await loadSession(root);
181
- const history = sessionData?.history ?? [];
182
- const combinedHistory = [...history];
183
- if (sessionData?.lastSessionId &&
184
- sessionData.lastBranch === selectedBranch.name &&
185
- sessionData.lastUsedTool) {
186
- const synthetic = {
187
- branch: sessionData.lastBranch,
188
- worktreePath: sessionData.lastWorktreePath ?? null,
189
- toolId: sessionData.lastUsedTool,
190
- toolLabel: sessionData.toolLabel ?? sessionData.lastUsedTool,
191
- sessionId: sessionData.lastSessionId,
192
- mode: sessionData.mode ?? null,
193
- model: sessionData.model ?? null,
194
- reasoningLevel: sessionData.reasoningLevel ?? null,
195
- skipPermissions: sessionData.skipPermissions ?? null,
196
- timestamp: sessionData.timestamp ?? Date.now(),
197
- };
198
- combinedHistory.push(synthetic);
199
- }
200
- const latestPerTool = findLatestBranchSessionsByTool(combinedHistory, selectedBranch.name, selectedWorktreePath);
201
- const mapped = await Promise.all(latestPerTool.map(async (entry) => {
202
- let sessionId = entry.sessionId ?? null;
203
- const worktree = selectedWorktreePath ?? workingDirectory;
204
- // For Codex, prefer a newer filesystem session over stale history
205
- if (!sessionId && entry.toolId === "codex-cli") {
206
- try {
207
- const historyTs = entry.timestamp ?? null;
208
- const latestCodex = await findLatestCodexSession({
209
- ...(historyTs
210
- ? {
211
- since: historyTs - 60_000,
212
- preferClosestTo: historyTs,
213
- windowMs: 60 * 60 * 1000,
214
- }
215
- : {}),
216
- cwd: worktree,
217
- });
218
- sessionId =
219
- latestCodex?.id ??
220
- (await findLatestCodexSessionId({ cwd: worktree })) ??
221
- null;
222
- }
223
- catch {
224
- // ignore lookup failure
225
- }
226
- }
227
- // For Claude Code, prefer the newest session file in the worktree even if history is stale.
228
- if (!sessionId && entry.toolId === "claude-code") {
229
- try {
230
- // Always resolve freshest on-disk session for this worktree (no window restriction)
231
- const latestAny = await findLatestClaudeSession(worktree);
232
- sessionId = latestAny?.id ?? null;
233
- }
234
- catch {
235
- // ignore lookup failure
236
- }
237
- }
238
- // For Gemini, prefer newest session file (Gemini keeps per-project chats)
239
- if (!sessionId && entry.toolId === "gemini-cli") {
240
- try {
241
- const gemOptions = {
242
- windowMs: 60 * 60 * 1000,
243
- cwd: worktree,
244
- };
245
- if (entry.timestamp !== null && entry.timestamp !== undefined) {
246
- gemOptions.since = entry.timestamp - 60_000;
247
- gemOptions.preferClosestTo = entry.timestamp;
248
- }
249
- const gemSession = await findLatestGeminiSession(gemOptions);
250
- sessionId = gemSession?.id ?? null;
251
- }
252
- catch {
253
- // ignore
254
- }
255
- }
256
- const normalizedModel = normalizeModelId(entry.toolId, entry.model ?? null);
257
- return {
258
- toolId: entry.toolId,
259
- toolLabel: entry.toolLabel,
260
- model: normalizedModel ?? null,
261
- inferenceLevel: (entry.reasoningLevel ??
262
- sessionData?.reasoningLevel ??
263
- null),
264
- sessionId,
265
- skipPermissions: entry.skipPermissions ?? sessionData?.skipPermissions ?? null,
266
- timestamp: entry.timestamp ?? null,
267
- };
268
- }));
269
- if (!cancelled) {
270
- setBranchQuickStart(mapped);
271
- }
272
- }
273
- catch {
274
- if (!cancelled)
275
- setBranchQuickStart([]);
276
- }
277
- finally {
278
- if (!cancelled)
279
- setBranchQuickStartLoading(false);
280
- }
281
- })();
282
- return () => {
283
- cancelled = true;
284
- };
285
- }, [selectedBranch, repoRoot]);
286
- // Load last session ID for "Continue" label when entering execution mode selector
287
- useEffect(() => {
288
- if (currentScreen !== "execution-mode-selector") {
289
- return;
290
- }
291
- if (!selectedTool || !selectedBranch) {
292
- setContinueSessionId(null);
293
- return;
294
- }
295
- (async () => {
296
- try {
297
- const root = repoRoot ?? (await getRepositoryRoot());
298
- if (!repoRoot && root) {
299
- setRepoRoot(root);
300
- }
301
- const sessionData = root ? await loadSession(root) : null;
302
- const history = sessionData?.history ?? [];
303
- const found = await resolveContinueSessionId({
304
- history,
305
- sessionData,
306
- branch: selectedBranch.name,
307
- toolId: selectedTool,
308
- repoRoot: root,
309
- });
310
- setContinueSessionId(found ?? null);
311
- }
312
- catch {
313
- setContinueSessionId(null);
314
- }
315
- })();
316
- }, [currentScreen, selectedTool, selectedBranch, repoRoot]);
317
- // Update preferred tool when branch or data changes
318
- useEffect(() => {
319
- if (!selectedBranch)
320
- return;
321
- const branchMatch = branches.find((b) => b.name === selectedBranch.name) ||
322
- branches.find((b) => selectedBranch.branchType === "remote" &&
323
- b.name === selectedBranch.displayName);
324
- setPreferredToolId(branchMatch?.lastToolUsage?.toolId ?? null);
325
- }, [branches, selectedBranch]);
326
- useEffect(() => () => {
327
- if (completionTimerRef.current) {
328
- clearTimeout(completionTimerRef.current);
329
- completionTimerRef.current = null;
330
- }
331
- }, []);
332
- const visibleBranches = useMemo(() => branches.filter((branch) => !hiddenBranches.includes(branch.name)), [branches, hiddenBranches]);
333
- const selectedWorktreePath = useMemo(() => {
334
- if (!selectedBranch)
335
- return null;
336
- const wt = worktrees.find((w) => w.branch === selectedBranch.name);
337
- return wt?.path ?? null;
338
- }, [selectedBranch, worktrees]);
339
- // Helper function to create content-based hash for branches
340
- const branchHash = useMemo(() => visibleBranches
341
- .map((b) => `${b.name}-${b.type}-${b.isCurrent}`)
342
- .join(","), [visibleBranches]);
343
- // Helper function to create content-based hash for worktrees
344
- const worktreeHash = useMemo(() => worktrees.map((w) => `${w.branch}-${w.path}`).join(","), [worktrees]);
345
- // Format branches to BranchItems (memoized for performance with content-based dependencies)
346
- const branchItems = useMemo(() => {
347
- // Build worktreeMap for sorting
348
- const worktreeMap = new Map();
349
- for (const wt of worktrees) {
350
- worktreeMap.set(wt.branch, {
351
- path: wt.path,
352
- locked: false,
353
- prunable: wt.isAccessible === false,
354
- isAccessible: wt.isAccessible ?? true,
355
- ...(wt.hasUncommittedChanges !== undefined
356
- ? { hasUncommittedChanges: wt.hasUncommittedChanges }
357
- : {}),
358
- });
359
- }
360
- const baseItems = formatBranchItems(visibleBranches, worktreeMap);
361
- return baseItems.map((item) => {
362
- const hasUncommitted = item.worktree?.hasUncommittedChanges ?? false;
363
- const hasUnpushed = Boolean(item.hasUnpushedCommits);
364
- const isMerged = Boolean(item.mergedPR);
365
- const safeToCleanup = item.type === "local" && isMerged && !hasUncommitted && !hasUnpushed;
366
- return { ...item, safeToCleanup };
367
- });
368
- }, [branchHash, worktreeHash, visibleBranches, worktrees]);
369
- // Calculate statistics (memoized for performance)
370
- const stats = useMemo(() => calculateStatistics(visibleBranches), [visibleBranches]);
371
- const resolveBaseBranch = useCallback(() => {
372
- const localMain = branches.find((branch) => branch.type === "local" &&
373
- (branch.name === "main" || branch.name === "master"));
374
- if (localMain) {
375
- return localMain.name;
376
- }
377
- const develop = branches.find((branch) => branch.type === "local" &&
378
- (branch.name === "develop" || branch.name === "dev"));
379
- if (develop) {
380
- return develop.name;
381
- }
382
- return "main";
383
- }, [branches]);
384
- const baseBranchLabel = useMemo(() => resolveBaseBranchLabel(creationSourceBranch, selectedBranch, resolveBaseBranch), [creationSourceBranch, resolveBaseBranch, selectedBranch]);
385
- // Handle branch selection
386
- const toLocalBranchName = useCallback((remoteName) => {
387
- const segments = remoteName.split("/");
388
- if (segments.length <= 1) {
389
- return remoteName;
390
- }
391
- return segments.slice(1).join("/");
392
- }, []);
393
- const inferBranchCategory = useCallback((branchName) => {
394
- const matched = branches.find((branch) => branch.name === branchName);
395
- if (matched) {
396
- return matched.branchType;
397
- }
398
- if (branchName === "main" || branchName === "master") {
399
- return "main";
400
- }
401
- if (branchName === "develop" || branchName === "dev") {
402
- return "develop";
403
- }
404
- if (branchName.startsWith("feature/")) {
405
- return "feature";
406
- }
407
- if (branchName.startsWith("hotfix/")) {
408
- return "hotfix";
409
- }
410
- if (branchName.startsWith("release/")) {
411
- return "release";
412
- }
413
- return "other";
414
- }, [branches]);
415
- const isProtectedSelection = useCallback((branch) => {
416
- if (!branch) {
417
- return false;
418
- }
419
- return (isProtectedBranchName(branch.name) ||
420
- isProtectedBranchName(branch.displayName) ||
421
- (branch.remoteBranch
422
- ? isProtectedBranchName(branch.remoteBranch)
423
- : false) ||
424
- branch.branchCategory === "main" ||
425
- branch.branchCategory === "develop");
426
- }, [isProtectedBranchName]);
427
- const toggleBranchSelection = useCallback((branchName) => {
428
- const branch = branches.find((b) => b.name === branchName);
429
- if (!branch || branch.type === "remote") {
430
- return;
431
- }
432
- if (isProtectedBranchName(branch.name) ||
433
- branch.branchType === "main" ||
434
- branch.branchType === "develop") {
435
- return;
436
- }
437
- setSelectedBranches((prev) => {
438
- const set = new Set(prev);
439
- if (set.has(branchName)) {
440
- set.delete(branchName);
441
- }
442
- else {
443
- set.add(branchName);
444
- }
445
- return Array.from(set);
446
- });
447
- }, [branches, isProtectedBranchName]);
448
- const protectedBranchInfo = useMemo(() => {
449
- if (!selectedBranch) {
450
- return null;
451
- }
452
- if (!isProtectedSelection(selectedBranch)) {
453
- return null;
454
- }
455
- const label = selectedBranch.displayName ?? selectedBranch.name;
456
- return {
457
- label,
458
- message: `${label} is a root branch. Switch within the repository root instead of creating a worktree.`,
459
- };
460
- }, [selectedBranch, isProtectedSelection]);
461
- const handleSelect = useCallback((item) => {
462
- const selection = item.type === "remote"
463
- ? {
464
- name: toLocalBranchName(item.name),
465
- displayName: item.name,
466
- branchType: "remote",
467
- branchCategory: item.branchType,
468
- remoteBranch: item.name,
469
- }
470
- : {
471
- name: item.name,
472
- displayName: item.name,
473
- branchType: "local",
474
- branchCategory: item.branchType,
475
- };
476
- const protectedSelected = isProtectedSelection(selection);
477
- setSelectedBranch(selection);
478
- setSelectedTool(null);
479
- setSelectedModel(null);
480
- setCreationSourceBranch(null);
481
- setPreferredToolId(item.lastToolUsage?.toolId ?? null);
482
- if (protectedSelected) {
483
- setCleanupFooterMessage({
484
- text: PROTECTED_BRANCH_WARNING,
485
- color: "yellow",
486
- });
487
- }
488
- else {
489
- setCleanupFooterMessage(null);
490
- }
491
- navigateTo("branch-action-selector");
492
- }, [
493
- isProtectedSelection,
494
- navigateTo,
495
- setCleanupFooterMessage,
496
- setCreationSourceBranch,
497
- setSelectedTool,
498
- toLocalBranchName,
499
- ]);
500
- // Handle branch action selection
501
- const handleProtectedBranchSwitch = useCallback(async () => {
502
- if (!selectedBranch) {
503
- return;
504
- }
505
- try {
506
- setCleanupFooterMessage({
507
- text: `Preparing root branch '${selectedBranch.displayName ?? selectedBranch.name}'...`,
508
- color: "cyan",
509
- });
510
- const repoRoot = await getRepositoryRoot();
511
- const remoteRef = selectedBranch.remoteBranch ??
512
- (selectedBranch.branchType === "remote"
513
- ? (selectedBranch.displayName ?? selectedBranch.name)
514
- : null);
515
- const result = await switchToProtectedBranch({
516
- branchName: selectedBranch.name,
517
- repoRoot,
518
- remoteRef: remoteRef ?? null,
519
- });
520
- let successMessage = `'${selectedBranch.displayName ?? selectedBranch.name}' will use the repository root.`;
521
- if (result === "remote") {
522
- successMessage = `Created a local tracking branch for '${selectedBranch.displayName ?? selectedBranch.name}' and switched to the protected branch.`;
523
- }
524
- else if (result === "local") {
525
- successMessage = `Checked out '${selectedBranch.displayName ?? selectedBranch.name}' in the repository root.`;
526
- }
527
- setCleanupFooterMessage({
528
- text: successMessage,
529
- color: "green",
530
- });
531
- refresh();
532
- const nextScreen = branchQuickStart.length || branchQuickStartLoading
533
- ? "branch-quick-start"
534
- : "coding-agent-selector";
535
- navigateTo(nextScreen);
536
- }
537
- catch (error) {
538
- const message = error instanceof Error ? error.message : String(error);
539
- setCleanupFooterMessage({
540
- text: `Failed to switch root branch: ${message}`,
541
- color: "red",
542
- });
543
- console.error("Failed to switch protected branch:", error);
544
- }
545
- }, [
546
- branchQuickStart,
547
- branchQuickStartLoading,
548
- navigateTo,
549
- refresh,
550
- selectedBranch,
551
- setCleanupFooterMessage,
552
- ]);
553
- const handleUseExistingBranch = useCallback(() => {
554
- if (selectedBranch && isProtectedSelection(selectedBranch)) {
555
- void handleProtectedBranchSwitch();
556
- return;
557
- }
558
- if (branchQuickStart.length) {
559
- navigateTo("branch-quick-start");
560
- }
561
- else {
562
- navigateTo("coding-agent-selector");
563
- }
564
- }, [
565
- handleProtectedBranchSwitch,
566
- isProtectedSelection,
567
- navigateTo,
568
- branchQuickStart.length,
569
- selectedBranch,
570
- ]);
571
- const handleCreateNewBranch = useCallback(() => {
572
- setCreationSourceBranch(selectedBranch);
573
- navigateTo("branch-creator");
574
- }, [navigateTo, selectedBranch]);
575
- // Handle quit
576
- const handleQuit = useCallback(() => {
577
- onExit();
578
- exit();
579
- }, [onExit, exit]);
580
- const handleOpenLogs = useCallback(() => {
581
- setLogSelectedDate(getTodayLogDate());
582
- setLogSelectedEntry(null);
583
- navigateTo("log-list");
584
- }, [navigateTo]);
585
- const handleSelectLogEntry = useCallback((entry) => {
586
- setLogSelectedEntry(entry);
587
- navigateTo("log-detail");
588
- }, [navigateTo]);
589
- const handleCopyLogEntry = useCallback(async (entry) => {
590
- try {
591
- await copyToClipboard(entry.json);
592
- showLogNotification("Copied to clipboard.", "success");
593
- }
594
- catch {
595
- showLogNotification("Failed to copy to clipboard.", "error");
596
- }
597
- }, [showLogNotification]);
598
- const handleOpenLogDates = useCallback(() => {
599
- navigateTo("log-date-picker");
600
- }, [navigateTo]);
601
- const handleSelectLogDate = useCallback((date) => {
602
- setLogSelectedDate(date);
603
- setLogSelectedEntry(null);
604
- navigateTo("log-list");
605
- }, [navigateTo]);
606
- // Handle branch creation
607
- const handleCreate = useCallback(async (branchName) => {
608
- try {
609
- const repoRoot = await getRepositoryRoot();
610
- const worktreePath = await generateWorktreePath(repoRoot, branchName);
611
- // Use selectedBranch as base if available, otherwise resolve from repo
612
- const baseBranch = resolveBaseBranchRef(creationSourceBranch, selectedBranch, resolveBaseBranch);
613
- await createWorktree({
614
- branchName,
615
- worktreePath,
616
- repoRoot,
617
- isNewBranch: true,
618
- baseBranch,
619
- });
620
- refresh();
621
- setCreationSourceBranch(null);
622
- setSelectedBranch({
623
- name: branchName,
624
- displayName: branchName,
625
- branchType: "local",
626
- branchCategory: inferBranchCategory(branchName),
627
- });
628
- setSelectedTool(null);
629
- setSelectedModel(null);
630
- setPreferredToolId(null);
631
- setCleanupFooterMessage(null);
632
- navigateTo("coding-agent-selector");
633
- }
634
- catch (error) {
635
- // On error, go back to branch list
636
- console.error("Failed to create branch:", error);
637
- goBack();
638
- refresh();
639
- }
640
- }, [
641
- navigateTo,
642
- goBack,
643
- refresh,
644
- resolveBaseBranch,
645
- selectedBranch,
646
- creationSourceBranch,
647
- inferBranchCategory,
648
- setCleanupFooterMessage,
649
- ]);
650
- const handleCleanupCommand = useCallback(async () => {
651
- if (cleanupInputLocked) {
652
- return;
653
- }
654
- if (completionTimerRef.current) {
655
- clearTimeout(completionTimerRef.current);
656
- completionTimerRef.current = null;
657
- }
658
- if (selectedBranches.length === 0) {
659
- setCleanupIndicators({});
660
- setCleanupFooterMessage({
661
- text: "No cleanup targets selected.",
662
- color: "yellow",
663
- });
664
- setCleanupInputLocked(false);
665
- completionTimerRef.current = setTimeout(() => {
666
- setCleanupFooterMessage(null);
667
- completionTimerRef.current = null;
668
- }, COMPLETION_HOLD_DURATION_MS);
669
- return;
670
- }
671
- const succeededBranches = [];
672
- const resetAfterWait = () => {
673
- setCleanupIndicators({});
674
- setCleanupInputLocked(false);
675
- setCleanupFooterMessage(null);
676
- if (succeededBranches.length > 0) {
677
- setHiddenBranches((prev) => {
678
- const merged = new Set(prev);
679
- succeededBranches.forEach((branch) => merged.add(branch));
680
- return Array.from(merged);
681
- });
682
- setSelectedBranches((prev) => prev.filter((name) => !succeededBranches.includes(name)));
683
- }
684
- refresh();
685
- completionTimerRef.current = null;
686
- };
687
- // Provide immediate feedback before fetching targets
688
- setCleanupInputLocked(true);
689
- setCleanupIndicators({});
690
- setCleanupFooterMessage({
691
- text: "Processing...",
692
- isSpinning: true,
693
- color: "cyan",
694
- });
695
- setCleanupProcessingBranch(null);
696
- const branchMap = new Map(branches.map((branch) => [branch.name, branch]));
697
- const worktreeMap = new Map(worktrees.map((worktree) => [worktree.branch, worktree]));
698
- const targets = selectedBranches.reduce((acc, name) => {
699
- const branch = branchMap.get(name);
700
- if (!branch || branch.type === "remote") {
701
- return acc;
702
- }
703
- if (isProtectedBranchName(branch.name) ||
704
- branch.branchType === "main" ||
705
- branch.branchType === "develop") {
706
- return acc;
707
- }
708
- const worktree = worktreeMap.get(branch.name);
709
- const hasRemoteBranch = typeof branch.hasRemoteCounterpart === "boolean"
710
- ? branch.hasRemoteCounterpart
711
- : undefined;
712
- const isAccessible = typeof worktree?.isAccessible === "boolean"
713
- ? worktree.isAccessible
714
- : undefined;
715
- acc.push({
716
- branch: branch.name,
717
- pullRequest: null,
718
- worktreePath: worktree?.path ?? null,
719
- cleanupType: worktree ? "worktree-and-branch" : "branch-only",
720
- hasUncommittedChanges: worktree?.hasUncommittedChanges ?? false,
721
- hasUnpushedCommits: Boolean(branch.hasUnpushedCommits),
722
- ...(hasRemoteBranch !== undefined ? { hasRemoteBranch } : {}),
723
- ...(isAccessible !== undefined ? { isAccessible } : {}),
724
- });
725
- return acc;
726
- }, []);
727
- if (targets.length === 0) {
728
- setCleanupIndicators({});
729
- setCleanupFooterMessage({
730
- text: "⚠️ No cleanup candidates among selected branches.",
731
- color: "yellow",
732
- });
733
- setCleanupInputLocked(false);
734
- completionTimerRef.current = setTimeout(() => {
735
- setCleanupFooterMessage(null);
736
- completionTimerRef.current = null;
737
- }, COMPLETION_HOLD_DURATION_MS);
738
- return;
739
- }
740
- // Reset hidden branches that may already be gone
741
- setHiddenBranches((prev) => prev.filter((name) => targets.find((t) => t.branch === name) === undefined));
742
- const initialIndicators = targets.reduce((acc, target, index) => {
743
- if (index === 0) {
744
- acc[target.branch] = { icon: "", isSpinning: true, color: "cyan" };
745
- }
746
- else {
747
- acc[target.branch] = { icon: "⏳", color: "yellow" };
748
- }
749
- return acc;
750
- }, {});
751
- setCleanupIndicators(initialIndicators);
752
- const firstTarget = targets.length > 0 ? targets[0] : undefined;
753
- setCleanupProcessingBranch(firstTarget ? firstTarget.branch : null);
754
- setCleanupFooterMessage({
755
- text: "Processing...",
756
- isSpinning: true,
757
- color: "cyan",
758
- });
759
- for (let index = 0; index < targets.length; index += 1) {
760
- const currentTarget = targets[index];
761
- if (!currentTarget) {
762
- continue;
763
- }
764
- const target = currentTarget;
765
- setCleanupProcessingBranch(target.branch);
766
- setCleanupIndicators((prev) => {
767
- const updated = { ...prev };
768
- updated[target.branch] = { icon: "", isSpinning: true, color: "cyan" };
769
- for (const pending of targets.slice(index + 1)) {
770
- const current = updated[pending.branch];
771
- if (!current || current.icon !== "⏳") {
772
- updated[pending.branch] = { icon: "⏳", color: "yellow" };
773
- }
774
- }
775
- return updated;
776
- });
777
- const shouldSkip = target.hasUncommittedChanges ||
778
- target.hasUnpushedCommits ||
779
- (target.cleanupType === "worktree-and-branch" &&
780
- (!target.worktreePath || target.isAccessible === false));
781
- if (shouldSkip) {
782
- setCleanupIndicators((prev) => ({
783
- ...prev,
784
- [target.branch]: { icon: "⏭️", color: "yellow" },
785
- }));
786
- setCleanupProcessingBranch(null);
787
- continue;
788
- }
789
- try {
790
- if (target.cleanupType === "worktree-and-branch" &&
791
- target.worktreePath) {
792
- await removeWorktree(target.worktreePath, true);
793
- }
794
- await deleteBranch(target.branch, true);
795
- // 自動クリーンアップではリモートブランチは削除しない
796
- // リモートブランチはユーザーが明示的に削除する必要がある
797
- succeededBranches.push(target.branch);
798
- setCleanupIndicators((prev) => ({
799
- ...prev,
800
- [target.branch]: { icon: "✅", color: "green" },
801
- }));
802
- }
803
- catch {
804
- const icon = "❌";
805
- setCleanupIndicators((prev) => ({
806
- ...prev,
807
- [target.branch]: { icon, color: "red" },
808
- }));
809
- }
810
- setCleanupProcessingBranch(null);
811
- }
812
- setCleanupProcessingBranch(null);
813
- setCleanupInputLocked(false);
814
- setCleanupFooterMessage({
815
- text: "Cleanup completed. Finalizing...",
816
- color: "green",
817
- });
818
- const holdDuration = typeof process !== "undefined" && process.env?.NODE_ENV === "test"
819
- ? 0
820
- : COMPLETION_HOLD_DURATION_MS;
821
- completionTimerRef.current = setTimeout(resetAfterWait, holdDuration);
822
- }, [
823
- cleanupInputLocked,
824
- branches,
825
- deleteBranch,
826
- refresh,
827
- removeWorktree,
828
- selectedBranches,
829
- worktrees,
830
- ]);
831
- // Handle AI tool selection
832
- const handleToolSelect = useCallback((tool) => {
833
- setSelectedTool(tool);
834
- setSelectedModel(lastModelByTool[tool] ?? null);
835
- navigateTo("model-selector");
836
- }, [lastModelByTool, navigateTo]);
837
- const handleModelSelect = useCallback((selection) => {
838
- setSelectedModel(selection);
839
- setLastModelByTool((prev) => ({
840
- ...prev,
841
- ...(selectedTool ? { [selectedTool]: selection } : {}),
842
- }));
843
- navigateTo("execution-mode-selector");
844
- }, [navigateTo, selectedTool]);
845
- const completeSelection = useCallback((executionMode, skip, sessionId) => {
846
- if (selectedBranch && selectedTool) {
847
- const defaultModel = getDefaultModelOption(selectedTool);
848
- const resolvedModel = selectedModel?.model ?? defaultModel?.id ?? null;
849
- const normalizedModel = normalizeModelId(selectedTool, resolvedModel);
850
- const resolvedInference = selectedModel?.inferenceLevel ??
851
- getDefaultInferenceForModel(defaultModel ?? undefined);
852
- const payload = {
853
- branch: selectedBranch.name,
854
- displayName: selectedBranch.displayName,
855
- branchType: selectedBranch.branchType,
856
- tool: selectedTool,
857
- mode: executionMode,
858
- skipPermissions: skip,
859
- ...(normalizedModel !== undefined ? { model: normalizedModel } : {}),
860
- ...(resolvedInference !== undefined
861
- ? { inferenceLevel: resolvedInference }
862
- : {}),
863
- ...(selectedBranch.remoteBranch
864
- ? { remoteBranch: selectedBranch.remoteBranch }
865
- : {}),
866
- ...(sessionId ? { sessionId } : {}),
867
- };
868
- onExit(payload);
869
- exit();
870
- }
871
- }, [
872
- selectedBranch,
873
- selectedTool,
874
- selectedModel,
875
- onExit,
876
- exit,
877
- getDefaultModelOption,
878
- getDefaultInferenceForModel,
879
- ]);
880
- const handleQuickStartSelect = useCallback((action, toolId) => {
881
- if (action === "manual" || !branchQuickStart.length) {
882
- navigateTo("coding-agent-selector");
883
- return;
884
- }
885
- const selected = branchQuickStart.find((opt) => opt.toolId === toolId) ??
886
- branchQuickStart[0];
887
- if (!selected) {
888
- navigateTo("coding-agent-selector");
889
- return;
890
- }
891
- setSelectedTool(selected.toolId);
892
- setPreferredToolId(selected.toolId);
893
- const normalizedQuickStartModel = normalizeModelId(selected.toolId, selected.model ?? null);
894
- setSelectedModel(normalizedQuickStartModel
895
- ? {
896
- model: normalizedQuickStartModel,
897
- inferenceLevel: selected.inferenceLevel ?? undefined,
898
- }
899
- : null);
900
- const skip = selected.skipPermissions ?? false;
901
- if (action === "reuse-continue") {
902
- const hasSession = Boolean(selected.sessionId);
903
- const mode = hasSession ? "resume" : "continue";
904
- completeSelection(mode, skip, selected.sessionId ?? null);
905
- return;
906
- }
907
- // "Start new with previous settings" skips the execution mode screen and launches immediately
908
- completeSelection("normal", skip, null);
909
- }, [
910
- branchQuickStart,
911
- navigateTo,
912
- setPreferredToolId,
913
- setSelectedModel,
914
- setSelectedTool,
915
- completeSelection,
916
- ]);
917
- // Handle execution mode and skipPermissions selection
918
- const handleModeSelect = useCallback((result) => {
919
- completeSelection(result.mode, result.skipPermissions, null);
920
- }, [completeSelection]);
921
- // Render screen based on currentScreen
922
- const renderScreen = () => {
923
- const renderBranchListScreen = (additionalProps) => (React.createElement(BranchListScreen, { branches: branchItems, stats: stats, onSelect: handleSelect, onQuit: handleQuit, onRefresh: refresh, loading: loading, error: error, lastUpdated: lastUpdated, loadingIndicatorDelay: loadingIndicatorDelay, version: version, workingDirectory: workingDirectory, activeProfile: activeProfileName, onOpenProfiles: () => navigateTo("environment-profile"), onOpenLogs: handleOpenLogs, toolStatuses: toolStatuses, ...additionalProps }));
924
- switch (currentScreen) {
925
- case "branch-list":
926
- return renderBranchListScreen({
927
- onCleanupCommand: handleCleanupCommand,
928
- cleanupUI: {
929
- indicators: cleanupIndicators,
930
- footerMessage: cleanupFooterMessage,
931
- inputLocked: cleanupInputLocked,
932
- },
933
- selectedBranches,
934
- onToggleSelect: toggleBranchSelection,
935
- });
936
- case "log-list":
937
- return (React.createElement(LogListScreen, { entries: logEntries, loading: logLoading, error: logError, onBack: goBack, onSelect: handleSelectLogEntry, onCopy: handleCopyLogEntry, onPickDate: handleOpenLogDates, notification: logNotification, version: version, selectedDate: logSelectedDate }));
938
- case "log-detail":
939
- return (React.createElement(LogDetailScreen, { entry: logSelectedEntry, onBack: goBack, onCopy: handleCopyLogEntry, notification: logNotification, version: version }));
940
- case "log-date-picker":
941
- return (React.createElement(LogDatePickerScreen, { dates: logDates, onBack: goBack, onSelect: handleSelectLogDate, version: version }));
942
- case "branch-creator":
943
- return (React.createElement(BranchCreatorScreen, { onBack: goBack, onCreate: handleCreate, baseBranch: baseBranchLabel, version: version }));
944
- case "branch-action-selector": {
945
- const isProtected = Boolean(protectedBranchInfo);
946
- const baseProps = {
947
- selectedBranch: selectedBranch?.displayName ?? "",
948
- onUseExisting: handleUseExistingBranch,
949
- onCreateNew: handleCreateNewBranch,
950
- onBack: goBack,
951
- canCreateNew: Boolean(selectedBranch),
952
- };
953
- if (isProtected) {
954
- return (React.createElement(BranchActionSelectorScreen, { ...baseProps, mode: "protected", infoMessage: protectedBranchInfo?.message ?? null, primaryLabel: "Use root branch (no worktree)", secondaryLabel: "Create new branch from this branch" }));
955
- }
956
- return React.createElement(BranchActionSelectorScreen, { ...baseProps });
957
- }
958
- case "branch-quick-start":
959
- return (React.createElement(BranchQuickStartScreen, { branchName: selectedBranch?.displayName ?? "", previousOptions: branchQuickStart.map((opt) => ({
960
- toolId: opt.toolId,
961
- toolLabel: opt.toolLabel,
962
- model: opt.model ?? null,
963
- inferenceLevel: opt.inferenceLevel ?? null,
964
- skipPermissions: opt.skipPermissions ?? null,
965
- sessionId: opt.sessionId ?? null,
966
- })), loading: branchQuickStartLoading, onBack: goBack, onSelect: handleQuickStartSelect, version: version }));
967
- case "coding-agent-selector":
968
- return (React.createElement(CodingAgentSelectorScreen, { onBack: goBack, onSelect: handleToolSelect, version: version, initialAgentId: selectedTool ?? preferredToolId ?? null }));
969
- case "model-selector":
970
- if (!selectedTool) {
971
- goBack();
972
- return null;
973
- }
974
- return (React.createElement(ModelSelectorScreen, { tool: selectedTool, onBack: goBack, onSelect: handleModelSelect, version: version, initialSelection: selectedModel }));
975
- case "execution-mode-selector":
976
- return (React.createElement(ExecutionModeSelectorScreen, { onBack: goBack, onSelect: handleModeSelect, version: version, continueSessionId: continueSessionId }));
977
- case "environment-profile":
978
- return (React.createElement(EnvironmentProfileScreen, { onBack: () => {
979
- void refreshProfiles();
980
- goBack();
981
- }, version: version }));
982
- default:
983
- return renderBranchListScreen();
984
- }
985
- };
986
- return React.createElement(ErrorBoundary, null, renderScreen());
987
- }
988
- //# sourceMappingURL=App.js.map