@akiojin/gwt 4.9.1 → 4.11.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (605) hide show
  1. package/README.ja.md +4 -4
  2. package/README.md +4 -4
  3. package/dist/claude.d.ts +1 -0
  4. package/dist/claude.d.ts.map +1 -1
  5. package/dist/claude.js +52 -49
  6. package/dist/claude.js.map +1 -1
  7. package/dist/cli/ui/App.solid.d.ts +29 -0
  8. package/dist/cli/ui/App.solid.d.ts.map +1 -0
  9. package/dist/cli/ui/App.solid.js +1197 -0
  10. package/dist/cli/ui/App.solid.js.map +1 -0
  11. package/dist/cli/ui/components/solid/Footer.d.ts +10 -0
  12. package/dist/cli/ui/components/solid/Footer.d.ts.map +1 -0
  13. package/dist/cli/ui/components/solid/Footer.js +10 -0
  14. package/dist/cli/ui/components/solid/Footer.js.map +1 -0
  15. package/dist/cli/ui/components/{parts → solid}/Header.d.ts +1 -6
  16. package/dist/cli/ui/components/solid/Header.d.ts.map +1 -0
  17. package/dist/cli/ui/components/solid/Header.js +13 -0
  18. package/dist/cli/ui/components/solid/Header.js.map +1 -0
  19. package/dist/cli/ui/components/solid/HelpOverlay.d.ts +8 -0
  20. package/dist/cli/ui/components/solid/HelpOverlay.d.ts.map +1 -0
  21. package/dist/cli/ui/components/solid/HelpOverlay.js +118 -0
  22. package/dist/cli/ui/components/solid/HelpOverlay.js.map +1 -0
  23. package/dist/cli/ui/components/solid/QuickStartStep.d.ts +17 -0
  24. package/dist/cli/ui/components/solid/QuickStartStep.d.ts.map +1 -0
  25. package/dist/cli/ui/components/solid/QuickStartStep.js +139 -0
  26. package/dist/cli/ui/components/solid/QuickStartStep.js.map +1 -0
  27. package/dist/cli/ui/components/solid/SelectInput.d.ts +22 -0
  28. package/dist/cli/ui/components/solid/SelectInput.d.ts.map +1 -0
  29. package/dist/cli/ui/components/solid/SelectInput.js +44 -0
  30. package/dist/cli/ui/components/solid/SelectInput.js.map +1 -0
  31. package/dist/cli/ui/components/solid/TextInput.d.ts +12 -0
  32. package/dist/cli/ui/components/solid/TextInput.d.ts.map +1 -0
  33. package/dist/cli/ui/components/solid/TextInput.js +9 -0
  34. package/dist/cli/ui/components/solid/TextInput.js.map +1 -0
  35. package/dist/cli/ui/components/solid/WizardController.d.ts +34 -0
  36. package/dist/cli/ui/components/solid/WizardController.d.ts.map +1 -0
  37. package/dist/cli/ui/components/solid/WizardController.js +215 -0
  38. package/dist/cli/ui/components/solid/WizardController.js.map +1 -0
  39. package/dist/cli/ui/components/solid/WizardPopup.d.ts +26 -0
  40. package/dist/cli/ui/components/solid/WizardPopup.d.ts.map +1 -0
  41. package/dist/cli/ui/components/solid/WizardPopup.js +68 -0
  42. package/dist/cli/ui/components/solid/WizardPopup.js.map +1 -0
  43. package/dist/cli/ui/components/solid/WizardSteps.d.ts +52 -0
  44. package/dist/cli/ui/components/solid/WizardSteps.d.ts.map +1 -0
  45. package/dist/cli/ui/components/solid/WizardSteps.js +462 -0
  46. package/dist/cli/ui/components/solid/WizardSteps.js.map +1 -0
  47. package/dist/cli/ui/core/index.d.ts +12 -0
  48. package/dist/cli/ui/core/index.d.ts.map +1 -0
  49. package/dist/cli/ui/core/index.js +15 -0
  50. package/dist/cli/ui/core/index.js.map +1 -0
  51. package/dist/cli/ui/core/keybindings.d.ts +106 -0
  52. package/dist/cli/ui/core/keybindings.d.ts.map +1 -0
  53. package/dist/cli/ui/core/keybindings.js +270 -0
  54. package/dist/cli/ui/core/keybindings.js.map +1 -0
  55. package/dist/cli/ui/core/theme.d.ts +114 -0
  56. package/dist/cli/ui/core/theme.d.ts.map +1 -0
  57. package/dist/cli/ui/core/theme.js +170 -0
  58. package/dist/cli/ui/core/theme.js.map +1 -0
  59. package/dist/cli/ui/core/types.d.ts +156 -0
  60. package/dist/cli/ui/core/types.d.ts.map +1 -0
  61. package/dist/cli/ui/core/types.js +10 -0
  62. package/dist/cli/ui/core/types.js.map +1 -0
  63. package/dist/cli/ui/hooks/solid/useScrollableList.d.ts +26 -0
  64. package/dist/cli/ui/hooks/solid/useScrollableList.d.ts.map +1 -0
  65. package/dist/cli/ui/hooks/solid/useScrollableList.js +89 -0
  66. package/dist/cli/ui/hooks/solid/useScrollableList.js.map +1 -0
  67. package/dist/cli/ui/hooks/solid/useTerminalSize.d.ts +10 -0
  68. package/dist/cli/ui/hooks/solid/useTerminalSize.d.ts.map +1 -0
  69. package/dist/cli/ui/hooks/solid/useTerminalSize.js +16 -0
  70. package/dist/cli/ui/hooks/solid/useTerminalSize.js.map +1 -0
  71. package/dist/cli/ui/index.solid.d.ts +5 -0
  72. package/dist/cli/ui/index.solid.d.ts.map +1 -0
  73. package/dist/cli/ui/index.solid.js +21 -0
  74. package/dist/cli/ui/index.solid.js.map +1 -0
  75. package/dist/cli/ui/{components/screens → screens/solid}/BranchListScreen.d.ts +8 -22
  76. package/dist/cli/ui/screens/solid/BranchListScreen.d.ts.map +1 -0
  77. package/dist/cli/ui/screens/solid/BranchListScreen.js +756 -0
  78. package/dist/cli/ui/screens/solid/BranchListScreen.js.map +1 -0
  79. package/dist/cli/ui/screens/solid/ConfirmScreen.d.ts +10 -0
  80. package/dist/cli/ui/screens/solid/ConfirmScreen.d.ts.map +1 -0
  81. package/dist/cli/ui/screens/solid/ConfirmScreen.js +37 -0
  82. package/dist/cli/ui/screens/solid/ConfirmScreen.js.map +1 -0
  83. package/dist/cli/ui/screens/solid/EnvironmentScreen.d.ts +14 -0
  84. package/dist/cli/ui/screens/solid/EnvironmentScreen.d.ts.map +1 -0
  85. package/dist/cli/ui/screens/solid/EnvironmentScreen.js +91 -0
  86. package/dist/cli/ui/screens/solid/EnvironmentScreen.js.map +1 -0
  87. package/dist/cli/ui/screens/solid/ErrorScreen.d.ts +8 -0
  88. package/dist/cli/ui/screens/solid/ErrorScreen.d.ts.map +1 -0
  89. package/dist/cli/ui/screens/solid/ErrorScreen.js +18 -0
  90. package/dist/cli/ui/screens/solid/ErrorScreen.js.map +1 -0
  91. package/dist/cli/ui/screens/solid/InputScreen.d.ts +13 -0
  92. package/dist/cli/ui/screens/solid/InputScreen.d.ts.map +1 -0
  93. package/dist/cli/ui/screens/solid/InputScreen.js +17 -0
  94. package/dist/cli/ui/screens/solid/InputScreen.js.map +1 -0
  95. package/dist/cli/ui/screens/solid/LoadingIndicator.d.ts +9 -0
  96. package/dist/cli/ui/screens/solid/LoadingIndicator.d.ts.map +1 -0
  97. package/dist/cli/ui/screens/solid/LoadingIndicator.js +43 -0
  98. package/dist/cli/ui/screens/solid/LoadingIndicator.js.map +1 -0
  99. package/dist/cli/ui/{components/screens → screens/solid}/LogDetailScreen.d.ts +2 -2
  100. package/dist/cli/ui/screens/solid/LogDetailScreen.d.ts.map +1 -0
  101. package/dist/cli/ui/screens/solid/LogDetailScreen.js +34 -0
  102. package/dist/cli/ui/screens/solid/LogDetailScreen.js.map +1 -0
  103. package/dist/cli/ui/{components/screens/LogListScreen.d.ts → screens/solid/LogScreen.d.ts} +4 -4
  104. package/dist/cli/ui/screens/solid/LogScreen.d.ts.map +1 -0
  105. package/dist/cli/ui/screens/solid/LogScreen.js +95 -0
  106. package/dist/cli/ui/screens/solid/LogScreen.js.map +1 -0
  107. package/dist/cli/ui/screens/solid/ProfileEnvScreen.d.ts +17 -0
  108. package/dist/cli/ui/screens/solid/ProfileEnvScreen.d.ts.map +1 -0
  109. package/dist/cli/ui/screens/solid/ProfileEnvScreen.js +112 -0
  110. package/dist/cli/ui/screens/solid/ProfileEnvScreen.js.map +1 -0
  111. package/dist/cli/ui/screens/solid/ProfileScreen.d.ts +17 -0
  112. package/dist/cli/ui/screens/solid/ProfileScreen.d.ts.map +1 -0
  113. package/dist/cli/ui/screens/solid/ProfileScreen.js +50 -0
  114. package/dist/cli/ui/screens/solid/ProfileScreen.js.map +1 -0
  115. package/dist/cli/ui/screens/solid/SelectorScreen.d.ts +20 -0
  116. package/dist/cli/ui/screens/solid/SelectorScreen.d.ts.map +1 -0
  117. package/dist/cli/ui/screens/solid/SelectorScreen.js +90 -0
  118. package/dist/cli/ui/screens/solid/SelectorScreen.js.map +1 -0
  119. package/dist/cli/ui/screens/solid/WorktreeCreateScreen.d.ts +13 -0
  120. package/dist/cli/ui/screens/solid/WorktreeCreateScreen.d.ts.map +1 -0
  121. package/dist/cli/ui/screens/solid/WorktreeCreateScreen.js +59 -0
  122. package/dist/cli/ui/screens/solid/WorktreeCreateScreen.js.map +1 -0
  123. package/dist/cli/ui/stores/appStore.d.ts +143 -0
  124. package/dist/cli/ui/stores/appStore.d.ts.map +1 -0
  125. package/dist/cli/ui/stores/appStore.js +158 -0
  126. package/dist/cli/ui/stores/appStore.js.map +1 -0
  127. package/dist/cli/ui/stores/branchStore.d.ts +159 -0
  128. package/dist/cli/ui/stores/branchStore.d.ts.map +1 -0
  129. package/dist/cli/ui/stores/branchStore.js +275 -0
  130. package/dist/cli/ui/stores/branchStore.js.map +1 -0
  131. package/dist/cli/ui/stores/index.d.ts +11 -0
  132. package/dist/cli/ui/stores/index.d.ts.map +1 -0
  133. package/dist/cli/ui/stores/index.js +14 -0
  134. package/dist/cli/ui/stores/index.js.map +1 -0
  135. package/dist/cli/ui/stores/uiStore.d.ts +146 -0
  136. package/dist/cli/ui/stores/uiStore.d.ts.map +1 -0
  137. package/dist/cli/ui/stores/uiStore.js +166 -0
  138. package/dist/cli/ui/stores/uiStore.js.map +1 -0
  139. package/dist/cli/ui/types.d.ts +16 -1
  140. package/dist/cli/ui/types.d.ts.map +1 -1
  141. package/dist/cli/ui/utils/branchFormatter.d.ts.map +1 -1
  142. package/dist/cli/ui/utils/branchFormatter.js +7 -210
  143. package/dist/cli/ui/utils/branchFormatter.js.map +1 -1
  144. package/dist/cli/ui/utils/continueSession.d.ts +4 -0
  145. package/dist/cli/ui/utils/continueSession.d.ts.map +1 -1
  146. package/dist/cli/ui/utils/continueSession.js +30 -0
  147. package/dist/cli/ui/utils/continueSession.js.map +1 -1
  148. package/dist/client/assets/{index-ChHC-Puh.css → index-BbfV7Wuj.css} +1 -1
  149. package/dist/client/assets/index-CoAyq5x1.js +78 -0
  150. package/dist/client/index.html +2 -2
  151. package/dist/codex.d.ts +1 -0
  152. package/dist/codex.d.ts.map +1 -1
  153. package/dist/codex.js +86 -45
  154. package/dist/codex.js.map +1 -1
  155. package/dist/config/builtin-coding-agents.d.ts +4 -0
  156. package/dist/config/builtin-coding-agents.d.ts.map +1 -1
  157. package/dist/config/builtin-coding-agents.js +18 -3
  158. package/dist/config/builtin-coding-agents.js.map +1 -1
  159. package/dist/config/index.d.ts +2 -0
  160. package/dist/config/index.d.ts.map +1 -1
  161. package/dist/config/index.js +2 -0
  162. package/dist/config/index.js.map +1 -1
  163. package/dist/config/tools.d.ts.map +1 -1
  164. package/dist/config/tools.js +11 -0
  165. package/dist/config/tools.js.map +1 -1
  166. package/dist/gemini.d.ts +1 -0
  167. package/dist/gemini.d.ts.map +1 -1
  168. package/dist/gemini.js +42 -37
  169. package/dist/gemini.js.map +1 -1
  170. package/dist/index.d.ts +1 -1
  171. package/dist/index.d.ts.map +1 -1
  172. package/dist/index.js +122 -102
  173. package/dist/index.js.map +1 -1
  174. package/dist/launcher.d.ts.map +1 -1
  175. package/dist/launcher.js +18 -3
  176. package/dist/launcher.js.map +1 -1
  177. package/dist/logging/logger.d.ts.map +1 -1
  178. package/dist/logging/logger.js +26 -9
  179. package/dist/logging/logger.js.map +1 -1
  180. package/dist/opentui/highlights-eq9cgrbb.scm +604 -0
  181. package/dist/opentui/highlights-ghv9g403.scm +205 -0
  182. package/dist/opentui/highlights-hk7bwhj4.scm +284 -0
  183. package/dist/opentui/highlights-r812a2qc.scm +150 -0
  184. package/dist/opentui/highlights-x6tmsnaa.scm +115 -0
  185. package/dist/opentui/index.solid.d.ts +2 -0
  186. package/dist/opentui/index.solid.d.ts.map +1 -0
  187. package/dist/opentui/index.solid.js +52034 -0
  188. package/dist/opentui/index.solid.js.map +1 -0
  189. package/dist/opentui/injections-73j83es3.scm +27 -0
  190. package/dist/opentui/tree-sitter-javascript-nd0q4pe9.wasm +0 -0
  191. package/dist/opentui/tree-sitter-markdown-411r6y9b.wasm +0 -0
  192. package/dist/opentui/tree-sitter-markdown_inline-j5349f42.wasm +0 -0
  193. package/dist/opentui/tree-sitter-typescript-zxjzwt75.wasm +0 -0
  194. package/dist/opentui/tree-sitter-zig-e78zbjpm.wasm +0 -0
  195. package/dist/repositories/worktree.repository.d.ts +1 -0
  196. package/dist/repositories/worktree.repository.d.ts.map +1 -1
  197. package/dist/repositories/worktree.repository.js +7 -0
  198. package/dist/repositories/worktree.repository.js.map +1 -1
  199. package/dist/services/codingAgentResolver.d.ts +2 -0
  200. package/dist/services/codingAgentResolver.d.ts.map +1 -1
  201. package/dist/services/codingAgentResolver.js +30 -4
  202. package/dist/services/codingAgentResolver.js.map +1 -1
  203. package/dist/services/dependency-installer.d.ts.map +1 -1
  204. package/dist/services/dependency-installer.js +0 -5
  205. package/dist/services/dependency-installer.js.map +1 -1
  206. package/dist/types/api.d.ts +3 -0
  207. package/dist/types/api.d.ts.map +1 -1
  208. package/dist/types/coding-agent.d.ts +62 -0
  209. package/dist/types/coding-agent.d.ts.map +1 -0
  210. package/dist/types/coding-agent.js +29 -0
  211. package/dist/types/coding-agent.js.map +1 -0
  212. package/dist/types/tools.d.ts +17 -0
  213. package/dist/types/tools.d.ts.map +1 -1
  214. package/dist/utils/coding-agent-colors.d.ts +88 -0
  215. package/dist/utils/coding-agent-colors.d.ts.map +1 -0
  216. package/dist/utils/coding-agent-colors.js +137 -0
  217. package/dist/utils/coding-agent-colors.js.map +1 -0
  218. package/dist/utils/command.d.ts +1 -1
  219. package/dist/utils/command.d.ts.map +1 -1
  220. package/dist/utils/command.js +10 -1
  221. package/dist/utils/command.js.map +1 -1
  222. package/dist/utils/error-utils.d.ts +27 -0
  223. package/dist/utils/error-utils.d.ts.map +1 -0
  224. package/dist/utils/error-utils.js +98 -0
  225. package/dist/utils/error-utils.js.map +1 -0
  226. package/dist/utils/npmRegistry.d.ts +61 -0
  227. package/dist/utils/npmRegistry.d.ts.map +1 -0
  228. package/dist/utils/npmRegistry.js +180 -0
  229. package/dist/utils/npmRegistry.js.map +1 -0
  230. package/dist/utils/prompt.d.ts +1 -1
  231. package/dist/utils/prompt.js +1 -1
  232. package/dist/utils/session/index.d.ts +5 -3
  233. package/dist/utils/session/index.d.ts.map +1 -1
  234. package/dist/utils/session/index.js +5 -2
  235. package/dist/utils/session/index.js.map +1 -1
  236. package/dist/utils/session/parsers/codex.d.ts.map +1 -1
  237. package/dist/utils/session/parsers/codex.js +8 -1
  238. package/dist/utils/session/parsers/codex.js.map +1 -1
  239. package/dist/utils/session/parsers/index.d.ts +1 -0
  240. package/dist/utils/session/parsers/index.d.ts.map +1 -1
  241. package/dist/utils/session/parsers/index.js +2 -0
  242. package/dist/utils/session/parsers/index.js.map +1 -1
  243. package/dist/utils/session/parsers/opencode.d.ts +23 -0
  244. package/dist/utils/session/parsers/opencode.d.ts.map +1 -0
  245. package/dist/utils/session/parsers/opencode.js +89 -0
  246. package/dist/utils/session/parsers/opencode.js.map +1 -0
  247. package/dist/utils/session/types.d.ts +4 -0
  248. package/dist/utils/session/types.d.ts.map +1 -1
  249. package/dist/utils/terminal.d.ts +1 -0
  250. package/dist/utils/terminal.d.ts.map +1 -1
  251. package/dist/utils/terminal.js +20 -0
  252. package/dist/utils/terminal.js.map +1 -1
  253. package/dist/utils.d.ts +9 -0
  254. package/dist/utils.d.ts.map +1 -1
  255. package/dist/utils.js +33 -2
  256. package/dist/utils.js.map +1 -1
  257. package/dist/web/client/src/components/CodingAgentLaunchModal.d.ts.map +1 -1
  258. package/dist/web/client/src/components/CodingAgentLaunchModal.js +7 -16
  259. package/dist/web/client/src/components/CodingAgentLaunchModal.js.map +1 -1
  260. package/dist/web/client/src/components/branch-detail/BranchInfoCards.d.ts.map +1 -1
  261. package/dist/web/client/src/components/branch-detail/BranchInfoCards.js +7 -2
  262. package/dist/web/client/src/components/branch-detail/BranchInfoCards.js.map +1 -1
  263. package/dist/web/client/src/components/branch-detail/SessionHistoryTable.d.ts.map +1 -1
  264. package/dist/web/client/src/components/branch-detail/SessionHistoryTable.js +2 -1
  265. package/dist/web/client/src/components/branch-detail/SessionHistoryTable.js.map +1 -1
  266. package/dist/web/client/src/components/branch-detail/ToolLauncher.d.ts +2 -2
  267. package/dist/web/client/src/components/branch-detail/ToolLauncher.d.ts.map +1 -1
  268. package/dist/web/client/src/components/branch-detail/ToolLauncher.js +5 -5
  269. package/dist/web/client/src/components/branch-detail/ToolLauncher.js.map +1 -1
  270. package/dist/web/client/src/lib/coding-agent-colors.d.ts +86 -0
  271. package/dist/web/client/src/lib/coding-agent-colors.d.ts.map +1 -0
  272. package/dist/web/client/src/lib/coding-agent-colors.js +135 -0
  273. package/dist/web/client/src/lib/coding-agent-colors.js.map +1 -0
  274. package/dist/web/client/src/pages/BranchDetailPage.js +10 -10
  275. package/dist/web/client/src/pages/BranchDetailPage.js.map +1 -1
  276. package/dist/web/server/pty/manager.d.ts +2 -0
  277. package/dist/web/server/pty/manager.d.ts.map +1 -1
  278. package/dist/web/server/pty/manager.js +104 -0
  279. package/dist/web/server/pty/manager.js.map +1 -1
  280. package/dist/web/server/routes/sessions.d.ts.map +1 -1
  281. package/dist/web/server/routes/sessions.js +5 -1
  282. package/dist/web/server/routes/sessions.js.map +1 -1
  283. package/dist/web/server/services/branches.d.ts.map +1 -1
  284. package/dist/web/server/services/branches.js +10 -8
  285. package/dist/web/server/services/branches.js.map +1 -1
  286. package/dist/web/server/services/worktrees.js +2 -2
  287. package/dist/web/server/services/worktrees.js.map +1 -1
  288. package/dist/worktree.d.ts +47 -1
  289. package/dist/worktree.d.ts.map +1 -1
  290. package/dist/worktree.js +280 -94
  291. package/dist/worktree.js.map +1 -1
  292. package/package.json +12 -14
  293. package/src/claude.ts +68 -70
  294. package/src/cli/ui/App.solid.tsx +1823 -0
  295. package/src/cli/ui/__tests__/solid/AppSolid.cleanup.test.tsx +255 -0
  296. package/src/cli/ui/__tests__/solid/BranchListScreen.test.tsx +243 -0
  297. package/src/cli/ui/__tests__/solid/components/QuickStartStep.test.tsx +237 -0
  298. package/src/cli/ui/__tests__/solid/components/WizardPopup.test.tsx +231 -0
  299. package/src/cli/ui/__tests__/solid/components/WizardSteps.test.tsx +238 -0
  300. package/src/cli/ui/__tests__/utils/branchFormatter.test.ts +7 -289
  301. package/src/cli/ui/__tests__/utils/clipboard.test.ts +3 -3
  302. package/src/cli/ui/__tests__/utils/statisticsCalculator.test.ts +1 -1
  303. package/src/cli/ui/components/solid/Footer.tsx +36 -0
  304. package/src/cli/ui/components/{parts → solid}/Header.tsx +17 -28
  305. package/src/cli/ui/components/solid/HelpOverlay.tsx +194 -0
  306. package/src/cli/ui/components/solid/QuickStartStep.tsx +197 -0
  307. package/src/cli/ui/components/{parts → solid}/ScrollableList.tsx +7 -8
  308. package/src/cli/ui/components/solid/SearchInput.tsx +42 -0
  309. package/src/cli/ui/components/solid/SelectInput.tsx +84 -0
  310. package/src/cli/ui/components/solid/Stats.tsx +92 -0
  311. package/src/cli/ui/components/solid/TextInput.tsx +49 -0
  312. package/src/cli/ui/components/solid/WizardController.tsx +384 -0
  313. package/src/cli/ui/components/solid/WizardPopup.tsx +135 -0
  314. package/src/cli/ui/components/solid/WizardSteps.tsx +793 -0
  315. package/src/cli/ui/core/index.ts +17 -0
  316. package/src/cli/ui/core/keybindings.ts +367 -0
  317. package/src/cli/ui/core/theme.ts +234 -0
  318. package/src/cli/ui/core/types.ts +235 -0
  319. package/src/cli/ui/hooks/solid/useAsyncOperation.ts +76 -0
  320. package/src/cli/ui/hooks/solid/useFilter.ts +86 -0
  321. package/src/cli/ui/hooks/solid/useGitOperations.ts +80 -0
  322. package/src/cli/ui/hooks/solid/useKeyHandler.ts +103 -0
  323. package/src/cli/ui/hooks/solid/useScrollableList.ts +149 -0
  324. package/src/cli/ui/hooks/solid/useSelection.ts +77 -0
  325. package/src/cli/ui/hooks/solid/useTerminalSize.ts +22 -0
  326. package/src/cli/ui/index.solid.ts +28 -0
  327. package/src/cli/ui/screens/solid/BranchListScreen.tsx +1050 -0
  328. package/src/cli/ui/screens/solid/ConfirmScreen.tsx +74 -0
  329. package/src/cli/ui/screens/solid/EnvironmentScreen.tsx +159 -0
  330. package/src/cli/ui/screens/solid/ErrorScreen.tsx +42 -0
  331. package/src/cli/ui/screens/solid/InputScreen.tsx +55 -0
  332. package/src/cli/ui/screens/solid/LoadingIndicator.tsx +77 -0
  333. package/src/cli/ui/screens/solid/LogDetailScreen.tsx +75 -0
  334. package/src/cli/ui/screens/solid/LogScreen.tsx +175 -0
  335. package/src/cli/ui/screens/solid/ProfileEnvScreen.tsx +192 -0
  336. package/src/cli/ui/screens/solid/ProfileScreen.tsx +98 -0
  337. package/src/cli/ui/screens/solid/SelectorScreen.tsx +170 -0
  338. package/src/cli/ui/screens/solid/SettingsScreen.tsx +50 -0
  339. package/src/cli/ui/screens/solid/WorktreeCreateScreen.tsx +136 -0
  340. package/src/cli/ui/screens/solid/WorktreeDeleteScreen.tsx +40 -0
  341. package/src/cli/ui/stores/appStore.ts +208 -0
  342. package/src/cli/ui/stores/branchStore.ts +357 -0
  343. package/src/cli/ui/stores/index.ts +31 -0
  344. package/src/cli/ui/stores/uiStore.ts +226 -0
  345. package/src/cli/ui/types.ts +20 -3
  346. package/src/cli/ui/utils/__tests__/branchFormatter.test.ts +180 -0
  347. package/src/cli/ui/utils/branchFormatter.ts +8 -215
  348. package/src/cli/ui/utils/continueSession.ts +44 -0
  349. package/src/cli/ui/utils/modelOptions.test.ts +1 -1
  350. package/src/codex.ts +100 -43
  351. package/src/config/__tests__/saveSession.test.ts +143 -0
  352. package/src/config/builtin-coding-agents.ts +19 -3
  353. package/src/config/index.ts +4 -0
  354. package/src/config/tools.ts +16 -0
  355. package/src/gemini.ts +58 -43
  356. package/src/index.test.ts +12 -12
  357. package/src/index.ts +164 -142
  358. package/src/launcher.ts +22 -3
  359. package/src/logging/logger.ts +32 -10
  360. package/src/opentui/index.solid.ts +1 -0
  361. package/src/repositories/worktree.repository.ts +8 -0
  362. package/src/services/__tests__/BatchMergeService.test.ts +62 -66
  363. package/src/services/__tests__/WorktreeOrchestrator.test.ts +8 -7
  364. package/src/services/codingAgentResolver.ts +30 -4
  365. package/src/services/dependency-installer.ts +0 -7
  366. package/src/types/api.ts +3 -0
  367. package/src/types/coding-agent.ts +85 -0
  368. package/src/types/tools.ts +19 -0
  369. package/src/utils/__tests__/npmRegistry.test.ts +250 -0
  370. package/src/utils/__tests__/prompt.test.ts +4 -5
  371. package/src/utils/coding-agent-colors.ts +165 -0
  372. package/src/utils/command.ts +10 -1
  373. package/src/utils/error-utils.ts +133 -0
  374. package/src/utils/npmRegistry.ts +249 -0
  375. package/src/utils/prompt.ts +1 -1
  376. package/src/utils/session/index.ts +10 -2
  377. package/src/utils/session/parsers/codex.ts +9 -1
  378. package/src/utils/session/parsers/index.ts +6 -0
  379. package/src/utils/session/parsers/opencode.ts +110 -0
  380. package/src/utils/session/types.ts +5 -0
  381. package/src/utils/terminal.ts +24 -0
  382. package/src/utils.test.ts +1 -1
  383. package/src/utils.ts +37 -4
  384. package/src/web/client/src/components/CodingAgentLaunchModal.tsx +12 -21
  385. package/src/web/client/src/components/branch-detail/BranchInfoCards.tsx +16 -1
  386. package/src/web/client/src/components/branch-detail/SessionHistoryTable.tsx +7 -1
  387. package/src/web/client/src/components/branch-detail/ToolLauncher.tsx +11 -6
  388. package/src/web/client/src/lib/coding-agent-colors.ts +149 -0
  389. package/src/web/client/src/pages/BranchDetailPage.tsx +11 -11
  390. package/src/web/server/pty/manager.ts +139 -0
  391. package/src/web/server/routes/sessions.ts +6 -0
  392. package/src/web/server/services/branches.ts +11 -8
  393. package/src/web/server/services/worktrees.ts +2 -2
  394. package/src/worktree.ts +366 -107
  395. package/dist/cli/ui/components/App.d.ts +0 -25
  396. package/dist/cli/ui/components/App.d.ts.map +0 -1
  397. package/dist/cli/ui/components/App.js +0 -988
  398. package/dist/cli/ui/components/App.js.map +0 -1
  399. package/dist/cli/ui/components/common/Confirm.d.ts +0 -13
  400. package/dist/cli/ui/components/common/Confirm.d.ts.map +0 -1
  401. package/dist/cli/ui/components/common/Confirm.js +0 -20
  402. package/dist/cli/ui/components/common/Confirm.js.map +0 -1
  403. package/dist/cli/ui/components/common/ErrorBoundary.d.ts +0 -23
  404. package/dist/cli/ui/components/common/ErrorBoundary.d.ts.map +0 -1
  405. package/dist/cli/ui/components/common/ErrorBoundary.js +0 -37
  406. package/dist/cli/ui/components/common/ErrorBoundary.js.map +0 -1
  407. package/dist/cli/ui/components/common/Input.d.ts +0 -19
  408. package/dist/cli/ui/components/common/Input.d.ts.map +0 -1
  409. package/dist/cli/ui/components/common/Input.js +0 -22
  410. package/dist/cli/ui/components/common/Input.js.map +0 -1
  411. package/dist/cli/ui/components/common/LoadingIndicator.d.ts +0 -19
  412. package/dist/cli/ui/components/common/LoadingIndicator.d.ts.map +0 -1
  413. package/dist/cli/ui/components/common/LoadingIndicator.js +0 -61
  414. package/dist/cli/ui/components/common/LoadingIndicator.js.map +0 -1
  415. package/dist/cli/ui/components/common/Select.d.ts +0 -38
  416. package/dist/cli/ui/components/common/Select.d.ts.map +0 -1
  417. package/dist/cli/ui/components/common/Select.js +0 -151
  418. package/dist/cli/ui/components/common/Select.js.map +0 -1
  419. package/dist/cli/ui/components/common/SpinnerIcon.d.ts +0 -20
  420. package/dist/cli/ui/components/common/SpinnerIcon.d.ts.map +0 -1
  421. package/dist/cli/ui/components/common/SpinnerIcon.js +0 -61
  422. package/dist/cli/ui/components/common/SpinnerIcon.js.map +0 -1
  423. package/dist/cli/ui/components/parts/Footer.d.ts +0 -15
  424. package/dist/cli/ui/components/parts/Footer.d.ts.map +0 -1
  425. package/dist/cli/ui/components/parts/Footer.js +0 -20
  426. package/dist/cli/ui/components/parts/Footer.js.map +0 -1
  427. package/dist/cli/ui/components/parts/Header.d.ts.map +0 -1
  428. package/dist/cli/ui/components/parts/Header.js +0 -24
  429. package/dist/cli/ui/components/parts/Header.js.map +0 -1
  430. package/dist/cli/ui/components/parts/MergeStatusList.d.ts +0 -13
  431. package/dist/cli/ui/components/parts/MergeStatusList.d.ts.map +0 -1
  432. package/dist/cli/ui/components/parts/MergeStatusList.js +0 -52
  433. package/dist/cli/ui/components/parts/MergeStatusList.js.map +0 -1
  434. package/dist/cli/ui/components/parts/ProgressBar.d.ts +0 -13
  435. package/dist/cli/ui/components/parts/ProgressBar.d.ts.map +0 -1
  436. package/dist/cli/ui/components/parts/ProgressBar.js +0 -53
  437. package/dist/cli/ui/components/parts/ProgressBar.js.map +0 -1
  438. package/dist/cli/ui/components/parts/ScrollableList.d.ts +0 -12
  439. package/dist/cli/ui/components/parts/ScrollableList.d.ts.map +0 -1
  440. package/dist/cli/ui/components/parts/ScrollableList.js +0 -11
  441. package/dist/cli/ui/components/parts/ScrollableList.js.map +0 -1
  442. package/dist/cli/ui/components/parts/Stats.d.ts +0 -10
  443. package/dist/cli/ui/components/parts/Stats.d.ts.map +0 -1
  444. package/dist/cli/ui/components/parts/Stats.js +0 -55
  445. package/dist/cli/ui/components/parts/Stats.js.map +0 -1
  446. package/dist/cli/ui/components/screens/BatchMergeProgressScreen.d.ts +0 -17
  447. package/dist/cli/ui/components/screens/BatchMergeProgressScreen.d.ts.map +0 -1
  448. package/dist/cli/ui/components/screens/BatchMergeProgressScreen.js +0 -42
  449. package/dist/cli/ui/components/screens/BatchMergeProgressScreen.js.map +0 -1
  450. package/dist/cli/ui/components/screens/BatchMergeResultScreen.d.ts +0 -17
  451. package/dist/cli/ui/components/screens/BatchMergeResultScreen.d.ts.map +0 -1
  452. package/dist/cli/ui/components/screens/BatchMergeResultScreen.js +0 -72
  453. package/dist/cli/ui/components/screens/BatchMergeResultScreen.js.map +0 -1
  454. package/dist/cli/ui/components/screens/BranchCreatorScreen.d.ts +0 -18
  455. package/dist/cli/ui/components/screens/BranchCreatorScreen.d.ts.map +0 -1
  456. package/dist/cli/ui/components/screens/BranchCreatorScreen.js +0 -151
  457. package/dist/cli/ui/components/screens/BranchCreatorScreen.js.map +0 -1
  458. package/dist/cli/ui/components/screens/BranchListScreen.d.ts.map +0 -1
  459. package/dist/cli/ui/components/screens/BranchListScreen.js +0 -476
  460. package/dist/cli/ui/components/screens/BranchListScreen.js.map +0 -1
  461. package/dist/cli/ui/components/screens/BranchQuickStartScreen.d.ts +0 -30
  462. package/dist/cli/ui/components/screens/BranchQuickStartScreen.d.ts.map +0 -1
  463. package/dist/cli/ui/components/screens/BranchQuickStartScreen.js +0 -145
  464. package/dist/cli/ui/components/screens/BranchQuickStartScreen.js.map +0 -1
  465. package/dist/cli/ui/components/screens/CodingAgentSelectorScreen.d.ts +0 -27
  466. package/dist/cli/ui/components/screens/CodingAgentSelectorScreen.d.ts.map +0 -1
  467. package/dist/cli/ui/components/screens/CodingAgentSelectorScreen.js +0 -93
  468. package/dist/cli/ui/components/screens/CodingAgentSelectorScreen.js.map +0 -1
  469. package/dist/cli/ui/components/screens/EnvironmentProfileScreen.d.ts +0 -19
  470. package/dist/cli/ui/components/screens/EnvironmentProfileScreen.d.ts.map +0 -1
  471. package/dist/cli/ui/components/screens/EnvironmentProfileScreen.js +0 -577
  472. package/dist/cli/ui/components/screens/EnvironmentProfileScreen.js.map +0 -1
  473. package/dist/cli/ui/components/screens/ExecutionModeSelectorScreen.d.ts +0 -45
  474. package/dist/cli/ui/components/screens/ExecutionModeSelectorScreen.d.ts.map +0 -1
  475. package/dist/cli/ui/components/screens/ExecutionModeSelectorScreen.js +0 -95
  476. package/dist/cli/ui/components/screens/ExecutionModeSelectorScreen.js.map +0 -1
  477. package/dist/cli/ui/components/screens/LogDatePickerScreen.d.ts +0 -10
  478. package/dist/cli/ui/components/screens/LogDatePickerScreen.d.ts.map +0 -1
  479. package/dist/cli/ui/components/screens/LogDatePickerScreen.js +0 -44
  480. package/dist/cli/ui/components/screens/LogDatePickerScreen.js.map +0 -1
  481. package/dist/cli/ui/components/screens/LogDetailScreen.d.ts.map +0 -1
  482. package/dist/cli/ui/components/screens/LogDetailScreen.js +0 -34
  483. package/dist/cli/ui/components/screens/LogDetailScreen.js.map +0 -1
  484. package/dist/cli/ui/components/screens/LogListScreen.d.ts.map +0 -1
  485. package/dist/cli/ui/components/screens/LogListScreen.js +0 -107
  486. package/dist/cli/ui/components/screens/LogListScreen.js.map +0 -1
  487. package/dist/cli/ui/components/screens/ModelSelectorScreen.d.ts +0 -24
  488. package/dist/cli/ui/components/screens/ModelSelectorScreen.d.ts.map +0 -1
  489. package/dist/cli/ui/components/screens/ModelSelectorScreen.js +0 -197
  490. package/dist/cli/ui/components/screens/ModelSelectorScreen.js.map +0 -1
  491. package/dist/cli/ui/components/screens/PRCleanupScreen.d.ts +0 -29
  492. package/dist/cli/ui/components/screens/PRCleanupScreen.d.ts.map +0 -1
  493. package/dist/cli/ui/components/screens/PRCleanupScreen.js +0 -92
  494. package/dist/cli/ui/components/screens/PRCleanupScreen.js.map +0 -1
  495. package/dist/cli/ui/components/screens/SessionSelectorScreen.d.ts +0 -31
  496. package/dist/cli/ui/components/screens/SessionSelectorScreen.d.ts.map +0 -1
  497. package/dist/cli/ui/components/screens/SessionSelectorScreen.js +0 -67
  498. package/dist/cli/ui/components/screens/SessionSelectorScreen.js.map +0 -1
  499. package/dist/cli/ui/hooks/useAppInput.d.ts +0 -21
  500. package/dist/cli/ui/hooks/useAppInput.d.ts.map +0 -1
  501. package/dist/cli/ui/hooks/useAppInput.js +0 -138
  502. package/dist/cli/ui/hooks/useAppInput.js.map +0 -1
  503. package/dist/cli/ui/hooks/useBatchMerge.d.ts +0 -17
  504. package/dist/cli/ui/hooks/useBatchMerge.d.ts.map +0 -1
  505. package/dist/cli/ui/hooks/useBatchMerge.js +0 -77
  506. package/dist/cli/ui/hooks/useBatchMerge.js.map +0 -1
  507. package/dist/cli/ui/hooks/useGitData.d.ts +0 -21
  508. package/dist/cli/ui/hooks/useGitData.d.ts.map +0 -1
  509. package/dist/cli/ui/hooks/useGitData.js +0 -229
  510. package/dist/cli/ui/hooks/useGitData.js.map +0 -1
  511. package/dist/cli/ui/hooks/useProfiles.d.ts +0 -41
  512. package/dist/cli/ui/hooks/useProfiles.d.ts.map +0 -1
  513. package/dist/cli/ui/hooks/useProfiles.js +0 -136
  514. package/dist/cli/ui/hooks/useProfiles.js.map +0 -1
  515. package/dist/cli/ui/hooks/useScreenState.d.ts +0 -12
  516. package/dist/cli/ui/hooks/useScreenState.d.ts.map +0 -1
  517. package/dist/cli/ui/hooks/useScreenState.js +0 -30
  518. package/dist/cli/ui/hooks/useScreenState.js.map +0 -1
  519. package/dist/cli/ui/hooks/useTerminalSize.d.ts +0 -9
  520. package/dist/cli/ui/hooks/useTerminalSize.d.ts.map +0 -1
  521. package/dist/cli/ui/hooks/useTerminalSize.js +0 -24
  522. package/dist/cli/ui/hooks/useTerminalSize.js.map +0 -1
  523. package/dist/cli/ui/hooks/useToolStatus.d.ts +0 -30
  524. package/dist/cli/ui/hooks/useToolStatus.d.ts.map +0 -1
  525. package/dist/cli/ui/hooks/useToolStatus.js +0 -49
  526. package/dist/cli/ui/hooks/useToolStatus.js.map +0 -1
  527. package/dist/cli/ui/screens/BranchActionSelectorScreen.d.ts +0 -24
  528. package/dist/cli/ui/screens/BranchActionSelectorScreen.d.ts.map +0 -1
  529. package/dist/cli/ui/screens/BranchActionSelectorScreen.js +0 -65
  530. package/dist/cli/ui/screens/BranchActionSelectorScreen.js.map +0 -1
  531. package/dist/client/assets/index-LNPtOrn3.js +0 -78
  532. package/src/cli/ui/__tests__/SKIPPED_TESTS.md +0 -119
  533. package/src/cli/ui/__tests__/acceptance/branchList.acceptance.test.tsx.skip +0 -239
  534. package/src/cli/ui/__tests__/acceptance/navigation.acceptance.test.tsx +0 -225
  535. package/src/cli/ui/__tests__/acceptance/realtimeUpdate.acceptance.test.tsx.skip +0 -219
  536. package/src/cli/ui/__tests__/components/App.protected-branch.test.tsx +0 -212
  537. package/src/cli/ui/__tests__/components/App.shortcuts.test.tsx +0 -440
  538. package/src/cli/ui/__tests__/components/App.test.tsx +0 -365
  539. package/src/cli/ui/__tests__/components/ModelSelectorScreen.initial.test.tsx +0 -91
  540. package/src/cli/ui/__tests__/components/common/Confirm.test.tsx +0 -80
  541. package/src/cli/ui/__tests__/components/common/ErrorBoundary.test.tsx +0 -104
  542. package/src/cli/ui/__tests__/components/common/Input.test.tsx +0 -100
  543. package/src/cli/ui/__tests__/components/common/LoadingIndicator.test.tsx +0 -148
  544. package/src/cli/ui/__tests__/components/common/Select.memo.test.tsx +0 -255
  545. package/src/cli/ui/__tests__/components/common/Select.test.tsx +0 -335
  546. package/src/cli/ui/__tests__/components/parts/Footer.test.tsx +0 -65
  547. package/src/cli/ui/__tests__/components/parts/Header.test.tsx +0 -55
  548. package/src/cli/ui/__tests__/components/parts/ScrollableList.test.tsx +0 -69
  549. package/src/cli/ui/__tests__/components/parts/Stats.test.tsx +0 -148
  550. package/src/cli/ui/__tests__/components/screens/BranchCreatorScreen.test.tsx +0 -253
  551. package/src/cli/ui/__tests__/components/screens/BranchListScreen.test.tsx +0 -1070
  552. package/src/cli/ui/__tests__/components/screens/BranchQuickStartScreen.test.tsx +0 -142
  553. package/src/cli/ui/__tests__/components/screens/CodingAgentSelectorScreen.test.tsx +0 -174
  554. package/src/cli/ui/__tests__/components/screens/ExecutionModeSelectorScreen.test.tsx +0 -182
  555. package/src/cli/ui/__tests__/components/screens/LogDetailScreen.test.tsx +0 -57
  556. package/src/cli/ui/__tests__/components/screens/LogListScreen.test.tsx +0 -102
  557. package/src/cli/ui/__tests__/components/screens/PRCleanupScreen.test.tsx +0 -216
  558. package/src/cli/ui/__tests__/components/screens/SessionSelectorScreen.test.tsx +0 -147
  559. package/src/cli/ui/__tests__/hooks/useGitData.nonblocking.test.tsx +0 -206
  560. package/src/cli/ui/__tests__/hooks/useGitData.test.ts +0 -197
  561. package/src/cli/ui/__tests__/hooks/useGitData.test.ts.skip +0 -228
  562. package/src/cli/ui/__tests__/hooks/useScreenState.test.ts +0 -147
  563. package/src/cli/ui/__tests__/hooks/useTerminalSize.test.ts +0 -99
  564. package/src/cli/ui/__tests__/integration/branchList.test.tsx.skip +0 -253
  565. package/src/cli/ui/__tests__/integration/edgeCases.test.tsx +0 -436
  566. package/src/cli/ui/__tests__/integration/navigation.test.tsx +0 -514
  567. package/src/cli/ui/__tests__/integration/realtimeUpdate.test.tsx +0 -509
  568. package/src/cli/ui/__tests__/integration/realtimeUpdate.test.tsx.skip +0 -216
  569. package/src/cli/ui/__tests__/performance/branchList.performance.test.tsx +0 -193
  570. package/src/cli/ui/__tests__/performance/useMemoOptimization.test.tsx +0 -234
  571. package/src/cli/ui/components/App.tsx +0 -1456
  572. package/src/cli/ui/components/common/Confirm.tsx +0 -44
  573. package/src/cli/ui/components/common/ErrorBoundary.tsx +0 -60
  574. package/src/cli/ui/components/common/Input.tsx +0 -58
  575. package/src/cli/ui/components/common/LoadingIndicator.tsx +0 -98
  576. package/src/cli/ui/components/common/Select.tsx +0 -247
  577. package/src/cli/ui/components/common/SpinnerIcon.tsx +0 -86
  578. package/src/cli/ui/components/parts/Footer.tsx +0 -41
  579. package/src/cli/ui/components/parts/Header.test.tsx +0 -75
  580. package/src/cli/ui/components/parts/MergeStatusList.tsx +0 -75
  581. package/src/cli/ui/components/parts/ProgressBar.tsx +0 -73
  582. package/src/cli/ui/components/parts/Stats.tsx +0 -88
  583. package/src/cli/ui/components/screens/BatchMergeProgressScreen.tsx +0 -74
  584. package/src/cli/ui/components/screens/BatchMergeResultScreen.tsx +0 -108
  585. package/src/cli/ui/components/screens/BranchCreatorScreen.tsx +0 -242
  586. package/src/cli/ui/components/screens/BranchListScreen.tsx +0 -744
  587. package/src/cli/ui/components/screens/BranchQuickStartScreen.tsx +0 -241
  588. package/src/cli/ui/components/screens/CodingAgentSelectorScreen.tsx +0 -159
  589. package/src/cli/ui/components/screens/EnvironmentProfileScreen.tsx +0 -928
  590. package/src/cli/ui/components/screens/ExecutionModeSelectorScreen.tsx +0 -176
  591. package/src/cli/ui/components/screens/LogDatePickerScreen.tsx +0 -83
  592. package/src/cli/ui/components/screens/LogDetailScreen.tsx +0 -67
  593. package/src/cli/ui/components/screens/LogListScreen.tsx +0 -192
  594. package/src/cli/ui/components/screens/ModelSelectorScreen.tsx +0 -320
  595. package/src/cli/ui/components/screens/PRCleanupScreen.tsx +0 -171
  596. package/src/cli/ui/components/screens/SessionSelectorScreen.tsx +0 -135
  597. package/src/cli/ui/hooks/useAppInput.ts +0 -172
  598. package/src/cli/ui/hooks/useBatchMerge.ts +0 -96
  599. package/src/cli/ui/hooks/useGitData.ts +0 -347
  600. package/src/cli/ui/hooks/useProfiles.ts +0 -211
  601. package/src/cli/ui/hooks/useScreenState.ts +0 -44
  602. package/src/cli/ui/hooks/useTerminalSize.ts +0 -33
  603. package/src/cli/ui/hooks/useToolStatus.ts +0 -68
  604. package/src/cli/ui/screens/BranchActionSelectorScreen.tsx +0 -111
  605. package/src/cli/ui/screens/__tests__/BranchActionSelectorScreen.test.tsx +0 -264
@@ -0,0 +1,1197 @@
1
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "@opentui/solid/jsx-runtime";
2
+ /** @jsxImportSource @opentui/solid */
3
+ import { useKeyboard, useRenderer } from "@opentui/solid";
4
+ import { createEffect, createMemo, createSignal, onCleanup, onMount, } from "solid-js";
5
+ import { BranchListScreen } from "./screens/solid/BranchListScreen.js";
6
+ import { HelpOverlay } from "./components/solid/HelpOverlay.js";
7
+ import { WizardController, } from "./components/solid/WizardController.js";
8
+ import { SelectorScreen, } from "./screens/solid/SelectorScreen.js";
9
+ import { LogScreen } from "./screens/solid/LogScreen.js";
10
+ import { LogDetailScreen } from "./screens/solid/LogDetailScreen.js";
11
+ import { ErrorScreen } from "./screens/solid/ErrorScreen.js";
12
+ import { LoadingIndicatorScreen } from "./screens/solid/LoadingIndicator.js";
13
+ import { WorktreeCreateScreen } from "./screens/solid/WorktreeCreateScreen.js";
14
+ import { InputScreen } from "./screens/solid/InputScreen.js";
15
+ import { ConfirmScreen } from "./screens/solid/ConfirmScreen.js";
16
+ import { EnvironmentScreen } from "./screens/solid/EnvironmentScreen.js";
17
+ import { ProfileScreen } from "./screens/solid/ProfileScreen.js";
18
+ import { ProfileEnvScreen } from "./screens/solid/ProfileEnvScreen.js";
19
+ import { calculateStatistics } from "./utils/statisticsCalculator.js";
20
+ import { formatBranchItems } from "./utils/branchFormatter.js";
21
+ import { createLogger } from "../../logging/logger.js";
22
+ const logger = createLogger({ category: "app" });
23
+ import { getDefaultInferenceForModel, getDefaultModelOption, normalizeModelId, } from "./utils/modelOptions.js";
24
+ import { resolveBaseBranchLabel, resolveBaseBranchRef, } from "./utils/baseBranch.js";
25
+ import { getAllBranches, getCurrentBranch, getLocalBranches, getRepositoryRoot, deleteBranch, } from "../../git.js";
26
+ import { isProtectedBranchName, getCleanupStatus, listAdditionalWorktrees, removeWorktree, repairWorktrees, } from "../../worktree.js";
27
+ import { getConfig, getLastToolUsageMap, loadSession, } from "../../config/index.js";
28
+ import { getAllCodingAgents } from "../../config/tools.js";
29
+ import { buildLogFilePath, getTodayLogDate, readLogFileLines, resolveLogDir, } from "../../logging/reader.js";
30
+ import { parseLogLines } from "../../logging/formatter.js";
31
+ import { copyToClipboard } from "./utils/clipboard.js";
32
+ import { getPackageVersion } from "../../utils.js";
33
+ import { createProfile, deleteProfile, loadProfiles, setActiveProfile, updateProfile, } from "../../config/profiles.js";
34
+ import { isValidProfileName, } from "../../types/profiles.js";
35
+ import { BRANCH_PREFIXES } from "../../config/constants.js";
36
+ const DEFAULT_SCREEN = "branch-list";
37
+ const buildStats = (branches) => calculateStatistics(branches);
38
+ const applyCleanupStatus = (items, statusByBranch) => items.map((branch) => {
39
+ const status = statusByBranch.get(branch.name);
40
+ if (!status) {
41
+ return { ...branch, safeToCleanup: false, isUnmerged: false };
42
+ }
43
+ const safeToCleanup = status.hasUpstream && status.reasons.includes("no-diff-with-base");
44
+ const isUnmerged = status.hasUpstream && status.hasUniqueCommits;
45
+ const worktree = branch.worktree
46
+ ? {
47
+ ...branch.worktree,
48
+ ...(status.hasUncommittedChanges !== undefined
49
+ ? { hasUncommittedChanges: status.hasUncommittedChanges }
50
+ : {}),
51
+ }
52
+ : undefined;
53
+ const base = {
54
+ ...branch,
55
+ safeToCleanup,
56
+ isUnmerged,
57
+ hasUnpushedCommits: status.hasUnpushedCommits,
58
+ };
59
+ return worktree ? { ...base, worktree } : base;
60
+ });
61
+ const toLocalBranchName = (name) => {
62
+ const segments = name.split("/");
63
+ if (segments.length <= 1) {
64
+ return name;
65
+ }
66
+ return segments.slice(1).join("/");
67
+ };
68
+ const toSelectedBranchState = (branch) => {
69
+ const isRemote = branch.type === "remote";
70
+ const baseName = isRemote ? toLocalBranchName(branch.name) : branch.name;
71
+ return {
72
+ name: baseName,
73
+ displayName: branch.name,
74
+ branchType: branch.type,
75
+ branchCategory: branch.branchType,
76
+ ...(isRemote ? { remoteBranch: branch.name } : {}),
77
+ };
78
+ };
79
+ export function AppSolid(props) {
80
+ const renderer = useRenderer();
81
+ let hasExited = false;
82
+ const exitApp = (result) => {
83
+ if (hasExited)
84
+ return;
85
+ hasExited = true;
86
+ props.onExit?.(result);
87
+ renderer.destroy();
88
+ };
89
+ const [currentScreen, setCurrentScreen] = createSignal(props.initialScreen ?? DEFAULT_SCREEN);
90
+ const [screenStack, setScreenStack] = createSignal([]);
91
+ const [helpVisible, setHelpVisible] = createSignal(false);
92
+ const [wizardVisible, setWizardVisible] = createSignal(false);
93
+ const [branchItems, setBranchItems] = createSignal(props.branches ?? []);
94
+ const [stats, setStats] = createSignal(props.stats ?? buildStats(props.branches ?? []));
95
+ const [loading, setLoading] = createSignal(!props.branches);
96
+ const [error, setError] = createSignal(null);
97
+ const [toolItems, setToolItems] = createSignal([]);
98
+ const [toolError, setToolError] = createSignal(null);
99
+ const [version, setVersion] = createSignal(props.version ?? null);
100
+ const workingDirectory = createMemo(() => props.workingDirectory ?? process.cwd());
101
+ const [selectedBranch, setSelectedBranch] = createSignal(null);
102
+ const [selectedTool, setSelectedTool] = createSignal(null);
103
+ const [selectedMode, setSelectedMode] = createSignal("normal");
104
+ const [selectedBranches, setSelectedBranches] = createSignal([]);
105
+ const [branchFooterMessage, setBranchFooterMessage] = createSignal(null);
106
+ const [branchInputLocked, setBranchInputLocked] = createSignal(false);
107
+ const [cleanupIndicators, setCleanupIndicators] = createSignal({});
108
+ const [cleanupStatusByBranch, setCleanupStatusByBranch] = createSignal(new Map());
109
+ const [cleanupSafetyLoading, setCleanupSafetyLoading] = createSignal(false);
110
+ const [isNewBranch, setIsNewBranch] = createSignal(false);
111
+ const [newBranchBaseRef, setNewBranchBaseRef] = createSignal(null);
112
+ const [creationSource, setCreationSource] = createSignal(null);
113
+ const [createBranchName, setCreateBranchName] = createSignal("", {
114
+ equals: false,
115
+ });
116
+ const [suppressCreateKey, setSuppressCreateKey] = createSignal(null);
117
+ const [defaultBaseBranch, setDefaultBaseBranch] = createSignal("main");
118
+ // セッション履歴(最終使用エージェントなど)
119
+ const [sessionHistory, setSessionHistory] = createSignal([]);
120
+ // 選択中ブランチの履歴をフィルタリング
121
+ const historyForBranch = createMemo(() => {
122
+ const history = sessionHistory();
123
+ const branch = selectedBranch();
124
+ if (!branch)
125
+ return [];
126
+ // 選択中ブランチにマッチする履歴エントリを新しい順で返す
127
+ return history
128
+ .filter((entry) => entry.branch === branch.name)
129
+ .sort((a, b) => (b.timestamp ?? 0) - (a.timestamp ?? 0));
130
+ });
131
+ const [logEntries, setLogEntries] = createSignal([]);
132
+ const [logLoading, setLogLoading] = createSignal(false);
133
+ const [logError, setLogError] = createSignal(null);
134
+ const [logSelectedEntry, setLogSelectedEntry] = createSignal(null);
135
+ const [logSelectedDate, _setLogSelectedDate] = createSignal(getTodayLogDate());
136
+ const [logNotification, setLogNotification] = createSignal(null);
137
+ const [profileItems, setProfileItems] = createSignal([]);
138
+ const [activeProfile, setActiveProfileName] = createSignal(null);
139
+ const [profileError, setProfileError] = createSignal(null);
140
+ const [profilesConfig, setProfilesConfig] = createSignal(null);
141
+ const [profileActionError, setProfileActionError] = createSignal(null);
142
+ const [profileActionHint, setProfileActionHint] = createSignal(null);
143
+ const [selectedProfileName, setSelectedProfileName] = createSignal(null);
144
+ const [profileInputValue, setProfileInputValue] = createSignal("", {
145
+ equals: false,
146
+ });
147
+ const [profileInputMode, setProfileInputMode] = createSignal("create-profile");
148
+ const [profileInputSuppressKey, setProfileInputSuppressKey] = createSignal(null);
149
+ const [profileEnvKey, setProfileEnvKey] = createSignal(null);
150
+ const [profileConfirmMode, setProfileConfirmMode] = createSignal("delete-profile");
151
+ const logDir = createMemo(() => resolveLogDir(workingDirectory()));
152
+ const selectedProfileConfig = createMemo(() => {
153
+ const name = selectedProfileName();
154
+ const config = profilesConfig();
155
+ if (!name || !config?.profiles?.[name]) {
156
+ return null;
157
+ }
158
+ return { name, profile: config.profiles[name] };
159
+ });
160
+ const profileEnvVariables = createMemo(() => {
161
+ const entry = selectedProfileConfig();
162
+ if (!entry) {
163
+ return [];
164
+ }
165
+ return Object.entries(entry.profile.env ?? {})
166
+ .map(([key, value]) => ({ key, value }))
167
+ .sort((a, b) => a.key.localeCompare(b.key));
168
+ });
169
+ const osEnvVariables = createMemo(() => Object.entries(process.env)
170
+ .filter(([, value]) => typeof value === "string")
171
+ .map(([key, value]) => ({ key, value: String(value) }))
172
+ .sort((a, b) => a.key.localeCompare(b.key)));
173
+ let cleanupSafetyRequestId = 0;
174
+ const refreshCleanupSafety = async () => {
175
+ const requestId = ++cleanupSafetyRequestId;
176
+ setCleanupSafetyLoading(true);
177
+ try {
178
+ const cleanupStatuses = await getCleanupStatus();
179
+ if (requestId !== cleanupSafetyRequestId) {
180
+ return;
181
+ }
182
+ const statusByBranch = new Map(cleanupStatuses.map((status) => [status.branch, status]));
183
+ setCleanupStatusByBranch(statusByBranch);
184
+ setBranchItems((items) => applyCleanupStatus(items, statusByBranch));
185
+ }
186
+ catch (err) {
187
+ if (requestId !== cleanupSafetyRequestId) {
188
+ return;
189
+ }
190
+ logger.warn({ err }, "Failed to refresh cleanup safety indicators");
191
+ const empty = new Map();
192
+ setCleanupStatusByBranch(empty);
193
+ setBranchItems((items) => applyCleanupStatus(items, empty));
194
+ }
195
+ finally {
196
+ if (requestId === cleanupSafetyRequestId) {
197
+ setCleanupSafetyLoading(false);
198
+ }
199
+ }
200
+ };
201
+ let logNotificationTimer = null;
202
+ let branchFooterTimer = null;
203
+ const BRANCH_LOAD_TIMEOUT_MS = 3000;
204
+ const BRANCH_FULL_LOAD_TIMEOUT_MS = 8000;
205
+ const isHelpKey = (key) => {
206
+ if (key.ctrl || key.meta || key.super || key.hyper || key.option) {
207
+ return false;
208
+ }
209
+ return key.name === "h" || key.sequence === "h" || key.sequence === "?";
210
+ };
211
+ useKeyboard((key) => {
212
+ if (key.repeated) {
213
+ return;
214
+ }
215
+ if (helpVisible()) {
216
+ if (key.name === "escape" || isHelpKey(key)) {
217
+ setHelpVisible(false);
218
+ }
219
+ return;
220
+ }
221
+ if (isHelpKey(key)) {
222
+ setHelpVisible(true);
223
+ }
224
+ });
225
+ const navigateTo = (screen) => {
226
+ setScreenStack((prev) => [...prev, currentScreen()]);
227
+ setCurrentScreen(screen);
228
+ };
229
+ const goBack = () => {
230
+ const stack = screenStack();
231
+ if (stack.length === 0) {
232
+ return;
233
+ }
234
+ const previous = stack[stack.length - 1] ?? DEFAULT_SCREEN;
235
+ setScreenStack(stack.slice(0, -1));
236
+ // branch-list に戻る場合は選択状態をリセット
237
+ if (previous === "branch-list") {
238
+ setSelectedBranch(null);
239
+ setSelectedTool(null);
240
+ setSelectedMode("normal");
241
+ setIsNewBranch(false);
242
+ setNewBranchBaseRef(null);
243
+ setCreationSource(null);
244
+ }
245
+ setCurrentScreen(previous);
246
+ };
247
+ const openProfileError = (err, hint) => {
248
+ setProfileActionError(err instanceof Error ? err : new Error(String(err)));
249
+ setProfileActionHint(hint);
250
+ navigateTo("profile-error");
251
+ };
252
+ const showLogNotification = (message, tone) => {
253
+ setLogNotification({ message, tone });
254
+ if (logNotificationTimer) {
255
+ clearTimeout(logNotificationTimer);
256
+ }
257
+ logNotificationTimer = setTimeout(() => {
258
+ setLogNotification(null);
259
+ }, 2000);
260
+ };
261
+ const loadLogEntries = async (date) => {
262
+ const targetDate = date ?? getTodayLogDate();
263
+ setLogLoading(true);
264
+ setLogError(null);
265
+ try {
266
+ const filePath = buildLogFilePath(logDir(), targetDate);
267
+ const lines = await readLogFileLines(filePath);
268
+ const parsed = parseLogLines(lines, { limit: 100 });
269
+ setLogEntries(parsed);
270
+ }
271
+ catch (err) {
272
+ setLogEntries([]);
273
+ setLogError(err instanceof Error ? err.message : "Failed to load logs");
274
+ }
275
+ finally {
276
+ setLogLoading(false);
277
+ }
278
+ };
279
+ const refreshBranches = async () => {
280
+ setLoading(true);
281
+ setError(null);
282
+ void refreshCleanupSafety();
283
+ try {
284
+ const repoRoot = await getRepositoryRoot();
285
+ const worktreesPromise = listAdditionalWorktrees();
286
+ const localBranchesPromise = getLocalBranches(repoRoot);
287
+ const currentBranchPromise = getCurrentBranch(repoRoot);
288
+ const lastToolUsagePromise = getLastToolUsageMap(repoRoot);
289
+ const [localBranches, currentBranch, worktrees, lastToolUsageMap] = await Promise.all([
290
+ withTimeout(localBranchesPromise, BRANCH_LOAD_TIMEOUT_MS).catch(() => []),
291
+ withTimeout(currentBranchPromise, BRANCH_LOAD_TIMEOUT_MS).catch(() => null),
292
+ withTimeout(worktreesPromise, BRANCH_LOAD_TIMEOUT_MS).catch(() => []),
293
+ withTimeout(lastToolUsagePromise, BRANCH_LOAD_TIMEOUT_MS).catch(() => new Map()),
294
+ ]);
295
+ if (currentBranch) {
296
+ localBranches.forEach((branch) => {
297
+ if (branch.name === currentBranch) {
298
+ branch.isCurrent = true;
299
+ }
300
+ });
301
+ }
302
+ const initial = buildBranchList(localBranches, worktrees, lastToolUsageMap);
303
+ const initialItems = applyCleanupStatus(initial.items, cleanupStatusByBranch());
304
+ setBranchItems(initialItems);
305
+ setStats(buildStats(initialItems));
306
+ void (async () => {
307
+ const [branches, latestWorktrees] = await Promise.all([
308
+ withTimeout(getAllBranches(repoRoot), BRANCH_FULL_LOAD_TIMEOUT_MS).catch(() => localBranches),
309
+ withTimeout(listAdditionalWorktrees(), BRANCH_FULL_LOAD_TIMEOUT_MS).catch(() => worktrees),
310
+ ]);
311
+ const full = buildBranchList(branches, latestWorktrees, lastToolUsageMap);
312
+ const fullItems = applyCleanupStatus(full.items, cleanupStatusByBranch());
313
+ setBranchItems(fullItems);
314
+ setStats(buildStats(fullItems));
315
+ })();
316
+ }
317
+ catch (err) {
318
+ setError(err instanceof Error ? err : new Error(String(err)));
319
+ }
320
+ finally {
321
+ setLoading(false);
322
+ }
323
+ };
324
+ const refreshProfiles = async () => {
325
+ try {
326
+ const config = await loadProfiles();
327
+ setProfilesConfig(config);
328
+ const items = Object.entries(config.profiles ?? {}).map(([name, profile]) => ({
329
+ name,
330
+ displayName: profile.displayName,
331
+ isActive: config.activeProfile === name,
332
+ }));
333
+ items.sort((a, b) => a.name.localeCompare(b.name));
334
+ setProfileItems(items);
335
+ setActiveProfileName(config.activeProfile ?? null);
336
+ setProfileError(null);
337
+ }
338
+ catch (err) {
339
+ setProfilesConfig(null);
340
+ setProfileItems([]);
341
+ setActiveProfileName(null);
342
+ setProfileError(err instanceof Error ? err : new Error(String(err)));
343
+ }
344
+ };
345
+ createEffect(() => {
346
+ if (props.branches) {
347
+ const statusByBranch = cleanupStatusByBranch();
348
+ const nextItems = applyCleanupStatus(props.branches, statusByBranch);
349
+ setBranchItems(nextItems);
350
+ setStats(props.stats ?? buildStats(nextItems));
351
+ setLoading(false);
352
+ }
353
+ });
354
+ onMount(() => {
355
+ if (!props.branches) {
356
+ void refreshBranches();
357
+ }
358
+ });
359
+ onMount(() => {
360
+ if (props.branches) {
361
+ void refreshCleanupSafety();
362
+ }
363
+ });
364
+ onMount(() => {
365
+ if (props.version === undefined) {
366
+ void getPackageVersion()
367
+ .then((value) => setVersion(value ?? null))
368
+ .catch(() => setVersion(null));
369
+ }
370
+ });
371
+ onMount(() => {
372
+ void refreshProfiles();
373
+ });
374
+ onMount(() => {
375
+ void getConfig()
376
+ .then((config) => setDefaultBaseBranch(config.defaultBaseBranch))
377
+ .catch(() => setDefaultBaseBranch("main"));
378
+ });
379
+ // セッション履歴をロード(最終使用エージェントなど)
380
+ onMount(() => {
381
+ void getRepositoryRoot()
382
+ .then((repoRoot) => loadSession(repoRoot))
383
+ .then((session) => {
384
+ if (session?.history) {
385
+ setSessionHistory(session.history);
386
+ }
387
+ })
388
+ .catch(() => setSessionHistory([]));
389
+ });
390
+ onMount(() => {
391
+ void getAllCodingAgents()
392
+ .then((agents) => {
393
+ setToolItems(agents.map((agent) => ({
394
+ label: agent.displayName,
395
+ value: agent.id,
396
+ })));
397
+ })
398
+ .catch((err) => {
399
+ setToolItems([]);
400
+ setToolError(err instanceof Error ? err : new Error(String(err)));
401
+ });
402
+ });
403
+ createEffect(() => {
404
+ if (currentScreen() === "log-list") {
405
+ void loadLogEntries(logSelectedDate());
406
+ }
407
+ });
408
+ onCleanup(() => {
409
+ if (logNotificationTimer) {
410
+ clearTimeout(logNotificationTimer);
411
+ }
412
+ if (branchFooterTimer) {
413
+ clearTimeout(branchFooterTimer);
414
+ }
415
+ });
416
+ const showBranchFooterMessage = (text, color, options) => {
417
+ if (branchFooterTimer) {
418
+ clearTimeout(branchFooterTimer);
419
+ branchFooterTimer = null;
420
+ }
421
+ setBranchFooterMessage({
422
+ text,
423
+ color,
424
+ ...(options?.spinning ? { isSpinning: true } : {}),
425
+ });
426
+ const timeout = options?.timeoutMs ?? 2000;
427
+ if (timeout > 0) {
428
+ branchFooterTimer = setTimeout(() => {
429
+ setBranchFooterMessage(null);
430
+ }, timeout);
431
+ }
432
+ };
433
+ const setCleanupIndicator = (branchName, indicator) => {
434
+ setCleanupIndicators((prev) => {
435
+ const next = { ...prev };
436
+ if (indicator) {
437
+ next[branchName] = indicator;
438
+ }
439
+ else {
440
+ delete next[branchName];
441
+ }
442
+ return next;
443
+ });
444
+ };
445
+ const handleBranchSelect = (branch) => {
446
+ setSelectedBranch(toSelectedBranchState(branch));
447
+ setIsNewBranch(false);
448
+ setNewBranchBaseRef(null);
449
+ setCreationSource(null);
450
+ setSelectedTool(null);
451
+ setSelectedMode("normal");
452
+ // FR-044: ウィザードポップアップをレイヤー表示
453
+ setWizardVisible(true);
454
+ };
455
+ const handleQuickCreate = (branch) => {
456
+ // 選択中のブランチをベースにウィザードを開始
457
+ if (branch) {
458
+ setSelectedBranch(toSelectedBranchState(branch));
459
+ }
460
+ setCreationSource(branch ? toSelectedBranchState(branch) : null);
461
+ setCreateBranchName("");
462
+ setSuppressCreateKey("n");
463
+ // FR-044: ウィザードポップアップをレイヤー表示(アクション選択から開始)
464
+ setWizardVisible(true);
465
+ };
466
+ // FR-049: Escapeキーでウィザードをキャンセル
467
+ const handleWizardClose = () => {
468
+ setWizardVisible(false);
469
+ };
470
+ // ウィザード完了時の処理
471
+ const handleWizardComplete = (result) => {
472
+ setWizardVisible(false);
473
+ const branch = selectedBranch();
474
+ if (!branch) {
475
+ return;
476
+ }
477
+ // 新規ブランチ作成の場合、ブランチ名を設定
478
+ const isCreatingNew = result.isNewBranch ?? false;
479
+ const finalBranchName = result.branchName
480
+ ? `${result.branchType ?? ""}${result.branchName}`
481
+ : branch.name;
482
+ // 新規作成時は選択中のブランチがベースとなる
483
+ const baseBranchRef = isCreatingNew ? branch.name : null;
484
+ const normalizedModel = normalizeModelId(result.tool, result.model);
485
+ exitApp({
486
+ branch: finalBranchName,
487
+ displayName: branch.displayName,
488
+ branchType: branch.branchType,
489
+ ...(branch.remoteBranch ? { remoteBranch: branch.remoteBranch } : {}),
490
+ ...(isCreatingNew
491
+ ? {
492
+ isNewBranch: true,
493
+ ...(baseBranchRef ? { baseBranch: baseBranchRef } : {}),
494
+ }
495
+ : {}),
496
+ tool: result.tool,
497
+ mode: result.mode,
498
+ skipPermissions: result.skipPermissions,
499
+ ...(normalizedModel !== undefined ? { model: normalizedModel } : {}),
500
+ ...(result.reasoningLevel !== undefined
501
+ ? { inferenceLevel: result.reasoningLevel }
502
+ : {}),
503
+ ...(result.toolVersion !== undefined
504
+ ? { toolVersion: result.toolVersion }
505
+ : {}),
506
+ });
507
+ };
508
+ // FR-010: クイックスタートからのResume(前回設定で続きから)
509
+ const handleWizardResume = (entry) => {
510
+ setWizardVisible(false);
511
+ const branch = selectedBranch();
512
+ if (!branch) {
513
+ return;
514
+ }
515
+ const normalizedModel = normalizeModelId(entry.toolId, entry.model ?? undefined);
516
+ exitApp({
517
+ branch: branch.name,
518
+ displayName: branch.displayName,
519
+ branchType: branch.branchType,
520
+ ...(branch.remoteBranch ? { remoteBranch: branch.remoteBranch } : {}),
521
+ tool: entry.toolId,
522
+ mode: "continue",
523
+ skipPermissions: entry.skipPermissions ?? false,
524
+ ...(normalizedModel !== undefined ? { model: normalizedModel } : {}),
525
+ ...(entry.reasoningLevel
526
+ ? { inferenceLevel: entry.reasoningLevel }
527
+ : {}),
528
+ ...(entry.sessionId ? { sessionId: entry.sessionId } : {}),
529
+ ...(entry.toolVersion !== undefined
530
+ ? { toolVersion: entry.toolVersion }
531
+ : {}),
532
+ });
533
+ };
534
+ // FR-010: クイックスタートからのStartNew(前回設定で新規)
535
+ const handleWizardStartNew = (entry) => {
536
+ setWizardVisible(false);
537
+ const branch = selectedBranch();
538
+ if (!branch) {
539
+ return;
540
+ }
541
+ const normalizedModel = normalizeModelId(entry.toolId, entry.model ?? undefined);
542
+ exitApp({
543
+ branch: branch.name,
544
+ displayName: branch.displayName,
545
+ branchType: branch.branchType,
546
+ ...(branch.remoteBranch ? { remoteBranch: branch.remoteBranch } : {}),
547
+ tool: entry.toolId,
548
+ mode: "normal",
549
+ skipPermissions: entry.skipPermissions ?? false,
550
+ ...(normalizedModel !== undefined ? { model: normalizedModel } : {}),
551
+ ...(entry.reasoningLevel
552
+ ? { inferenceLevel: entry.reasoningLevel }
553
+ : {}),
554
+ ...(entry.toolVersion !== undefined
555
+ ? { toolVersion: entry.toolVersion }
556
+ : {}),
557
+ });
558
+ };
559
+ const buildSkipNotice = (skip, unsafeLabel) => {
560
+ const parts = [];
561
+ if (skip.unsafe > 0) {
562
+ parts.push(`${skip.unsafe} ${unsafeLabel}`);
563
+ }
564
+ if (skip.protected > 0) {
565
+ parts.push(`${skip.protected} protected`);
566
+ }
567
+ if (skip.remote > 0) {
568
+ parts.push(`${skip.remote} remote-only`);
569
+ }
570
+ if (skip.current > 0) {
571
+ parts.push(`${skip.current} current`);
572
+ }
573
+ if (parts.length === 0) {
574
+ return null;
575
+ }
576
+ return `Skipped branches: ${parts.join(", ")}.`;
577
+ };
578
+ const handleCleanupCommand = async () => {
579
+ if (branchInputLocked()) {
580
+ return;
581
+ }
582
+ const selection = selectedBranches();
583
+ const hasSelection = selection.length > 0;
584
+ const skipCounts = {
585
+ unsafe: 0,
586
+ protected: 0,
587
+ remote: 0,
588
+ current: 0,
589
+ };
590
+ setBranchInputLocked(true);
591
+ setCleanupIndicators({});
592
+ showBranchFooterMessage(hasSelection
593
+ ? "Preparing cleanup..."
594
+ : "Scanning for cleanup candidates...", "yellow", { spinning: true, timeoutMs: 0 });
595
+ try {
596
+ const tasks = [];
597
+ if (hasSelection) {
598
+ const branchMap = new Map(branchItems().map((branch) => [branch.name, branch]));
599
+ for (const branchName of selection) {
600
+ const branch = branchMap.get(branchName);
601
+ if (!branch) {
602
+ continue;
603
+ }
604
+ if (branch.type === "remote") {
605
+ skipCounts.remote += 1;
606
+ continue;
607
+ }
608
+ if (isProtectedBranchName(branch.name)) {
609
+ skipCounts.protected += 1;
610
+ continue;
611
+ }
612
+ if (branch.isCurrent) {
613
+ skipCounts.current += 1;
614
+ continue;
615
+ }
616
+ const hasUncommitted = branch.worktree?.hasUncommittedChanges === true;
617
+ const hasUnpushed = branch.hasUnpushedCommits === true;
618
+ if (hasUncommitted || hasUnpushed) {
619
+ skipCounts.unsafe += 1;
620
+ continue;
621
+ }
622
+ if (branch.safeToCleanup !== true) {
623
+ skipCounts.unsafe += 1;
624
+ continue;
625
+ }
626
+ const worktreePath = branch.worktree?.path ?? null;
627
+ const cleanupType = worktreePath
628
+ ? "worktree-and-branch"
629
+ : "branch-only";
630
+ const baseTask = {
631
+ branch: branch.name,
632
+ worktreePath,
633
+ cleanupType,
634
+ };
635
+ const isAccessible = branch.worktree?.isAccessible;
636
+ tasks.push(isAccessible === undefined
637
+ ? baseTask
638
+ : { ...baseTask, isAccessible });
639
+ }
640
+ }
641
+ else {
642
+ // FR-028: 選択が0件の場合は警告を表示して処理をスキップ
643
+ setBranchInputLocked(false);
644
+ showBranchFooterMessage("No branches selected.", "yellow");
645
+ return;
646
+ }
647
+ const skipNotice = buildSkipNotice(skipCounts, hasSelection
648
+ ? "unsafe (uncommitted/unpushed, unmerged, or missing upstream)"
649
+ : "with uncommitted or unpushed changes");
650
+ if (tasks.length === 0) {
651
+ const baseMessage = hasSelection
652
+ ? "No eligible branches selected for cleanup."
653
+ : "No cleanup candidates found.";
654
+ showBranchFooterMessage(skipNotice ? `${baseMessage} ${skipNotice}` : baseMessage, "yellow");
655
+ return;
656
+ }
657
+ setCleanupIndicators(() => {
658
+ const next = {};
659
+ tasks.forEach((task) => {
660
+ next[task.branch] = {
661
+ icon: "-",
662
+ isSpinning: true,
663
+ color: "yellow",
664
+ };
665
+ });
666
+ return next;
667
+ });
668
+ showBranchFooterMessage(`Cleaning up ${tasks.length} branch(es)...`, "yellow", { spinning: true, timeoutMs: 0 });
669
+ let successCount = 0;
670
+ let failedCount = 0;
671
+ for (const task of tasks) {
672
+ try {
673
+ if (task.cleanupType === "worktree-and-branch" && task.worktreePath) {
674
+ await removeWorktree(task.worktreePath, task.isAccessible === false);
675
+ }
676
+ await deleteBranch(task.branch, true);
677
+ setCleanupIndicator(task.branch, { icon: "v", color: "green" });
678
+ successCount += 1;
679
+ }
680
+ catch {
681
+ setCleanupIndicator(task.branch, { icon: "x", color: "red" });
682
+ failedCount += 1;
683
+ }
684
+ }
685
+ setSelectedBranches([]);
686
+ await refreshBranches();
687
+ const skippedTotal = skipCounts.unsafe +
688
+ skipCounts.protected +
689
+ skipCounts.remote +
690
+ skipCounts.current;
691
+ const summaryParts = [`${successCount} cleaned`];
692
+ if (failedCount > 0) {
693
+ summaryParts.push(`${failedCount} failed`);
694
+ }
695
+ if (skippedTotal > 0) {
696
+ summaryParts.push(`${skippedTotal} skipped`);
697
+ }
698
+ const summary = `Cleanup finished: ${summaryParts.join(", ")}.`;
699
+ const message = skipNotice ? `${summary} ${skipNotice}` : summary;
700
+ showBranchFooterMessage(message, failedCount > 0 ? "red" : "green");
701
+ }
702
+ catch (err) {
703
+ const errorMessage = err instanceof Error ? err.message : String(err);
704
+ showBranchFooterMessage(`Cleanup failed: ${errorMessage}`, "red");
705
+ }
706
+ finally {
707
+ setBranchInputLocked(false);
708
+ }
709
+ };
710
+ const handleRepairWorktrees = async () => {
711
+ if (branchInputLocked()) {
712
+ return;
713
+ }
714
+ // FR-002/FR-007: 選択済みブランチのみを対象とする
715
+ const selection = selectedBranches();
716
+ if (selection.length === 0) {
717
+ showBranchFooterMessage("No branches selected.", "yellow");
718
+ return;
719
+ }
720
+ // 選択されたブランチのうち、inaccessibleなものを修復対象とする
721
+ const selectionSet = new Set(selection);
722
+ const targets = branchItems()
723
+ .filter((branch) => selectionSet.has(branch.name) &&
724
+ branch.worktreeStatus === "inaccessible")
725
+ .map((branch) => branch.name);
726
+ if (targets.length === 0) {
727
+ showBranchFooterMessage("No worktrees to repair.", "yellow");
728
+ return;
729
+ }
730
+ setBranchInputLocked(true);
731
+ showBranchFooterMessage("Repairing worktrees...", "yellow", {
732
+ spinning: true,
733
+ timeoutMs: 0,
734
+ });
735
+ try {
736
+ const result = await repairWorktrees(targets);
737
+ await refreshBranches();
738
+ // エラー詳細をログに出力
739
+ if (result.failedCount > 0) {
740
+ logger.error({ failures: result.failures, targets }, "Worktree repair failed for some branches");
741
+ }
742
+ const message = result.failedCount > 0
743
+ ? `Repair finished: ${result.repairedCount} repaired, ${result.failedCount} failed.`
744
+ : result.repairedCount > 0
745
+ ? `Repaired ${result.repairedCount} worktree(s).`
746
+ : "No worktrees repaired.";
747
+ showBranchFooterMessage(message, result.failedCount > 0 ? "red" : "green");
748
+ }
749
+ catch (err) {
750
+ const errorMessage = err instanceof Error ? err.message : String(err);
751
+ logger.error({ error: err, targets }, "Worktree repair threw an error");
752
+ showBranchFooterMessage(`Repair failed: ${errorMessage}`, "red");
753
+ }
754
+ finally {
755
+ setBranchInputLocked(false);
756
+ }
757
+ };
758
+ const openProfileCreate = () => {
759
+ setProfileInputMode("create-profile");
760
+ setProfileInputValue("");
761
+ setProfileEnvKey(null);
762
+ setProfileInputSuppressKey("n");
763
+ navigateTo("profile-input");
764
+ };
765
+ const openProfileDelete = (profile) => {
766
+ setSelectedProfileName(profile.name);
767
+ setProfileConfirmMode("delete-profile");
768
+ navigateTo("profile-confirm");
769
+ };
770
+ const openProfileEnv = (profile) => {
771
+ setSelectedProfileName(profile.name);
772
+ navigateTo("profile-env");
773
+ };
774
+ const openProfileEnvAdd = () => {
775
+ setProfileInputMode("add-env");
776
+ setProfileInputValue("");
777
+ setProfileEnvKey(null);
778
+ setProfileInputSuppressKey("a");
779
+ navigateTo("profile-input");
780
+ };
781
+ const openProfileEnvEdit = (variable) => {
782
+ setProfileInputMode("edit-env");
783
+ setProfileEnvKey(variable.key);
784
+ setProfileInputValue(variable.value);
785
+ setProfileInputSuppressKey("e");
786
+ navigateTo("profile-input");
787
+ };
788
+ const openProfileEnvDelete = (variable) => {
789
+ setProfileConfirmMode("delete-env");
790
+ setProfileEnvKey(variable.key);
791
+ navigateTo("profile-confirm");
792
+ };
793
+ const handleProfileInputChange = (value) => {
794
+ const suppressKey = profileInputSuppressKey();
795
+ if (suppressKey && profileInputValue() === "" && value === suppressKey) {
796
+ setProfileInputSuppressKey(null);
797
+ setProfileInputValue("");
798
+ return;
799
+ }
800
+ setProfileInputSuppressKey(null);
801
+ setProfileInputValue(value);
802
+ };
803
+ const submitProfileInput = async (value) => {
804
+ const mode = profileInputMode();
805
+ const trimmed = value.trim();
806
+ if (mode === "create-profile") {
807
+ if (!trimmed) {
808
+ openProfileError(new Error("Profile name is required."), "Invalid name.");
809
+ return;
810
+ }
811
+ if (!isValidProfileName(trimmed)) {
812
+ openProfileError(new Error(`Invalid profile name: "${trimmed}".`), "Profile names must use lowercase letters, numbers, and hyphens.");
813
+ return;
814
+ }
815
+ try {
816
+ await createProfile(trimmed, { displayName: trimmed, env: {} });
817
+ await refreshProfiles();
818
+ setSelectedProfileName(trimmed);
819
+ setProfileInputValue("");
820
+ setProfileInputSuppressKey(null);
821
+ goBack();
822
+ }
823
+ catch (err) {
824
+ openProfileError(err, "Unable to create profile.");
825
+ }
826
+ return;
827
+ }
828
+ const entry = selectedProfileConfig();
829
+ if (!entry) {
830
+ openProfileError(new Error("Profile not selected."), "Profile not found.");
831
+ return;
832
+ }
833
+ if (mode === "add-env") {
834
+ const separatorIndex = trimmed.indexOf("=");
835
+ if (separatorIndex <= 0) {
836
+ openProfileError(new Error("Environment variable must be in KEY=VALUE format."), "Invalid environment variable.");
837
+ return;
838
+ }
839
+ const key = trimmed.slice(0, separatorIndex).trim();
840
+ const valuePart = trimmed.slice(separatorIndex + 1);
841
+ if (!key) {
842
+ openProfileError(new Error("Environment variable key is required."), "Invalid environment variable.");
843
+ return;
844
+ }
845
+ const nextEnv = { ...(entry.profile.env ?? {}) };
846
+ nextEnv[key] = valuePart;
847
+ try {
848
+ await updateProfile(entry.name, { env: nextEnv });
849
+ await refreshProfiles();
850
+ setProfileInputValue("");
851
+ setProfileInputSuppressKey(null);
852
+ goBack();
853
+ }
854
+ catch (err) {
855
+ openProfileError(err, "Unable to update profile.");
856
+ }
857
+ return;
858
+ }
859
+ if (mode === "edit-env") {
860
+ const envKey = profileEnvKey();
861
+ if (!envKey) {
862
+ openProfileError(new Error("Environment variable not selected."), "Select a variable to edit.");
863
+ return;
864
+ }
865
+ const nextEnv = { ...(entry.profile.env ?? {}) };
866
+ nextEnv[envKey] = value;
867
+ try {
868
+ await updateProfile(entry.name, { env: nextEnv });
869
+ await refreshProfiles();
870
+ setProfileInputValue("");
871
+ setProfileInputSuppressKey(null);
872
+ goBack();
873
+ }
874
+ catch (err) {
875
+ openProfileError(err, "Unable to update profile.");
876
+ }
877
+ }
878
+ };
879
+ const confirmProfileAction = async (confirmed) => {
880
+ if (!confirmed) {
881
+ goBack();
882
+ return;
883
+ }
884
+ const mode = profileConfirmMode();
885
+ const entry = selectedProfileConfig();
886
+ if (mode === "delete-profile") {
887
+ const name = selectedProfileName();
888
+ if (!name) {
889
+ openProfileError(new Error("Profile not selected."), "Profile not found.");
890
+ return;
891
+ }
892
+ try {
893
+ await deleteProfile(name);
894
+ await refreshProfiles();
895
+ setProfileEnvKey(null);
896
+ goBack();
897
+ }
898
+ catch (err) {
899
+ openProfileError(err, "Unable to delete profile.");
900
+ }
901
+ return;
902
+ }
903
+ if (mode === "delete-env") {
904
+ if (!entry) {
905
+ openProfileError(new Error("Profile not selected."), "Profile not found.");
906
+ return;
907
+ }
908
+ const envKey = profileEnvKey();
909
+ if (!envKey) {
910
+ openProfileError(new Error("Environment variable not selected."), "Select a variable to delete.");
911
+ return;
912
+ }
913
+ const nextEnv = { ...(entry.profile.env ?? {}) };
914
+ delete nextEnv[envKey];
915
+ try {
916
+ await updateProfile(entry.name, { env: nextEnv });
917
+ await refreshProfiles();
918
+ setProfileEnvKey(null);
919
+ goBack();
920
+ }
921
+ catch (err) {
922
+ openProfileError(err, "Unable to update profile.");
923
+ }
924
+ }
925
+ };
926
+ const toggleSelectedBranch = (branchName) => {
927
+ setSelectedBranches((prev) => {
928
+ const next = new Set(prev);
929
+ if (next.has(branchName)) {
930
+ next.delete(branchName);
931
+ }
932
+ else {
933
+ next.add(branchName);
934
+ }
935
+ return Array.from(next);
936
+ });
937
+ };
938
+ const handleToolSelect = (item) => {
939
+ setSelectedTool(item.value);
940
+ navigateTo("mode-select");
941
+ };
942
+ const handleModeSelect = (item) => {
943
+ setSelectedMode(item.value);
944
+ navigateTo("skip-permissions");
945
+ };
946
+ const finalizeSelection = (skipPermissions) => {
947
+ const branch = selectedBranch();
948
+ const tool = selectedTool();
949
+ if (!branch || !tool) {
950
+ return;
951
+ }
952
+ const defaultModel = getDefaultModelOption(tool);
953
+ const resolvedModel = defaultModel?.id ?? null;
954
+ const normalizedModel = normalizeModelId(tool, resolvedModel);
955
+ const resolvedInference = getDefaultInferenceForModel(defaultModel);
956
+ const baseRef = newBranchBaseRef();
957
+ exitApp({
958
+ branch: branch.name,
959
+ displayName: branch.displayName,
960
+ branchType: branch.branchType,
961
+ ...(branch.remoteBranch ? { remoteBranch: branch.remoteBranch } : {}),
962
+ ...(isNewBranch()
963
+ ? {
964
+ isNewBranch: true,
965
+ ...(baseRef ? { baseBranch: baseRef } : {}),
966
+ }
967
+ : {}),
968
+ tool,
969
+ mode: selectedMode(),
970
+ skipPermissions,
971
+ ...(normalizedModel !== undefined ? { model: normalizedModel } : {}),
972
+ ...(resolvedInference !== undefined
973
+ ? { inferenceLevel: resolvedInference }
974
+ : {}),
975
+ });
976
+ };
977
+ const renderCurrentScreen = () => {
978
+ const screen = currentScreen();
979
+ if (screen === "branch-list") {
980
+ const cleanupUI = {
981
+ indicators: cleanupIndicators(),
982
+ footerMessage: branchFooterMessage(),
983
+ inputLocked: branchInputLocked(),
984
+ safetyLoading: cleanupSafetyLoading(),
985
+ };
986
+ return (_jsx(BranchListScreen, { branches: branchItems(), stats: stats(), onSelect: handleBranchSelect, onQuit: () => exitApp(undefined), onCleanupCommand: handleCleanupCommand, onRefresh: refreshBranches, onRepairWorktrees: handleRepairWorktrees, loading: loading(), error: error(), loadingIndicatorDelay: props.loadingIndicatorDelay ?? 0, lastUpdated: stats().lastUpdated, version: version(), workingDirectory: workingDirectory(), activeProfile: activeProfile(), onOpenLogs: () => navigateTo("log-list"), onOpenProfiles: () => navigateTo("profile"), selectedBranches: selectedBranches(), onToggleSelect: toggleSelectedBranch, onCreateBranch: handleQuickCreate, cleanupUI: cleanupUI, helpVisible: helpVisible(), wizardVisible: wizardVisible() }));
987
+ }
988
+ if (screen === "tool-select") {
989
+ if (toolError()) {
990
+ return (_jsx(ErrorScreen, { error: toolError(), onBack: goBack, hint: "Unable to load available tools." }));
991
+ }
992
+ return (_jsx(SelectorScreen, { title: "Select tool", items: toolItems(), onSelect: handleToolSelect, onBack: goBack, helpVisible: helpVisible() }));
993
+ }
994
+ if (screen === "mode-select") {
995
+ return (_jsx(SelectorScreen, { title: "Execution mode", items: [
996
+ { label: "Normal", value: "normal" },
997
+ { label: "Continue", value: "continue" },
998
+ { label: "Resume", value: "resume" },
999
+ ], onSelect: handleModeSelect, onBack: goBack, helpVisible: helpVisible() }));
1000
+ }
1001
+ if (screen === "skip-permissions") {
1002
+ return (_jsx(SelectorScreen, { title: "Skip permission prompts?", items: [
1003
+ { label: "Yes", value: "true" },
1004
+ { label: "No", value: "false" },
1005
+ ], onSelect: (item) => finalizeSelection(item.value === "true"), onBack: goBack, helpVisible: helpVisible() }));
1006
+ }
1007
+ if (screen === "log-list") {
1008
+ return (_jsx(LogScreen, { entries: logEntries(), loading: logLoading(), error: logError(), onBack: goBack, onSelect: (entry) => {
1009
+ setLogSelectedEntry(entry);
1010
+ navigateTo("log-detail");
1011
+ }, onCopy: async (entry) => {
1012
+ try {
1013
+ await copyToClipboard(entry.json);
1014
+ showLogNotification("Copied to clipboard.", "success");
1015
+ }
1016
+ catch {
1017
+ showLogNotification("Failed to copy to clipboard.", "error");
1018
+ }
1019
+ }, notification: logNotification(), version: version(), selectedDate: logSelectedDate(), helpVisible: helpVisible() }));
1020
+ }
1021
+ if (screen === "log-detail") {
1022
+ return (_jsx(LogDetailScreen, { entry: logSelectedEntry(), onBack: goBack, onCopy: async (entry) => {
1023
+ try {
1024
+ await copyToClipboard(entry.json);
1025
+ showLogNotification("Copied to clipboard.", "success");
1026
+ }
1027
+ catch {
1028
+ showLogNotification("Failed to copy to clipboard.", "error");
1029
+ }
1030
+ }, notification: logNotification(), version: version(), helpVisible: helpVisible() }));
1031
+ }
1032
+ if (screen === "profile") {
1033
+ if (profileError()) {
1034
+ return (_jsx(ErrorScreen, { error: profileError(), onBack: goBack, hint: "Unable to load profiles." }));
1035
+ }
1036
+ return (_jsx(ProfileScreen, { profiles: profileItems(), version: version(), helpVisible: helpVisible(), onCreate: openProfileCreate, onDelete: openProfileDelete, onEdit: openProfileEnv, onSelect: (profile) => {
1037
+ void setActiveProfile(profile.name)
1038
+ .then(() => {
1039
+ void refreshProfiles();
1040
+ })
1041
+ .catch((err) => {
1042
+ openProfileError(err, "Unable to set active profile.");
1043
+ });
1044
+ }, onBack: goBack }));
1045
+ }
1046
+ if (screen === "profile-env") {
1047
+ const entry = selectedProfileConfig();
1048
+ if (!entry) {
1049
+ return (_jsx(ErrorScreen, { error: "Profile not found.", onBack: goBack, hint: "Select a profile before editing." }));
1050
+ }
1051
+ return (_jsx(ProfileEnvScreen, { profileName: entry.name, variables: profileEnvVariables(), onAdd: openProfileEnvAdd, onEdit: openProfileEnvEdit, onDelete: openProfileEnvDelete, onViewOsEnv: () => navigateTo("profile-os-env"), onBack: goBack, version: version(), helpVisible: helpVisible() }));
1052
+ }
1053
+ if (screen === "profile-input") {
1054
+ const mode = profileInputMode();
1055
+ const envKey = profileEnvKey();
1056
+ const message = mode === "create-profile"
1057
+ ? "New profile name"
1058
+ : mode === "add-env"
1059
+ ? "Add environment variable"
1060
+ : `Edit value for ${envKey ?? "(unknown)"}`;
1061
+ const label = mode === "create-profile"
1062
+ ? "Profile name"
1063
+ : mode === "add-env"
1064
+ ? "KEY=VALUE"
1065
+ : "Value";
1066
+ const placeholder = mode === "create-profile"
1067
+ ? "development"
1068
+ : mode === "add-env"
1069
+ ? "MY_VAR=value"
1070
+ : undefined;
1071
+ return (_jsx(InputScreen, { message: message, value: profileInputValue(), onChange: handleProfileInputChange, onSubmit: (value) => void submitProfileInput(value), onCancel: () => {
1072
+ setProfileInputSuppressKey(null);
1073
+ goBack();
1074
+ }, label: label, ...(placeholder !== undefined ? { placeholder } : {}), width: 32, helpVisible: helpVisible() }));
1075
+ }
1076
+ if (screen === "profile-confirm") {
1077
+ const mode = profileConfirmMode();
1078
+ const profileName = selectedProfileName();
1079
+ const envKey = profileEnvKey();
1080
+ const message = mode === "delete-profile"
1081
+ ? `Delete profile ${profileName ?? "(unknown)"}?`
1082
+ : `Delete ${envKey ?? "(unknown)"}?`;
1083
+ return (_jsx(ConfirmScreen, { message: message, onConfirm: (confirmed) => void confirmProfileAction(confirmed), defaultNo: true, helpVisible: helpVisible() }));
1084
+ }
1085
+ if (screen === "profile-os-env") {
1086
+ const highlightKeys = profileEnvVariables().map((variable) => variable.key);
1087
+ return (_jsx(EnvironmentScreen, { variables: osEnvVariables(), highlightKeys: highlightKeys, onBack: goBack, version: version(), helpVisible: helpVisible() }));
1088
+ }
1089
+ if (screen === "profile-error") {
1090
+ return (_jsx(ErrorScreen, { error: profileActionError() ?? "Profile error", onBack: () => {
1091
+ setProfileActionError(null);
1092
+ setProfileActionHint(null);
1093
+ goBack();
1094
+ }, ...(profileActionHint()
1095
+ ? { hint: profileActionHint() }
1096
+ : {}), helpVisible: helpVisible() }));
1097
+ }
1098
+ if (screen === "worktree-create") {
1099
+ const baseBranchRef = resolveBaseBranchRef(creationSource(), null, () => defaultBaseBranch());
1100
+ const baseBranchLabel = resolveBaseBranchLabel(creationSource(), null, () => defaultBaseBranch());
1101
+ return (_jsx(WorktreeCreateScreen, { branchName: createBranchName(), baseBranch: baseBranchLabel, version: version(), helpVisible: helpVisible(), onChange: (value) => {
1102
+ const suppressKey = suppressCreateKey();
1103
+ if (suppressKey &&
1104
+ createBranchName() === "" &&
1105
+ value === suppressKey) {
1106
+ setSuppressCreateKey(null);
1107
+ setCreateBranchName("");
1108
+ return;
1109
+ }
1110
+ setSuppressCreateKey(null);
1111
+ setCreateBranchName(value);
1112
+ }, onSubmit: (value, branchType) => {
1113
+ const trimmed = value.trim();
1114
+ if (!trimmed) {
1115
+ return;
1116
+ }
1117
+ // Add prefix based on selected branch type
1118
+ const prefixKey = branchType.toUpperCase();
1119
+ const prefix = BRANCH_PREFIXES[prefixKey] ?? "";
1120
+ const fullBranchName = `${prefix}${trimmed}`;
1121
+ setSelectedBranch({
1122
+ name: fullBranchName,
1123
+ displayName: fullBranchName,
1124
+ branchType: "local",
1125
+ branchCategory: branchType,
1126
+ });
1127
+ setIsNewBranch(true);
1128
+ setNewBranchBaseRef(baseBranchRef);
1129
+ setSelectedTool(null);
1130
+ setSelectedMode("normal");
1131
+ setSuppressCreateKey(null);
1132
+ navigateTo("tool-select");
1133
+ }, onCancel: () => {
1134
+ setSuppressCreateKey(null);
1135
+ goBack();
1136
+ } }));
1137
+ }
1138
+ if (screen === "loading") {
1139
+ return (_jsx(LoadingIndicatorScreen, { message: "Loading...", delay: props.loadingIndicatorDelay ?? 0 }));
1140
+ }
1141
+ if (screen === "error") {
1142
+ return (_jsx(ErrorScreen, { error: error() ?? "Unknown error", helpVisible: helpVisible() }));
1143
+ }
1144
+ return (_jsx(ErrorScreen, { error: `Unknown screen: ${screen}`, onBack: goBack, helpVisible: helpVisible() }));
1145
+ };
1146
+ return (_jsxs(_Fragment, { children: [renderCurrentScreen(), _jsx(HelpOverlay, { visible: helpVisible(), context: currentScreen() }), _jsx(WizardController, { visible: wizardVisible(), selectedBranchName: selectedBranch()?.name ?? "", history: historyForBranch(), onClose: handleWizardClose, onComplete: handleWizardComplete, onResume: handleWizardResume, onStartNew: handleWizardStartNew })] }));
1147
+ }
1148
+ const withTimeout = async (promise, timeoutMs) => new Promise((resolve, reject) => {
1149
+ const timer = setTimeout(() => {
1150
+ reject(new Error("timeout"));
1151
+ }, timeoutMs);
1152
+ promise
1153
+ .then((value) => {
1154
+ clearTimeout(timer);
1155
+ resolve(value);
1156
+ })
1157
+ .catch((err) => {
1158
+ clearTimeout(timer);
1159
+ reject(err);
1160
+ });
1161
+ });
1162
+ const buildBranchList = (branches, worktrees, lastToolUsageMap) => {
1163
+ const localBranchNames = new Set(branches.filter((branch) => branch.type === "local").map((b) => b.name));
1164
+ const filtered = branches.filter((branch) => {
1165
+ if (branch.type === "remote") {
1166
+ const remoteName = branch.name.replace(/^origin\//, "");
1167
+ return !localBranchNames.has(remoteName);
1168
+ }
1169
+ return true;
1170
+ });
1171
+ const worktreeMap = new Map();
1172
+ for (const worktree of worktrees) {
1173
+ worktreeMap.set(worktree.branch, {
1174
+ path: worktree.path,
1175
+ locked: worktree.locked ?? false,
1176
+ prunable: worktree.prunable ?? false,
1177
+ isAccessible: worktree.isAccessible ?? true,
1178
+ ...(worktree.hasUncommittedChanges !== undefined
1179
+ ? { hasUncommittedChanges: worktree.hasUncommittedChanges }
1180
+ : {}),
1181
+ });
1182
+ }
1183
+ const enriched = filtered.map((branch) => {
1184
+ const lastToolUsage = lastToolUsageMap?.get(branch.name);
1185
+ const baseBranch = lastToolUsage ? { ...branch, lastToolUsage } : branch;
1186
+ if (branch.type === "local") {
1187
+ const worktree = worktreeMap.get(branch.name);
1188
+ if (worktree) {
1189
+ return { ...baseBranch, worktree };
1190
+ }
1191
+ }
1192
+ return baseBranch;
1193
+ });
1194
+ const items = formatBranchItems(enriched, worktreeMap);
1195
+ return { items, worktreeMap };
1196
+ };
1197
+ //# sourceMappingURL=App.solid.js.map