@akiojin/gwt 2.12.1 → 2.14.0
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.
- package/README.ja.md +33 -0
- package/README.md +31 -0
- package/dist/claude.d.ts.map +1 -1
- package/dist/claude.js +17 -11
- package/dist/claude.js.map +1 -1
- package/dist/cli/ui/components/App.d.ts +0 -6
- package/dist/cli/ui/components/App.d.ts.map +1 -1
- package/dist/cli/ui/components/App.js +93 -85
- package/dist/cli/ui/components/App.js.map +1 -1
- package/dist/cli/ui/components/common/Select.js +2 -2
- package/dist/cli/ui/components/common/Select.js.map +1 -1
- package/dist/cli/ui/components/screens/BranchListScreen.d.ts +3 -1
- package/dist/cli/ui/components/screens/BranchListScreen.d.ts.map +1 -1
- package/dist/cli/ui/components/screens/BranchListScreen.js +168 -34
- package/dist/cli/ui/components/screens/BranchListScreen.js.map +1 -1
- package/dist/cli/ui/components/screens/BranchQuickStartScreen.d.ts.map +1 -1
- package/dist/cli/ui/components/screens/BranchQuickStartScreen.js +3 -3
- package/dist/cli/ui/components/screens/BranchQuickStartScreen.js.map +1 -1
- package/dist/cli/ui/hooks/useGitData.d.ts.map +1 -1
- package/dist/cli/ui/hooks/useGitData.js +17 -0
- package/dist/cli/ui/hooks/useGitData.js.map +1 -1
- package/dist/cli/ui/types.d.ts +2 -0
- package/dist/cli/ui/types.d.ts.map +1 -1
- package/dist/cli/ui/utils/branchFormatter.d.ts.map +1 -1
- package/dist/cli/ui/utils/branchFormatter.js +7 -2
- package/dist/cli/ui/utils/branchFormatter.js.map +1 -1
- package/dist/cli/ui/utils/continueSession.d.ts.map +1 -1
- package/dist/cli/ui/utils/continueSession.js +1 -1
- package/dist/cli/ui/utils/continueSession.js.map +1 -1
- package/dist/cli/ui/utils/modelOptions.d.ts.map +1 -1
- package/dist/cli/ui/utils/modelOptions.js +7 -0
- package/dist/cli/ui/utils/modelOptions.js.map +1 -1
- package/dist/client/assets/index-DPWWHorC.js +72 -0
- package/dist/client/assets/index-DsDNCy5f.css +1 -0
- package/dist/client/index.html +2 -2
- package/dist/codex.d.ts.map +1 -1
- package/dist/codex.js +21 -11
- package/dist/codex.js.map +1 -1
- package/dist/config/builtin-tools.d.ts.map +1 -1
- package/dist/config/builtin-tools.js +3 -2
- package/dist/config/builtin-tools.js.map +1 -1
- package/dist/config/shared-env.d.ts +41 -0
- package/dist/config/shared-env.d.ts.map +1 -0
- package/dist/config/shared-env.js +114 -0
- package/dist/config/shared-env.js.map +1 -0
- package/dist/gemini.d.ts.map +1 -1
- package/dist/gemini.js +20 -17
- package/dist/gemini.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +55 -7
- package/dist/index.js.map +1 -1
- package/dist/logging/logger.d.ts +24 -0
- package/dist/logging/logger.d.ts.map +1 -0
- package/dist/logging/logger.js +60 -0
- package/dist/logging/logger.js.map +1 -0
- package/dist/logging/rotation.d.ts +6 -0
- package/dist/logging/rotation.d.ts.map +1 -0
- package/dist/logging/rotation.js +26 -0
- package/dist/logging/rotation.js.map +1 -0
- package/dist/qwen.d.ts.map +1 -1
- package/dist/qwen.js +15 -11
- package/dist/qwen.js.map +1 -1
- package/dist/services/aiToolResolver.d.ts +41 -0
- package/dist/services/aiToolResolver.d.ts.map +1 -0
- package/dist/services/aiToolResolver.js +194 -0
- package/dist/services/aiToolResolver.js.map +1 -0
- package/dist/services/customToolResolver.d.ts +10 -0
- package/dist/services/customToolResolver.d.ts.map +1 -0
- package/dist/services/customToolResolver.js +71 -0
- package/dist/services/customToolResolver.js.map +1 -0
- package/dist/shared/aiToolConstants.d.ts +9 -0
- package/dist/shared/aiToolConstants.d.ts.map +1 -0
- package/dist/shared/aiToolConstants.js +29 -0
- package/dist/shared/aiToolConstants.js.map +1 -0
- package/dist/types/tools.d.ts +12 -0
- package/dist/types/tools.d.ts.map +1 -1
- package/dist/utils/prompt.d.ts.map +1 -1
- package/dist/utils/prompt.js.map +1 -1
- package/dist/utils/session.d.ts.map +1 -1
- package/dist/utils/session.js +15 -6
- package/dist/utils/session.js.map +1 -1
- package/dist/utils/terminal.d.ts +12 -3
- package/dist/utils/terminal.d.ts.map +1 -1
- package/dist/utils/terminal.js +5 -34
- package/dist/utils/terminal.js.map +1 -1
- package/dist/utils/webui.d.ts +8 -0
- package/dist/utils/webui.d.ts.map +1 -0
- package/dist/utils/webui.js +35 -0
- package/dist/utils/webui.js.map +1 -0
- package/dist/web/client/src/components/AIToolLaunchModal.d.ts +9 -0
- package/dist/web/client/src/components/AIToolLaunchModal.d.ts.map +1 -0
- package/dist/web/client/src/components/AIToolLaunchModal.js +363 -0
- package/dist/web/client/src/components/AIToolLaunchModal.js.map +1 -0
- package/dist/web/client/src/components/BranchGraph.d.ts.map +1 -1
- package/dist/web/client/src/components/BranchGraph.js +46 -49
- package/dist/web/client/src/components/BranchGraph.js.map +1 -1
- package/dist/web/client/src/components/CustomToolForm.d.ts +23 -0
- package/dist/web/client/src/components/CustomToolForm.d.ts.map +1 -0
- package/dist/web/client/src/components/CustomToolForm.js +209 -0
- package/dist/web/client/src/components/CustomToolForm.js.map +1 -0
- package/dist/web/client/src/components/CustomToolList.d.ts +10 -0
- package/dist/web/client/src/components/CustomToolList.d.ts.map +1 -0
- package/dist/web/client/src/components/CustomToolList.js +57 -0
- package/dist/web/client/src/components/CustomToolList.js.map +1 -0
- package/dist/web/client/src/components/EnvEditor.d.ts.map +1 -1
- package/dist/web/client/src/components/EnvEditor.js +33 -26
- package/dist/web/client/src/components/EnvEditor.js.map +1 -1
- package/dist/web/client/src/components/EnvironmentEditor.d.ts +17 -0
- package/dist/web/client/src/components/EnvironmentEditor.d.ts.map +1 -0
- package/dist/web/client/src/components/EnvironmentEditor.js +22 -0
- package/dist/web/client/src/components/EnvironmentEditor.js.map +1 -0
- package/dist/web/client/src/components/Terminal.d.ts.map +1 -1
- package/dist/web/client/src/components/Terminal.js +10 -3
- package/dist/web/client/src/components/Terminal.js.map +1 -1
- package/dist/web/client/src/components/branch-detail/BranchInfoCards.d.ts +10 -0
- package/dist/web/client/src/components/branch-detail/BranchInfoCards.d.ts.map +1 -0
- package/dist/web/client/src/components/branch-detail/BranchInfoCards.js +104 -0
- package/dist/web/client/src/components/branch-detail/BranchInfoCards.js.map +1 -0
- package/dist/web/client/src/components/branch-detail/SessionHistoryTable.d.ts +22 -0
- package/dist/web/client/src/components/branch-detail/SessionHistoryTable.d.ts.map +1 -0
- package/dist/web/client/src/components/branch-detail/SessionHistoryTable.js +79 -0
- package/dist/web/client/src/components/branch-detail/SessionHistoryTable.js.map +1 -0
- package/dist/web/client/src/components/branch-detail/TerminalPanel.d.ts +11 -0
- package/dist/web/client/src/components/branch-detail/TerminalPanel.d.ts.map +1 -0
- package/dist/web/client/src/components/branch-detail/TerminalPanel.js +32 -0
- package/dist/web/client/src/components/branch-detail/TerminalPanel.js.map +1 -0
- package/dist/web/client/src/components/branch-detail/ToolLauncher.d.ts +40 -0
- package/dist/web/client/src/components/branch-detail/ToolLauncher.d.ts.map +1 -0
- package/dist/web/client/src/components/branch-detail/ToolLauncher.js +147 -0
- package/dist/web/client/src/components/branch-detail/ToolLauncher.js.map +1 -0
- package/dist/web/client/src/components/branch-detail/index.d.ts +5 -0
- package/dist/web/client/src/components/branch-detail/index.d.ts.map +1 -0
- package/dist/web/client/src/components/branch-detail/index.js +5 -0
- package/dist/web/client/src/components/branch-detail/index.js.map +1 -0
- package/dist/web/client/src/components/common/BranchCard.d.ts +17 -0
- package/dist/web/client/src/components/common/BranchCard.d.ts.map +1 -0
- package/dist/web/client/src/components/common/BranchCard.js +36 -0
- package/dist/web/client/src/components/common/BranchCard.js.map +1 -0
- package/dist/web/client/src/components/common/MetricCard.d.ts +10 -0
- package/dist/web/client/src/components/common/MetricCard.d.ts.map +1 -0
- package/dist/web/client/src/components/common/MetricCard.js +10 -0
- package/dist/web/client/src/components/common/MetricCard.js.map +1 -0
- package/dist/web/client/src/components/common/PageHeader.d.ts +12 -0
- package/dist/web/client/src/components/common/PageHeader.d.ts.map +1 -0
- package/dist/web/client/src/components/common/PageHeader.js +14 -0
- package/dist/web/client/src/components/common/PageHeader.js.map +1 -0
- package/dist/web/client/src/components/common/SearchInput.d.ts +14 -0
- package/dist/web/client/src/components/common/SearchInput.d.ts.map +1 -0
- package/dist/web/client/src/components/common/SearchInput.js +15 -0
- package/dist/web/client/src/components/common/SearchInput.js.map +1 -0
- package/dist/web/client/src/components/common/StatusBadge.d.ts +10 -0
- package/dist/web/client/src/components/common/StatusBadge.d.ts.map +1 -0
- package/dist/web/client/src/components/common/StatusBadge.js +15 -0
- package/dist/web/client/src/components/common/StatusBadge.js.map +1 -0
- package/dist/web/client/src/components/common/index.d.ts +6 -0
- package/dist/web/client/src/components/common/index.d.ts.map +1 -0
- package/dist/web/client/src/components/common/index.js +6 -0
- package/dist/web/client/src/components/common/index.js.map +1 -0
- package/dist/web/client/src/components/ui/alert.d.ts +9 -0
- package/dist/web/client/src/components/ui/alert.d.ts.map +1 -0
- package/dist/web/client/src/components/ui/alert.js +25 -0
- package/dist/web/client/src/components/ui/alert.js.map +1 -0
- package/dist/web/client/src/components/ui/badge.d.ts +10 -0
- package/dist/web/client/src/components/ui/badge.d.ts.map +1 -0
- package/dist/web/client/src/components/ui/badge.js +25 -0
- package/dist/web/client/src/components/ui/badge.js.map +1 -0
- package/dist/web/client/src/components/ui/button.d.ts +12 -0
- package/dist/web/client/src/components/ui/button.d.ts.map +1 -0
- package/dist/web/client/src/components/ui/button.js +33 -0
- package/dist/web/client/src/components/ui/button.js.map +1 -0
- package/dist/web/client/src/components/ui/card.d.ts +9 -0
- package/dist/web/client/src/components/ui/card.d.ts.map +1 -0
- package/dist/web/client/src/components/ui/card.js +16 -0
- package/dist/web/client/src/components/ui/card.js.map +1 -0
- package/dist/web/client/src/components/ui/index.d.ts +8 -0
- package/dist/web/client/src/components/ui/index.d.ts.map +1 -0
- package/dist/web/client/src/components/ui/index.js +8 -0
- package/dist/web/client/src/components/ui/index.js.map +1 -0
- package/dist/web/client/src/components/ui/input.d.ts +4 -0
- package/dist/web/client/src/components/ui/input.d.ts.map +1 -0
- package/dist/web/client/src/components/ui/input.js +8 -0
- package/dist/web/client/src/components/ui/input.js.map +1 -0
- package/dist/web/client/src/components/ui/select.d.ts +14 -0
- package/dist/web/client/src/components/ui/select.d.ts.map +1 -0
- package/dist/web/client/src/components/ui/select.js +39 -0
- package/dist/web/client/src/components/ui/select.js.map +1 -0
- package/dist/web/client/src/components/ui/table.d.ts +11 -0
- package/dist/web/client/src/components/ui/table.d.ts.map +1 -0
- package/dist/web/client/src/components/ui/table.js +21 -0
- package/dist/web/client/src/components/ui/table.js.map +1 -0
- package/dist/web/client/src/hooks/useSessions.d.ts.map +1 -1
- package/dist/web/client/src/hooks/useSessions.js +6 -1
- package/dist/web/client/src/hooks/useSessions.js.map +1 -1
- package/dist/web/client/src/lib/utils.d.ts +7 -0
- package/dist/web/client/src/lib/utils.d.ts.map +1 -0
- package/dist/web/client/src/lib/utils.js +10 -0
- package/dist/web/client/src/lib/utils.js.map +1 -0
- package/dist/web/client/src/lib/websocket.d.ts +7 -0
- package/dist/web/client/src/lib/websocket.d.ts.map +1 -1
- package/dist/web/client/src/lib/websocket.js +44 -0
- package/dist/web/client/src/lib/websocket.js.map +1 -1
- package/dist/web/client/src/pages/BranchDetailPage.d.ts.map +1 -1
- package/dist/web/client/src/pages/BranchDetailPage.js +113 -361
- package/dist/web/client/src/pages/BranchDetailPage.js.map +1 -1
- package/dist/web/client/src/pages/BranchListPage.d.ts.map +1 -1
- package/dist/web/client/src/pages/BranchListPage.js +89 -127
- package/dist/web/client/src/pages/BranchListPage.js.map +1 -1
- package/dist/web/client/src/pages/ConfigManagementPage.d.ts.map +1 -1
- package/dist/web/client/src/pages/ConfigManagementPage.js +46 -41
- package/dist/web/client/src/pages/ConfigManagementPage.js.map +1 -1
- package/dist/web/client/src/pages/ConfigPage.d.ts +3 -0
- package/dist/web/client/src/pages/ConfigPage.d.ts.map +1 -0
- package/dist/web/client/src/pages/ConfigPage.js +216 -0
- package/dist/web/client/src/pages/ConfigPage.js.map +1 -0
- package/dist/web/client/vite.config.d.ts.map +1 -1
- package/dist/web/client/vite.config.js +8 -1
- package/dist/web/client/vite.config.js.map +1 -1
- package/dist/web/server/index.d.ts +24 -2
- package/dist/web/server/index.d.ts.map +1 -1
- package/dist/web/server/index.js +49 -18
- package/dist/web/server/index.js.map +1 -1
- package/dist/web/server/pty/manager.d.ts +12 -10
- package/dist/web/server/pty/manager.d.ts.map +1 -1
- package/dist/web/server/pty/manager.js +76 -43
- package/dist/web/server/pty/manager.js.map +1 -1
- package/dist/web/server/routes/branches.d.ts +2 -2
- package/dist/web/server/routes/branches.d.ts.map +1 -1
- package/dist/web/server/routes/branches.js.map +1 -1
- package/dist/web/server/routes/config.d.ts +2 -2
- package/dist/web/server/routes/config.d.ts.map +1 -1
- package/dist/web/server/routes/config.js.map +1 -1
- package/dist/web/server/routes/index.d.ts +2 -2
- package/dist/web/server/routes/index.d.ts.map +1 -1
- package/dist/web/server/routes/index.js.map +1 -1
- package/dist/web/server/routes/sessions.d.ts +2 -2
- package/dist/web/server/routes/sessions.d.ts.map +1 -1
- package/dist/web/server/routes/sessions.js +35 -2
- package/dist/web/server/routes/sessions.js.map +1 -1
- package/dist/web/server/routes/worktrees.d.ts +2 -2
- package/dist/web/server/routes/worktrees.d.ts.map +1 -1
- package/dist/web/server/routes/worktrees.js +2 -2
- package/dist/web/server/routes/worktrees.js.map +1 -1
- package/dist/web/server/services/worktrees.d.ts.map +1 -1
- package/dist/web/server/services/worktrees.js +7 -1
- package/dist/web/server/services/worktrees.js.map +1 -1
- package/dist/web/server/tray.d.ts +24 -0
- package/dist/web/server/tray.d.ts.map +1 -0
- package/dist/web/server/tray.js +79 -0
- package/dist/web/server/tray.js.map +1 -0
- package/dist/web/server/types.d.ts +4 -0
- package/dist/web/server/types.d.ts.map +1 -0
- package/dist/web/server/types.js +2 -0
- package/dist/web/server/types.js.map +1 -0
- package/dist/web/server/websocket/handler.d.ts +18 -2
- package/dist/web/server/websocket/handler.d.ts.map +1 -1
- package/dist/web/server/websocket/handler.js +82 -9
- package/dist/web/server/websocket/handler.js.map +1 -1
- package/dist/worktree.d.ts +1 -0
- package/dist/worktree.d.ts.map +1 -1
- package/dist/worktree.js.map +1 -1
- package/package.json +17 -3
- package/src/claude.ts +26 -15
- package/src/cli/ui/__tests__/components/ModelSelectorScreen.initial.test.tsx +13 -13
- package/src/cli/ui/__tests__/components/common/Select.test.tsx +11 -0
- package/src/cli/ui/__tests__/components/screens/BranchListScreen.test.tsx +97 -33
- package/src/cli/ui/__tests__/components/screens/BranchQuickStartScreen.test.tsx +4 -4
- package/src/cli/ui/__tests__/performance/branchList.performance.test.tsx +7 -3
- package/src/cli/ui/components/App.tsx +111 -125
- package/src/cli/ui/components/common/Select.tsx +2 -2
- package/src/cli/ui/components/screens/BranchListScreen.tsx +220 -34
- package/src/cli/ui/components/screens/BranchQuickStartScreen.tsx +41 -46
- package/src/cli/ui/hooks/useGitData.ts +20 -0
- package/src/cli/ui/types.ts +3 -0
- package/src/cli/ui/utils/branchFormatter.ts +7 -2
- package/src/cli/ui/utils/continueSession.ts +1 -7
- package/src/cli/ui/utils/modelOptions.test.ts +14 -0
- package/src/cli/ui/utils/modelOptions.ts +7 -0
- package/src/codex.ts +31 -22
- package/src/config/builtin-tools.ts +6 -2
- package/src/config/shared-env.ts +139 -0
- package/src/gemini.ts +35 -22
- package/src/index.ts +61 -7
- package/src/logging/logger.ts +82 -0
- package/src/logging/rotation.ts +25 -0
- package/src/qwen.ts +28 -19
- package/src/services/aiToolResolver.ts +276 -0
- package/src/services/customToolResolver.ts +98 -0
- package/src/shared/aiToolConstants.ts +30 -0
- package/src/trayicon.d.ts +30 -0
- package/src/types/tools.ts +15 -0
- package/src/utils/prompt.ts +15 -9
- package/src/utils/session.ts +80 -26
- package/src/utils/terminal.ts +11 -41
- package/src/utils/webui.ts +43 -0
- package/src/web/client/components.json +21 -0
- package/src/web/client/src/components/AIToolLaunchModal.tsx +575 -0
- package/src/web/client/src/components/BranchGraph.tsx +95 -75
- package/src/web/client/src/components/CustomToolForm.tsx +386 -0
- package/src/web/client/src/components/CustomToolList.tsx +119 -0
- package/src/web/client/src/components/EnvEditor.tsx +91 -81
- package/src/web/client/src/components/EnvironmentEditor.tsx +97 -0
- package/src/web/client/src/components/Terminal.tsx +11 -3
- package/src/web/client/src/components/branch-detail/BranchInfoCards.tsx +179 -0
- package/src/web/client/src/components/branch-detail/SessionHistoryTable.tsx +181 -0
- package/src/web/client/src/components/branch-detail/TerminalPanel.tsx +92 -0
- package/src/web/client/src/components/branch-detail/ToolLauncher.tsx +327 -0
- package/src/web/client/src/components/branch-detail/index.ts +4 -0
- package/src/web/client/src/components/common/BranchCard.tsx +117 -0
- package/src/web/client/src/components/common/MetricCard.tsx +22 -0
- package/src/web/client/src/components/common/PageHeader.tsx +44 -0
- package/src/web/client/src/components/common/SearchInput.tsx +40 -0
- package/src/web/client/src/components/common/StatusBadge.tsx +37 -0
- package/src/web/client/src/components/common/index.ts +5 -0
- package/src/web/client/src/components/ui/alert.tsx +63 -0
- package/src/web/client/src/components/ui/badge.tsx +44 -0
- package/src/web/client/src/components/ui/button.tsx +57 -0
- package/src/web/client/src/components/ui/card.tsx +82 -0
- package/src/web/client/src/components/ui/index.ts +32 -0
- package/src/web/client/src/components/ui/input.tsx +21 -0
- package/src/web/client/src/components/ui/select.tsx +156 -0
- package/src/web/client/src/components/ui/table.tsx +119 -0
- package/src/web/client/src/hooks/useSessions.ts +10 -1
- package/src/web/client/src/index.css +46 -816
- package/src/web/client/src/lib/utils.ts +10 -0
- package/src/web/client/src/lib/websocket.ts +48 -1
- package/src/web/client/src/pages/BranchDetailPage.tsx +222 -694
- package/src/web/client/src/pages/BranchListPage.tsx +190 -236
- package/src/web/client/src/pages/ConfigManagementPage.tsx +94 -76
- package/src/web/client/src/pages/ConfigPage.tsx +362 -0
- package/src/web/client/vite.config.ts +8 -1
- package/src/web/server/index.ts +78 -19
- package/src/web/server/pty/manager.ts +128 -55
- package/src/web/server/routes/branches.ts +2 -2
- package/src/web/server/routes/config.ts +2 -2
- package/src/web/server/routes/index.ts +2 -2
- package/src/web/server/routes/sessions.ts +61 -9
- package/src/web/server/routes/worktrees.ts +5 -5
- package/src/web/server/services/worktrees.ts +12 -4
- package/src/web/server/tray.ts +93 -0
- package/src/web/server/types.ts +14 -0
- package/src/web/server/websocket/handler.ts +119 -13
- package/src/worktree.ts +1 -0
- package/dist/client/assets/index-DeNwPosA.css +0 -1
- package/dist/client/assets/index-Dl798X5w.js +0 -32
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, { useCallback, useState, useMemo } from "react";
|
|
1
|
+
import React, { useCallback, useState, useMemo, useEffect } from "react";
|
|
2
2
|
import { Box, Text, useInput } from "ink";
|
|
3
3
|
import { Header } from "../parts/Header.js";
|
|
4
4
|
import { Stats } from "../parts/Stats.js";
|
|
@@ -9,8 +9,12 @@ import { LoadingIndicator } from "../common/LoadingIndicator.js";
|
|
|
9
9
|
import { useTerminalSize } from "../../hooks/useTerminalSize.js";
|
|
10
10
|
import type { BranchItem, Statistics } from "../../types.js";
|
|
11
11
|
import stringWidth from "string-width";
|
|
12
|
+
import stripAnsi from "strip-ansi";
|
|
12
13
|
import chalk from "chalk";
|
|
14
|
+
import { resolveWebUiPort } from "../../../../utils/webui.js";
|
|
13
15
|
|
|
16
|
+
// Emoji 幅は端末によって 1 または 2 になることがあるため、最小幅を上書きして
|
|
17
|
+
// 実測より小さくならないようにする(過小評価=折り返しの原因を防ぐ)
|
|
14
18
|
const WIDTH_OVERRIDES: Record<string, number> = {
|
|
15
19
|
// Remote icon
|
|
16
20
|
"☁": 1,
|
|
@@ -22,19 +26,24 @@ const WIDTH_OVERRIDES: Record<string, number> = {
|
|
|
22
26
|
"🚀": 1,
|
|
23
27
|
"📌": 1,
|
|
24
28
|
// Worktree status icons
|
|
25
|
-
"🟢":
|
|
29
|
+
"🟢": 2,
|
|
30
|
+
"⚪": 2,
|
|
26
31
|
"🟠": 1,
|
|
27
32
|
// Change status icons
|
|
28
33
|
"👉": 1,
|
|
29
34
|
"💾": 1,
|
|
30
35
|
"📤": 1,
|
|
31
36
|
"🔃": 1,
|
|
32
|
-
"✅":
|
|
33
|
-
"
|
|
37
|
+
"✅": 2,
|
|
38
|
+
"⚠": 2,
|
|
39
|
+
"⚠️": 2,
|
|
40
|
+
"🛡": 2,
|
|
34
41
|
// Remote markers
|
|
35
|
-
"🔗":
|
|
36
|
-
"💻":
|
|
37
|
-
"☁️":
|
|
42
|
+
"🔗": 2,
|
|
43
|
+
"💻": 2,
|
|
44
|
+
"☁️": 2,
|
|
45
|
+
"☑": 2,
|
|
46
|
+
"☐": 2,
|
|
38
47
|
};
|
|
39
48
|
|
|
40
49
|
const getCharWidth = (char: string): number => {
|
|
@@ -88,6 +97,8 @@ export interface BranchListScreenProps {
|
|
|
88
97
|
testOnFilterModeChange?: (mode: boolean) => void;
|
|
89
98
|
testFilterQuery?: string;
|
|
90
99
|
testOnFilterQueryChange?: (query: string) => void;
|
|
100
|
+
selectedBranches?: string[];
|
|
101
|
+
onToggleSelect?: (branchName: string) => void;
|
|
91
102
|
}
|
|
92
103
|
|
|
93
104
|
/**
|
|
@@ -111,11 +122,15 @@ export function BranchListScreen({
|
|
|
111
122
|
testOnFilterModeChange,
|
|
112
123
|
testFilterQuery,
|
|
113
124
|
testOnFilterQueryChange,
|
|
125
|
+
selectedBranches = [],
|
|
126
|
+
onToggleSelect,
|
|
114
127
|
}: BranchListScreenProps) {
|
|
115
128
|
const { rows } = useTerminalSize();
|
|
116
|
-
const
|
|
117
|
-
const
|
|
118
|
-
|
|
129
|
+
const headerText = " Legend: [ ]/[ * ] select 🟢/⚪ worktree 🛡/⚠ safe";
|
|
130
|
+
const selectedSet = useMemo(
|
|
131
|
+
() => new Set(selectedBranches),
|
|
132
|
+
[selectedBranches],
|
|
133
|
+
);
|
|
119
134
|
|
|
120
135
|
// Filter state - allow test control via props
|
|
121
136
|
const [internalFilterQuery, setInternalFilterQuery] = useState("");
|
|
@@ -142,6 +157,9 @@ export function BranchListScreen({
|
|
|
142
157
|
[testOnFilterModeChange],
|
|
143
158
|
);
|
|
144
159
|
|
|
160
|
+
// Cursor position for Select (controlled to enable space toggle)
|
|
161
|
+
const [selectedIndex, setSelectedIndex] = useState(0);
|
|
162
|
+
|
|
145
163
|
// Handle keyboard input
|
|
146
164
|
// Note: Input component blocks specific keys (c/r/f) using blockKeys prop
|
|
147
165
|
// This prevents shortcuts from triggering while typing in the filter
|
|
@@ -170,6 +188,15 @@ export function BranchListScreen({
|
|
|
170
188
|
return;
|
|
171
189
|
}
|
|
172
190
|
|
|
191
|
+
// Toggle selection with space (only in branch selection mode)
|
|
192
|
+
if (input === " " && !filterMode) {
|
|
193
|
+
const target = filteredBranches[selectedIndex];
|
|
194
|
+
if (target) {
|
|
195
|
+
onToggleSelect?.(target.name);
|
|
196
|
+
}
|
|
197
|
+
return;
|
|
198
|
+
}
|
|
199
|
+
|
|
173
200
|
// Disable global shortcuts while in filter mode
|
|
174
201
|
if (filterMode) {
|
|
175
202
|
return;
|
|
@@ -205,20 +232,36 @@ export function BranchListScreen({
|
|
|
205
232
|
});
|
|
206
233
|
}, [branches, filterQuery]);
|
|
207
234
|
|
|
235
|
+
useEffect(() => {
|
|
236
|
+
setSelectedIndex((prev) => {
|
|
237
|
+
if (filteredBranches.length === 0) {
|
|
238
|
+
return 0;
|
|
239
|
+
}
|
|
240
|
+
return Math.min(prev, filteredBranches.length - 1);
|
|
241
|
+
});
|
|
242
|
+
}, [filteredBranches.length]);
|
|
243
|
+
|
|
208
244
|
// Calculate available space for branch list
|
|
209
245
|
// Header: 2 lines (title + divider)
|
|
210
246
|
// Filter input: 1 line
|
|
211
247
|
// Stats: 1 line
|
|
212
248
|
// Empty line: 1 line
|
|
249
|
+
// Web UI URL: 1 line
|
|
213
250
|
// Footer: 1 line
|
|
214
|
-
// Total fixed:
|
|
251
|
+
// Total fixed: 7 lines
|
|
215
252
|
const headerLines = 2;
|
|
216
253
|
const filterLines = 1;
|
|
217
254
|
const statsLines = 1;
|
|
218
255
|
const emptyLine = 1;
|
|
256
|
+
const webUiLines = 1;
|
|
219
257
|
const footerLines = 1;
|
|
220
258
|
const fixedLines =
|
|
221
|
-
headerLines +
|
|
259
|
+
headerLines +
|
|
260
|
+
filterLines +
|
|
261
|
+
statsLines +
|
|
262
|
+
emptyLine +
|
|
263
|
+
webUiLines +
|
|
264
|
+
footerLines;
|
|
222
265
|
const contentHeight = rows - fixedLines;
|
|
223
266
|
const limit = Math.max(5, contentHeight); // Minimum 5 items visible
|
|
224
267
|
|
|
@@ -275,18 +318,70 @@ export function BranchListScreen({
|
|
|
275
318
|
return result + ellipsis;
|
|
276
319
|
}, []);
|
|
277
320
|
|
|
321
|
+
const colorToolLabel = useCallback(
|
|
322
|
+
(label: string, toolId?: string | null) => {
|
|
323
|
+
switch (toolId) {
|
|
324
|
+
case "claude-code":
|
|
325
|
+
return chalk.hex("#ffaf00")(label); // orange-ish
|
|
326
|
+
case "codex-cli":
|
|
327
|
+
return chalk.cyan(label);
|
|
328
|
+
case "gemini-cli":
|
|
329
|
+
return chalk.magenta(label);
|
|
330
|
+
case "qwen-cli":
|
|
331
|
+
return chalk.green(label);
|
|
332
|
+
default: {
|
|
333
|
+
const trimmed = label.trim().toLowerCase();
|
|
334
|
+
if (!toolId || trimmed === "unknown") {
|
|
335
|
+
return chalk.gray(label);
|
|
336
|
+
}
|
|
337
|
+
return chalk.white(label);
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
},
|
|
341
|
+
[],
|
|
342
|
+
);
|
|
343
|
+
|
|
278
344
|
const renderBranchRow = useCallback(
|
|
279
345
|
(item: BranchItem, isSelected: boolean, context: { columns: number }) => {
|
|
280
|
-
//
|
|
346
|
+
// 端末幅ピッタリでの自動折返しを避けるため、1桁だけ余白を取る
|
|
281
347
|
const columns = Math.max(20, context.columns - 1);
|
|
348
|
+
const visibleWidth = (value: string) =>
|
|
349
|
+
measureDisplayWidth(stripAnsi(value));
|
|
282
350
|
const arrow = isSelected ? ">" : " ";
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
351
|
+
let commitText = "---";
|
|
352
|
+
if (item.latestCommitTimestamp) {
|
|
353
|
+
commitText = formatLatestCommit(item.latestCommitTimestamp);
|
|
354
|
+
} else if (item.lastToolUsage?.timestamp) {
|
|
355
|
+
const seconds = Math.floor(item.lastToolUsage.timestamp / 1000);
|
|
356
|
+
commitText = formatLatestCommit(seconds);
|
|
357
|
+
}
|
|
358
|
+
const toolLabelRaw =
|
|
359
|
+
item.lastToolUsageLabel?.split("|")?.[0]?.trim() ??
|
|
360
|
+
item.lastToolUsage?.toolId ??
|
|
361
|
+
"Unknown";
|
|
362
|
+
|
|
363
|
+
const formatFixedWidth = (value: string, targetWidth: number) => {
|
|
364
|
+
let v = value;
|
|
365
|
+
if (measureDisplayWidth(v) > targetWidth) {
|
|
366
|
+
v = truncateToWidth(v, targetWidth);
|
|
367
|
+
}
|
|
368
|
+
const padding = Math.max(0, targetWidth - measureDisplayWidth(v));
|
|
369
|
+
return v + " ".repeat(padding);
|
|
370
|
+
};
|
|
371
|
+
|
|
372
|
+
const TOOL_WIDTH = 7;
|
|
373
|
+
const DATE_WIDTH = 16; // "YYYY-MM-DD HH:mm"
|
|
374
|
+
const paddedTool = formatFixedWidth(toolLabelRaw, TOOL_WIDTH);
|
|
375
|
+
const paddedDate =
|
|
376
|
+
commitText === "---"
|
|
377
|
+
? " ".repeat(DATE_WIDTH)
|
|
378
|
+
: commitText.padStart(DATE_WIDTH, " ");
|
|
379
|
+
const timestampText = `${paddedTool} | ${paddedDate}`;
|
|
380
|
+
const displayTimestampText = `${colorToolLabel(
|
|
381
|
+
paddedTool,
|
|
382
|
+
item.lastToolUsage?.toolId,
|
|
383
|
+
)} | ${paddedDate}`;
|
|
384
|
+
const timestampWidth = measureDisplayWidth(timestampText);
|
|
290
385
|
|
|
291
386
|
const indicatorInfo = cleanupUI?.indicators?.[item.name];
|
|
292
387
|
let indicatorIcon = indicatorInfo?.icon ?? "";
|
|
@@ -309,30 +404,114 @@ export function BranchListScreen({
|
|
|
309
404
|
}
|
|
310
405
|
}
|
|
311
406
|
const indicatorPrefix = indicatorIcon ? `${indicatorIcon} ` : "";
|
|
312
|
-
|
|
313
|
-
const
|
|
407
|
+
|
|
408
|
+
const isChecked = selectedSet.has(item.name);
|
|
409
|
+
const selectionIcon = isChecked ? "[*]" : "[ ]";
|
|
410
|
+
const hasWorktree =
|
|
411
|
+
item.worktreeStatus === "active" ||
|
|
412
|
+
item.worktreeStatus === "inaccessible";
|
|
413
|
+
const worktreeIcon = hasWorktree ? chalk.green("🟢") : chalk.gray("⚪");
|
|
414
|
+
const safeIcon =
|
|
415
|
+
item.safeToCleanup === true ? chalk.green("🛡") : chalk.yellow("⚠");
|
|
416
|
+
const stateCluster = `${selectionIcon} ${worktreeIcon} ${safeIcon}`;
|
|
417
|
+
|
|
418
|
+
const staticPrefix = `${arrow} ${indicatorPrefix}${stateCluster} `;
|
|
419
|
+
const staticPrefixWidth = visibleWidth(staticPrefix);
|
|
314
420
|
const maxLeftDisplayWidth = Math.max(0, columns - timestampWidth - 1);
|
|
315
421
|
const maxLabelWidth = Math.max(
|
|
316
422
|
0,
|
|
317
423
|
maxLeftDisplayWidth - staticPrefixWidth,
|
|
318
424
|
);
|
|
319
|
-
const
|
|
320
|
-
|
|
425
|
+
const displayLabel =
|
|
426
|
+
item.type === "remote" && item.remoteName ? item.remoteName : item.name;
|
|
427
|
+
let truncatedLabel = truncateToWidth(displayLabel, maxLabelWidth);
|
|
428
|
+
let leftText = `${staticPrefix}${truncatedLabel}`;
|
|
429
|
+
|
|
430
|
+
let leftDisplayWidth = visibleWidth(leftText);
|
|
431
|
+
// Gap between labelとツール/日時。右端に寄せるため必要分だけ確保。
|
|
432
|
+
let gapWidth = Math.max(1, columns - leftDisplayWidth - timestampWidth);
|
|
433
|
+
|
|
434
|
+
// もしまだオーバーする場合、隙間→ラベルの順で削って収める
|
|
435
|
+
let totalWidth = leftDisplayWidth + gapWidth + timestampWidth;
|
|
436
|
+
if (totalWidth > columns) {
|
|
437
|
+
const overflow = totalWidth - columns;
|
|
438
|
+
const reducedGap = Math.max(1, gapWidth - overflow);
|
|
439
|
+
gapWidth = reducedGap;
|
|
440
|
+
totalWidth = leftDisplayWidth + gapWidth + timestampWidth;
|
|
441
|
+
}
|
|
442
|
+
if (leftDisplayWidth + gapWidth + timestampWidth > columns) {
|
|
443
|
+
const extra = leftDisplayWidth + gapWidth + timestampWidth - columns;
|
|
444
|
+
const newLabelWidth = Math.max(
|
|
445
|
+
0,
|
|
446
|
+
measureDisplayWidth(truncatedLabel) - extra,
|
|
447
|
+
);
|
|
448
|
+
truncatedLabel = truncateToWidth(displayLabel, newLabelWidth);
|
|
449
|
+
leftText = `${staticPrefix}${truncatedLabel}`;
|
|
450
|
+
leftDisplayWidth = visibleWidth(leftText);
|
|
451
|
+
gapWidth = Math.max(1, columns - leftDisplayWidth - timestampWidth);
|
|
452
|
+
}
|
|
321
453
|
|
|
322
|
-
const
|
|
323
|
-
|
|
454
|
+
const buildLine = () =>
|
|
455
|
+
`${leftText}${" ".repeat(gapWidth)}${timestampText}`;
|
|
324
456
|
|
|
325
|
-
let line =
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
457
|
+
let line = buildLine();
|
|
458
|
+
// Replace timestamp with colorized tool name (keep alignment from width calc)
|
|
459
|
+
let lineWithColoredTimestamp = line.replace(
|
|
460
|
+
timestampText,
|
|
461
|
+
displayTimestampText,
|
|
462
|
+
);
|
|
331
463
|
|
|
332
|
-
|
|
464
|
+
// 端末幅を超えた場合は隙間→ラベルの順で詰めて収める
|
|
465
|
+
const clampToWidth = () => {
|
|
466
|
+
const finalWidth = measureDisplayWidth(
|
|
467
|
+
stripAnsi(lineWithColoredTimestamp),
|
|
468
|
+
);
|
|
469
|
+
if (finalWidth <= columns) {
|
|
470
|
+
return;
|
|
471
|
+
}
|
|
472
|
+
const overflow = finalWidth - columns;
|
|
473
|
+
const reducedGap = Math.max(1, gapWidth - overflow);
|
|
474
|
+
gapWidth = reducedGap;
|
|
475
|
+
line = buildLine();
|
|
476
|
+
lineWithColoredTimestamp = line.replace(
|
|
477
|
+
timestampText,
|
|
478
|
+
displayTimestampText,
|
|
479
|
+
);
|
|
480
|
+
const widthAfterGap = measureDisplayWidth(
|
|
481
|
+
stripAnsi(lineWithColoredTimestamp),
|
|
482
|
+
);
|
|
483
|
+
if (widthAfterGap > columns) {
|
|
484
|
+
const extra = widthAfterGap - columns;
|
|
485
|
+
const newLabelWidth = Math.max(
|
|
486
|
+
0,
|
|
487
|
+
measureDisplayWidth(truncatedLabel) - extra,
|
|
488
|
+
);
|
|
489
|
+
truncatedLabel = truncateToWidth(displayLabel, newLabelWidth);
|
|
490
|
+
leftText = `${staticPrefix}${truncatedLabel}`;
|
|
491
|
+
leftDisplayWidth = visibleWidth(leftText);
|
|
492
|
+
gapWidth = Math.max(1, columns - leftDisplayWidth - timestampWidth);
|
|
493
|
+
line = buildLine();
|
|
494
|
+
lineWithColoredTimestamp = line.replace(
|
|
495
|
+
timestampText,
|
|
496
|
+
displayTimestampText,
|
|
497
|
+
);
|
|
498
|
+
}
|
|
499
|
+
};
|
|
500
|
+
|
|
501
|
+
clampToWidth();
|
|
502
|
+
|
|
503
|
+
const output = isSelected
|
|
504
|
+
? `\u001b[46m\u001b[30m${lineWithColoredTimestamp}\u001b[0m`
|
|
505
|
+
: lineWithColoredTimestamp;
|
|
333
506
|
return <Text>{output}</Text>;
|
|
334
507
|
},
|
|
335
|
-
[
|
|
508
|
+
[
|
|
509
|
+
cleanupUI,
|
|
510
|
+
formatLatestCommit,
|
|
511
|
+
truncateToWidth,
|
|
512
|
+
selectedSet,
|
|
513
|
+
colorToolLabel,
|
|
514
|
+
],
|
|
336
515
|
);
|
|
337
516
|
|
|
338
517
|
return (
|
|
@@ -425,6 +604,8 @@ export function BranchListScreen({
|
|
|
425
604
|
disabled={Boolean(cleanupUI?.inputLocked)}
|
|
426
605
|
renderIndicator={() => null}
|
|
427
606
|
renderItem={renderBranchRow}
|
|
607
|
+
selectedIndex={selectedIndex}
|
|
608
|
+
onSelectedIndexChange={setSelectedIndex}
|
|
428
609
|
/>
|
|
429
610
|
</>
|
|
430
611
|
)}
|
|
@@ -442,6 +623,11 @@ export function BranchListScreen({
|
|
|
442
623
|
</Box>
|
|
443
624
|
)}
|
|
444
625
|
|
|
626
|
+
{/* Web UI URL */}
|
|
627
|
+
<Box>
|
|
628
|
+
<Text dimColor>Web UI: http://localhost:{resolveWebUiPort()}</Text>
|
|
629
|
+
</Box>
|
|
630
|
+
|
|
445
631
|
{/* Footer */}
|
|
446
632
|
<Footer actions={footerActions} />
|
|
447
633
|
</Box>
|
|
@@ -25,13 +25,12 @@ const REASONING_LABELS: Record<string, string> = {
|
|
|
25
25
|
};
|
|
26
26
|
|
|
27
27
|
const formatReasoning = (level?: string | null) =>
|
|
28
|
-
level ? REASONING_LABELS[level] ?? level : "Default";
|
|
28
|
+
level ? (REASONING_LABELS[level] ?? level) : "Default";
|
|
29
29
|
|
|
30
30
|
const formatSkip = (skip?: boolean | null) =>
|
|
31
31
|
skip === true ? "Yes" : skip === false ? "No" : "No";
|
|
32
32
|
|
|
33
|
-
const supportsReasoning = (toolId?: string | null) =>
|
|
34
|
-
toolId === "codex-cli";
|
|
33
|
+
const supportsReasoning = (toolId?: string | null) => toolId === "codex-cli";
|
|
35
34
|
|
|
36
35
|
const describe = (opt: BranchQuickStartOption, includeSessionId = true) => {
|
|
37
36
|
const parts = [`Model: ${opt.model ?? "default"}`];
|
|
@@ -103,45 +102,45 @@ export function BranchQuickStartScreen({
|
|
|
103
102
|
const items: QuickStartItem[] = previousOptions.length
|
|
104
103
|
? (() => {
|
|
105
104
|
const order = ["Claude", "Codex", "Gemini", "Qwen", "Other"];
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
105
|
+
const sorted = [...previousOptions].sort((a, b) => {
|
|
106
|
+
const ca = resolveCategory(a.toolId).label;
|
|
107
|
+
const cb = resolveCategory(b.toolId).label;
|
|
108
|
+
return order.indexOf(ca) - order.indexOf(cb);
|
|
109
|
+
});
|
|
111
110
|
|
|
112
|
-
|
|
111
|
+
const flat: QuickStartItem[] = [];
|
|
113
112
|
sorted.forEach((opt, idx) => {
|
|
114
113
|
const cat = resolveCategory(opt.toolId);
|
|
115
114
|
const prevCat =
|
|
116
115
|
idx > 0 ? resolveCategory(sorted[idx - 1]?.toolId).label : null;
|
|
117
116
|
const isNewCategory = prevCat !== cat.label;
|
|
118
117
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
118
|
+
flat.push(
|
|
119
|
+
{
|
|
120
|
+
label: "Resume",
|
|
121
|
+
value: `reuse-continue:${opt.toolId ?? "unknown"}:${idx}`,
|
|
122
|
+
action: "reuse-continue",
|
|
123
|
+
toolId: opt.toolId ?? null,
|
|
124
|
+
description: describe(opt, true),
|
|
125
|
+
groupStart: isNewCategory && flat.length > 0,
|
|
126
|
+
category: cat.label,
|
|
127
|
+
categoryColor: cat.color,
|
|
128
|
+
},
|
|
129
|
+
{
|
|
130
|
+
label: "New",
|
|
131
|
+
value: `reuse-new:${opt.toolId ?? "unknown"}:${idx}`,
|
|
132
|
+
action: "reuse-new",
|
|
133
|
+
toolId: opt.toolId ?? null,
|
|
134
|
+
description: describe(opt, false),
|
|
135
|
+
groupStart: false,
|
|
136
|
+
category: cat.label,
|
|
137
|
+
categoryColor: cat.color,
|
|
138
|
+
},
|
|
139
|
+
);
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
return flat;
|
|
143
|
+
})()
|
|
145
144
|
: [
|
|
146
145
|
{
|
|
147
146
|
label: "Resume with previous settings",
|
|
@@ -180,11 +179,7 @@ export function BranchQuickStartScreen({
|
|
|
180
179
|
|
|
181
180
|
return (
|
|
182
181
|
<Box flexDirection="column" height={containerHeight}>
|
|
183
|
-
<Header
|
|
184
|
-
title="Quick Start"
|
|
185
|
-
titleColor="cyan"
|
|
186
|
-
version={version}
|
|
187
|
-
/>
|
|
182
|
+
<Header title="Quick Start" titleColor="cyan" version={version} />
|
|
188
183
|
|
|
189
184
|
<Box flexDirection="column" flexGrow={1} marginTop={1}>
|
|
190
185
|
<Box marginBottom={1} flexDirection="column">
|
|
@@ -197,6 +192,7 @@ export function BranchQuickStartScreen({
|
|
|
197
192
|
</Box>
|
|
198
193
|
<Select
|
|
199
194
|
items={items}
|
|
195
|
+
disabled={loading}
|
|
200
196
|
onSelect={(item: QuickStartItem) => {
|
|
201
197
|
if (item.disabled) return;
|
|
202
198
|
onSelect(item.action, item.toolId ?? null);
|
|
@@ -204,13 +200,12 @@ export function BranchQuickStartScreen({
|
|
|
204
200
|
renderItem={(item: QuickStartItem, isSelected) => (
|
|
205
201
|
<Box
|
|
206
202
|
flexDirection="column"
|
|
207
|
-
marginTop={
|
|
203
|
+
marginTop={
|
|
204
|
+
item.groupStart ? 1 : item.category === "Other" ? 1 : 0
|
|
205
|
+
}
|
|
208
206
|
>
|
|
209
207
|
<Text>
|
|
210
|
-
<Text
|
|
211
|
-
color={item.categoryColor}
|
|
212
|
-
inverse={isSelected}
|
|
213
|
-
>
|
|
208
|
+
<Text color={item.categoryColor} inverse={isSelected}>
|
|
214
209
|
{`[${item.category}] `}
|
|
215
210
|
</Text>
|
|
216
211
|
<Text inverse={isSelected}>
|
|
@@ -219,7 +214,7 @@ export function BranchQuickStartScreen({
|
|
|
219
214
|
</Text>
|
|
220
215
|
</Text>
|
|
221
216
|
{item.description && (
|
|
222
|
-
<Text color="gray">
|
|
217
|
+
<Text color="gray"> {item.description}</Text>
|
|
223
218
|
)}
|
|
224
219
|
</Box>
|
|
225
220
|
)}
|
|
@@ -12,6 +12,7 @@ import { getPullRequestByBranch } from "../../../github.js";
|
|
|
12
12
|
import type { BranchInfo, WorktreeInfo } from "../types.js";
|
|
13
13
|
import type { WorktreeInfo as GitWorktreeInfo } from "../../../worktree.js";
|
|
14
14
|
import { getLastToolUsageMap } from "../../../config/index.js";
|
|
15
|
+
import { hasUncommittedChanges } from "../../../git.js";
|
|
15
16
|
|
|
16
17
|
export interface UseGitDataOptions {
|
|
17
18
|
enableAutoRefresh?: boolean;
|
|
@@ -65,6 +66,22 @@ export function useGitData(options?: UseGitDataOptions): UseGitDataResult {
|
|
|
65
66
|
}
|
|
66
67
|
worktreesData = [];
|
|
67
68
|
}
|
|
69
|
+
|
|
70
|
+
// enrich worktrees with uncommitted status (only for accessible paths)
|
|
71
|
+
worktreesData = await Promise.all(
|
|
72
|
+
worktreesData.map(async (wt) => {
|
|
73
|
+
if (wt.isAccessible === false) {
|
|
74
|
+
return wt;
|
|
75
|
+
}
|
|
76
|
+
try {
|
|
77
|
+
const hasUncommitted = await hasUncommittedChanges(wt.path);
|
|
78
|
+
return { ...wt, hasUncommittedChanges: hasUncommitted };
|
|
79
|
+
} catch {
|
|
80
|
+
return wt;
|
|
81
|
+
}
|
|
82
|
+
}),
|
|
83
|
+
);
|
|
84
|
+
|
|
68
85
|
const lastToolUsageMap = await getLastToolUsageMap(repoRoot);
|
|
69
86
|
|
|
70
87
|
// upstream情報とdivergence情報を取得
|
|
@@ -109,6 +126,9 @@ export function useGitData(options?: UseGitDataOptions): UseGitDataResult {
|
|
|
109
126
|
locked: false, // worktree.ts doesn't expose locked status
|
|
110
127
|
prunable: worktree.isAccessible === false,
|
|
111
128
|
isAccessible: worktree.isAccessible ?? true, // Default to true if undefined
|
|
129
|
+
...(worktree.hasUncommittedChanges !== undefined
|
|
130
|
+
? { hasUncommittedChanges: worktree.hasUncommittedChanges }
|
|
131
|
+
: {}),
|
|
112
132
|
};
|
|
113
133
|
worktreeMap.set(worktree.branch, uiWorktreeInfo);
|
|
114
134
|
}
|
package/src/cli/ui/types.ts
CHANGED
|
@@ -6,6 +6,7 @@ export interface WorktreeInfo {
|
|
|
6
6
|
locked: boolean;
|
|
7
7
|
prunable: boolean;
|
|
8
8
|
isAccessible?: boolean;
|
|
9
|
+
hasUncommittedChanges?: boolean;
|
|
9
10
|
}
|
|
10
11
|
|
|
11
12
|
export type AITool = string;
|
|
@@ -229,6 +230,8 @@ export interface BranchItem extends BranchInfo {
|
|
|
229
230
|
syncStatus?: SyncStatus;
|
|
230
231
|
syncInfo?: string | undefined;
|
|
231
232
|
remoteName?: string | undefined;
|
|
233
|
+
// クリーンアップ判定で「未コミット/未プッシュなし」と評価された場合に true
|
|
234
|
+
safeToCleanup?: boolean;
|
|
232
235
|
}
|
|
233
236
|
|
|
234
237
|
/**
|
|
@@ -65,7 +65,8 @@ const iconWidthOverrides: Record<string, number> = {
|
|
|
65
65
|
"🚀": 1,
|
|
66
66
|
"📌": 1,
|
|
67
67
|
// Worktree status icons
|
|
68
|
-
"🟢":
|
|
68
|
+
"🟢": 2,
|
|
69
|
+
"⚪": 2,
|
|
69
70
|
"🟠": 1,
|
|
70
71
|
// Change status icons
|
|
71
72
|
"👉": 1,
|
|
@@ -73,7 +74,11 @@ const iconWidthOverrides: Record<string, number> = {
|
|
|
73
74
|
"📤": 1,
|
|
74
75
|
"🔃": 1,
|
|
75
76
|
"✅": 1,
|
|
76
|
-
"⚠️":
|
|
77
|
+
"⚠️": 2,
|
|
78
|
+
"⚠": 1,
|
|
79
|
+
"🛡": 2,
|
|
80
|
+
"☑": 2,
|
|
81
|
+
"☐": 2,
|
|
77
82
|
// Remote markers
|
|
78
83
|
"🔗": 1,
|
|
79
84
|
"💻": 1,
|
|
@@ -17,13 +17,7 @@ export interface ContinueSessionContext {
|
|
|
17
17
|
export async function resolveContinueSessionId(
|
|
18
18
|
context: ContinueSessionContext,
|
|
19
19
|
): Promise<string | null> {
|
|
20
|
-
const {
|
|
21
|
-
history,
|
|
22
|
-
sessionData,
|
|
23
|
-
branch,
|
|
24
|
-
toolId,
|
|
25
|
-
repoRoot,
|
|
26
|
-
} = context;
|
|
20
|
+
const { history, sessionData, branch, toolId, repoRoot: _repoRoot } = context;
|
|
27
21
|
|
|
28
22
|
// 1) 履歴から最新マッチを探す(末尾から遡る)
|
|
29
23
|
for (let i = history.length - 1; i >= 0; i -= 1) {
|
|
@@ -23,6 +23,7 @@ describe("modelOptions", () => {
|
|
|
23
23
|
expect(unique.size).toBe(ids.length);
|
|
24
24
|
expect(ids).toEqual([
|
|
25
25
|
"gpt-5.1-codex",
|
|
26
|
+
"gpt-5.2",
|
|
26
27
|
"gpt-5.1-codex-max",
|
|
27
28
|
"gpt-5.1-codex-mini",
|
|
28
29
|
"gpt-5.1",
|
|
@@ -36,6 +37,19 @@ describe("modelOptions", () => {
|
|
|
36
37
|
expect(getDefaultInferenceForModel(codexMax)).toBe("medium");
|
|
37
38
|
});
|
|
38
39
|
|
|
40
|
+
it("exposes gpt-5.2 with xhigh reasoning and medium default", () => {
|
|
41
|
+
const codex52 = getModelOptions("codex-cli").find(
|
|
42
|
+
(m) => m.id === "gpt-5.2",
|
|
43
|
+
);
|
|
44
|
+
expect(codex52?.inferenceLevels).toEqual([
|
|
45
|
+
"xhigh",
|
|
46
|
+
"high",
|
|
47
|
+
"medium",
|
|
48
|
+
"low",
|
|
49
|
+
]);
|
|
50
|
+
expect(getDefaultInferenceForModel(codex52)).toBe("medium");
|
|
51
|
+
});
|
|
52
|
+
|
|
39
53
|
it("lists expected Gemini models", () => {
|
|
40
54
|
expect(byId("gemini-cli")).toEqual([
|
|
41
55
|
"gemini-3-pro-preview",
|
|
@@ -33,6 +33,13 @@ const MODEL_OPTIONS: Record<string, ModelOption[]> = {
|
|
|
33
33
|
defaultInference: "high",
|
|
34
34
|
isDefault: true,
|
|
35
35
|
},
|
|
36
|
+
{
|
|
37
|
+
id: "gpt-5.2",
|
|
38
|
+
label: "gpt-5.2",
|
|
39
|
+
description: "Latest frontier model with extra high reasoning",
|
|
40
|
+
inferenceLevels: CODEX_MAX_LEVELS,
|
|
41
|
+
defaultInference: "medium",
|
|
42
|
+
},
|
|
36
43
|
{
|
|
37
44
|
id: "gpt-5.1-codex-max",
|
|
38
45
|
label: "gpt-5.1-codex-max",
|