@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,335 +0,0 @@
1
- /**
2
- * @vitest-environment happy-dom
3
- */
4
-
5
- import { describe, it, expect, vi } from "vitest";
6
- import { render } from "ink-testing-library";
7
- import React from "react";
8
- import { Select } from "../../../components/common/Select.js";
9
- import { ESCAPE_SEQUENCE_TIMEOUT_MS } from "../../../hooks/useAppInput.js";
10
-
11
- interface TestItem {
12
- label: string;
13
- value: string;
14
- }
15
-
16
- const delay = (ms = 0): Promise<void> =>
17
- new Promise((resolve) => setTimeout(resolve, ms));
18
-
19
- describe("Select", () => {
20
- const mockItems: TestItem[] = [
21
- { label: "Option 1", value: "opt1" },
22
- { label: "Option 2", value: "opt2" },
23
- { label: "Option 3", value: "opt3" },
24
- { label: "Option 4", value: "opt4" },
25
- { label: "Option 5", value: "opt5" },
26
- ];
27
-
28
- describe("Rendering", () => {
29
- it("should render all items", () => {
30
- const onSelect = vi.fn();
31
- const { lastFrame } = render(
32
- <Select items={mockItems} onSelect={onSelect} />,
33
- );
34
-
35
- expect(lastFrame()).toContain("Option 1");
36
- expect(lastFrame()).toContain("Option 2");
37
- expect(lastFrame()).toContain("Option 3");
38
- });
39
-
40
- it("should highlight first item by default", () => {
41
- const onSelect = vi.fn();
42
- const { lastFrame } = render(
43
- <Select items={mockItems} onSelect={onSelect} />,
44
- );
45
-
46
- // Cyan color code indicates selected item
47
- expect(lastFrame()).toContain("›");
48
- });
49
-
50
- it("should highlight item at initialIndex", () => {
51
- const onSelect = vi.fn();
52
- const { lastFrame } = render(
53
- <Select items={mockItems} onSelect={onSelect} initialIndex={2} />,
54
- );
55
-
56
- const output = lastFrame();
57
- // Should have exactly one selected indicator
58
- const selectedCount = (output.match(/›/g) || []).length;
59
- expect(selectedCount).toBe(1);
60
- });
61
-
62
- it("should render with empty items array", () => {
63
- const onSelect = vi.fn();
64
- const { lastFrame } = render(<Select items={[]} onSelect={onSelect} />);
65
-
66
- expect(lastFrame()).toBeDefined();
67
- });
68
-
69
- it("should respect limit prop for scrolling", () => {
70
- const onSelect = vi.fn();
71
- const { lastFrame } = render(
72
- <Select items={mockItems} onSelect={onSelect} limit={3} />,
73
- );
74
-
75
- const output = lastFrame();
76
- // Should only show 3 items when limit is 3
77
- expect(output).toContain("Option 1");
78
- expect(output).toContain("Option 2");
79
- expect(output).toContain("Option 3");
80
- // Option 4 and 5 should not be visible initially
81
- expect(output).not.toContain("Option 4");
82
- expect(output).not.toContain("Option 5");
83
- });
84
- });
85
-
86
- describe("Navigation - No Looping (Critical Feature)", () => {
87
- it("should implement boundary checks to prevent looping", () => {
88
- // Unit test: verify the logic used in implementation
89
- // Math.max(0, current - 1) - prevents going below 0
90
- // Math.min(items.length - 1, current + 1) - prevents going above max
91
-
92
- const onSelect = vi.fn();
93
- const { lastFrame } = render(
94
- <Select items={mockItems} onSelect={onSelect} />,
95
- );
96
-
97
- // Verify component renders (implementation uses Math.max/min for boundaries)
98
- expect(lastFrame()).toBeDefined();
99
- expect(lastFrame()).toContain("Option 1");
100
- });
101
-
102
- it("should start at first item by default", () => {
103
- const onSelect = vi.fn();
104
- const { lastFrame } = render(
105
- <Select items={mockItems} onSelect={onSelect} />,
106
- );
107
-
108
- const output = lastFrame();
109
- // First line should have the selection indicator
110
- const lines = output.split("\n").filter((l) => l.trim());
111
- expect(lines[0]).toContain("›");
112
- expect(lines[0]).toContain("Option 1");
113
- });
114
-
115
- it("should respect initialIndex without looping", () => {
116
- const onSelect = vi.fn();
117
- const { lastFrame } = render(
118
- <Select items={mockItems} onSelect={onSelect} initialIndex={4} />,
119
- );
120
-
121
- // Should start at last item (index 4)
122
- const output = lastFrame();
123
- expect(output).toContain("Option 5");
124
- expect(output).toContain("›");
125
- });
126
-
127
- it("should handle initialIndex at 0", () => {
128
- const onSelect = vi.fn();
129
- const { lastFrame } = render(
130
- <Select items={mockItems} onSelect={onSelect} initialIndex={0} />,
131
- );
132
-
133
- const output = lastFrame();
134
- const lines = output.split("\n").filter((l) => l.trim());
135
- expect(lines[0]).toContain("Option 1");
136
- });
137
- });
138
-
139
- describe("Navigation - Input Handling", () => {
140
- it("should use useInput hook for keyboard handling", () => {
141
- // Verify component accepts keyboard input by checking it renders properly
142
- const onSelect = vi.fn();
143
- const { stdin } = render(
144
- <Select items={mockItems} onSelect={onSelect} />,
145
- );
146
-
147
- // Component should handle input without errors
148
- expect(() => stdin.write("\u001B[B")).not.toThrow();
149
- expect(() => stdin.write("\u001B[A")).not.toThrow();
150
- expect(() => stdin.write("j")).not.toThrow();
151
- expect(() => stdin.write("k")).not.toThrow();
152
- });
153
-
154
- it("should support vim-style navigation keys (j/k)", () => {
155
- const onSelect = vi.fn();
156
- const { stdin } = render(
157
- <Select items={mockItems} onSelect={onSelect} />,
158
- );
159
-
160
- // Should accept j and k keys
161
- expect(() => stdin.write("j")).not.toThrow();
162
- expect(() => stdin.write("k")).not.toThrow();
163
- });
164
-
165
- it("should support arrow keys", () => {
166
- const onSelect = vi.fn();
167
- const { stdin } = render(
168
- <Select items={mockItems} onSelect={onSelect} />,
169
- );
170
-
171
- // Should accept arrow keys
172
- expect(() => stdin.write("\u001B[A")).not.toThrow(); // Up
173
- expect(() => stdin.write("\u001B[B")).not.toThrow(); // Down
174
- });
175
- });
176
-
177
- describe("Selection", () => {
178
- it("should call onSelect when Enter is pressed", () => {
179
- const onSelect = vi.fn();
180
- const { stdin } = render(
181
- <Select items={mockItems} onSelect={onSelect} />,
182
- );
183
-
184
- stdin.write("\r"); // Enter key
185
-
186
- // Should be called at least once
187
- expect(onSelect).toHaveBeenCalled();
188
- });
189
-
190
- it("should call onSelect when linefeed is pressed (cooked mode Enter)", () => {
191
- const onSelect = vi.fn();
192
- const { stdin } = render(
193
- <Select items={mockItems} onSelect={onSelect} />,
194
- );
195
-
196
- stdin.write("\n"); // Linefeed key
197
-
198
- expect(onSelect).toHaveBeenCalled();
199
- });
200
-
201
- it("should pass selected item to onSelect callback", () => {
202
- const onSelect = vi.fn();
203
- render(<Select items={mockItems} onSelect={onSelect} initialIndex={2} />);
204
-
205
- // onSelect should be configured to receive item objects
206
- // Actual keyboard testing is limited by ink-testing-library
207
- expect(onSelect).toBeInstanceOf(Function);
208
- });
209
-
210
- it("should handle Enter key without errors", () => {
211
- const onSelect = vi.fn();
212
- const { stdin } = render(
213
- <Select items={mockItems} onSelect={onSelect} />,
214
- );
215
-
216
- expect(() => stdin.write("\r")).not.toThrow();
217
- });
218
- });
219
-
220
- describe("Scrolling with limit", () => {
221
- it("should implement offset-based scrolling logic", () => {
222
- // Verify limit prop is accepted and used for slicing
223
- const onSelect = vi.fn();
224
- const { lastFrame } = render(
225
- <Select items={mockItems} onSelect={onSelect} limit={3} />,
226
- );
227
-
228
- const output = lastFrame();
229
- // Should show limited items initially
230
- expect(output).toContain("Option 1");
231
- expect(output).toContain("Option 2");
232
- expect(output).toContain("Option 3");
233
- });
234
-
235
- it("should handle limit smaller than items length", () => {
236
- const onSelect = vi.fn();
237
- const { lastFrame } = render(
238
- <Select items={mockItems} onSelect={onSelect} limit={2} />,
239
- );
240
-
241
- const output = lastFrame();
242
- const lines = output.split("\n").filter((l) => l.trim());
243
- // Should only show 2 items
244
- expect(lines.length).toBeLessThanOrEqual(2);
245
- });
246
-
247
- it("should handle limit larger than items length", () => {
248
- const onSelect = vi.fn();
249
- const { lastFrame } = render(
250
- <Select items={mockItems} onSelect={onSelect} limit={100} />,
251
- );
252
-
253
- // Should show all items without error
254
- const output = lastFrame();
255
- expect(output).toContain("Option 1");
256
- expect(output).toContain("Option 5");
257
- });
258
- });
259
-
260
- describe("Key propagation (Critical Feature)", () => {
261
- it("should not interfere with other keys like q", () => {
262
- const onSelect = vi.fn();
263
- const { stdin } = render(
264
- <Select items={mockItems} onSelect={onSelect} />,
265
- );
266
-
267
- // Press q key (should be ignored by Select and propagate to parent)
268
- stdin.write("q");
269
-
270
- // onSelect should not be called
271
- expect(onSelect).not.toHaveBeenCalled();
272
- });
273
-
274
- it("should not interfere with other keys like m, n, c", () => {
275
- const onSelect = vi.fn();
276
- const { stdin } = render(
277
- <Select items={mockItems} onSelect={onSelect} />,
278
- );
279
-
280
- stdin.write("m");
281
- stdin.write("n");
282
- stdin.write("c");
283
-
284
- // None of these should trigger selection
285
- expect(onSelect).not.toHaveBeenCalled();
286
- });
287
- });
288
-
289
- describe("Space/Escape handlers", () => {
290
- it("should call onSpace with the currently highlighted item", async () => {
291
- const onSelect = vi.fn();
292
- const onSpace = vi.fn();
293
- const { stdin } = render(
294
- <Select items={mockItems} onSelect={onSelect} onSpace={onSpace} />,
295
- );
296
-
297
- stdin.write(" ");
298
- await delay(10);
299
-
300
- expect(onSpace).toHaveBeenCalledTimes(1);
301
- expect(onSpace).toHaveBeenCalledWith(mockItems[0]);
302
- });
303
-
304
- it("should not trigger onSpace when disabled", async () => {
305
- const onSelect = vi.fn();
306
- const onSpace = vi.fn();
307
- const { stdin } = render(
308
- <Select
309
- items={mockItems}
310
- onSelect={onSelect}
311
- onSpace={onSpace}
312
- disabled
313
- />,
314
- );
315
-
316
- stdin.write(" ");
317
- await delay(10);
318
-
319
- expect(onSpace).not.toHaveBeenCalled();
320
- });
321
-
322
- it("should call onEscape when escape key is pressed", async () => {
323
- const onSelect = vi.fn();
324
- const onEscape = vi.fn();
325
- const { stdin } = render(
326
- <Select items={mockItems} onSelect={onSelect} onEscape={onEscape} />,
327
- );
328
-
329
- stdin.write("\u001B");
330
- await delay(ESCAPE_SEQUENCE_TIMEOUT_MS + 20);
331
-
332
- expect(onEscape).toHaveBeenCalledTimes(1);
333
- });
334
- });
335
- });
@@ -1,65 +0,0 @@
1
- /**
2
- * @vitest-environment happy-dom
3
- */
4
- import { describe, it, expect, beforeEach } from "vitest";
5
- import { render } from "@testing-library/react";
6
- import React from "react";
7
- import { Footer } from "../../../components/parts/Footer.js";
8
- import { Window } from "happy-dom";
9
-
10
- describe("Footer", () => {
11
- beforeEach(() => {
12
- // Setup happy-dom
13
- const window = new Window();
14
- globalThis.window = window as unknown as typeof globalThis.window;
15
- globalThis.document =
16
- window.document as unknown as typeof globalThis.document;
17
- });
18
-
19
- const mockActions = [
20
- { key: "enter", description: "Select" },
21
- { key: "esc", description: "Back" },
22
- { key: "h", description: "Help" },
23
- ];
24
-
25
- it("should render all actions", () => {
26
- const { getByText } = render(<Footer actions={mockActions} />);
27
-
28
- expect(getByText(/enter/)).toBeDefined();
29
- expect(getByText(/Select/)).toBeDefined();
30
- expect(getByText(/esc/)).toBeDefined();
31
- expect(getByText(/Back/)).toBeDefined();
32
- expect(getByText(/h/)).toBeDefined();
33
- expect(getByText(/Help/)).toBeDefined();
34
- });
35
-
36
- it("should render with empty actions array", () => {
37
- const { container } = render(<Footer actions={[]} />);
38
-
39
- expect(container).toBeDefined();
40
- });
41
-
42
- it("should render single action", () => {
43
- const singleAction = [{ key: "esc", description: "Exit" }];
44
- const { getByText } = render(<Footer actions={singleAction} />);
45
-
46
- expect(getByText(/esc/)).toBeDefined();
47
- expect(getByText(/Exit/)).toBeDefined();
48
- });
49
-
50
- it("should render actions in a horizontal layout", () => {
51
- const { container } = render(<Footer actions={mockActions} />);
52
-
53
- // Verify component renders without error
54
- expect(container).toBeDefined();
55
- });
56
-
57
- it("should accept custom separator", () => {
58
- const { getAllByText } = render(
59
- <Footer actions={mockActions} separator=" | " />,
60
- );
61
-
62
- const separators = getAllByText(/\|/);
63
- expect(separators.length).toBeGreaterThan(0);
64
- });
65
- });
@@ -1,55 +0,0 @@
1
- /**
2
- * @vitest-environment happy-dom
3
- */
4
- import { describe, it, expect, beforeEach } from "vitest";
5
- import { render } from "@testing-library/react";
6
- import React from "react";
7
- import { Header } from "../../../components/parts/Header.js";
8
- import { Window } from "happy-dom";
9
-
10
- describe("Header", () => {
11
- beforeEach(() => {
12
- // Setup happy-dom
13
- const window = new Window();
14
- globalThis.window = window as unknown as typeof globalThis.window;
15
- globalThis.document =
16
- window.document as unknown as typeof globalThis.document;
17
- });
18
-
19
- it("should render title", () => {
20
- const { getByText } = render(<Header title="gwt" />);
21
-
22
- expect(getByText("gwt")).toBeDefined();
23
- });
24
-
25
- it("should render divider", () => {
26
- const { getByText } = render(<Header title="Test" />);
27
-
28
- // Check for a line of dashes (divider)
29
- expect(getByText(/─+/)).toBeDefined();
30
- });
31
-
32
- it("should render title in bold and cyan by default", () => {
33
- const { container } = render(<Header title="Test Title" />);
34
-
35
- expect(container).toBeDefined();
36
- });
37
-
38
- it("should accept custom title color", () => {
39
- const { container } = render(<Header title="Test" titleColor="green" />);
40
-
41
- expect(container).toBeDefined();
42
- });
43
-
44
- it("should accept custom divider character", () => {
45
- const { getByText } = render(<Header title="Test" dividerChar="=" />);
46
-
47
- expect(getByText(/=+/)).toBeDefined();
48
- });
49
-
50
- it("should render without divider when showDivider is false", () => {
51
- const { queryByText } = render(<Header title="Test" showDivider={false} />);
52
-
53
- expect(queryByText(/─+/)).toBeNull();
54
- });
55
- });
@@ -1,69 +0,0 @@
1
- /**
2
- * @vitest-environment happy-dom
3
- */
4
- import { describe, it, expect, beforeEach } from "vitest";
5
- import { render } from "@testing-library/react";
6
- import React from "react";
7
- import { ScrollableList } from "../../../components/parts/ScrollableList.js";
8
- import { Text } from "ink";
9
- import { Window } from "happy-dom";
10
-
11
- describe("ScrollableList", () => {
12
- beforeEach(() => {
13
- // Setup happy-dom
14
- const window = new Window();
15
- globalThis.window = window as unknown as typeof globalThis.window;
16
- globalThis.document =
17
- window.document as unknown as typeof globalThis.document;
18
- });
19
-
20
- it("should render children", () => {
21
- const { getByText } = render(
22
- <ScrollableList>
23
- <Text>Item 1</Text>
24
- <Text>Item 2</Text>
25
- <Text>Item 3</Text>
26
- </ScrollableList>,
27
- );
28
-
29
- expect(getByText("Item 1")).toBeDefined();
30
- expect(getByText("Item 2")).toBeDefined();
31
- expect(getByText("Item 3")).toBeDefined();
32
- });
33
-
34
- it("should render with no children", () => {
35
- const { container } = render(<ScrollableList>{null}</ScrollableList>);
36
-
37
- expect(container).toBeDefined();
38
- });
39
-
40
- it("should accept maxHeight prop", () => {
41
- const { container } = render(
42
- <ScrollableList maxHeight={10}>
43
- <Text>Content</Text>
44
- </ScrollableList>,
45
- );
46
-
47
- expect(container).toBeDefined();
48
- });
49
-
50
- it("should render in a vertical layout", () => {
51
- const { container } = render(
52
- <ScrollableList>
53
- <Text>Content</Text>
54
- </ScrollableList>,
55
- );
56
-
57
- expect(container).toBeDefined();
58
- });
59
-
60
- it("should handle single child", () => {
61
- const { getByText } = render(
62
- <ScrollableList>
63
- <Text>Single Item</Text>
64
- </ScrollableList>,
65
- );
66
-
67
- expect(getByText("Single Item")).toBeDefined();
68
- });
69
- });
@@ -1,148 +0,0 @@
1
- /**
2
- * @vitest-environment happy-dom
3
- */
4
- import { describe, it, expect, beforeEach } from "vitest";
5
- import { render } from "@testing-library/react";
6
- import React from "react";
7
- import { Stats } from "../../../components/parts/Stats.js";
8
- import type { Statistics } from "../../../types.js";
9
- import { Window } from "happy-dom";
10
-
11
- describe("Stats", () => {
12
- beforeEach(() => {
13
- // Setup happy-dom
14
- const window = new Window();
15
- globalThis.window = window as unknown as typeof globalThis.window;
16
- globalThis.document =
17
- window.document as unknown as typeof globalThis.document;
18
- });
19
-
20
- const mockStats: Statistics = {
21
- localCount: 10,
22
- remoteCount: 8,
23
- worktreeCount: 3,
24
- changesCount: 2,
25
- lastUpdated: new Date("2025-01-25T12:00:00Z"),
26
- };
27
-
28
- it("should render all statistics", () => {
29
- const { getByText } = render(<Stats stats={mockStats} />);
30
-
31
- expect(getByText(/Local:/)).toBeDefined();
32
- expect(getByText(/10/)).toBeDefined();
33
- expect(getByText(/Remote:/)).toBeDefined();
34
- expect(getByText(/8/)).toBeDefined();
35
- expect(getByText(/Worktrees:/)).toBeDefined();
36
- expect(getByText(/3/)).toBeDefined();
37
- expect(getByText(/Changes:/)).toBeDefined();
38
- expect(getByText(/2/)).toBeDefined();
39
- });
40
-
41
- it("should render with zero counts", () => {
42
- const zeroStats: Statistics = {
43
- localCount: 0,
44
- remoteCount: 0,
45
- worktreeCount: 0,
46
- changesCount: 0,
47
- lastUpdated: new Date(),
48
- };
49
-
50
- const { getByText, getAllByText } = render(<Stats stats={zeroStats} />);
51
-
52
- expect(getByText(/Local:/)).toBeDefined();
53
- const zeros = getAllByText(/0/);
54
- expect(zeros.length).toBe(4); // All 4 counts are 0
55
- });
56
-
57
- it("should render in a horizontal layout", () => {
58
- const { container } = render(<Stats stats={mockStats} />);
59
-
60
- // Verify component renders without error
61
- expect(container).toBeDefined();
62
- });
63
-
64
- it("should accept custom separator", () => {
65
- const { getAllByText } = render(
66
- <Stats stats={mockStats} separator=" | " />,
67
- );
68
-
69
- const separators = getAllByText(/\|/);
70
- expect(separators.length).toBeGreaterThan(0);
71
- });
72
-
73
- it("should handle large numbers", () => {
74
- const largeStats: Statistics = {
75
- localCount: 999,
76
- remoteCount: 888,
77
- worktreeCount: 777,
78
- changesCount: 666,
79
- lastUpdated: new Date(),
80
- };
81
-
82
- const { getByText } = render(<Stats stats={largeStats} />);
83
-
84
- expect(getByText(/999/)).toBeDefined();
85
- expect(getByText(/888/)).toBeDefined();
86
- expect(getByText(/777/)).toBeDefined();
87
- expect(getByText(/666/)).toBeDefined();
88
- });
89
-
90
- it("should display lastUpdated when provided", () => {
91
- const now = new Date();
92
- const lastUpdated = new Date(now.getTime() - 5000); // 5 seconds ago
93
-
94
- const { getByText } = render(
95
- <Stats stats={mockStats} lastUpdated={lastUpdated} />,
96
- );
97
-
98
- expect(getByText(/Updated:/)).toBeDefined();
99
- expect(getByText(/ago/)).toBeDefined();
100
- });
101
-
102
- it("should not display lastUpdated when null", () => {
103
- const { queryByText } = render(
104
- <Stats stats={mockStats} lastUpdated={null} />,
105
- );
106
-
107
- expect(queryByText(/Updated:/)).toBeNull();
108
- });
109
-
110
- it("should not display lastUpdated when not provided", () => {
111
- const { queryByText } = render(<Stats stats={mockStats} />);
112
-
113
- expect(queryByText(/Updated:/)).toBeNull();
114
- });
115
-
116
- it("should format relative time correctly (seconds)", () => {
117
- const now = new Date();
118
- const lastUpdated = new Date(now.getTime() - 30000); // 30 seconds ago
119
-
120
- const { getByText } = render(
121
- <Stats stats={mockStats} lastUpdated={lastUpdated} />,
122
- );
123
-
124
- expect(getByText(/30s ago/)).toBeDefined();
125
- });
126
-
127
- it("should format relative time correctly (minutes)", () => {
128
- const now = new Date();
129
- const lastUpdated = new Date(now.getTime() - 120000); // 2 minutes ago
130
-
131
- const { getByText } = render(
132
- <Stats stats={mockStats} lastUpdated={lastUpdated} />,
133
- );
134
-
135
- expect(getByText(/2m ago/)).toBeDefined();
136
- });
137
-
138
- it("should format relative time correctly (hours)", () => {
139
- const now = new Date();
140
- const lastUpdated = new Date(now.getTime() - 7200000); // 2 hours ago
141
-
142
- const { getByText } = render(
143
- <Stats stats={mockStats} lastUpdated={lastUpdated} />,
144
- );
145
-
146
- expect(getByText(/2h ago/)).toBeDefined();
147
- });
148
- });