@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,928 +0,0 @@
1
- /**
2
- * 環境変数プロファイルエディター画面
3
- *
4
- * プロファイルの選択・作成・削除・環境変数の編集を行います。
5
- * @see specs/SPEC-dafff079/spec.md
6
- */
7
-
8
- import React, { useState, useCallback, useMemo, useEffect } from "react";
9
- import { Box, Text } from "ink";
10
- import { Header } from "../parts/Header.js";
11
- import { Footer } from "../parts/Footer.js";
12
- import { Select } from "../common/Select.js";
13
- import { Input } from "../common/Input.js";
14
- import { Confirm } from "../common/Confirm.js";
15
- import { useAppInput } from "../../hooks/useAppInput.js";
16
- import { useTerminalSize } from "../../hooks/useTerminalSize.js";
17
- import { useProfiles } from "../../hooks/useProfiles.js";
18
- import { isValidProfileName } from "../../../../types/profiles.js";
19
-
20
- /**
21
- * Props for `EnvironmentProfileScreen`.
22
- */
23
- export interface EnvironmentProfileScreenProps {
24
- onBack: () => void;
25
- version?: string | null;
26
- }
27
-
28
- type ScreenMode =
29
- | "list" // プロファイル一覧
30
- | "view" // プロファイル詳細
31
- | "create-name" // 新規作成:名前入力
32
- | "create-display" // 新規作成:表示名入力
33
- | "add-env-key" // 環境変数追加:キー入力
34
- | "add-env-value" // 環境変数追加:値入力
35
- | "edit-env-value" // 環境変数編集:値入力
36
- | "confirm-delete-profile" // プロファイル削除確認
37
- | "confirm-delete-env"; // 環境変数削除確認
38
-
39
- interface ProfileItem {
40
- label: string;
41
- value: string;
42
- profileName: string | null;
43
- isActive: boolean;
44
- }
45
-
46
- interface EnvVarItem {
47
- label: string;
48
- value: string;
49
- key: string;
50
- envValue: string;
51
- }
52
-
53
- const UI_CHROME_HEIGHT = 20; // ヘッダー/フッター/余白などの固定行数
54
- const ENV_VAR_KEY_PATTERN = /^[A-Za-z_][A-Za-z0-9_]*$/;
55
- const NO_PROFILE_VALUE = "__gwt_no_profile__";
56
-
57
- type FocusTarget = "profiles" | "env" | "osenv";
58
-
59
- interface SelectionState {
60
- profileIndex: number;
61
- envIndex: number;
62
- osEnvIndex: number;
63
- focus: FocusTarget;
64
- selectedProfileName: string | null;
65
- }
66
-
67
- interface ProfileCreationState {
68
- name: string;
69
- displayName: string;
70
- }
71
-
72
- interface EnvEditState {
73
- key: string;
74
- value: string;
75
- selectedKey: string | null;
76
- }
77
-
78
- type NumberUpdater = number | ((prev: number) => number);
79
- type FocusUpdater = FocusTarget | ((prev: FocusTarget) => FocusTarget);
80
-
81
- /**
82
- * 環境変数プロファイルエディター画面
83
- */
84
- export function EnvironmentProfileScreen({
85
- onBack,
86
- version,
87
- }: EnvironmentProfileScreenProps) {
88
- const { rows } = useTerminalSize();
89
- const {
90
- profiles,
91
- loading,
92
- error,
93
- activeProfileName,
94
- setActiveProfile,
95
- createProfile,
96
- deleteProfile,
97
- updateEnvVar,
98
- deleteEnvVar,
99
- } = useProfiles();
100
-
101
- // 画面モード
102
- const [mode, setMode] = useState<ScreenMode>("list");
103
-
104
- const [selection, setSelection] = useState<SelectionState>({
105
- profileIndex: 0,
106
- envIndex: 0,
107
- osEnvIndex: 0,
108
- focus: "profiles",
109
- selectedProfileName: null,
110
- });
111
-
112
- const [profileCreation, setProfileCreation] = useState<ProfileCreationState>({
113
- name: "",
114
- displayName: "",
115
- });
116
-
117
- const [envEdit, setEnvEdit] = useState<EnvEditState>({
118
- key: "",
119
- value: "",
120
- selectedKey: null,
121
- });
122
-
123
- // バリデーションエラー
124
- const [validationError, setValidationError] = useState<string | null>(null);
125
-
126
- const profileIndex = selection.profileIndex;
127
- const envIndex = selection.envIndex;
128
- const osEnvIndex = selection.osEnvIndex;
129
- const focus = selection.focus;
130
- const selectedProfileName = selection.selectedProfileName;
131
-
132
- const newProfileName = profileCreation.name;
133
- const newProfileDisplayName = profileCreation.displayName;
134
-
135
- const newEnvKey = envEdit.key;
136
- const newEnvValue = envEdit.value;
137
- const selectedEnvKey = envEdit.selectedKey;
138
-
139
- const setProfileIndex = useCallback((index: number) => {
140
- setSelection((prev) => ({ ...prev, profileIndex: index }));
141
- }, []);
142
-
143
- const setEnvIndex = useCallback((updater: NumberUpdater) => {
144
- setSelection((prev) => ({
145
- ...prev,
146
- envIndex:
147
- typeof updater === "function" ? updater(prev.envIndex) : updater,
148
- }));
149
- }, []);
150
-
151
- const setOsEnvIndex = useCallback((updater: NumberUpdater) => {
152
- setSelection((prev) => ({
153
- ...prev,
154
- osEnvIndex:
155
- typeof updater === "function" ? updater(prev.osEnvIndex) : updater,
156
- }));
157
- }, []);
158
-
159
- const setFocus = useCallback((updater: FocusUpdater) => {
160
- setSelection((prev) => ({
161
- ...prev,
162
- focus: typeof updater === "function" ? updater(prev.focus) : updater,
163
- }));
164
- }, []);
165
-
166
- const setSelectedProfileName = useCallback((name: string | null) => {
167
- setSelection((prev) => ({ ...prev, selectedProfileName: name }));
168
- }, []);
169
-
170
- const setNewProfileName = useCallback((value: string) => {
171
- setProfileCreation((prev) => ({ ...prev, name: value }));
172
- }, []);
173
-
174
- const setNewProfileDisplayName = useCallback((value: string) => {
175
- setProfileCreation((prev) => ({ ...prev, displayName: value }));
176
- }, []);
177
-
178
- const setNewEnvKey = useCallback((value: string) => {
179
- setEnvEdit((prev) => ({ ...prev, key: value }));
180
- }, []);
181
-
182
- const setNewEnvValue = useCallback((value: string) => {
183
- setEnvEdit((prev) => ({ ...prev, value }));
184
- }, []);
185
-
186
- const setSelectedEnvKey = useCallback((key: string | null) => {
187
- setEnvEdit((prev) => ({ ...prev, selectedKey: key }));
188
- }, []);
189
-
190
- // プロファイル一覧アイテム
191
- const profileItems: ProfileItem[] = useMemo(() => {
192
- if (!profiles) return [];
193
- const items = Object.entries(profiles.profiles).map(([name, profile]) => ({
194
- label: `${profile.displayName}${name === activeProfileName ? " (active)" : ""}`,
195
- value: name,
196
- profileName: name,
197
- isActive: name === activeProfileName,
198
- }));
199
- return [
200
- {
201
- label: `(none)${activeProfileName === null ? " (active)" : ""}`,
202
- value: NO_PROFILE_VALUE,
203
- profileName: null,
204
- isActive: activeProfileName === null,
205
- },
206
- ...items,
207
- ];
208
- }, [profiles, activeProfileName]);
209
-
210
- // 現在選択中のプロファイル
211
- const currentProfile =
212
- selectedProfileName && profiles
213
- ? profiles.profiles[selectedProfileName]
214
- : null;
215
-
216
- // 環境変数一覧アイテム
217
- const envItems: EnvVarItem[] = useMemo(() => {
218
- if (!currentProfile) return [];
219
- return Object.entries(currentProfile.env).map(([key, value]) => ({
220
- label: `${key}=${value}`,
221
- value: key,
222
- key,
223
- envValue: value,
224
- }));
225
- }, [currentProfile]);
226
-
227
- // OS環境変数(プロファイルで上書きされるものをハイライト)
228
- const osEnvItems = useMemo(() => {
229
- const profileEnvKeys = new Set(
230
- currentProfile ? Object.keys(currentProfile.env) : [],
231
- );
232
- return Object.entries(process.env)
233
- .filter(([, value]) => value !== undefined)
234
- .map(([key, value]) => ({
235
- key,
236
- value: value ?? "",
237
- isOverwritten: profileEnvKeys.has(key),
238
- }))
239
- .sort((a, b) => a.key.localeCompare(b.key));
240
- }, [currentProfile]);
241
-
242
- // 配列サイズ変更に追従してインデックスをクランプ(削除後の範囲外アクセス防止)
243
- useEffect(() => {
244
- if (profileItems.length === 0) {
245
- if (profileIndex !== 0) {
246
- setProfileIndex(0);
247
- }
248
- return;
249
- }
250
- if (profileIndex >= profileItems.length) {
251
- setProfileIndex(profileItems.length - 1);
252
- }
253
- }, [profileItems.length, profileIndex, setProfileIndex]);
254
-
255
- useEffect(() => {
256
- if (envItems.length === 0) {
257
- if (envIndex !== 0) {
258
- setEnvIndex(0);
259
- }
260
- return;
261
- }
262
- if (envIndex >= envItems.length) {
263
- setEnvIndex(envItems.length - 1);
264
- }
265
- }, [envItems.length, envIndex, setEnvIndex]);
266
-
267
- useEffect(() => {
268
- if (osEnvItems.length === 0) {
269
- if (osEnvIndex !== 0) {
270
- setOsEnvIndex(0);
271
- }
272
- return;
273
- }
274
- if (osEnvIndex >= osEnvItems.length) {
275
- setOsEnvIndex(osEnvItems.length - 1);
276
- }
277
- }, [osEnvItems.length, osEnvIndex, setOsEnvIndex]);
278
-
279
- // プロファイルを選択してアクティブ化
280
- const handleActivateProfile = useCallback(
281
- async (item: ProfileItem) => {
282
- try {
283
- await setActiveProfile(item.profileName);
284
- if (item.profileName === null) {
285
- setSelectedProfileName(null);
286
- setFocus("profiles");
287
- setProfileIndex(0);
288
- setMode("list");
289
- return;
290
- }
291
-
292
- setSelectedProfileName(item.profileName);
293
- setFocus("env"); // viewモードでは環境変数にフォーカス
294
- setMode("view");
295
- } catch {
296
- // エラー状態は useProfiles フック側で管理するため、ここでは握りつぶす
297
- }
298
- },
299
- [setActiveProfile, setSelectedProfileName, setFocus, setProfileIndex],
300
- );
301
-
302
- // 新規プロファイル作成開始
303
- const handleStartCreateProfile = useCallback(() => {
304
- setNewProfileName("");
305
- setNewProfileDisplayName("");
306
- setValidationError(null);
307
- setMode("create-name");
308
- }, []);
309
-
310
- // 新規プロファイル名入力完了
311
- const handleCreateNameSubmit = useCallback((name: string) => {
312
- if (!isValidProfileName(name)) {
313
- setValidationError(
314
- "Invalid profile name. Use lowercase letters, numbers, and hyphens (must start and end with a letter or number).",
315
- );
316
- return;
317
- }
318
- setValidationError(null);
319
- setNewProfileName(name);
320
- setNewProfileDisplayName(name);
321
- setMode("create-display");
322
- }, []);
323
-
324
- // 新規プロファイル作成完了
325
- const handleCreateProfileSubmit = useCallback(
326
- async (displayName: string) => {
327
- try {
328
- await createProfile(newProfileName, {
329
- displayName,
330
- env: {},
331
- });
332
- setSelectedProfileName(newProfileName);
333
- setFocus("env"); // viewモードでは環境変数にフォーカス
334
- setMode("view");
335
- } catch {
336
- // エラー状態は useProfiles フック側で管理するため、ここでは一覧に戻す
337
- setMode("list");
338
- }
339
- },
340
- [createProfile, newProfileName],
341
- );
342
-
343
- // プロファイル削除確認
344
- const handleConfirmDeleteProfile = useCallback(
345
- async (confirmed: boolean) => {
346
- if (confirmed && selectedProfileName) {
347
- try {
348
- await deleteProfile(selectedProfileName);
349
- setSelectedProfileName(null);
350
- } catch {
351
- // エラー状態は useProfiles フック側で管理するため、ここでは握りつぶす
352
- }
353
- }
354
- setMode("list");
355
- },
356
- [deleteProfile, selectedProfileName],
357
- );
358
-
359
- // 環境変数追加開始
360
- const handleStartAddEnv = useCallback(() => {
361
- setNewEnvKey("");
362
- setNewEnvValue("");
363
- setValidationError(null);
364
- setMode("add-env-key");
365
- }, []);
366
-
367
- // 環境変数キー入力完了
368
- const handleEnvKeySubmit = useCallback((key: string) => {
369
- const trimmedKey = key.trim();
370
- if (!trimmedKey || !ENV_VAR_KEY_PATTERN.test(trimmedKey)) {
371
- setValidationError(
372
- "Invalid variable name. Use letters, numbers, and underscores (must start with a letter or underscore).",
373
- );
374
- setNewEnvKey(trimmedKey);
375
- return;
376
- }
377
-
378
- setValidationError(null);
379
- setNewEnvKey(trimmedKey);
380
- setMode("add-env-value");
381
- }, []);
382
-
383
- // 環境変数追加完了
384
- const handleEnvValueSubmit = useCallback(
385
- async (value: string) => {
386
- if (selectedProfileName) {
387
- try {
388
- await updateEnvVar(selectedProfileName, newEnvKey, value);
389
- } catch {
390
- // エラー状態は useProfiles フック側で管理するため、ここでは握りつぶす
391
- }
392
- }
393
- setMode("view");
394
- },
395
- [updateEnvVar, selectedProfileName, newEnvKey],
396
- );
397
-
398
- // 環境変数編集開始
399
- const handleStartEditEnv = useCallback(
400
- (key: string, currentValue: string) => {
401
- setSelectedEnvKey(key);
402
- setNewEnvValue(currentValue);
403
- setMode("edit-env-value");
404
- },
405
- [],
406
- );
407
-
408
- // 環境変数編集完了
409
- const handleEditEnvSubmit = useCallback(
410
- async (value: string) => {
411
- if (selectedProfileName && selectedEnvKey) {
412
- try {
413
- await updateEnvVar(selectedProfileName, selectedEnvKey, value);
414
- } catch {
415
- // エラー状態は useProfiles フック側で管理するため、ここでは握りつぶす
416
- }
417
- }
418
- setMode("view");
419
- },
420
- [updateEnvVar, selectedProfileName, selectedEnvKey],
421
- );
422
-
423
- // 環境変数削除確認
424
- const handleConfirmDeleteEnv = useCallback(
425
- async (confirmed: boolean) => {
426
- if (confirmed && selectedProfileName && selectedEnvKey) {
427
- try {
428
- await deleteEnvVar(selectedProfileName, selectedEnvKey);
429
- } catch {
430
- // エラー状態は useProfiles フック側で管理するため、ここでは握りつぶす
431
- }
432
- }
433
- setMode("view");
434
- },
435
- [deleteEnvVar, selectedProfileName, selectedEnvKey],
436
- );
437
-
438
- // キーボード入力ハンドリング
439
- useAppInput(
440
- (input, key) => {
441
- // 入力モード時は他のキーハンドリングをスキップ
442
- if (
443
- mode === "create-name" ||
444
- mode === "create-display" ||
445
- mode === "add-env-key" ||
446
- mode === "add-env-value" ||
447
- mode === "edit-env-value"
448
- ) {
449
- if (key.escape) {
450
- setMode(mode.startsWith("create") ? "list" : "view");
451
- }
452
- return;
453
- }
454
-
455
- // 確認ダイアログ時は Confirm コンポーネントがハンドリング
456
- if (mode === "confirm-delete-profile" || mode === "confirm-delete-env") {
457
- return;
458
- }
459
-
460
- // Escape で戻る
461
- if (key.escape) {
462
- if (mode === "view") {
463
- setMode("list");
464
- setSelectedProfileName(null);
465
- } else {
466
- onBack();
467
- }
468
- return;
469
- }
470
-
471
- // プロファイル一覧モード
472
- if (mode === "list") {
473
- if (input === "n") {
474
- handleStartCreateProfile();
475
- return;
476
- }
477
- if (input === "d" && profileItems.length > 0) {
478
- const item = profileItems[profileIndex];
479
- if (item?.profileName && item.profileName !== activeProfileName) {
480
- setSelectedProfileName(item.profileName);
481
- setMode("confirm-delete-profile");
482
- }
483
- return;
484
- }
485
- return;
486
- }
487
-
488
- // プロファイル詳細モード
489
- if (mode === "view") {
490
- // Tab でフォーカス切り替え (env ↔ osenv)
491
- if (key.tab) {
492
- setFocus((prev) => (prev === "env" ? "osenv" : "env"));
493
- return;
494
- }
495
-
496
- // j/k でスクロール
497
- if (input === "j" || key.downArrow) {
498
- if (focus === "env") {
499
- setEnvIndex((prev) =>
500
- Math.min(prev + 1, Math.max(0, envItems.length - 1)),
501
- );
502
- } else if (focus === "osenv") {
503
- setOsEnvIndex((prev) =>
504
- Math.min(prev + 1, Math.max(0, osEnvItems.length - 1)),
505
- );
506
- }
507
- return;
508
- }
509
- if (input === "k" || key.upArrow) {
510
- if (focus === "env") {
511
- setEnvIndex((prev) => Math.max(prev - 1, 0));
512
- } else if (focus === "osenv") {
513
- setOsEnvIndex((prev) => Math.max(prev - 1, 0));
514
- }
515
- return;
516
- }
517
-
518
- // 環境変数操作
519
- if (focus === "env") {
520
- if (input === "a") {
521
- handleStartAddEnv();
522
- return;
523
- }
524
- if (input === "e" && envItems.length > 0) {
525
- const item = envItems[envIndex];
526
- if (item) {
527
- handleStartEditEnv(item.key, item.envValue);
528
- }
529
- return;
530
- }
531
- if (input === "d" && envItems.length > 0) {
532
- const item = envItems[envIndex];
533
- if (item) {
534
- setSelectedEnvKey(item.key);
535
- setMode("confirm-delete-env");
536
- }
537
- return;
538
- }
539
- }
540
- }
541
- },
542
- { isActive: true },
543
- );
544
-
545
- // フッターアクション
546
- const getFooterActions = () => {
547
- if (mode === "list") {
548
- return [
549
- { key: "enter", description: "Select" },
550
- { key: "n", description: "New" },
551
- { key: "d", description: "Delete" },
552
- { key: "esc", description: "Back" },
553
- ];
554
- }
555
- if (mode === "view") {
556
- return [
557
- { key: "tab", description: "Switch focus" },
558
- { key: "j/k", description: "Scroll" },
559
- { key: "a", description: "Add env" },
560
- { key: "e", description: "Edit env" },
561
- { key: "d", description: "Delete env" },
562
- { key: "esc", description: "Back" },
563
- ];
564
- }
565
- return [{ key: "esc", description: "Cancel" }];
566
- };
567
-
568
- // ローディング表示
569
- if (loading) {
570
- return (
571
- <Box flexDirection="column" height={rows}>
572
- <Header
573
- title="Environment Profiles"
574
- titleColor="magenta"
575
- version={version}
576
- />
577
- <Box flexGrow={1} justifyContent="center" alignItems="center">
578
- <Text>Loading profiles...</Text>
579
- </Box>
580
- </Box>
581
- );
582
- }
583
-
584
- // エラー表示
585
- if (error) {
586
- return (
587
- <Box flexDirection="column" height={rows}>
588
- <Header
589
- title="Environment Profiles"
590
- titleColor="magenta"
591
- version={version}
592
- />
593
- <Box flexGrow={1} marginTop={1}>
594
- <Text color="red">Error: {error.message}</Text>
595
- </Box>
596
- <Footer actions={[{ key: "esc", description: "Back" }]} />
597
- </Box>
598
- );
599
- }
600
-
601
- // 新規プロファイル作成:名前入力
602
- if (mode === "create-name") {
603
- return (
604
- <Box flexDirection="column" height={rows}>
605
- <Header
606
- title="Environment Profiles"
607
- titleColor="magenta"
608
- version={version}
609
- />
610
- <Box flexDirection="column" flexGrow={1} marginTop={1}>
611
- <Text>Create new profile</Text>
612
- <Box marginTop={1}>
613
- <Input
614
- value={newProfileName}
615
- onChange={setNewProfileName}
616
- onSubmit={handleCreateNameSubmit}
617
- label="Profile name (lowercase, a-z0-9-):"
618
- placeholder="development"
619
- />
620
- </Box>
621
- {validationError && (
622
- <Box marginTop={1}>
623
- <Text color="red">{validationError}</Text>
624
- </Box>
625
- )}
626
- </Box>
627
- <Footer actions={getFooterActions()} />
628
- </Box>
629
- );
630
- }
631
-
632
- // 新規プロファイル作成:表示名入力
633
- if (mode === "create-display") {
634
- return (
635
- <Box flexDirection="column" height={rows}>
636
- <Header
637
- title="Environment Profiles"
638
- titleColor="magenta"
639
- version={version}
640
- />
641
- <Box flexDirection="column" flexGrow={1} marginTop={1}>
642
- <Text>Create new profile: {newProfileName}</Text>
643
- <Box marginTop={1}>
644
- <Input
645
- value={newProfileDisplayName}
646
- onChange={setNewProfileDisplayName}
647
- onSubmit={handleCreateProfileSubmit}
648
- label="Display name:"
649
- placeholder="Development"
650
- />
651
- </Box>
652
- </Box>
653
- <Footer actions={getFooterActions()} />
654
- </Box>
655
- );
656
- }
657
-
658
- // 環境変数追加:キー入力
659
- if (mode === "add-env-key") {
660
- return (
661
- <Box flexDirection="column" height={rows}>
662
- <Header
663
- title="Environment Profiles"
664
- titleColor="magenta"
665
- version={version}
666
- />
667
- <Box flexDirection="column" flexGrow={1} marginTop={1}>
668
- <Text>Add environment variable</Text>
669
- <Box marginTop={1}>
670
- <Input
671
- value={newEnvKey}
672
- onChange={setNewEnvKey}
673
- onSubmit={handleEnvKeySubmit}
674
- label="Variable name:"
675
- placeholder="API_KEY"
676
- />
677
- </Box>
678
- {validationError && (
679
- <Box marginTop={1}>
680
- <Text color="red">{validationError}</Text>
681
- </Box>
682
- )}
683
- </Box>
684
- <Footer actions={getFooterActions()} />
685
- </Box>
686
- );
687
- }
688
-
689
- // 環境変数追加:値入力
690
- if (mode === "add-env-value") {
691
- return (
692
- <Box flexDirection="column" height={rows}>
693
- <Header
694
- title="Environment Profiles"
695
- titleColor="magenta"
696
- version={version}
697
- />
698
- <Box flexDirection="column" flexGrow={1} marginTop={1}>
699
- <Text>Add environment variable: {newEnvKey}</Text>
700
- <Box marginTop={1}>
701
- <Input
702
- value={newEnvValue}
703
- onChange={setNewEnvValue}
704
- onSubmit={handleEnvValueSubmit}
705
- label="Value:"
706
- placeholder="your-value"
707
- />
708
- </Box>
709
- </Box>
710
- <Footer actions={getFooterActions()} />
711
- </Box>
712
- );
713
- }
714
-
715
- // 環境変数編集:値入力
716
- if (mode === "edit-env-value") {
717
- return (
718
- <Box flexDirection="column" height={rows}>
719
- <Header
720
- title="Environment Profiles"
721
- titleColor="magenta"
722
- version={version}
723
- />
724
- <Box flexDirection="column" flexGrow={1} marginTop={1}>
725
- <Text>Edit environment variable: {selectedEnvKey}</Text>
726
- <Box marginTop={1}>
727
- <Input
728
- value={newEnvValue}
729
- onChange={setNewEnvValue}
730
- onSubmit={handleEditEnvSubmit}
731
- label="New value:"
732
- placeholder="new-value"
733
- />
734
- </Box>
735
- </Box>
736
- <Footer actions={getFooterActions()} />
737
- </Box>
738
- );
739
- }
740
-
741
- // プロファイル削除確認
742
- if (mode === "confirm-delete-profile") {
743
- const profileToDelete = selectedProfileName
744
- ? profiles?.profiles[selectedProfileName]
745
- : null;
746
- return (
747
- <Box flexDirection="column" height={rows}>
748
- <Header
749
- title="Environment Profiles"
750
- titleColor="magenta"
751
- version={version}
752
- />
753
- <Box flexDirection="column" flexGrow={1} marginTop={1}>
754
- <Confirm
755
- message={`Delete profile "${profileToDelete?.displayName ?? selectedProfileName}"?`}
756
- onConfirm={handleConfirmDeleteProfile}
757
- />
758
- </Box>
759
- </Box>
760
- );
761
- }
762
-
763
- // 環境変数削除確認
764
- if (mode === "confirm-delete-env") {
765
- return (
766
- <Box flexDirection="column" height={rows}>
767
- <Header
768
- title="Environment Profiles"
769
- titleColor="magenta"
770
- version={version}
771
- />
772
- <Box flexDirection="column" flexGrow={1} marginTop={1}>
773
- <Confirm
774
- message={`Delete environment variable "${selectedEnvKey}"?`}
775
- onConfirm={handleConfirmDeleteEnv}
776
- />
777
- </Box>
778
- </Box>
779
- );
780
- }
781
-
782
- // プロファイル一覧
783
- if (mode === "list") {
784
- const hasProfiles = Boolean(
785
- profiles && Object.keys(profiles.profiles).length > 0,
786
- );
787
- return (
788
- <Box flexDirection="column" height={rows}>
789
- <Header
790
- title="Environment Profiles"
791
- titleColor="magenta"
792
- version={version}
793
- activeProfile={activeProfileName}
794
- />
795
-
796
- <Box flexDirection="column" flexGrow={1} marginTop={1}>
797
- <Box marginBottom={1}>
798
- <Text>Select a profile to activate (or choose "(none)"):</Text>
799
- </Box>
800
-
801
- <Select
802
- items={profileItems}
803
- onSelect={handleActivateProfile}
804
- selectedIndex={profileIndex}
805
- onSelectedIndexChange={setProfileIndex}
806
- />
807
- {!hasProfiles && (
808
- <Box marginTop={1}>
809
- <Text dimColor>No profiles. Press [n] to create one.</Text>
810
- </Box>
811
- )}
812
- </Box>
813
-
814
- <Footer actions={getFooterActions()} />
815
- </Box>
816
- );
817
- }
818
-
819
- // プロファイル詳細
820
- const maxOsEnvVisible = Math.max(
821
- 5,
822
- Math.floor((rows - UI_CHROME_HEIGHT) / 2),
823
- );
824
-
825
- return (
826
- <Box flexDirection="column" height={rows}>
827
- <Header
828
- title="Environment Profiles"
829
- titleColor="magenta"
830
- version={version}
831
- activeProfile={activeProfileName}
832
- />
833
-
834
- <Box flexDirection="column" flexGrow={1} marginTop={1}>
835
- {/* プロファイル情報 */}
836
- <Box marginBottom={1}>
837
- <Text bold>Profile: </Text>
838
- <Text color="cyan">
839
- {currentProfile?.displayName ?? selectedProfileName}
840
- </Text>
841
- {selectedProfileName === activeProfileName && (
842
- <Text color="green"> (active)</Text>
843
- )}
844
- </Box>
845
-
846
- {currentProfile?.description && (
847
- <Box marginBottom={1}>
848
- <Text dimColor>{currentProfile.description}</Text>
849
- </Box>
850
- )}
851
-
852
- {/* プロファイル環境変数 */}
853
- <Box marginBottom={1}>
854
- <Text bold {...(focus === "env" ? { color: "cyan" as const } : {})}>
855
- Profile Environment Variables:
856
- </Text>
857
- </Box>
858
-
859
- <Box flexDirection="column" marginLeft={2} marginBottom={1}>
860
- {envItems.length === 0 ? (
861
- <Text dimColor>No environment variables. Press [a] to add.</Text>
862
- ) : (
863
- envItems.map((item, idx) => {
864
- const isEnvSelected = focus === "env" && idx === envIndex;
865
- return (
866
- <Box key={item.key}>
867
- <Text
868
- {...(isEnvSelected ? { color: "cyan" as const } : {})}
869
- inverse={isEnvSelected}
870
- >
871
- {item.key}
872
- </Text>
873
- <Text>=</Text>
874
- <Text>{item.envValue}</Text>
875
- </Box>
876
- );
877
- })
878
- )}
879
- </Box>
880
-
881
- {/* OS環境変数(上書きされるものをハイライト) */}
882
- <Box marginBottom={1}>
883
- <Text bold {...(focus === "osenv" ? { color: "cyan" as const } : {})}>
884
- OS Environment (overwritten keys in yellow):
885
- </Text>
886
- </Box>
887
-
888
- <Box flexDirection="column" marginLeft={2} overflow="hidden">
889
- {osEnvItems
890
- .slice(osEnvIndex, osEnvIndex + maxOsEnvVisible)
891
- .map((item, idx) => {
892
- // osEnvIndex は「選択中のOS環境変数のインデックス」であり、同時にスクロールの先頭位置でもある
893
- // そのため、表示上は slice した先頭要素が選択状態になる
894
- const actualIndex = osEnvIndex + idx;
895
- const isOsEnvSelected =
896
- focus === "osenv" && actualIndex === osEnvIndex;
897
- return (
898
- <Box key={item.key}>
899
- <Text
900
- {...(item.isOverwritten
901
- ? { color: "yellow" as const }
902
- : {})}
903
- inverse={isOsEnvSelected}
904
- >
905
- {item.key}
906
- </Text>
907
- <Text>=</Text>
908
- <Text dimColor>
909
- {item.value.slice(0, 50)}
910
- {item.value.length > 50 ? "..." : ""}
911
- </Text>
912
- </Box>
913
- );
914
- })}
915
- {osEnvItems.length > maxOsEnvVisible && (
916
- <Text dimColor>
917
- ... ({osEnvIndex + 1}-
918
- {Math.min(osEnvIndex + maxOsEnvVisible, osEnvItems.length)} of{" "}
919
- {osEnvItems.length})
920
- </Text>
921
- )}
922
- </Box>
923
- </Box>
924
-
925
- <Footer actions={getFooterActions()} />
926
- </Box>
927
- );
928
- }