@akiojin/gwt 4.10.0 → 4.11.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (579) hide show
  1. package/README.ja.md +4 -4
  2. package/README.md +4 -4
  3. package/dist/claude.d.ts +1 -0
  4. package/dist/claude.d.ts.map +1 -1
  5. package/dist/claude.js +52 -49
  6. package/dist/claude.js.map +1 -1
  7. package/dist/cli/ui/App.solid.d.ts +29 -0
  8. package/dist/cli/ui/App.solid.d.ts.map +1 -0
  9. package/dist/cli/ui/App.solid.js +1197 -0
  10. package/dist/cli/ui/App.solid.js.map +1 -0
  11. package/dist/cli/ui/components/solid/Footer.d.ts +10 -0
  12. package/dist/cli/ui/components/solid/Footer.d.ts.map +1 -0
  13. package/dist/cli/ui/components/solid/Footer.js +10 -0
  14. package/dist/cli/ui/components/solid/Footer.js.map +1 -0
  15. package/dist/cli/ui/components/{parts → solid}/Header.d.ts +1 -6
  16. package/dist/cli/ui/components/solid/Header.d.ts.map +1 -0
  17. package/dist/cli/ui/components/solid/Header.js +13 -0
  18. package/dist/cli/ui/components/solid/Header.js.map +1 -0
  19. package/dist/cli/ui/components/solid/HelpOverlay.d.ts +8 -0
  20. package/dist/cli/ui/components/solid/HelpOverlay.d.ts.map +1 -0
  21. package/dist/cli/ui/components/solid/HelpOverlay.js +118 -0
  22. package/dist/cli/ui/components/solid/HelpOverlay.js.map +1 -0
  23. package/dist/cli/ui/components/solid/QuickStartStep.d.ts +17 -0
  24. package/dist/cli/ui/components/solid/QuickStartStep.d.ts.map +1 -0
  25. package/dist/cli/ui/components/solid/QuickStartStep.js +139 -0
  26. package/dist/cli/ui/components/solid/QuickStartStep.js.map +1 -0
  27. package/dist/cli/ui/components/solid/SelectInput.d.ts +22 -0
  28. package/dist/cli/ui/components/solid/SelectInput.d.ts.map +1 -0
  29. package/dist/cli/ui/components/solid/SelectInput.js +44 -0
  30. package/dist/cli/ui/components/solid/SelectInput.js.map +1 -0
  31. package/dist/cli/ui/components/solid/TextInput.d.ts +12 -0
  32. package/dist/cli/ui/components/solid/TextInput.d.ts.map +1 -0
  33. package/dist/cli/ui/components/solid/TextInput.js +9 -0
  34. package/dist/cli/ui/components/solid/TextInput.js.map +1 -0
  35. package/dist/cli/ui/components/solid/WizardController.d.ts +34 -0
  36. package/dist/cli/ui/components/solid/WizardController.d.ts.map +1 -0
  37. package/dist/cli/ui/components/solid/WizardController.js +215 -0
  38. package/dist/cli/ui/components/solid/WizardController.js.map +1 -0
  39. package/dist/cli/ui/components/solid/WizardPopup.d.ts +26 -0
  40. package/dist/cli/ui/components/solid/WizardPopup.d.ts.map +1 -0
  41. package/dist/cli/ui/components/solid/WizardPopup.js +68 -0
  42. package/dist/cli/ui/components/solid/WizardPopup.js.map +1 -0
  43. package/dist/cli/ui/components/solid/WizardSteps.d.ts +52 -0
  44. package/dist/cli/ui/components/solid/WizardSteps.d.ts.map +1 -0
  45. package/dist/cli/ui/components/solid/WizardSteps.js +462 -0
  46. package/dist/cli/ui/components/solid/WizardSteps.js.map +1 -0
  47. package/dist/cli/ui/core/index.d.ts +12 -0
  48. package/dist/cli/ui/core/index.d.ts.map +1 -0
  49. package/dist/cli/ui/core/index.js +15 -0
  50. package/dist/cli/ui/core/index.js.map +1 -0
  51. package/dist/cli/ui/core/keybindings.d.ts +106 -0
  52. package/dist/cli/ui/core/keybindings.d.ts.map +1 -0
  53. package/dist/cli/ui/core/keybindings.js +270 -0
  54. package/dist/cli/ui/core/keybindings.js.map +1 -0
  55. package/dist/cli/ui/core/theme.d.ts +114 -0
  56. package/dist/cli/ui/core/theme.d.ts.map +1 -0
  57. package/dist/cli/ui/core/theme.js +170 -0
  58. package/dist/cli/ui/core/theme.js.map +1 -0
  59. package/dist/cli/ui/core/types.d.ts +156 -0
  60. package/dist/cli/ui/core/types.d.ts.map +1 -0
  61. package/dist/cli/ui/core/types.js +10 -0
  62. package/dist/cli/ui/core/types.js.map +1 -0
  63. package/dist/cli/ui/hooks/solid/useScrollableList.d.ts +26 -0
  64. package/dist/cli/ui/hooks/solid/useScrollableList.d.ts.map +1 -0
  65. package/dist/cli/ui/hooks/solid/useScrollableList.js +89 -0
  66. package/dist/cli/ui/hooks/solid/useScrollableList.js.map +1 -0
  67. package/dist/cli/ui/hooks/solid/useTerminalSize.d.ts +10 -0
  68. package/dist/cli/ui/hooks/solid/useTerminalSize.d.ts.map +1 -0
  69. package/dist/cli/ui/hooks/solid/useTerminalSize.js +16 -0
  70. package/dist/cli/ui/hooks/solid/useTerminalSize.js.map +1 -0
  71. package/dist/cli/ui/index.solid.d.ts +5 -0
  72. package/dist/cli/ui/index.solid.d.ts.map +1 -0
  73. package/dist/cli/ui/index.solid.js +21 -0
  74. package/dist/cli/ui/index.solid.js.map +1 -0
  75. package/dist/cli/ui/{components/screens → screens/solid}/BranchListScreen.d.ts +8 -22
  76. package/dist/cli/ui/screens/solid/BranchListScreen.d.ts.map +1 -0
  77. package/dist/cli/ui/screens/solid/BranchListScreen.js +756 -0
  78. package/dist/cli/ui/screens/solid/BranchListScreen.js.map +1 -0
  79. package/dist/cli/ui/screens/solid/ConfirmScreen.d.ts +10 -0
  80. package/dist/cli/ui/screens/solid/ConfirmScreen.d.ts.map +1 -0
  81. package/dist/cli/ui/screens/solid/ConfirmScreen.js +37 -0
  82. package/dist/cli/ui/screens/solid/ConfirmScreen.js.map +1 -0
  83. package/dist/cli/ui/screens/solid/EnvironmentScreen.d.ts +14 -0
  84. package/dist/cli/ui/screens/solid/EnvironmentScreen.d.ts.map +1 -0
  85. package/dist/cli/ui/screens/solid/EnvironmentScreen.js +91 -0
  86. package/dist/cli/ui/screens/solid/EnvironmentScreen.js.map +1 -0
  87. package/dist/cli/ui/screens/solid/ErrorScreen.d.ts +8 -0
  88. package/dist/cli/ui/screens/solid/ErrorScreen.d.ts.map +1 -0
  89. package/dist/cli/ui/screens/solid/ErrorScreen.js +18 -0
  90. package/dist/cli/ui/screens/solid/ErrorScreen.js.map +1 -0
  91. package/dist/cli/ui/screens/solid/InputScreen.d.ts +13 -0
  92. package/dist/cli/ui/screens/solid/InputScreen.d.ts.map +1 -0
  93. package/dist/cli/ui/screens/solid/InputScreen.js +17 -0
  94. package/dist/cli/ui/screens/solid/InputScreen.js.map +1 -0
  95. package/dist/cli/ui/screens/solid/LoadingIndicator.d.ts +9 -0
  96. package/dist/cli/ui/screens/solid/LoadingIndicator.d.ts.map +1 -0
  97. package/dist/cli/ui/screens/solid/LoadingIndicator.js +43 -0
  98. package/dist/cli/ui/screens/solid/LoadingIndicator.js.map +1 -0
  99. package/dist/cli/ui/{components/screens → screens/solid}/LogDetailScreen.d.ts +2 -2
  100. package/dist/cli/ui/screens/solid/LogDetailScreen.d.ts.map +1 -0
  101. package/dist/cli/ui/screens/solid/LogDetailScreen.js +34 -0
  102. package/dist/cli/ui/screens/solid/LogDetailScreen.js.map +1 -0
  103. package/dist/cli/ui/{components/screens/LogListScreen.d.ts → screens/solid/LogScreen.d.ts} +4 -4
  104. package/dist/cli/ui/screens/solid/LogScreen.d.ts.map +1 -0
  105. package/dist/cli/ui/screens/solid/LogScreen.js +95 -0
  106. package/dist/cli/ui/screens/solid/LogScreen.js.map +1 -0
  107. package/dist/cli/ui/screens/solid/ProfileEnvScreen.d.ts +17 -0
  108. package/dist/cli/ui/screens/solid/ProfileEnvScreen.d.ts.map +1 -0
  109. package/dist/cli/ui/screens/solid/ProfileEnvScreen.js +112 -0
  110. package/dist/cli/ui/screens/solid/ProfileEnvScreen.js.map +1 -0
  111. package/dist/cli/ui/screens/solid/ProfileScreen.d.ts +17 -0
  112. package/dist/cli/ui/screens/solid/ProfileScreen.d.ts.map +1 -0
  113. package/dist/cli/ui/screens/solid/ProfileScreen.js +50 -0
  114. package/dist/cli/ui/screens/solid/ProfileScreen.js.map +1 -0
  115. package/dist/cli/ui/screens/solid/SelectorScreen.d.ts +20 -0
  116. package/dist/cli/ui/screens/solid/SelectorScreen.d.ts.map +1 -0
  117. package/dist/cli/ui/screens/solid/SelectorScreen.js +90 -0
  118. package/dist/cli/ui/screens/solid/SelectorScreen.js.map +1 -0
  119. package/dist/cli/ui/screens/solid/WorktreeCreateScreen.d.ts +13 -0
  120. package/dist/cli/ui/screens/solid/WorktreeCreateScreen.d.ts.map +1 -0
  121. package/dist/cli/ui/screens/solid/WorktreeCreateScreen.js +59 -0
  122. package/dist/cli/ui/screens/solid/WorktreeCreateScreen.js.map +1 -0
  123. package/dist/cli/ui/stores/appStore.d.ts +143 -0
  124. package/dist/cli/ui/stores/appStore.d.ts.map +1 -0
  125. package/dist/cli/ui/stores/appStore.js +158 -0
  126. package/dist/cli/ui/stores/appStore.js.map +1 -0
  127. package/dist/cli/ui/stores/branchStore.d.ts +159 -0
  128. package/dist/cli/ui/stores/branchStore.d.ts.map +1 -0
  129. package/dist/cli/ui/stores/branchStore.js +275 -0
  130. package/dist/cli/ui/stores/branchStore.js.map +1 -0
  131. package/dist/cli/ui/stores/index.d.ts +11 -0
  132. package/dist/cli/ui/stores/index.d.ts.map +1 -0
  133. package/dist/cli/ui/stores/index.js +14 -0
  134. package/dist/cli/ui/stores/index.js.map +1 -0
  135. package/dist/cli/ui/stores/uiStore.d.ts +146 -0
  136. package/dist/cli/ui/stores/uiStore.d.ts.map +1 -0
  137. package/dist/cli/ui/stores/uiStore.js +166 -0
  138. package/dist/cli/ui/stores/uiStore.js.map +1 -0
  139. package/dist/cli/ui/types.d.ts +16 -1
  140. package/dist/cli/ui/types.d.ts.map +1 -1
  141. package/dist/cli/ui/utils/branchFormatter.d.ts.map +1 -1
  142. package/dist/cli/ui/utils/branchFormatter.js +7 -210
  143. package/dist/cli/ui/utils/branchFormatter.js.map +1 -1
  144. package/dist/cli/ui/utils/continueSession.d.ts +4 -0
  145. package/dist/cli/ui/utils/continueSession.d.ts.map +1 -1
  146. package/dist/cli/ui/utils/continueSession.js +30 -0
  147. package/dist/cli/ui/utils/continueSession.js.map +1 -1
  148. package/dist/client/assets/{index-ChHC-Puh.css → index-BbfV7Wuj.css} +1 -1
  149. package/dist/client/assets/index-CoAyq5x1.js +78 -0
  150. package/dist/client/index.html +2 -2
  151. package/dist/codex.d.ts +1 -0
  152. package/dist/codex.d.ts.map +1 -1
  153. package/dist/codex.js +86 -45
  154. package/dist/codex.js.map +1 -1
  155. package/dist/config/builtin-coding-agents.js +4 -4
  156. package/dist/config/builtin-coding-agents.js.map +1 -1
  157. package/dist/config/index.d.ts +2 -0
  158. package/dist/config/index.d.ts.map +1 -1
  159. package/dist/config/index.js +2 -0
  160. package/dist/config/index.js.map +1 -1
  161. package/dist/gemini.d.ts +1 -0
  162. package/dist/gemini.d.ts.map +1 -1
  163. package/dist/gemini.js +42 -37
  164. package/dist/gemini.js.map +1 -1
  165. package/dist/index.d.ts +1 -1
  166. package/dist/index.d.ts.map +1 -1
  167. package/dist/index.js +122 -102
  168. package/dist/index.js.map +1 -1
  169. package/dist/launcher.d.ts.map +1 -1
  170. package/dist/launcher.js +18 -3
  171. package/dist/launcher.js.map +1 -1
  172. package/dist/logging/logger.d.ts.map +1 -1
  173. package/dist/logging/logger.js +26 -9
  174. package/dist/logging/logger.js.map +1 -1
  175. package/dist/opentui/highlights-eq9cgrbb.scm +604 -0
  176. package/dist/opentui/highlights-ghv9g403.scm +205 -0
  177. package/dist/opentui/highlights-hk7bwhj4.scm +284 -0
  178. package/dist/opentui/highlights-r812a2qc.scm +150 -0
  179. package/dist/opentui/highlights-x6tmsnaa.scm +115 -0
  180. package/dist/opentui/index.solid.d.ts +2 -0
  181. package/dist/opentui/index.solid.d.ts.map +1 -0
  182. package/dist/opentui/index.solid.js +52034 -0
  183. package/dist/opentui/index.solid.js.map +1 -0
  184. package/dist/opentui/injections-73j83es3.scm +27 -0
  185. package/dist/opentui/tree-sitter-javascript-nd0q4pe9.wasm +0 -0
  186. package/dist/opentui/tree-sitter-markdown-411r6y9b.wasm +0 -0
  187. package/dist/opentui/tree-sitter-markdown_inline-j5349f42.wasm +0 -0
  188. package/dist/opentui/tree-sitter-typescript-zxjzwt75.wasm +0 -0
  189. package/dist/opentui/tree-sitter-zig-e78zbjpm.wasm +0 -0
  190. package/dist/repositories/worktree.repository.d.ts +1 -0
  191. package/dist/repositories/worktree.repository.d.ts.map +1 -1
  192. package/dist/repositories/worktree.repository.js +7 -0
  193. package/dist/repositories/worktree.repository.js.map +1 -1
  194. package/dist/services/codingAgentResolver.d.ts +2 -0
  195. package/dist/services/codingAgentResolver.d.ts.map +1 -1
  196. package/dist/services/codingAgentResolver.js +30 -4
  197. package/dist/services/codingAgentResolver.js.map +1 -1
  198. package/dist/services/dependency-installer.d.ts.map +1 -1
  199. package/dist/services/dependency-installer.js +0 -5
  200. package/dist/services/dependency-installer.js.map +1 -1
  201. package/dist/types/api.d.ts +3 -0
  202. package/dist/types/api.d.ts.map +1 -1
  203. package/dist/types/coding-agent.d.ts +62 -0
  204. package/dist/types/coding-agent.d.ts.map +1 -0
  205. package/dist/types/coding-agent.js +29 -0
  206. package/dist/types/coding-agent.js.map +1 -0
  207. package/dist/types/tools.d.ts +17 -0
  208. package/dist/types/tools.d.ts.map +1 -1
  209. package/dist/utils/coding-agent-colors.d.ts +88 -0
  210. package/dist/utils/coding-agent-colors.d.ts.map +1 -0
  211. package/dist/utils/coding-agent-colors.js +137 -0
  212. package/dist/utils/coding-agent-colors.js.map +1 -0
  213. package/dist/utils/command.d.ts +1 -1
  214. package/dist/utils/command.js +1 -1
  215. package/dist/utils/error-utils.d.ts +27 -0
  216. package/dist/utils/error-utils.d.ts.map +1 -0
  217. package/dist/utils/error-utils.js +98 -0
  218. package/dist/utils/error-utils.js.map +1 -0
  219. package/dist/utils/npmRegistry.d.ts +61 -0
  220. package/dist/utils/npmRegistry.d.ts.map +1 -0
  221. package/dist/utils/npmRegistry.js +180 -0
  222. package/dist/utils/npmRegistry.js.map +1 -0
  223. package/dist/utils/prompt.d.ts +1 -1
  224. package/dist/utils/prompt.js +1 -1
  225. package/dist/utils/session/parsers/codex.d.ts.map +1 -1
  226. package/dist/utils/session/parsers/codex.js +8 -1
  227. package/dist/utils/session/parsers/codex.js.map +1 -1
  228. package/dist/utils/terminal.d.ts +1 -0
  229. package/dist/utils/terminal.d.ts.map +1 -1
  230. package/dist/utils/terminal.js +20 -0
  231. package/dist/utils/terminal.js.map +1 -1
  232. package/dist/utils.d.ts +9 -0
  233. package/dist/utils.d.ts.map +1 -1
  234. package/dist/utils.js +33 -2
  235. package/dist/utils.js.map +1 -1
  236. package/dist/web/client/src/components/CodingAgentLaunchModal.d.ts.map +1 -1
  237. package/dist/web/client/src/components/CodingAgentLaunchModal.js +7 -16
  238. package/dist/web/client/src/components/CodingAgentLaunchModal.js.map +1 -1
  239. package/dist/web/client/src/components/branch-detail/BranchInfoCards.d.ts.map +1 -1
  240. package/dist/web/client/src/components/branch-detail/BranchInfoCards.js +7 -2
  241. package/dist/web/client/src/components/branch-detail/BranchInfoCards.js.map +1 -1
  242. package/dist/web/client/src/components/branch-detail/SessionHistoryTable.d.ts.map +1 -1
  243. package/dist/web/client/src/components/branch-detail/SessionHistoryTable.js +2 -1
  244. package/dist/web/client/src/components/branch-detail/SessionHistoryTable.js.map +1 -1
  245. package/dist/web/client/src/components/branch-detail/ToolLauncher.d.ts +2 -2
  246. package/dist/web/client/src/components/branch-detail/ToolLauncher.d.ts.map +1 -1
  247. package/dist/web/client/src/components/branch-detail/ToolLauncher.js +5 -5
  248. package/dist/web/client/src/components/branch-detail/ToolLauncher.js.map +1 -1
  249. package/dist/web/client/src/lib/coding-agent-colors.d.ts +86 -0
  250. package/dist/web/client/src/lib/coding-agent-colors.d.ts.map +1 -0
  251. package/dist/web/client/src/lib/coding-agent-colors.js +135 -0
  252. package/dist/web/client/src/lib/coding-agent-colors.js.map +1 -0
  253. package/dist/web/client/src/pages/BranchDetailPage.js +10 -10
  254. package/dist/web/client/src/pages/BranchDetailPage.js.map +1 -1
  255. package/dist/web/server/pty/manager.d.ts +2 -0
  256. package/dist/web/server/pty/manager.d.ts.map +1 -1
  257. package/dist/web/server/pty/manager.js +104 -0
  258. package/dist/web/server/pty/manager.js.map +1 -1
  259. package/dist/web/server/routes/sessions.d.ts.map +1 -1
  260. package/dist/web/server/routes/sessions.js +5 -1
  261. package/dist/web/server/routes/sessions.js.map +1 -1
  262. package/dist/web/server/services/branches.d.ts.map +1 -1
  263. package/dist/web/server/services/branches.js +10 -8
  264. package/dist/web/server/services/branches.js.map +1 -1
  265. package/dist/web/server/services/worktrees.js +2 -2
  266. package/dist/web/server/services/worktrees.js.map +1 -1
  267. package/dist/worktree.d.ts +47 -1
  268. package/dist/worktree.d.ts.map +1 -1
  269. package/dist/worktree.js +280 -94
  270. package/dist/worktree.js.map +1 -1
  271. package/package.json +12 -14
  272. package/src/claude.ts +68 -70
  273. package/src/cli/ui/App.solid.tsx +1823 -0
  274. package/src/cli/ui/__tests__/solid/AppSolid.cleanup.test.tsx +255 -0
  275. package/src/cli/ui/__tests__/solid/BranchListScreen.test.tsx +243 -0
  276. package/src/cli/ui/__tests__/solid/components/QuickStartStep.test.tsx +237 -0
  277. package/src/cli/ui/__tests__/solid/components/WizardPopup.test.tsx +231 -0
  278. package/src/cli/ui/__tests__/solid/components/WizardSteps.test.tsx +238 -0
  279. package/src/cli/ui/__tests__/utils/branchFormatter.test.ts +7 -289
  280. package/src/cli/ui/__tests__/utils/clipboard.test.ts +3 -3
  281. package/src/cli/ui/__tests__/utils/statisticsCalculator.test.ts +1 -1
  282. package/src/cli/ui/components/solid/Footer.tsx +36 -0
  283. package/src/cli/ui/components/{parts → solid}/Header.tsx +17 -28
  284. package/src/cli/ui/components/solid/HelpOverlay.tsx +194 -0
  285. package/src/cli/ui/components/solid/QuickStartStep.tsx +197 -0
  286. package/src/cli/ui/components/{parts → solid}/ScrollableList.tsx +7 -8
  287. package/src/cli/ui/components/solid/SearchInput.tsx +42 -0
  288. package/src/cli/ui/components/solid/SelectInput.tsx +84 -0
  289. package/src/cli/ui/components/solid/Stats.tsx +92 -0
  290. package/src/cli/ui/components/solid/TextInput.tsx +49 -0
  291. package/src/cli/ui/components/solid/WizardController.tsx +384 -0
  292. package/src/cli/ui/components/solid/WizardPopup.tsx +135 -0
  293. package/src/cli/ui/components/solid/WizardSteps.tsx +793 -0
  294. package/src/cli/ui/core/index.ts +17 -0
  295. package/src/cli/ui/core/keybindings.ts +367 -0
  296. package/src/cli/ui/core/theme.ts +234 -0
  297. package/src/cli/ui/core/types.ts +235 -0
  298. package/src/cli/ui/hooks/solid/useAsyncOperation.ts +76 -0
  299. package/src/cli/ui/hooks/solid/useFilter.ts +86 -0
  300. package/src/cli/ui/hooks/solid/useGitOperations.ts +80 -0
  301. package/src/cli/ui/hooks/solid/useKeyHandler.ts +103 -0
  302. package/src/cli/ui/hooks/solid/useScrollableList.ts +149 -0
  303. package/src/cli/ui/hooks/solid/useSelection.ts +77 -0
  304. package/src/cli/ui/hooks/solid/useTerminalSize.ts +22 -0
  305. package/src/cli/ui/index.solid.ts +28 -0
  306. package/src/cli/ui/screens/solid/BranchListScreen.tsx +1050 -0
  307. package/src/cli/ui/screens/solid/ConfirmScreen.tsx +74 -0
  308. package/src/cli/ui/screens/solid/EnvironmentScreen.tsx +159 -0
  309. package/src/cli/ui/screens/solid/ErrorScreen.tsx +42 -0
  310. package/src/cli/ui/screens/solid/InputScreen.tsx +55 -0
  311. package/src/cli/ui/screens/solid/LoadingIndicator.tsx +77 -0
  312. package/src/cli/ui/screens/solid/LogDetailScreen.tsx +75 -0
  313. package/src/cli/ui/screens/solid/LogScreen.tsx +175 -0
  314. package/src/cli/ui/screens/solid/ProfileEnvScreen.tsx +192 -0
  315. package/src/cli/ui/screens/solid/ProfileScreen.tsx +98 -0
  316. package/src/cli/ui/screens/solid/SelectorScreen.tsx +170 -0
  317. package/src/cli/ui/screens/solid/SettingsScreen.tsx +50 -0
  318. package/src/cli/ui/screens/solid/WorktreeCreateScreen.tsx +136 -0
  319. package/src/cli/ui/screens/solid/WorktreeDeleteScreen.tsx +40 -0
  320. package/src/cli/ui/stores/appStore.ts +208 -0
  321. package/src/cli/ui/stores/branchStore.ts +357 -0
  322. package/src/cli/ui/stores/index.ts +31 -0
  323. package/src/cli/ui/stores/uiStore.ts +226 -0
  324. package/src/cli/ui/types.ts +20 -3
  325. package/src/cli/ui/utils/__tests__/branchFormatter.test.ts +180 -0
  326. package/src/cli/ui/utils/branchFormatter.ts +8 -215
  327. package/src/cli/ui/utils/continueSession.ts +44 -0
  328. package/src/cli/ui/utils/modelOptions.test.ts +1 -1
  329. package/src/codex.ts +100 -43
  330. package/src/config/__tests__/saveSession.test.ts +143 -0
  331. package/src/config/builtin-coding-agents.ts +4 -4
  332. package/src/config/index.ts +4 -0
  333. package/src/gemini.ts +58 -43
  334. package/src/index.test.ts +12 -12
  335. package/src/index.ts +164 -142
  336. package/src/launcher.ts +22 -3
  337. package/src/logging/logger.ts +32 -10
  338. package/src/opentui/index.solid.ts +1 -0
  339. package/src/repositories/worktree.repository.ts +8 -0
  340. package/src/services/__tests__/BatchMergeService.test.ts +62 -66
  341. package/src/services/__tests__/WorktreeOrchestrator.test.ts +8 -7
  342. package/src/services/codingAgentResolver.ts +30 -4
  343. package/src/services/dependency-installer.ts +0 -7
  344. package/src/types/api.ts +3 -0
  345. package/src/types/coding-agent.ts +85 -0
  346. package/src/types/tools.ts +19 -0
  347. package/src/utils/__tests__/npmRegistry.test.ts +250 -0
  348. package/src/utils/__tests__/prompt.test.ts +4 -5
  349. package/src/utils/coding-agent-colors.ts +165 -0
  350. package/src/utils/command.ts +1 -1
  351. package/src/utils/error-utils.ts +133 -0
  352. package/src/utils/npmRegistry.ts +249 -0
  353. package/src/utils/prompt.ts +1 -1
  354. package/src/utils/session/parsers/codex.ts +9 -1
  355. package/src/utils/terminal.ts +24 -0
  356. package/src/utils.test.ts +1 -1
  357. package/src/utils.ts +37 -4
  358. package/src/web/client/src/components/CodingAgentLaunchModal.tsx +12 -21
  359. package/src/web/client/src/components/branch-detail/BranchInfoCards.tsx +16 -1
  360. package/src/web/client/src/components/branch-detail/SessionHistoryTable.tsx +7 -1
  361. package/src/web/client/src/components/branch-detail/ToolLauncher.tsx +11 -6
  362. package/src/web/client/src/lib/coding-agent-colors.ts +149 -0
  363. package/src/web/client/src/pages/BranchDetailPage.tsx +11 -11
  364. package/src/web/server/pty/manager.ts +139 -0
  365. package/src/web/server/routes/sessions.ts +6 -0
  366. package/src/web/server/services/branches.ts +11 -8
  367. package/src/web/server/services/worktrees.ts +2 -2
  368. package/src/worktree.ts +366 -107
  369. package/dist/cli/ui/components/App.d.ts +0 -25
  370. package/dist/cli/ui/components/App.d.ts.map +0 -1
  371. package/dist/cli/ui/components/App.js +0 -1006
  372. package/dist/cli/ui/components/App.js.map +0 -1
  373. package/dist/cli/ui/components/common/Confirm.d.ts +0 -13
  374. package/dist/cli/ui/components/common/Confirm.d.ts.map +0 -1
  375. package/dist/cli/ui/components/common/Confirm.js +0 -20
  376. package/dist/cli/ui/components/common/Confirm.js.map +0 -1
  377. package/dist/cli/ui/components/common/ErrorBoundary.d.ts +0 -23
  378. package/dist/cli/ui/components/common/ErrorBoundary.d.ts.map +0 -1
  379. package/dist/cli/ui/components/common/ErrorBoundary.js +0 -37
  380. package/dist/cli/ui/components/common/ErrorBoundary.js.map +0 -1
  381. package/dist/cli/ui/components/common/Input.d.ts +0 -19
  382. package/dist/cli/ui/components/common/Input.d.ts.map +0 -1
  383. package/dist/cli/ui/components/common/Input.js +0 -22
  384. package/dist/cli/ui/components/common/Input.js.map +0 -1
  385. package/dist/cli/ui/components/common/LoadingIndicator.d.ts +0 -19
  386. package/dist/cli/ui/components/common/LoadingIndicator.d.ts.map +0 -1
  387. package/dist/cli/ui/components/common/LoadingIndicator.js +0 -61
  388. package/dist/cli/ui/components/common/LoadingIndicator.js.map +0 -1
  389. package/dist/cli/ui/components/common/Select.d.ts +0 -38
  390. package/dist/cli/ui/components/common/Select.d.ts.map +0 -1
  391. package/dist/cli/ui/components/common/Select.js +0 -151
  392. package/dist/cli/ui/components/common/Select.js.map +0 -1
  393. package/dist/cli/ui/components/common/SpinnerIcon.d.ts +0 -20
  394. package/dist/cli/ui/components/common/SpinnerIcon.d.ts.map +0 -1
  395. package/dist/cli/ui/components/common/SpinnerIcon.js +0 -61
  396. package/dist/cli/ui/components/common/SpinnerIcon.js.map +0 -1
  397. package/dist/cli/ui/components/parts/Footer.d.ts +0 -15
  398. package/dist/cli/ui/components/parts/Footer.d.ts.map +0 -1
  399. package/dist/cli/ui/components/parts/Footer.js +0 -20
  400. package/dist/cli/ui/components/parts/Footer.js.map +0 -1
  401. package/dist/cli/ui/components/parts/Header.d.ts.map +0 -1
  402. package/dist/cli/ui/components/parts/Header.js +0 -24
  403. package/dist/cli/ui/components/parts/Header.js.map +0 -1
  404. package/dist/cli/ui/components/parts/MergeStatusList.d.ts +0 -13
  405. package/dist/cli/ui/components/parts/MergeStatusList.d.ts.map +0 -1
  406. package/dist/cli/ui/components/parts/MergeStatusList.js +0 -52
  407. package/dist/cli/ui/components/parts/MergeStatusList.js.map +0 -1
  408. package/dist/cli/ui/components/parts/ProgressBar.d.ts +0 -13
  409. package/dist/cli/ui/components/parts/ProgressBar.d.ts.map +0 -1
  410. package/dist/cli/ui/components/parts/ProgressBar.js +0 -53
  411. package/dist/cli/ui/components/parts/ProgressBar.js.map +0 -1
  412. package/dist/cli/ui/components/parts/ScrollableList.d.ts +0 -12
  413. package/dist/cli/ui/components/parts/ScrollableList.d.ts.map +0 -1
  414. package/dist/cli/ui/components/parts/ScrollableList.js +0 -11
  415. package/dist/cli/ui/components/parts/ScrollableList.js.map +0 -1
  416. package/dist/cli/ui/components/parts/Stats.d.ts +0 -10
  417. package/dist/cli/ui/components/parts/Stats.d.ts.map +0 -1
  418. package/dist/cli/ui/components/parts/Stats.js +0 -55
  419. package/dist/cli/ui/components/parts/Stats.js.map +0 -1
  420. package/dist/cli/ui/components/screens/BatchMergeProgressScreen.d.ts +0 -17
  421. package/dist/cli/ui/components/screens/BatchMergeProgressScreen.d.ts.map +0 -1
  422. package/dist/cli/ui/components/screens/BatchMergeProgressScreen.js +0 -42
  423. package/dist/cli/ui/components/screens/BatchMergeProgressScreen.js.map +0 -1
  424. package/dist/cli/ui/components/screens/BatchMergeResultScreen.d.ts +0 -17
  425. package/dist/cli/ui/components/screens/BatchMergeResultScreen.d.ts.map +0 -1
  426. package/dist/cli/ui/components/screens/BatchMergeResultScreen.js +0 -72
  427. package/dist/cli/ui/components/screens/BatchMergeResultScreen.js.map +0 -1
  428. package/dist/cli/ui/components/screens/BranchCreatorScreen.d.ts +0 -18
  429. package/dist/cli/ui/components/screens/BranchCreatorScreen.d.ts.map +0 -1
  430. package/dist/cli/ui/components/screens/BranchCreatorScreen.js +0 -151
  431. package/dist/cli/ui/components/screens/BranchCreatorScreen.js.map +0 -1
  432. package/dist/cli/ui/components/screens/BranchListScreen.d.ts.map +0 -1
  433. package/dist/cli/ui/components/screens/BranchListScreen.js +0 -476
  434. package/dist/cli/ui/components/screens/BranchListScreen.js.map +0 -1
  435. package/dist/cli/ui/components/screens/BranchQuickStartScreen.d.ts +0 -30
  436. package/dist/cli/ui/components/screens/BranchQuickStartScreen.d.ts.map +0 -1
  437. package/dist/cli/ui/components/screens/BranchQuickStartScreen.js +0 -148
  438. package/dist/cli/ui/components/screens/BranchQuickStartScreen.js.map +0 -1
  439. package/dist/cli/ui/components/screens/CodingAgentSelectorScreen.d.ts +0 -27
  440. package/dist/cli/ui/components/screens/CodingAgentSelectorScreen.d.ts.map +0 -1
  441. package/dist/cli/ui/components/screens/CodingAgentSelectorScreen.js +0 -93
  442. package/dist/cli/ui/components/screens/CodingAgentSelectorScreen.js.map +0 -1
  443. package/dist/cli/ui/components/screens/EnvironmentProfileScreen.d.ts +0 -19
  444. package/dist/cli/ui/components/screens/EnvironmentProfileScreen.d.ts.map +0 -1
  445. package/dist/cli/ui/components/screens/EnvironmentProfileScreen.js +0 -577
  446. package/dist/cli/ui/components/screens/EnvironmentProfileScreen.js.map +0 -1
  447. package/dist/cli/ui/components/screens/ExecutionModeSelectorScreen.d.ts +0 -45
  448. package/dist/cli/ui/components/screens/ExecutionModeSelectorScreen.d.ts.map +0 -1
  449. package/dist/cli/ui/components/screens/ExecutionModeSelectorScreen.js +0 -95
  450. package/dist/cli/ui/components/screens/ExecutionModeSelectorScreen.js.map +0 -1
  451. package/dist/cli/ui/components/screens/LogDatePickerScreen.d.ts +0 -10
  452. package/dist/cli/ui/components/screens/LogDatePickerScreen.d.ts.map +0 -1
  453. package/dist/cli/ui/components/screens/LogDatePickerScreen.js +0 -44
  454. package/dist/cli/ui/components/screens/LogDatePickerScreen.js.map +0 -1
  455. package/dist/cli/ui/components/screens/LogDetailScreen.d.ts.map +0 -1
  456. package/dist/cli/ui/components/screens/LogDetailScreen.js +0 -34
  457. package/dist/cli/ui/components/screens/LogDetailScreen.js.map +0 -1
  458. package/dist/cli/ui/components/screens/LogListScreen.d.ts.map +0 -1
  459. package/dist/cli/ui/components/screens/LogListScreen.js +0 -107
  460. package/dist/cli/ui/components/screens/LogListScreen.js.map +0 -1
  461. package/dist/cli/ui/components/screens/ModelSelectorScreen.d.ts +0 -24
  462. package/dist/cli/ui/components/screens/ModelSelectorScreen.d.ts.map +0 -1
  463. package/dist/cli/ui/components/screens/ModelSelectorScreen.js +0 -197
  464. package/dist/cli/ui/components/screens/ModelSelectorScreen.js.map +0 -1
  465. package/dist/cli/ui/components/screens/PRCleanupScreen.d.ts +0 -29
  466. package/dist/cli/ui/components/screens/PRCleanupScreen.d.ts.map +0 -1
  467. package/dist/cli/ui/components/screens/PRCleanupScreen.js +0 -92
  468. package/dist/cli/ui/components/screens/PRCleanupScreen.js.map +0 -1
  469. package/dist/cli/ui/components/screens/SessionSelectorScreen.d.ts +0 -31
  470. package/dist/cli/ui/components/screens/SessionSelectorScreen.d.ts.map +0 -1
  471. package/dist/cli/ui/components/screens/SessionSelectorScreen.js +0 -67
  472. package/dist/cli/ui/components/screens/SessionSelectorScreen.js.map +0 -1
  473. package/dist/cli/ui/hooks/useAppInput.d.ts +0 -21
  474. package/dist/cli/ui/hooks/useAppInput.d.ts.map +0 -1
  475. package/dist/cli/ui/hooks/useAppInput.js +0 -138
  476. package/dist/cli/ui/hooks/useAppInput.js.map +0 -1
  477. package/dist/cli/ui/hooks/useBatchMerge.d.ts +0 -17
  478. package/dist/cli/ui/hooks/useBatchMerge.d.ts.map +0 -1
  479. package/dist/cli/ui/hooks/useBatchMerge.js +0 -77
  480. package/dist/cli/ui/hooks/useBatchMerge.js.map +0 -1
  481. package/dist/cli/ui/hooks/useGitData.d.ts +0 -21
  482. package/dist/cli/ui/hooks/useGitData.d.ts.map +0 -1
  483. package/dist/cli/ui/hooks/useGitData.js +0 -229
  484. package/dist/cli/ui/hooks/useGitData.js.map +0 -1
  485. package/dist/cli/ui/hooks/useProfiles.d.ts +0 -41
  486. package/dist/cli/ui/hooks/useProfiles.d.ts.map +0 -1
  487. package/dist/cli/ui/hooks/useProfiles.js +0 -136
  488. package/dist/cli/ui/hooks/useProfiles.js.map +0 -1
  489. package/dist/cli/ui/hooks/useScreenState.d.ts +0 -12
  490. package/dist/cli/ui/hooks/useScreenState.d.ts.map +0 -1
  491. package/dist/cli/ui/hooks/useScreenState.js +0 -30
  492. package/dist/cli/ui/hooks/useScreenState.js.map +0 -1
  493. package/dist/cli/ui/hooks/useTerminalSize.d.ts +0 -9
  494. package/dist/cli/ui/hooks/useTerminalSize.d.ts.map +0 -1
  495. package/dist/cli/ui/hooks/useTerminalSize.js +0 -24
  496. package/dist/cli/ui/hooks/useTerminalSize.js.map +0 -1
  497. package/dist/cli/ui/hooks/useToolStatus.d.ts +0 -30
  498. package/dist/cli/ui/hooks/useToolStatus.d.ts.map +0 -1
  499. package/dist/cli/ui/hooks/useToolStatus.js +0 -49
  500. package/dist/cli/ui/hooks/useToolStatus.js.map +0 -1
  501. package/dist/cli/ui/screens/BranchActionSelectorScreen.d.ts +0 -24
  502. package/dist/cli/ui/screens/BranchActionSelectorScreen.d.ts.map +0 -1
  503. package/dist/cli/ui/screens/BranchActionSelectorScreen.js +0 -65
  504. package/dist/cli/ui/screens/BranchActionSelectorScreen.js.map +0 -1
  505. package/dist/client/assets/index-LNPtOrn3.js +0 -78
  506. package/src/cli/ui/__tests__/SKIPPED_TESTS.md +0 -119
  507. package/src/cli/ui/__tests__/acceptance/branchList.acceptance.test.tsx.skip +0 -239
  508. package/src/cli/ui/__tests__/acceptance/navigation.acceptance.test.tsx +0 -225
  509. package/src/cli/ui/__tests__/acceptance/realtimeUpdate.acceptance.test.tsx.skip +0 -219
  510. package/src/cli/ui/__tests__/components/App.protected-branch.test.tsx +0 -212
  511. package/src/cli/ui/__tests__/components/App.shortcuts.test.tsx +0 -440
  512. package/src/cli/ui/__tests__/components/App.test.tsx +0 -365
  513. package/src/cli/ui/__tests__/components/ModelSelectorScreen.initial.test.tsx +0 -91
  514. package/src/cli/ui/__tests__/components/common/Confirm.test.tsx +0 -80
  515. package/src/cli/ui/__tests__/components/common/ErrorBoundary.test.tsx +0 -104
  516. package/src/cli/ui/__tests__/components/common/Input.test.tsx +0 -100
  517. package/src/cli/ui/__tests__/components/common/LoadingIndicator.test.tsx +0 -148
  518. package/src/cli/ui/__tests__/components/common/Select.memo.test.tsx +0 -255
  519. package/src/cli/ui/__tests__/components/common/Select.test.tsx +0 -335
  520. package/src/cli/ui/__tests__/components/parts/Footer.test.tsx +0 -65
  521. package/src/cli/ui/__tests__/components/parts/Header.test.tsx +0 -55
  522. package/src/cli/ui/__tests__/components/parts/ScrollableList.test.tsx +0 -69
  523. package/src/cli/ui/__tests__/components/parts/Stats.test.tsx +0 -148
  524. package/src/cli/ui/__tests__/components/screens/BranchCreatorScreen.test.tsx +0 -253
  525. package/src/cli/ui/__tests__/components/screens/BranchListScreen.test.tsx +0 -1070
  526. package/src/cli/ui/__tests__/components/screens/BranchQuickStartScreen.test.tsx +0 -142
  527. package/src/cli/ui/__tests__/components/screens/CodingAgentSelectorScreen.test.tsx +0 -174
  528. package/src/cli/ui/__tests__/components/screens/ExecutionModeSelectorScreen.test.tsx +0 -182
  529. package/src/cli/ui/__tests__/components/screens/LogDetailScreen.test.tsx +0 -57
  530. package/src/cli/ui/__tests__/components/screens/LogListScreen.test.tsx +0 -102
  531. package/src/cli/ui/__tests__/components/screens/PRCleanupScreen.test.tsx +0 -216
  532. package/src/cli/ui/__tests__/components/screens/SessionSelectorScreen.test.tsx +0 -147
  533. package/src/cli/ui/__tests__/hooks/useGitData.nonblocking.test.tsx +0 -206
  534. package/src/cli/ui/__tests__/hooks/useGitData.test.ts +0 -197
  535. package/src/cli/ui/__tests__/hooks/useGitData.test.ts.skip +0 -228
  536. package/src/cli/ui/__tests__/hooks/useScreenState.test.ts +0 -147
  537. package/src/cli/ui/__tests__/hooks/useTerminalSize.test.ts +0 -99
  538. package/src/cli/ui/__tests__/integration/branchList.test.tsx.skip +0 -253
  539. package/src/cli/ui/__tests__/integration/edgeCases.test.tsx +0 -436
  540. package/src/cli/ui/__tests__/integration/navigation.test.tsx +0 -514
  541. package/src/cli/ui/__tests__/integration/realtimeUpdate.test.tsx +0 -509
  542. package/src/cli/ui/__tests__/integration/realtimeUpdate.test.tsx.skip +0 -216
  543. package/src/cli/ui/__tests__/performance/branchList.performance.test.tsx +0 -193
  544. package/src/cli/ui/__tests__/performance/useMemoOptimization.test.tsx +0 -234
  545. package/src/cli/ui/components/App.tsx +0 -1478
  546. package/src/cli/ui/components/common/Confirm.tsx +0 -44
  547. package/src/cli/ui/components/common/ErrorBoundary.tsx +0 -60
  548. package/src/cli/ui/components/common/Input.tsx +0 -58
  549. package/src/cli/ui/components/common/LoadingIndicator.tsx +0 -98
  550. package/src/cli/ui/components/common/Select.tsx +0 -247
  551. package/src/cli/ui/components/common/SpinnerIcon.tsx +0 -86
  552. package/src/cli/ui/components/parts/Footer.tsx +0 -41
  553. package/src/cli/ui/components/parts/Header.test.tsx +0 -75
  554. package/src/cli/ui/components/parts/MergeStatusList.tsx +0 -75
  555. package/src/cli/ui/components/parts/ProgressBar.tsx +0 -73
  556. package/src/cli/ui/components/parts/Stats.tsx +0 -88
  557. package/src/cli/ui/components/screens/BatchMergeProgressScreen.tsx +0 -74
  558. package/src/cli/ui/components/screens/BatchMergeResultScreen.tsx +0 -108
  559. package/src/cli/ui/components/screens/BranchCreatorScreen.tsx +0 -242
  560. package/src/cli/ui/components/screens/BranchListScreen.tsx +0 -744
  561. package/src/cli/ui/components/screens/BranchQuickStartScreen.tsx +0 -244
  562. package/src/cli/ui/components/screens/CodingAgentSelectorScreen.tsx +0 -159
  563. package/src/cli/ui/components/screens/EnvironmentProfileScreen.tsx +0 -928
  564. package/src/cli/ui/components/screens/ExecutionModeSelectorScreen.tsx +0 -176
  565. package/src/cli/ui/components/screens/LogDatePickerScreen.tsx +0 -83
  566. package/src/cli/ui/components/screens/LogDetailScreen.tsx +0 -67
  567. package/src/cli/ui/components/screens/LogListScreen.tsx +0 -192
  568. package/src/cli/ui/components/screens/ModelSelectorScreen.tsx +0 -320
  569. package/src/cli/ui/components/screens/PRCleanupScreen.tsx +0 -171
  570. package/src/cli/ui/components/screens/SessionSelectorScreen.tsx +0 -135
  571. package/src/cli/ui/hooks/useAppInput.ts +0 -172
  572. package/src/cli/ui/hooks/useBatchMerge.ts +0 -96
  573. package/src/cli/ui/hooks/useGitData.ts +0 -347
  574. package/src/cli/ui/hooks/useProfiles.ts +0 -211
  575. package/src/cli/ui/hooks/useScreenState.ts +0 -44
  576. package/src/cli/ui/hooks/useTerminalSize.ts +0 -33
  577. package/src/cli/ui/hooks/useToolStatus.ts +0 -68
  578. package/src/cli/ui/screens/BranchActionSelectorScreen.tsx +0 -111
  579. package/src/cli/ui/screens/__tests__/BranchActionSelectorScreen.test.tsx +0 -264
@@ -1,216 +0,0 @@
1
- /**
2
- * @vitest-environment happy-dom
3
- * Integration tests for realtime update functionality
4
- */
5
- import { describe, it, expect, beforeEach, vi } from 'vitest';
6
- import { renderHook, waitFor } from '@testing-library/react';
7
- import { useGitData } from '../../hooks/useGitData.js';
8
- import { Window } from 'happy-dom';
9
- import type { BranchInfo } from '../../types.js';
10
-
11
- // Mock git.js and worktree.js
12
- vi.mock('../../../git.js', () => ({
13
- getAllBranches: vi.fn(),
14
- }));
15
-
16
- vi.mock('../../../worktree.js', () => ({
17
- listAdditionalWorktrees: vi.fn(),
18
- }));
19
-
20
- import { getAllBranches } from '../../../git.js';
21
- import { listAdditionalWorktrees } from '../../../worktree.js';
22
-
23
- describe('Realtime Update Integration Tests', () => {
24
- beforeEach(() => {
25
- // Setup happy-dom
26
- const window = new Window();
27
- globalThis.window = window as any;
28
- globalThis.document = window.document as any;
29
-
30
- // Reset mocks
31
- (getAllBranches as ReturnType<typeof vi.fn>).mockReset();
32
- (listAdditionalWorktrees as ReturnType<typeof vi.fn>).mockReset();
33
- });
34
-
35
- const mockBranches: BranchInfo[] = [
36
- {
37
- name: 'main',
38
- type: 'local',
39
- branchType: 'main',
40
- isCurrent: true,
41
- },
42
- ];
43
-
44
- it('should update lastUpdated timestamp after data refresh', async () => {
45
- (getAllBranches as ReturnType<typeof vi.fn>).mockResolvedValue(mockBranches);
46
- (listAdditionalWorktrees as ReturnType<typeof vi.fn>).mockResolvedValue([]);
47
-
48
- const { result } = renderHook(() => useGitData());
49
-
50
- // Wait for initial load
51
- await waitFor(() => {
52
- expect(result.current.loading).toBe(false);
53
- });
54
-
55
- const firstUpdated = result.current.lastUpdated;
56
- expect(firstUpdated).toBeInstanceOf(Date);
57
-
58
- // Wait to ensure timestamp difference (increased from 50ms to 100ms)
59
- await new Promise((resolve) => setTimeout(resolve, 100));
60
-
61
- // Trigger manual refresh
62
- result.current.refresh();
63
-
64
- await waitFor(() => {
65
- expect(result.current.loading).toBe(false);
66
- });
67
-
68
- const secondUpdated = result.current.lastUpdated;
69
- expect(secondUpdated).toBeInstanceOf(Date);
70
- // Use greaterThanOrEqual to handle rare cases where timestamps are identical
71
- expect(secondUpdated!.getTime()).toBeGreaterThanOrEqual(firstUpdated!.getTime());
72
- });
73
-
74
- it('should maintain data consistency during auto-refresh', async () => {
75
- let callCount = 0;
76
- (getAllBranches as ReturnType<typeof vi.fn>).mockImplementation(async () => {
77
- callCount++;
78
- if (callCount === 1) {
79
- return mockBranches;
80
- }
81
- // Return updated branches on subsequent calls
82
- return [
83
- ...mockBranches,
84
- {
85
- name: 'feature/new',
86
- type: 'local',
87
- branchType: 'feature',
88
- isCurrent: false,
89
- },
90
- ];
91
- });
92
- (listAdditionalWorktrees as ReturnType<typeof vi.fn>).mockResolvedValue([]);
93
-
94
- const { result } = renderHook(() =>
95
- useGitData({ enableAutoRefresh: true, refreshInterval: 100 })
96
- );
97
-
98
- // Wait for initial load
99
- await waitFor(() => {
100
- expect(result.current.loading).toBe(false);
101
- });
102
-
103
- expect(result.current.branches).toHaveLength(1);
104
-
105
- // Wait for auto-refresh to trigger
106
- await new Promise((resolve) => setTimeout(resolve, 150));
107
-
108
- await waitFor(() => {
109
- expect(result.current.branches).toHaveLength(2);
110
- });
111
-
112
- // Verify data integrity
113
- expect(result.current.branches[0].name).toBe('main');
114
- expect(result.current.branches[1].name).toBe('feature/new');
115
- expect(result.current.error).toBeNull();
116
- });
117
-
118
- it('should handle errors during auto-refresh gracefully', async () => {
119
- let callCount = 0;
120
- (getAllBranches as ReturnType<typeof vi.fn>).mockImplementation(async () => {
121
- callCount++;
122
- if (callCount === 1) {
123
- return mockBranches;
124
- }
125
- // Simulate error on second call
126
- throw new Error('Network error');
127
- });
128
- (listAdditionalWorktrees as ReturnType<typeof vi.fn>).mockResolvedValue([]);
129
-
130
- const { result } = renderHook(() =>
131
- useGitData({ enableAutoRefresh: true, refreshInterval: 100 })
132
- );
133
-
134
- // Wait for initial load
135
- await waitFor(() => {
136
- expect(result.current.loading).toBe(false);
137
- });
138
-
139
- expect(result.current.branches).toHaveLength(1);
140
- expect(result.current.error).toBeNull();
141
-
142
- // Wait for auto-refresh to trigger and fail
143
- await new Promise((resolve) => setTimeout(resolve, 150));
144
-
145
- await waitFor(() => {
146
- expect(result.current.error).not.toBeNull();
147
- });
148
-
149
- expect(result.current.error?.message).toBe('Network error');
150
- // Data should be cleared on error
151
- expect(result.current.branches).toEqual([]);
152
- });
153
-
154
- it('should stop auto-refresh when component unmounts', async () => {
155
- (getAllBranches as ReturnType<typeof vi.fn>).mockResolvedValue(mockBranches);
156
- (listAdditionalWorktrees as ReturnType<typeof vi.fn>).mockResolvedValue([]);
157
-
158
- const { result, unmount } = renderHook(() =>
159
- useGitData({ enableAutoRefresh: true, refreshInterval: 100 })
160
- );
161
-
162
- // Wait for initial load
163
- await waitFor(() => {
164
- expect(result.current.loading).toBe(false);
165
- });
166
-
167
- const initialCallCount = (getAllBranches as ReturnType<typeof vi.fn>).mock.calls.length;
168
-
169
- // Unmount the hook
170
- unmount();
171
-
172
- // Wait longer than refresh interval
173
- await new Promise((resolve) => setTimeout(resolve, 200));
174
-
175
- // Call count should not increase after unmount
176
- const finalCallCount = (getAllBranches as ReturnType<typeof vi.fn>).mock.calls.length;
177
- expect(finalCallCount).toBe(initialCallCount);
178
- });
179
-
180
- it('should update statistics in real-time', async () => {
181
- let callCount = 0;
182
- (getAllBranches as ReturnType<typeof vi.fn>).mockImplementation(async () => {
183
- callCount++;
184
- if (callCount === 1) {
185
- return [mockBranches[0]];
186
- }
187
- // Return more branches on subsequent calls
188
- return [
189
- mockBranches[0],
190
- { name: 'feature/a', type: 'local', branchType: 'feature', isCurrent: false },
191
- { name: 'feature/b', type: 'local', branchType: 'feature', isCurrent: false },
192
- ];
193
- });
194
- (listAdditionalWorktrees as ReturnType<typeof vi.fn>).mockResolvedValue([]);
195
-
196
- const { result } = renderHook(() =>
197
- useGitData({ enableAutoRefresh: true, refreshInterval: 100 })
198
- );
199
-
200
- // Wait for initial load
201
- await waitFor(() => {
202
- expect(result.current.loading).toBe(false);
203
- });
204
-
205
- expect(result.current.branches).toHaveLength(1);
206
-
207
- // Wait for auto-refresh
208
- await new Promise((resolve) => setTimeout(resolve, 150));
209
-
210
- await waitFor(() => {
211
- expect(result.current.branches).toHaveLength(3);
212
- });
213
-
214
- expect(result.current.lastUpdated).toBeInstanceOf(Date);
215
- });
216
- });
@@ -1,193 +0,0 @@
1
- import { describe, it, expect } from "vitest";
2
- import { render } from "ink-testing-library";
3
- import React from "react";
4
- import { BranchListScreen } from "../../components/screens/BranchListScreen.js";
5
- import type { BranchItem, Statistics } from "../../types.js";
6
-
7
- const isCI = Boolean(process.env.CI);
8
- const describeFn = isCI ? describe.skip : describe;
9
-
10
- /**
11
- * Generate mock branch items for performance testing
12
- */
13
- function generateMockBranches(count: number): BranchItem[] {
14
- const branches: BranchItem[] = [];
15
- const types = ["feature", "hotfix", "release", "other"] as const;
16
- const branchTypes = [
17
- "main",
18
- "develop",
19
- "feature",
20
- "hotfix",
21
- "release",
22
- "other",
23
- ] as const;
24
-
25
- for (let i = 0; i < count; i++) {
26
- const type = types[i % types.length];
27
- const branchType = branchTypes[i % branchTypes.length];
28
- const hasWorktree = i % 3 === 0;
29
-
30
- branches.push({
31
- name: `${type}/test-branch-${i.toString().padStart(4, "0")}`,
32
- branchType,
33
- type: i % 10 === 0 ? "remote" : "local",
34
- isCurrent: i === 0,
35
- worktree: hasWorktree
36
- ? {
37
- path: `/mock/worktree/${type}-${i}`,
38
- branch: `${type}/test-branch-${i.toString().padStart(4, "0")}`,
39
- isAccessible: i % 5 !== 0, // Some inaccessible
40
- }
41
- : undefined,
42
- worktreeStatus: hasWorktree
43
- ? i % 5 !== 0
44
- ? "active"
45
- : "inaccessible"
46
- : undefined,
47
- hasChanges: i % 4 === 0,
48
- icons: [],
49
- label: `${type}/test-branch-${i.toString().padStart(4, "0")}`,
50
- value: `${type}/test-branch-${i.toString().padStart(4, "0")}`,
51
- });
52
- }
53
-
54
- return branches;
55
- }
56
-
57
- // Unused for now - keeping for potential future use
58
- // const mockStats: Statistics = {
59
- // total: 0,
60
- // local: 0,
61
- // remote: 0,
62
- // current: 0,
63
- // feature: 0,
64
- // hotfix: 0,
65
- // release: 0,
66
- // worktree: 0,
67
- // };
68
-
69
- describeFn("BranchListScreen Performance", () => {
70
- it("should render 100+ branches within acceptable time", () => {
71
- const branches = generateMockBranches(150);
72
- const stats: Statistics = {
73
- total: branches.length,
74
- local: branches.filter((b) => b.type === "local").length,
75
- remote: branches.filter((b) => b.type === "remote").length,
76
- current: 1,
77
- feature: branches.filter((b) => b.branchType === "feature").length,
78
- hotfix: branches.filter((b) => b.branchType === "hotfix").length,
79
- release: branches.filter((b) => b.branchType === "release").length,
80
- worktree: branches.filter((b) => b.worktree).length,
81
- };
82
-
83
- const startTime = performance.now();
84
-
85
- const { unmount } = render(
86
- <BranchListScreen
87
- branches={branches}
88
- stats={stats}
89
- onSelect={() => {}}
90
- onQuit={() => {}}
91
- />,
92
- );
93
-
94
- const renderTime = performance.now() - startTime;
95
-
96
- unmount();
97
-
98
- // Rendering should complete within 500ms (generous threshold)
99
- expect(renderTime).toBeLessThan(500);
100
-
101
- // Log performance metrics
102
- console.log(`\n📊 Performance Test Results:`);
103
- console.log(` Branches: ${branches.length}`);
104
- console.log(` Render time: ${renderTime.toFixed(2)}ms`);
105
- console.log(
106
- ` Average per branch: ${(renderTime / branches.length).toFixed(3)}ms`,
107
- );
108
- });
109
-
110
- it("should handle re-render efficiently when stats update", () => {
111
- const branches = generateMockBranches(100);
112
- const stats: Statistics = {
113
- total: branches.length,
114
- local: branches.filter((b) => b.type === "local").length,
115
- remote: branches.filter((b) => b.type === "remote").length,
116
- current: 1,
117
- feature: branches.filter((b) => b.branchType === "feature").length,
118
- hotfix: branches.filter((b) => b.branchType === "hotfix").length,
119
- release: branches.filter((b) => b.branchType === "release").length,
120
- worktree: branches.filter((b) => b.worktree).length,
121
- };
122
-
123
- const { rerender, unmount } = render(
124
- <BranchListScreen
125
- branches={branches}
126
- stats={stats}
127
- onSelect={() => {}}
128
- onQuit={() => {}}
129
- lastUpdated={new Date()}
130
- />,
131
- );
132
-
133
- // Simulate stats update (real-time refresh)
134
- const startTime = performance.now();
135
-
136
- rerender(
137
- <BranchListScreen
138
- branches={branches}
139
- stats={{ ...stats, total: stats.total + 1 }}
140
- onSelect={() => {}}
141
- onQuit={() => {}}
142
- lastUpdated={new Date()}
143
- />,
144
- );
145
-
146
- const rerenderTime = performance.now() - startTime;
147
-
148
- unmount();
149
-
150
- // Performance threshold for re-render
151
- const threshold = 100;
152
- expect(rerenderTime).toBeLessThan(threshold);
153
-
154
- console.log(`\n🔄 Re-render Performance:`);
155
- console.log(` Re-render time: ${rerenderTime.toFixed(2)}ms`);
156
- });
157
-
158
- it("should handle large branch list (200+ branches)", () => {
159
- const branches = generateMockBranches(250);
160
- const stats: Statistics = {
161
- total: branches.length,
162
- local: branches.filter((b) => b.type === "local").length,
163
- remote: branches.filter((b) => b.type === "remote").length,
164
- current: 1,
165
- feature: branches.filter((b) => b.branchType === "feature").length,
166
- hotfix: branches.filter((b) => b.branchType === "hotfix").length,
167
- release: branches.filter((b) => b.branchType === "release").length,
168
- worktree: branches.filter((b) => b.worktree).length,
169
- };
170
-
171
- const startTime = performance.now();
172
-
173
- const { unmount } = render(
174
- <BranchListScreen
175
- branches={branches}
176
- stats={stats}
177
- onSelect={() => {}}
178
- onQuit={() => {}}
179
- />,
180
- );
181
-
182
- const renderTime = performance.now() - startTime;
183
-
184
- unmount();
185
-
186
- // Even with 250+ branches, should render within 1 second
187
- expect(renderTime).toBeLessThan(1000);
188
-
189
- console.log(`\n🚀 Large Branch List Performance:`);
190
- console.log(` Branches: ${branches.length}`);
191
- console.log(` Render time: ${renderTime.toFixed(2)}ms`);
192
- });
193
- });
@@ -1,234 +0,0 @@
1
- /**
2
- * @vitest-environment happy-dom
3
- */
4
- import { describe, it, expect, vi, beforeEach } from "vitest";
5
- import { render } from "@testing-library/react";
6
- import React, { useMemo } from "react";
7
- import { Window } from "happy-dom";
8
- import type { BranchInfo, WorktreeInfo } from "../../types.js";
9
- import { formatBranchItems } from "../../utils/branchFormatter.js";
10
-
11
- /**
12
- * T082-1: useMemo optimization tests
13
- * Tests that branchItems are not unnecessarily regenerated when data content is the same
14
- */
15
-
16
- // Mock useGitData hook
17
- vi.mock("../../hooks/useGitData.js", () => ({
18
- useGitData: vi.fn(),
19
- }));
20
-
21
- // Helper function to create a stable hash of branch data
22
- function createBranchHash(branches: BranchInfo[]): string {
23
- return branches.map((b) => `${b.name}-${b.type}-${b.isCurrent}`).join(",");
24
- }
25
-
26
- // Helper function to create a stable hash of worktree data
27
- function createWorktreeHash(worktrees: WorktreeInfo[]): string {
28
- return worktrees.map((w) => `${w.branch}-${w.path}`).join(",");
29
- }
30
-
31
- // Test component that uses optimized useMemo
32
- function TestComponent({
33
- branches,
34
- worktrees,
35
- }: {
36
- branches: BranchInfo[];
37
- worktrees: WorktreeInfo[];
38
- }) {
39
- // Count how many times formatBranchItems is called
40
- const formatCallCount = React.useRef(0);
41
-
42
- // Optimized useMemo with content-based dependencies
43
- const branchItems = useMemo(() => {
44
- formatCallCount.current++;
45
- const worktreeMap = new Map();
46
- for (const wt of worktrees) {
47
- worktreeMap.set(wt.branch, {
48
- path: wt.path,
49
- locked: false,
50
- prunable: wt.isAccessible === false,
51
- isAccessible: wt.isAccessible ?? true,
52
- });
53
- }
54
- return formatBranchItems(branches, worktreeMap);
55
- }, [createBranchHash(branches), createWorktreeHash(worktrees)]);
56
-
57
- return <div data-testid="branch-count">{branchItems.length}</div>;
58
- }
59
-
60
- describe("useMemo Optimization (T082-1)", () => {
61
- beforeEach(() => {
62
- const window = new Window();
63
- globalThis.window = window as unknown as typeof globalThis.window;
64
- globalThis.document =
65
- window.document as unknown as typeof globalThis.document;
66
- vi.clearAllMocks();
67
- });
68
-
69
- it("should not regenerate branchItems when data content is the same", () => {
70
- const mockBranches: BranchInfo[] = [
71
- {
72
- name: "main",
73
- branchType: "main",
74
- type: "local",
75
- isCurrent: true,
76
- },
77
- {
78
- name: "feature/test-1",
79
- branchType: "feature",
80
- type: "local",
81
- isCurrent: false,
82
- },
83
- ];
84
-
85
- const mockWorktrees: WorktreeInfo[] = [
86
- {
87
- path: "/mock/worktree/feature-test-1",
88
- branch: "feature/test-1",
89
- isAccessible: true,
90
- },
91
- ];
92
-
93
- const { rerender } = render(
94
- <TestComponent branches={mockBranches} worktrees={mockWorktrees} />,
95
- );
96
-
97
- // Create new arrays with the same content
98
- const sameBranches: BranchInfo[] = [
99
- {
100
- name: "main",
101
- branchType: "main",
102
- type: "local",
103
- isCurrent: true,
104
- },
105
- {
106
- name: "feature/test-1",
107
- branchType: "feature",
108
- type: "local",
109
- isCurrent: false,
110
- },
111
- ];
112
-
113
- const sameWorktrees: WorktreeInfo[] = [
114
- {
115
- path: "/mock/worktree/feature-test-1",
116
- branch: "feature/test-1",
117
- isAccessible: true,
118
- },
119
- ];
120
-
121
- // Verify that arrays are different references
122
- expect(sameBranches).not.toBe(mockBranches);
123
- expect(sameWorktrees).not.toBe(mockWorktrees);
124
-
125
- // Verify that content is the same
126
- expect(createBranchHash(sameBranches)).toBe(createBranchHash(mockBranches));
127
- expect(createWorktreeHash(sameWorktrees)).toBe(
128
- createWorktreeHash(mockWorktrees),
129
- );
130
-
131
- // Re-render with same content but different references
132
- rerender(
133
- <TestComponent branches={sameBranches} worktrees={sameWorktrees} />,
134
- );
135
-
136
- // formatBranchItems should only be called once (not twice)
137
- // This test would fail with the current implementation because useMemo
138
- // depends on array references, not content
139
- });
140
-
141
- it("should regenerate branchItems when data content changes", () => {
142
- const initialBranches: BranchInfo[] = [
143
- {
144
- name: "main",
145
- branchType: "main",
146
- type: "local",
147
- isCurrent: true,
148
- },
149
- ];
150
-
151
- const { rerender } = render(
152
- <TestComponent branches={initialBranches} worktrees={[]} />,
153
- );
154
-
155
- // Add a new branch
156
- const updatedBranches: BranchInfo[] = [
157
- ...initialBranches,
158
- {
159
- name: "feature/new",
160
- branchType: "feature",
161
- type: "local",
162
- isCurrent: false,
163
- },
164
- ];
165
-
166
- // Verify content changed
167
- expect(createBranchHash(updatedBranches)).not.toBe(
168
- createBranchHash(initialBranches),
169
- );
170
-
171
- // Re-render with new content
172
- rerender(<TestComponent branches={updatedBranches} worktrees={[]} />);
173
-
174
- // formatBranchItems should be called twice (once for initial, once for update)
175
- });
176
-
177
- it("should handle branch order changes correctly", () => {
178
- const branches1: BranchInfo[] = [
179
- {
180
- name: "main",
181
- branchType: "main",
182
- type: "local",
183
- isCurrent: true,
184
- },
185
- {
186
- name: "feature/test",
187
- branchType: "feature",
188
- type: "local",
189
- isCurrent: false,
190
- },
191
- ];
192
-
193
- const branches2: BranchInfo[] = [
194
- {
195
- name: "feature/test",
196
- branchType: "feature",
197
- type: "local",
198
- isCurrent: false,
199
- },
200
- {
201
- name: "main",
202
- branchType: "main",
203
- type: "local",
204
- isCurrent: true,
205
- },
206
- ];
207
-
208
- // Different order should produce different hashes
209
- expect(createBranchHash(branches1)).not.toBe(createBranchHash(branches2));
210
- });
211
-
212
- it("should detect subtle branch property changes", () => {
213
- const branches1: BranchInfo[] = [
214
- {
215
- name: "main",
216
- branchType: "main",
217
- type: "local",
218
- isCurrent: false,
219
- },
220
- ];
221
-
222
- const branches2: BranchInfo[] = [
223
- {
224
- name: "main",
225
- branchType: "main",
226
- type: "local",
227
- isCurrent: true, // Changed from false to true
228
- },
229
- ];
230
-
231
- // isCurrent change should be detected
232
- expect(createBranchHash(branches1)).not.toBe(createBranchHash(branches2));
233
- });
234
- });