@akiojin/gwt 4.10.0 → 4.12.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 +4 -4
- package/README.md +4 -4
- package/bin/gwt.js +1 -1
- package/dist/claude.d.ts +2 -0
- package/dist/claude.d.ts.map +1 -1
- package/dist/claude.js +97 -68
- package/dist/claude.js.map +1 -1
- package/dist/cli/ui/App.solid.d.ts +29 -0
- package/dist/cli/ui/App.solid.d.ts.map +1 -0
- package/dist/cli/ui/App.solid.js +1395 -0
- package/dist/cli/ui/App.solid.js.map +1 -0
- package/dist/cli/ui/components/solid/Footer.d.ts +10 -0
- package/dist/cli/ui/components/solid/Footer.d.ts.map +1 -0
- package/dist/cli/ui/components/solid/Footer.js +10 -0
- package/dist/cli/ui/components/solid/Footer.js.map +1 -0
- package/dist/cli/ui/components/{parts → solid}/Header.d.ts +1 -6
- package/dist/cli/ui/components/solid/Header.d.ts.map +1 -0
- package/dist/cli/ui/components/solid/Header.js +13 -0
- package/dist/cli/ui/components/solid/Header.js.map +1 -0
- package/dist/cli/ui/components/solid/HelpOverlay.d.ts +8 -0
- package/dist/cli/ui/components/solid/HelpOverlay.d.ts.map +1 -0
- package/dist/cli/ui/components/solid/HelpOverlay.js +118 -0
- package/dist/cli/ui/components/solid/HelpOverlay.js.map +1 -0
- package/dist/cli/ui/components/solid/QuickStartStep.d.ts +17 -0
- package/dist/cli/ui/components/solid/QuickStartStep.d.ts.map +1 -0
- package/dist/cli/ui/components/solid/QuickStartStep.js +152 -0
- package/dist/cli/ui/components/solid/QuickStartStep.js.map +1 -0
- package/dist/cli/ui/components/solid/SelectInput.d.ts +22 -0
- package/dist/cli/ui/components/solid/SelectInput.d.ts.map +1 -0
- package/dist/cli/ui/components/solid/SelectInput.js +45 -0
- package/dist/cli/ui/components/solid/SelectInput.js.map +1 -0
- package/dist/cli/ui/components/solid/TextInput.d.ts +12 -0
- package/dist/cli/ui/components/solid/TextInput.d.ts.map +1 -0
- package/dist/cli/ui/components/solid/TextInput.js +9 -0
- package/dist/cli/ui/components/solid/TextInput.js.map +1 -0
- package/dist/cli/ui/components/solid/WizardController.d.ts +34 -0
- package/dist/cli/ui/components/solid/WizardController.d.ts.map +1 -0
- package/dist/cli/ui/components/solid/WizardController.js +223 -0
- package/dist/cli/ui/components/solid/WizardController.js.map +1 -0
- package/dist/cli/ui/components/solid/WizardPopup.d.ts +26 -0
- package/dist/cli/ui/components/solid/WizardPopup.d.ts.map +1 -0
- package/dist/cli/ui/components/solid/WizardPopup.js +68 -0
- package/dist/cli/ui/components/solid/WizardPopup.js.map +1 -0
- package/dist/cli/ui/components/solid/WizardSteps.d.ts +52 -0
- package/dist/cli/ui/components/solid/WizardSteps.d.ts.map +1 -0
- package/dist/cli/ui/components/solid/WizardSteps.js +419 -0
- package/dist/cli/ui/components/solid/WizardSteps.js.map +1 -0
- package/dist/cli/ui/core/index.d.ts +12 -0
- package/dist/cli/ui/core/index.d.ts.map +1 -0
- package/dist/cli/ui/core/index.js +15 -0
- package/dist/cli/ui/core/index.js.map +1 -0
- package/dist/cli/ui/core/keybindings.d.ts +106 -0
- package/dist/cli/ui/core/keybindings.d.ts.map +1 -0
- package/dist/cli/ui/core/keybindings.js +270 -0
- package/dist/cli/ui/core/keybindings.js.map +1 -0
- package/dist/cli/ui/core/theme.d.ts +123 -0
- package/dist/cli/ui/core/theme.d.ts.map +1 -0
- package/dist/cli/ui/core/theme.js +191 -0
- package/dist/cli/ui/core/theme.js.map +1 -0
- package/dist/cli/ui/core/types.d.ts +156 -0
- package/dist/cli/ui/core/types.d.ts.map +1 -0
- package/dist/cli/ui/core/types.js +10 -0
- package/dist/cli/ui/core/types.js.map +1 -0
- package/dist/cli/ui/hooks/solid/useScrollableList.d.ts +26 -0
- package/dist/cli/ui/hooks/solid/useScrollableList.d.ts.map +1 -0
- package/dist/cli/ui/hooks/solid/useScrollableList.js +89 -0
- package/dist/cli/ui/hooks/solid/useScrollableList.js.map +1 -0
- package/dist/cli/ui/hooks/solid/useTerminalSize.d.ts +10 -0
- package/dist/cli/ui/hooks/solid/useTerminalSize.d.ts.map +1 -0
- package/dist/cli/ui/hooks/solid/useTerminalSize.js +16 -0
- package/dist/cli/ui/hooks/solid/useTerminalSize.js.map +1 -0
- package/dist/cli/ui/index.solid.d.ts +5 -0
- package/dist/cli/ui/index.solid.d.ts.map +1 -0
- package/dist/cli/ui/index.solid.js +21 -0
- package/dist/cli/ui/index.solid.js.map +1 -0
- package/dist/cli/ui/screens/solid/BranchListScreen.d.ts +53 -0
- package/dist/cli/ui/screens/solid/BranchListScreen.d.ts.map +1 -0
- package/dist/cli/ui/screens/solid/BranchListScreen.js +829 -0
- package/dist/cli/ui/screens/solid/BranchListScreen.js.map +1 -0
- package/dist/cli/ui/screens/solid/ConfirmScreen.d.ts +11 -0
- package/dist/cli/ui/screens/solid/ConfirmScreen.d.ts.map +1 -0
- package/dist/cli/ui/screens/solid/ConfirmScreen.js +45 -0
- package/dist/cli/ui/screens/solid/ConfirmScreen.js.map +1 -0
- package/dist/cli/ui/screens/solid/EnvironmentScreen.d.ts +14 -0
- package/dist/cli/ui/screens/solid/EnvironmentScreen.d.ts.map +1 -0
- package/dist/cli/ui/screens/solid/EnvironmentScreen.js +90 -0
- package/dist/cli/ui/screens/solid/EnvironmentScreen.js.map +1 -0
- package/dist/cli/ui/screens/solid/ErrorScreen.d.ts +8 -0
- package/dist/cli/ui/screens/solid/ErrorScreen.d.ts.map +1 -0
- package/dist/cli/ui/screens/solid/ErrorScreen.js +18 -0
- package/dist/cli/ui/screens/solid/ErrorScreen.js.map +1 -0
- package/dist/cli/ui/screens/solid/InputScreen.d.ts +13 -0
- package/dist/cli/ui/screens/solid/InputScreen.d.ts.map +1 -0
- package/dist/cli/ui/screens/solid/InputScreen.js +17 -0
- package/dist/cli/ui/screens/solid/InputScreen.js.map +1 -0
- package/dist/cli/ui/screens/solid/LoadingIndicator.d.ts +9 -0
- package/dist/cli/ui/screens/solid/LoadingIndicator.d.ts.map +1 -0
- package/dist/cli/ui/screens/solid/LoadingIndicator.js +43 -0
- package/dist/cli/ui/screens/solid/LoadingIndicator.js.map +1 -0
- package/dist/cli/ui/{components/screens → screens/solid}/LogDetailScreen.d.ts +2 -2
- package/dist/cli/ui/screens/solid/LogDetailScreen.d.ts.map +1 -0
- package/dist/cli/ui/screens/solid/LogDetailScreen.js +34 -0
- package/dist/cli/ui/screens/solid/LogDetailScreen.js.map +1 -0
- package/dist/cli/ui/{components/screens/LogListScreen.d.ts → screens/solid/LogScreen.d.ts} +10 -4
- package/dist/cli/ui/screens/solid/LogScreen.d.ts.map +1 -0
- package/dist/cli/ui/screens/solid/LogScreen.js +333 -0
- package/dist/cli/ui/screens/solid/LogScreen.js.map +1 -0
- package/dist/cli/ui/screens/solid/ProfileEnvScreen.d.ts +17 -0
- package/dist/cli/ui/screens/solid/ProfileEnvScreen.d.ts.map +1 -0
- package/dist/cli/ui/screens/solid/ProfileEnvScreen.js +115 -0
- package/dist/cli/ui/screens/solid/ProfileEnvScreen.js.map +1 -0
- package/dist/cli/ui/screens/solid/ProfileScreen.d.ts +17 -0
- package/dist/cli/ui/screens/solid/ProfileScreen.d.ts.map +1 -0
- package/dist/cli/ui/screens/solid/ProfileScreen.js +50 -0
- package/dist/cli/ui/screens/solid/ProfileScreen.js.map +1 -0
- package/dist/cli/ui/screens/solid/SelectorScreen.d.ts +20 -0
- package/dist/cli/ui/screens/solid/SelectorScreen.d.ts.map +1 -0
- package/dist/cli/ui/screens/solid/SelectorScreen.js +98 -0
- package/dist/cli/ui/screens/solid/SelectorScreen.js.map +1 -0
- package/dist/cli/ui/screens/solid/WorktreeCreateScreen.d.ts +13 -0
- package/dist/cli/ui/screens/solid/WorktreeCreateScreen.d.ts.map +1 -0
- package/dist/cli/ui/screens/solid/WorktreeCreateScreen.js +59 -0
- package/dist/cli/ui/screens/solid/WorktreeCreateScreen.js.map +1 -0
- package/dist/cli/ui/stores/appStore.d.ts +143 -0
- package/dist/cli/ui/stores/appStore.d.ts.map +1 -0
- package/dist/cli/ui/stores/appStore.js +158 -0
- package/dist/cli/ui/stores/appStore.js.map +1 -0
- package/dist/cli/ui/stores/branchStore.d.ts +159 -0
- package/dist/cli/ui/stores/branchStore.d.ts.map +1 -0
- package/dist/cli/ui/stores/branchStore.js +275 -0
- package/dist/cli/ui/stores/branchStore.js.map +1 -0
- package/dist/cli/ui/stores/index.d.ts +11 -0
- package/dist/cli/ui/stores/index.d.ts.map +1 -0
- package/dist/cli/ui/stores/index.js +14 -0
- package/dist/cli/ui/stores/index.js.map +1 -0
- package/dist/cli/ui/stores/uiStore.d.ts +146 -0
- package/dist/cli/ui/stores/uiStore.d.ts.map +1 -0
- package/dist/cli/ui/stores/uiStore.js +166 -0
- package/dist/cli/ui/stores/uiStore.js.map +1 -0
- package/dist/cli/ui/types.d.ts +17 -1
- package/dist/cli/ui/types.d.ts.map +1 -1
- package/dist/cli/ui/utils/branchFormatter.d.ts +1 -0
- package/dist/cli/ui/utils/branchFormatter.d.ts.map +1 -1
- package/dist/cli/ui/utils/branchFormatter.js +36 -217
- package/dist/cli/ui/utils/branchFormatter.js.map +1 -1
- package/dist/cli/ui/utils/continueSession.d.ts +18 -0
- package/dist/cli/ui/utils/continueSession.d.ts.map +1 -1
- package/dist/cli/ui/utils/continueSession.js +90 -2
- package/dist/cli/ui/utils/continueSession.js.map +1 -1
- package/dist/cli/ui/utils/versionCache.d.ts +37 -0
- package/dist/cli/ui/utils/versionCache.d.ts.map +1 -0
- package/dist/cli/ui/utils/versionCache.js +70 -0
- package/dist/cli/ui/utils/versionCache.js.map +1 -0
- package/dist/cli/ui/utils/versionFetcher.d.ts +41 -0
- package/dist/cli/ui/utils/versionFetcher.d.ts.map +1 -0
- package/dist/cli/ui/utils/versionFetcher.js +89 -0
- package/dist/cli/ui/utils/versionFetcher.js.map +1 -0
- package/dist/client/assets/{index-ChHC-Puh.css → index-BbfV7Wuj.css} +1 -1
- package/dist/client/assets/index-CoAyq5x1.js +78 -0
- package/dist/client/index.html +2 -2
- package/dist/codex.d.ts +2 -0
- package/dist/codex.d.ts.map +1 -1
- package/dist/codex.js +109 -39
- package/dist/codex.js.map +1 -1
- package/dist/config/builtin-coding-agents.js +4 -4
- package/dist/config/builtin-coding-agents.js.map +1 -1
- package/dist/config/index.d.ts +2 -0
- package/dist/config/index.d.ts.map +1 -1
- package/dist/config/index.js +11 -0
- package/dist/config/index.js.map +1 -1
- package/dist/gemini.d.ts +2 -0
- package/dist/gemini.d.ts.map +1 -1
- package/dist/gemini.js +77 -39
- package/dist/gemini.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +153 -103
- package/dist/index.js.map +1 -1
- package/dist/launcher.d.ts.map +1 -1
- package/dist/launcher.js +56 -6
- package/dist/launcher.js.map +1 -1
- package/dist/logging/agentOutput.d.ts +21 -0
- package/dist/logging/agentOutput.d.ts.map +1 -0
- package/dist/logging/agentOutput.js +164 -0
- package/dist/logging/agentOutput.js.map +1 -0
- package/dist/logging/formatter.d.ts.map +1 -1
- package/dist/logging/formatter.js +18 -4
- package/dist/logging/formatter.js.map +1 -1
- package/dist/logging/logger.d.ts.map +1 -1
- package/dist/logging/logger.js +28 -9
- package/dist/logging/logger.js.map +1 -1
- package/dist/logging/reader.d.ts +21 -0
- package/dist/logging/reader.d.ts.map +1 -1
- package/dist/logging/reader.js +79 -0
- package/dist/logging/reader.js.map +1 -1
- package/dist/opentui/highlights-eq9cgrbb.scm +604 -0
- package/dist/opentui/highlights-ghv9g403.scm +205 -0
- package/dist/opentui/highlights-hk7bwhj4.scm +284 -0
- package/dist/opentui/highlights-r812a2qc.scm +150 -0
- package/dist/opentui/highlights-x6tmsnaa.scm +115 -0
- package/dist/opentui/index.solid.d.ts +2 -0
- package/dist/opentui/index.solid.d.ts.map +1 -0
- package/dist/opentui/index.solid.js +53687 -0
- package/dist/opentui/index.solid.js.map +1 -0
- package/dist/opentui/injections-73j83es3.scm +27 -0
- package/dist/opentui/tree-sitter-javascript-nd0q4pe9.wasm +0 -0
- package/dist/opentui/tree-sitter-markdown-411r6y9b.wasm +0 -0
- package/dist/opentui/tree-sitter-markdown_inline-j5349f42.wasm +0 -0
- package/dist/opentui/tree-sitter-typescript-zxjzwt75.wasm +0 -0
- package/dist/opentui/tree-sitter-zig-e78zbjpm.wasm +0 -0
- package/dist/repositories/worktree.repository.d.ts +1 -0
- package/dist/repositories/worktree.repository.d.ts.map +1 -1
- package/dist/repositories/worktree.repository.js +7 -0
- package/dist/repositories/worktree.repository.js.map +1 -1
- package/dist/services/codingAgentResolver.d.ts +2 -0
- package/dist/services/codingAgentResolver.d.ts.map +1 -1
- package/dist/services/codingAgentResolver.js +30 -4
- package/dist/services/codingAgentResolver.js.map +1 -1
- package/dist/services/dependency-installer.d.ts.map +1 -1
- package/dist/services/dependency-installer.js +2 -7
- package/dist/services/dependency-installer.js.map +1 -1
- package/dist/types/api.d.ts +3 -0
- package/dist/types/api.d.ts.map +1 -1
- package/dist/types/coding-agent.d.ts +62 -0
- package/dist/types/coding-agent.d.ts.map +1 -0
- package/dist/types/coding-agent.js +29 -0
- package/dist/types/coding-agent.js.map +1 -0
- package/dist/types/tools.d.ts +17 -0
- package/dist/types/tools.d.ts.map +1 -1
- package/dist/utils/coding-agent-colors.d.ts +88 -0
- package/dist/utils/coding-agent-colors.d.ts.map +1 -0
- package/dist/utils/coding-agent-colors.js +137 -0
- package/dist/utils/coding-agent-colors.js.map +1 -0
- package/dist/utils/command.d.ts +1 -1
- package/dist/utils/command.js +1 -1
- package/dist/utils/error-utils.d.ts +27 -0
- package/dist/utils/error-utils.d.ts.map +1 -0
- package/dist/utils/error-utils.js +98 -0
- package/dist/utils/error-utils.js.map +1 -0
- package/dist/utils/npmRegistry.d.ts +61 -0
- package/dist/utils/npmRegistry.d.ts.map +1 -0
- package/dist/utils/npmRegistry.js +180 -0
- package/dist/utils/npmRegistry.js.map +1 -0
- package/dist/utils/prompt.d.ts +1 -1
- package/dist/utils/prompt.js +1 -1
- package/dist/utils/session/common.d.ts +8 -0
- package/dist/utils/session/common.d.ts.map +1 -1
- package/dist/utils/session/common.js +22 -0
- package/dist/utils/session/common.js.map +1 -1
- package/dist/utils/session/parsers/claude.d.ts +10 -4
- package/dist/utils/session/parsers/claude.d.ts.map +1 -1
- package/dist/utils/session/parsers/claude.js +64 -18
- package/dist/utils/session/parsers/claude.js.map +1 -1
- package/dist/utils/session/parsers/codex.d.ts.map +1 -1
- package/dist/utils/session/parsers/codex.js +47 -20
- package/dist/utils/session/parsers/codex.js.map +1 -1
- package/dist/utils/session/parsers/gemini.d.ts.map +1 -1
- package/dist/utils/session/parsers/gemini.js +43 -6
- package/dist/utils/session/parsers/gemini.js.map +1 -1
- package/dist/utils/session/parsers/opencode.d.ts.map +1 -1
- package/dist/utils/session/parsers/opencode.js +43 -6
- package/dist/utils/session/parsers/opencode.js.map +1 -1
- package/dist/utils/session/types.d.ts +7 -0
- package/dist/utils/session/types.d.ts.map +1 -1
- package/dist/utils/terminal.d.ts +1 -0
- package/dist/utils/terminal.d.ts.map +1 -1
- package/dist/utils/terminal.js +20 -0
- package/dist/utils/terminal.js.map +1 -1
- package/dist/utils.d.ts +9 -0
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +33 -2
- package/dist/utils.js.map +1 -1
- package/dist/web/client/src/components/CodingAgentLaunchModal.d.ts.map +1 -1
- package/dist/web/client/src/components/CodingAgentLaunchModal.js +7 -16
- package/dist/web/client/src/components/CodingAgentLaunchModal.js.map +1 -1
- package/dist/web/client/src/components/branch-detail/BranchInfoCards.d.ts.map +1 -1
- package/dist/web/client/src/components/branch-detail/BranchInfoCards.js +7 -2
- package/dist/web/client/src/components/branch-detail/BranchInfoCards.js.map +1 -1
- package/dist/web/client/src/components/branch-detail/SessionHistoryTable.d.ts.map +1 -1
- package/dist/web/client/src/components/branch-detail/SessionHistoryTable.js +2 -1
- package/dist/web/client/src/components/branch-detail/SessionHistoryTable.js.map +1 -1
- package/dist/web/client/src/components/branch-detail/ToolLauncher.d.ts +2 -2
- package/dist/web/client/src/components/branch-detail/ToolLauncher.d.ts.map +1 -1
- package/dist/web/client/src/components/branch-detail/ToolLauncher.js +5 -5
- package/dist/web/client/src/components/branch-detail/ToolLauncher.js.map +1 -1
- package/dist/web/client/src/components/ui/alert.d.ts +1 -1
- package/dist/web/client/src/lib/coding-agent-colors.d.ts +86 -0
- package/dist/web/client/src/lib/coding-agent-colors.d.ts.map +1 -0
- package/dist/web/client/src/lib/coding-agent-colors.js +135 -0
- package/dist/web/client/src/lib/coding-agent-colors.js.map +1 -0
- package/dist/web/client/src/pages/BranchDetailPage.js +10 -10
- package/dist/web/client/src/pages/BranchDetailPage.js.map +1 -1
- package/dist/web/server/pty/manager.d.ts +2 -0
- package/dist/web/server/pty/manager.d.ts.map +1 -1
- package/dist/web/server/pty/manager.js +104 -0
- package/dist/web/server/pty/manager.js.map +1 -1
- package/dist/web/server/routes/sessions.d.ts.map +1 -1
- package/dist/web/server/routes/sessions.js +5 -1
- package/dist/web/server/routes/sessions.js.map +1 -1
- package/dist/web/server/services/branches.d.ts.map +1 -1
- package/dist/web/server/services/branches.js +10 -8
- package/dist/web/server/services/branches.js.map +1 -1
- package/dist/web/server/services/worktrees.js +2 -2
- package/dist/web/server/services/worktrees.js.map +1 -1
- package/dist/worktree.d.ts +50 -1
- package/dist/worktree.d.ts.map +1 -1
- package/dist/worktree.js +292 -100
- package/dist/worktree.js.map +1 -1
- package/package.json +13 -14
- package/src/claude.ts +129 -95
- package/src/cli/ui/App.solid.tsx +2096 -0
- package/src/cli/ui/__tests__/solid/AppSolid.cleanup.test.tsx +1084 -0
- package/src/cli/ui/__tests__/solid/BranchListScreen.test.tsx +343 -0
- package/src/cli/ui/__tests__/solid/ConfirmScreen.test.tsx +77 -0
- package/src/cli/ui/__tests__/solid/LogScreen.test.tsx +351 -0
- package/src/cli/ui/__tests__/solid/components/QuickStartStep.test.tsx +308 -0
- package/src/cli/ui/__tests__/solid/components/WizardPopup.test.tsx +231 -0
- package/src/cli/ui/__tests__/solid/components/WizardSteps.test.tsx +241 -0
- package/src/cli/ui/__tests__/utils/branchFormatter.test.ts +79 -334
- package/src/cli/ui/__tests__/utils/clipboard.test.ts +3 -3
- package/src/cli/ui/__tests__/utils/statisticsCalculator.test.ts +1 -1
- package/src/cli/ui/components/solid/Footer.tsx +36 -0
- package/src/cli/ui/components/{parts → solid}/Header.tsx +17 -28
- package/src/cli/ui/components/solid/HelpOverlay.tsx +194 -0
- package/src/cli/ui/components/solid/QuickStartStep.tsx +209 -0
- package/src/cli/ui/components/{parts → solid}/ScrollableList.tsx +7 -8
- package/src/cli/ui/components/solid/SearchInput.tsx +42 -0
- package/src/cli/ui/components/solid/SelectInput.tsx +88 -0
- package/src/cli/ui/components/solid/Stats.tsx +92 -0
- package/src/cli/ui/components/solid/TextInput.tsx +49 -0
- package/src/cli/ui/components/solid/WizardController.tsx +393 -0
- package/src/cli/ui/components/solid/WizardPopup.tsx +135 -0
- package/src/cli/ui/components/solid/WizardSteps.tsx +736 -0
- package/src/cli/ui/core/index.ts +17 -0
- package/src/cli/ui/core/keybindings.ts +367 -0
- package/src/cli/ui/core/theme.ts +266 -0
- package/src/cli/ui/core/types.ts +235 -0
- package/src/cli/ui/hooks/solid/useAsyncOperation.ts +78 -0
- package/src/cli/ui/hooks/solid/useFilter.ts +86 -0
- package/src/cli/ui/hooks/solid/useGitOperations.ts +81 -0
- package/src/cli/ui/hooks/solid/useKeyHandler.ts +103 -0
- package/src/cli/ui/hooks/solid/useScrollableList.ts +149 -0
- package/src/cli/ui/hooks/solid/useSelection.ts +77 -0
- package/src/cli/ui/hooks/solid/useTerminalSize.ts +22 -0
- package/src/cli/ui/index.solid.ts +28 -0
- package/src/cli/ui/screens/solid/BranchListScreen.tsx +1153 -0
- package/src/cli/ui/screens/solid/ConfirmScreen.tsx +86 -0
- package/src/cli/ui/screens/solid/EnvironmentScreen.tsx +161 -0
- package/src/cli/ui/screens/solid/ErrorScreen.tsx +42 -0
- package/src/cli/ui/screens/solid/InputScreen.tsx +55 -0
- package/src/cli/ui/screens/solid/LoadingIndicator.tsx +77 -0
- package/src/cli/ui/screens/solid/LogDetailScreen.tsx +75 -0
- package/src/cli/ui/screens/solid/LogScreen.tsx +504 -0
- package/src/cli/ui/screens/solid/ProfileEnvScreen.tsx +196 -0
- package/src/cli/ui/screens/solid/ProfileScreen.tsx +98 -0
- package/src/cli/ui/screens/solid/SelectorScreen.tsx +181 -0
- package/src/cli/ui/screens/solid/SettingsScreen.tsx +52 -0
- package/src/cli/ui/screens/solid/WorktreeCreateScreen.tsx +136 -0
- package/src/cli/ui/screens/solid/WorktreeDeleteScreen.tsx +40 -0
- package/src/cli/ui/stores/appStore.ts +208 -0
- package/src/cli/ui/stores/branchStore.ts +357 -0
- package/src/cli/ui/stores/index.ts +31 -0
- package/src/cli/ui/stores/uiStore.ts +226 -0
- package/src/cli/ui/types.ts +21 -3
- package/src/cli/ui/utils/__tests__/branchFormatter.test.ts +227 -0
- package/src/cli/ui/utils/branchFormatter.ts +43 -222
- package/src/cli/ui/utils/continueSession.ts +133 -2
- package/src/cli/ui/utils/modelOptions.test.ts +1 -1
- package/src/cli/ui/utils/versionCache.ts +93 -0
- package/src/cli/ui/utils/versionFetcher.ts +120 -0
- package/src/codex.ts +138 -39
- package/src/config/__tests__/saveSession.test.ts +143 -0
- package/src/config/builtin-coding-agents.ts +4 -4
- package/src/config/index.ts +14 -0
- package/src/gemini.ts +107 -46
- package/src/index.test.ts +25 -19
- package/src/index.ts +202 -143
- package/src/launcher.ts +66 -6
- package/src/logging/agentOutput.ts +216 -0
- package/src/logging/formatter.ts +23 -4
- package/src/logging/logger.ts +34 -10
- package/src/logging/reader.ts +117 -0
- package/src/opentui/index.solid.ts +1 -0
- package/src/repositories/worktree.repository.ts +8 -0
- package/src/services/__tests__/BatchMergeService.test.ts +83 -67
- package/src/services/__tests__/WorktreeOrchestrator.test.ts +8 -7
- package/src/services/codingAgentResolver.ts +30 -4
- package/src/services/dependency-installer.ts +2 -9
- package/src/types/api.ts +3 -0
- package/src/types/coding-agent.ts +85 -0
- package/src/types/tools.ts +19 -0
- package/src/utils/__tests__/npmRegistry.test.ts +250 -0
- package/src/utils/__tests__/prompt.test.ts +4 -5
- package/src/utils/coding-agent-colors.ts +165 -0
- package/src/utils/command.ts +1 -1
- package/src/utils/error-utils.ts +133 -0
- package/src/utils/npmRegistry.ts +249 -0
- package/src/utils/prompt.ts +1 -1
- package/src/utils/session/common.ts +28 -0
- package/src/utils/session/parsers/claude.ts +79 -29
- package/src/utils/session/parsers/codex.ts +50 -18
- package/src/utils/session/parsers/gemini.ts +46 -5
- package/src/utils/session/parsers/opencode.ts +46 -5
- package/src/utils/session/types.ts +4 -0
- package/src/utils/terminal.ts +24 -0
- package/src/utils.test.ts +1 -1
- package/src/utils.ts +37 -4
- package/src/web/client/src/components/CodingAgentLaunchModal.tsx +12 -21
- package/src/web/client/src/components/branch-detail/BranchInfoCards.tsx +16 -1
- package/src/web/client/src/components/branch-detail/SessionHistoryTable.tsx +7 -1
- package/src/web/client/src/components/branch-detail/ToolLauncher.tsx +11 -6
- package/src/web/client/src/lib/coding-agent-colors.ts +149 -0
- package/src/web/client/src/pages/BranchDetailPage.tsx +11 -11
- package/src/web/server/pty/manager.ts +139 -0
- package/src/web/server/routes/sessions.ts +6 -0
- package/src/web/server/services/branches.ts +11 -8
- package/src/web/server/services/worktrees.ts +2 -2
- package/src/worktree.ts +386 -114
- package/dist/cli/ui/components/App.d.ts +0 -25
- package/dist/cli/ui/components/App.d.ts.map +0 -1
- package/dist/cli/ui/components/App.js +0 -1006
- package/dist/cli/ui/components/App.js.map +0 -1
- package/dist/cli/ui/components/common/Confirm.d.ts +0 -13
- package/dist/cli/ui/components/common/Confirm.d.ts.map +0 -1
- package/dist/cli/ui/components/common/Confirm.js +0 -20
- package/dist/cli/ui/components/common/Confirm.js.map +0 -1
- package/dist/cli/ui/components/common/ErrorBoundary.d.ts +0 -23
- package/dist/cli/ui/components/common/ErrorBoundary.d.ts.map +0 -1
- package/dist/cli/ui/components/common/ErrorBoundary.js +0 -37
- package/dist/cli/ui/components/common/ErrorBoundary.js.map +0 -1
- package/dist/cli/ui/components/common/Input.d.ts +0 -19
- package/dist/cli/ui/components/common/Input.d.ts.map +0 -1
- package/dist/cli/ui/components/common/Input.js +0 -22
- package/dist/cli/ui/components/common/Input.js.map +0 -1
- package/dist/cli/ui/components/common/LoadingIndicator.d.ts +0 -19
- package/dist/cli/ui/components/common/LoadingIndicator.d.ts.map +0 -1
- package/dist/cli/ui/components/common/LoadingIndicator.js +0 -61
- package/dist/cli/ui/components/common/LoadingIndicator.js.map +0 -1
- package/dist/cli/ui/components/common/Select.d.ts +0 -38
- package/dist/cli/ui/components/common/Select.d.ts.map +0 -1
- package/dist/cli/ui/components/common/Select.js +0 -151
- package/dist/cli/ui/components/common/Select.js.map +0 -1
- package/dist/cli/ui/components/common/SpinnerIcon.d.ts +0 -20
- package/dist/cli/ui/components/common/SpinnerIcon.d.ts.map +0 -1
- package/dist/cli/ui/components/common/SpinnerIcon.js +0 -61
- package/dist/cli/ui/components/common/SpinnerIcon.js.map +0 -1
- package/dist/cli/ui/components/parts/Footer.d.ts +0 -15
- package/dist/cli/ui/components/parts/Footer.d.ts.map +0 -1
- package/dist/cli/ui/components/parts/Footer.js +0 -20
- package/dist/cli/ui/components/parts/Footer.js.map +0 -1
- package/dist/cli/ui/components/parts/Header.d.ts.map +0 -1
- package/dist/cli/ui/components/parts/Header.js +0 -24
- package/dist/cli/ui/components/parts/Header.js.map +0 -1
- package/dist/cli/ui/components/parts/MergeStatusList.d.ts +0 -13
- package/dist/cli/ui/components/parts/MergeStatusList.d.ts.map +0 -1
- package/dist/cli/ui/components/parts/MergeStatusList.js +0 -52
- package/dist/cli/ui/components/parts/MergeStatusList.js.map +0 -1
- package/dist/cli/ui/components/parts/ProgressBar.d.ts +0 -13
- package/dist/cli/ui/components/parts/ProgressBar.d.ts.map +0 -1
- package/dist/cli/ui/components/parts/ProgressBar.js +0 -53
- package/dist/cli/ui/components/parts/ProgressBar.js.map +0 -1
- package/dist/cli/ui/components/parts/ScrollableList.d.ts +0 -12
- package/dist/cli/ui/components/parts/ScrollableList.d.ts.map +0 -1
- package/dist/cli/ui/components/parts/ScrollableList.js +0 -11
- package/dist/cli/ui/components/parts/ScrollableList.js.map +0 -1
- package/dist/cli/ui/components/parts/Stats.d.ts +0 -10
- package/dist/cli/ui/components/parts/Stats.d.ts.map +0 -1
- package/dist/cli/ui/components/parts/Stats.js +0 -55
- package/dist/cli/ui/components/parts/Stats.js.map +0 -1
- package/dist/cli/ui/components/screens/BatchMergeProgressScreen.d.ts +0 -17
- package/dist/cli/ui/components/screens/BatchMergeProgressScreen.d.ts.map +0 -1
- package/dist/cli/ui/components/screens/BatchMergeProgressScreen.js +0 -42
- package/dist/cli/ui/components/screens/BatchMergeProgressScreen.js.map +0 -1
- package/dist/cli/ui/components/screens/BatchMergeResultScreen.d.ts +0 -17
- package/dist/cli/ui/components/screens/BatchMergeResultScreen.d.ts.map +0 -1
- package/dist/cli/ui/components/screens/BatchMergeResultScreen.js +0 -72
- package/dist/cli/ui/components/screens/BatchMergeResultScreen.js.map +0 -1
- package/dist/cli/ui/components/screens/BranchCreatorScreen.d.ts +0 -18
- package/dist/cli/ui/components/screens/BranchCreatorScreen.d.ts.map +0 -1
- package/dist/cli/ui/components/screens/BranchCreatorScreen.js +0 -151
- package/dist/cli/ui/components/screens/BranchCreatorScreen.js.map +0 -1
- package/dist/cli/ui/components/screens/BranchListScreen.d.ts +0 -60
- package/dist/cli/ui/components/screens/BranchListScreen.d.ts.map +0 -1
- package/dist/cli/ui/components/screens/BranchListScreen.js +0 -476
- package/dist/cli/ui/components/screens/BranchListScreen.js.map +0 -1
- package/dist/cli/ui/components/screens/BranchQuickStartScreen.d.ts +0 -30
- package/dist/cli/ui/components/screens/BranchQuickStartScreen.d.ts.map +0 -1
- package/dist/cli/ui/components/screens/BranchQuickStartScreen.js +0 -148
- package/dist/cli/ui/components/screens/BranchQuickStartScreen.js.map +0 -1
- package/dist/cli/ui/components/screens/CodingAgentSelectorScreen.d.ts +0 -27
- package/dist/cli/ui/components/screens/CodingAgentSelectorScreen.d.ts.map +0 -1
- package/dist/cli/ui/components/screens/CodingAgentSelectorScreen.js +0 -93
- package/dist/cli/ui/components/screens/CodingAgentSelectorScreen.js.map +0 -1
- package/dist/cli/ui/components/screens/EnvironmentProfileScreen.d.ts +0 -19
- package/dist/cli/ui/components/screens/EnvironmentProfileScreen.d.ts.map +0 -1
- package/dist/cli/ui/components/screens/EnvironmentProfileScreen.js +0 -577
- package/dist/cli/ui/components/screens/EnvironmentProfileScreen.js.map +0 -1
- package/dist/cli/ui/components/screens/ExecutionModeSelectorScreen.d.ts +0 -45
- package/dist/cli/ui/components/screens/ExecutionModeSelectorScreen.d.ts.map +0 -1
- package/dist/cli/ui/components/screens/ExecutionModeSelectorScreen.js +0 -95
- package/dist/cli/ui/components/screens/ExecutionModeSelectorScreen.js.map +0 -1
- package/dist/cli/ui/components/screens/LogDatePickerScreen.d.ts +0 -10
- package/dist/cli/ui/components/screens/LogDatePickerScreen.d.ts.map +0 -1
- package/dist/cli/ui/components/screens/LogDatePickerScreen.js +0 -44
- package/dist/cli/ui/components/screens/LogDatePickerScreen.js.map +0 -1
- package/dist/cli/ui/components/screens/LogDetailScreen.d.ts.map +0 -1
- package/dist/cli/ui/components/screens/LogDetailScreen.js +0 -34
- package/dist/cli/ui/components/screens/LogDetailScreen.js.map +0 -1
- package/dist/cli/ui/components/screens/LogListScreen.d.ts.map +0 -1
- package/dist/cli/ui/components/screens/LogListScreen.js +0 -107
- package/dist/cli/ui/components/screens/LogListScreen.js.map +0 -1
- package/dist/cli/ui/components/screens/ModelSelectorScreen.d.ts +0 -24
- package/dist/cli/ui/components/screens/ModelSelectorScreen.d.ts.map +0 -1
- package/dist/cli/ui/components/screens/ModelSelectorScreen.js +0 -197
- package/dist/cli/ui/components/screens/ModelSelectorScreen.js.map +0 -1
- package/dist/cli/ui/components/screens/PRCleanupScreen.d.ts +0 -29
- package/dist/cli/ui/components/screens/PRCleanupScreen.d.ts.map +0 -1
- package/dist/cli/ui/components/screens/PRCleanupScreen.js +0 -92
- package/dist/cli/ui/components/screens/PRCleanupScreen.js.map +0 -1
- package/dist/cli/ui/components/screens/SessionSelectorScreen.d.ts +0 -31
- package/dist/cli/ui/components/screens/SessionSelectorScreen.d.ts.map +0 -1
- package/dist/cli/ui/components/screens/SessionSelectorScreen.js +0 -67
- package/dist/cli/ui/components/screens/SessionSelectorScreen.js.map +0 -1
- package/dist/cli/ui/hooks/useAppInput.d.ts +0 -21
- package/dist/cli/ui/hooks/useAppInput.d.ts.map +0 -1
- package/dist/cli/ui/hooks/useAppInput.js +0 -138
- package/dist/cli/ui/hooks/useAppInput.js.map +0 -1
- package/dist/cli/ui/hooks/useBatchMerge.d.ts +0 -17
- package/dist/cli/ui/hooks/useBatchMerge.d.ts.map +0 -1
- package/dist/cli/ui/hooks/useBatchMerge.js +0 -77
- package/dist/cli/ui/hooks/useBatchMerge.js.map +0 -1
- package/dist/cli/ui/hooks/useGitData.d.ts +0 -21
- package/dist/cli/ui/hooks/useGitData.d.ts.map +0 -1
- package/dist/cli/ui/hooks/useGitData.js +0 -229
- package/dist/cli/ui/hooks/useGitData.js.map +0 -1
- package/dist/cli/ui/hooks/useProfiles.d.ts +0 -41
- package/dist/cli/ui/hooks/useProfiles.d.ts.map +0 -1
- package/dist/cli/ui/hooks/useProfiles.js +0 -136
- package/dist/cli/ui/hooks/useProfiles.js.map +0 -1
- package/dist/cli/ui/hooks/useScreenState.d.ts +0 -12
- package/dist/cli/ui/hooks/useScreenState.d.ts.map +0 -1
- package/dist/cli/ui/hooks/useScreenState.js +0 -30
- package/dist/cli/ui/hooks/useScreenState.js.map +0 -1
- package/dist/cli/ui/hooks/useTerminalSize.d.ts +0 -9
- package/dist/cli/ui/hooks/useTerminalSize.d.ts.map +0 -1
- package/dist/cli/ui/hooks/useTerminalSize.js +0 -24
- package/dist/cli/ui/hooks/useTerminalSize.js.map +0 -1
- package/dist/cli/ui/hooks/useToolStatus.d.ts +0 -30
- package/dist/cli/ui/hooks/useToolStatus.d.ts.map +0 -1
- package/dist/cli/ui/hooks/useToolStatus.js +0 -49
- package/dist/cli/ui/hooks/useToolStatus.js.map +0 -1
- package/dist/cli/ui/screens/BranchActionSelectorScreen.d.ts +0 -24
- package/dist/cli/ui/screens/BranchActionSelectorScreen.d.ts.map +0 -1
- package/dist/cli/ui/screens/BranchActionSelectorScreen.js +0 -65
- package/dist/cli/ui/screens/BranchActionSelectorScreen.js.map +0 -1
- package/dist/client/assets/index-LNPtOrn3.js +0 -78
- package/src/cli/ui/__tests__/SKIPPED_TESTS.md +0 -119
- package/src/cli/ui/__tests__/acceptance/branchList.acceptance.test.tsx.skip +0 -239
- package/src/cli/ui/__tests__/acceptance/navigation.acceptance.test.tsx +0 -225
- package/src/cli/ui/__tests__/acceptance/realtimeUpdate.acceptance.test.tsx.skip +0 -219
- package/src/cli/ui/__tests__/components/App.protected-branch.test.tsx +0 -212
- package/src/cli/ui/__tests__/components/App.shortcuts.test.tsx +0 -440
- package/src/cli/ui/__tests__/components/App.test.tsx +0 -365
- package/src/cli/ui/__tests__/components/ModelSelectorScreen.initial.test.tsx +0 -91
- package/src/cli/ui/__tests__/components/common/Confirm.test.tsx +0 -80
- package/src/cli/ui/__tests__/components/common/ErrorBoundary.test.tsx +0 -104
- package/src/cli/ui/__tests__/components/common/Input.test.tsx +0 -100
- package/src/cli/ui/__tests__/components/common/LoadingIndicator.test.tsx +0 -148
- package/src/cli/ui/__tests__/components/common/Select.memo.test.tsx +0 -255
- package/src/cli/ui/__tests__/components/common/Select.test.tsx +0 -335
- package/src/cli/ui/__tests__/components/parts/Footer.test.tsx +0 -65
- package/src/cli/ui/__tests__/components/parts/Header.test.tsx +0 -55
- package/src/cli/ui/__tests__/components/parts/ScrollableList.test.tsx +0 -69
- package/src/cli/ui/__tests__/components/parts/Stats.test.tsx +0 -148
- package/src/cli/ui/__tests__/components/screens/BranchCreatorScreen.test.tsx +0 -253
- package/src/cli/ui/__tests__/components/screens/BranchListScreen.test.tsx +0 -1070
- package/src/cli/ui/__tests__/components/screens/BranchQuickStartScreen.test.tsx +0 -142
- package/src/cli/ui/__tests__/components/screens/CodingAgentSelectorScreen.test.tsx +0 -174
- package/src/cli/ui/__tests__/components/screens/ExecutionModeSelectorScreen.test.tsx +0 -182
- package/src/cli/ui/__tests__/components/screens/LogDetailScreen.test.tsx +0 -57
- package/src/cli/ui/__tests__/components/screens/LogListScreen.test.tsx +0 -102
- package/src/cli/ui/__tests__/components/screens/PRCleanupScreen.test.tsx +0 -216
- package/src/cli/ui/__tests__/components/screens/SessionSelectorScreen.test.tsx +0 -147
- package/src/cli/ui/__tests__/hooks/useGitData.nonblocking.test.tsx +0 -206
- package/src/cli/ui/__tests__/hooks/useGitData.test.ts +0 -197
- package/src/cli/ui/__tests__/hooks/useGitData.test.ts.skip +0 -228
- package/src/cli/ui/__tests__/hooks/useScreenState.test.ts +0 -147
- package/src/cli/ui/__tests__/hooks/useTerminalSize.test.ts +0 -99
- package/src/cli/ui/__tests__/integration/branchList.test.tsx.skip +0 -253
- package/src/cli/ui/__tests__/integration/edgeCases.test.tsx +0 -436
- package/src/cli/ui/__tests__/integration/navigation.test.tsx +0 -514
- package/src/cli/ui/__tests__/integration/realtimeUpdate.test.tsx +0 -509
- package/src/cli/ui/__tests__/integration/realtimeUpdate.test.tsx.skip +0 -216
- package/src/cli/ui/__tests__/performance/branchList.performance.test.tsx +0 -193
- package/src/cli/ui/__tests__/performance/useMemoOptimization.test.tsx +0 -234
- package/src/cli/ui/components/App.tsx +0 -1478
- package/src/cli/ui/components/common/Confirm.tsx +0 -44
- package/src/cli/ui/components/common/ErrorBoundary.tsx +0 -60
- package/src/cli/ui/components/common/Input.tsx +0 -58
- package/src/cli/ui/components/common/LoadingIndicator.tsx +0 -98
- package/src/cli/ui/components/common/Select.tsx +0 -247
- package/src/cli/ui/components/common/SpinnerIcon.tsx +0 -86
- package/src/cli/ui/components/parts/Footer.tsx +0 -41
- package/src/cli/ui/components/parts/Header.test.tsx +0 -75
- package/src/cli/ui/components/parts/MergeStatusList.tsx +0 -75
- package/src/cli/ui/components/parts/ProgressBar.tsx +0 -73
- package/src/cli/ui/components/parts/Stats.tsx +0 -88
- package/src/cli/ui/components/screens/BatchMergeProgressScreen.tsx +0 -74
- package/src/cli/ui/components/screens/BatchMergeResultScreen.tsx +0 -108
- package/src/cli/ui/components/screens/BranchCreatorScreen.tsx +0 -242
- package/src/cli/ui/components/screens/BranchListScreen.tsx +0 -744
- package/src/cli/ui/components/screens/BranchQuickStartScreen.tsx +0 -244
- package/src/cli/ui/components/screens/CodingAgentSelectorScreen.tsx +0 -159
- package/src/cli/ui/components/screens/EnvironmentProfileScreen.tsx +0 -928
- package/src/cli/ui/components/screens/ExecutionModeSelectorScreen.tsx +0 -176
- package/src/cli/ui/components/screens/LogDatePickerScreen.tsx +0 -83
- package/src/cli/ui/components/screens/LogDetailScreen.tsx +0 -67
- package/src/cli/ui/components/screens/LogListScreen.tsx +0 -192
- package/src/cli/ui/components/screens/ModelSelectorScreen.tsx +0 -320
- package/src/cli/ui/components/screens/PRCleanupScreen.tsx +0 -171
- package/src/cli/ui/components/screens/SessionSelectorScreen.tsx +0 -135
- package/src/cli/ui/hooks/useAppInput.ts +0 -172
- package/src/cli/ui/hooks/useBatchMerge.ts +0 -96
- package/src/cli/ui/hooks/useGitData.ts +0 -347
- package/src/cli/ui/hooks/useProfiles.ts +0 -211
- package/src/cli/ui/hooks/useScreenState.ts +0 -44
- package/src/cli/ui/hooks/useTerminalSize.ts +0 -33
- package/src/cli/ui/hooks/useToolStatus.ts +0 -68
- package/src/cli/ui/screens/BranchActionSelectorScreen.tsx +0 -111
- package/src/cli/ui/screens/__tests__/BranchActionSelectorScreen.test.tsx +0 -264
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Version cache for coding agents (FR-028 ~ FR-031)
|
|
3
|
+
*
|
|
4
|
+
* Provides caching mechanism for npm package versions to avoid
|
|
5
|
+
* repeated API calls during wizard navigation.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import type { VersionInfo } from "../../../utils/npmRegistry.js";
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* In-memory cache for agent versions
|
|
12
|
+
* Maps agentId -> VersionInfo[]
|
|
13
|
+
*/
|
|
14
|
+
const versionCache = new Map<string, VersionInfo[]>();
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Type for version fetch function (injectable for testing)
|
|
18
|
+
*/
|
|
19
|
+
export type VersionFetcher = (agentId: string) => Promise<VersionInfo[]>;
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Get cached versions for an agent
|
|
23
|
+
* @returns Cached versions or null if not cached
|
|
24
|
+
*/
|
|
25
|
+
export function getVersionCache(agentId: string): VersionInfo[] | null {
|
|
26
|
+
const cached = versionCache.get(agentId);
|
|
27
|
+
return cached !== undefined ? cached : null;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Check if versions are cached for an agent
|
|
32
|
+
*/
|
|
33
|
+
export function isVersionCachePopulated(agentId: string): boolean {
|
|
34
|
+
return versionCache.has(agentId);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Clear all cached versions
|
|
39
|
+
*/
|
|
40
|
+
export function clearVersionCache(): void {
|
|
41
|
+
versionCache.clear();
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Prefetch versions for multiple agents in parallel
|
|
46
|
+
* This should be called at application startup
|
|
47
|
+
*
|
|
48
|
+
* @param agentIds - List of agent IDs to prefetch versions for
|
|
49
|
+
* @param fetchFn - Optional custom fetch function (for testing)
|
|
50
|
+
*/
|
|
51
|
+
export async function prefetchAgentVersions(
|
|
52
|
+
agentIds: string[],
|
|
53
|
+
fetchFn?: VersionFetcher,
|
|
54
|
+
): Promise<void> {
|
|
55
|
+
// Import default fetcher if not provided
|
|
56
|
+
const fetcher =
|
|
57
|
+
fetchFn ??
|
|
58
|
+
(async (agentId: string) => {
|
|
59
|
+
const { fetchVersionOptionsForAgent } =
|
|
60
|
+
await import("./versionFetcher.js");
|
|
61
|
+
return fetchVersionOptionsForAgent(agentId);
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
// Fetch all versions in parallel
|
|
65
|
+
const results = await Promise.allSettled(
|
|
66
|
+
agentIds.map(async (agentId) => {
|
|
67
|
+
try {
|
|
68
|
+
const versions = await fetcher(agentId);
|
|
69
|
+
versionCache.set(agentId, versions);
|
|
70
|
+
} catch {
|
|
71
|
+
// On error, don't set cache (getVersionCache will return null)
|
|
72
|
+
}
|
|
73
|
+
}),
|
|
74
|
+
);
|
|
75
|
+
|
|
76
|
+
// Log any failures for debugging (silently handled)
|
|
77
|
+
for (let i = 0; i < results.length; i++) {
|
|
78
|
+
const result = results[i];
|
|
79
|
+
if (result && result.status === "rejected") {
|
|
80
|
+
// Silently handle - cache will return null for this agent
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Set versions in cache (for testing or direct population)
|
|
87
|
+
*/
|
|
88
|
+
export function setVersionCache(
|
|
89
|
+
agentId: string,
|
|
90
|
+
versions: VersionInfo[],
|
|
91
|
+
): void {
|
|
92
|
+
versionCache.set(agentId, versions);
|
|
93
|
+
}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Version fetcher for coding agents
|
|
3
|
+
*
|
|
4
|
+
* Provides functions to fetch version information from npm registry
|
|
5
|
+
* and local installations.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import type { VersionInfo } from "../../../utils/npmRegistry.js";
|
|
9
|
+
import {
|
|
10
|
+
fetchPackageVersions,
|
|
11
|
+
parsePackageCommand,
|
|
12
|
+
} from "../../../utils/npmRegistry.js";
|
|
13
|
+
import { BUILTIN_CODING_AGENTS } from "../../../config/builtin-coding-agents.js";
|
|
14
|
+
import { findCommand } from "../../../utils/command.js";
|
|
15
|
+
import type { SelectInputItem } from "../components/solid/SelectInput.js";
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Get package name for an agent ID (only for bunx-type agents)
|
|
19
|
+
*/
|
|
20
|
+
export function getPackageNameForAgent(agentId: string): string | null {
|
|
21
|
+
const agent = BUILTIN_CODING_AGENTS.find((a) => a.id === agentId);
|
|
22
|
+
if (!agent || agent.type !== "bunx") {
|
|
23
|
+
return null;
|
|
24
|
+
}
|
|
25
|
+
const { packageName } = parsePackageCommand(agent.command);
|
|
26
|
+
return packageName;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Fetch version options for an agent from npm registry
|
|
31
|
+
*/
|
|
32
|
+
export async function fetchVersionOptionsForAgent(
|
|
33
|
+
agentId: string,
|
|
34
|
+
): Promise<VersionInfo[]> {
|
|
35
|
+
const packageName = getPackageNameForAgent(agentId);
|
|
36
|
+
if (!packageName) {
|
|
37
|
+
return [];
|
|
38
|
+
}
|
|
39
|
+
return fetchPackageVersions(packageName);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Agent ID to command name mapping
|
|
44
|
+
*/
|
|
45
|
+
const AGENT_COMMAND_MAP: Record<string, string> = {
|
|
46
|
+
"claude-code": "claude",
|
|
47
|
+
"codex-cli": "codex",
|
|
48
|
+
"gemini-cli": "gemini",
|
|
49
|
+
opencode: "opencode",
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Installed version information
|
|
54
|
+
*/
|
|
55
|
+
export interface InstalledVersionInfo {
|
|
56
|
+
version: string;
|
|
57
|
+
path: string;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Fetch installed version information for an agent
|
|
62
|
+
* Returns null if not installed locally
|
|
63
|
+
*/
|
|
64
|
+
export async function fetchInstalledVersionForAgent(
|
|
65
|
+
agentId: string,
|
|
66
|
+
): Promise<InstalledVersionInfo | null> {
|
|
67
|
+
const commandName = AGENT_COMMAND_MAP[agentId];
|
|
68
|
+
if (!commandName) {
|
|
69
|
+
return null;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
const result = await findCommand(commandName);
|
|
73
|
+
if (result.source !== "installed" || !result.path) {
|
|
74
|
+
return null;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// Version format: v1.0.3 -> 1.0.3
|
|
78
|
+
const version = result.version?.replace(/^v/, "") ?? "unknown";
|
|
79
|
+
|
|
80
|
+
return {
|
|
81
|
+
version,
|
|
82
|
+
path: result.path,
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Convert VersionInfo to SelectInputItem for UI
|
|
88
|
+
*/
|
|
89
|
+
export function versionInfoToSelectItem(v: VersionInfo): SelectInputItem {
|
|
90
|
+
const item: SelectInputItem = {
|
|
91
|
+
label: v.isPrerelease ? `${v.version} (pre)` : v.version,
|
|
92
|
+
value: v.version,
|
|
93
|
+
};
|
|
94
|
+
if (v.publishedAt) {
|
|
95
|
+
item.description = new Date(v.publishedAt).toLocaleDateString();
|
|
96
|
+
}
|
|
97
|
+
return item;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Create installed option for SelectInput
|
|
102
|
+
*/
|
|
103
|
+
export function createInstalledOption(
|
|
104
|
+
installed: InstalledVersionInfo,
|
|
105
|
+
): SelectInputItem {
|
|
106
|
+
return {
|
|
107
|
+
label: `installed@${installed.version}`,
|
|
108
|
+
value: "installed",
|
|
109
|
+
description: installed.path,
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Get all bunx-type agent IDs
|
|
115
|
+
*/
|
|
116
|
+
export function getBunxAgentIds(): string[] {
|
|
117
|
+
return BUILTIN_CODING_AGENTS.filter((a) => a.type === "bunx").map(
|
|
118
|
+
(a) => a.id,
|
|
119
|
+
);
|
|
120
|
+
}
|
package/src/codex.ts
CHANGED
|
@@ -6,10 +6,19 @@ import {
|
|
|
6
6
|
createChildStdio,
|
|
7
7
|
getTerminalStreams,
|
|
8
8
|
resetTerminalModes,
|
|
9
|
+
writeTerminalLine,
|
|
9
10
|
} from "./utils/terminal.js";
|
|
10
|
-
import {
|
|
11
|
+
import {
|
|
12
|
+
findLatestCodexSession,
|
|
13
|
+
waitForCodexSessionId,
|
|
14
|
+
} from "./utils/session.js";
|
|
15
|
+
import { findCommand } from "./utils/command.js";
|
|
16
|
+
import {
|
|
17
|
+
runAgentWithPty,
|
|
18
|
+
shouldCaptureAgentOutput,
|
|
19
|
+
} from "./logging/agentOutput.js";
|
|
11
20
|
|
|
12
|
-
const CODEX_CLI_PACKAGE = "@openai/codex
|
|
21
|
+
const CODEX_CLI_PACKAGE = "@openai/codex";
|
|
13
22
|
|
|
14
23
|
/**
|
|
15
24
|
* Reasoning effort levels supported by Codex CLI.
|
|
@@ -91,6 +100,8 @@ export async function launchCodexCLI(
|
|
|
91
100
|
model?: string;
|
|
92
101
|
reasoningEffort?: CodexReasoningEffort;
|
|
93
102
|
sessionId?: string | null;
|
|
103
|
+
branch?: string | null;
|
|
104
|
+
version?: string | null;
|
|
94
105
|
} = {},
|
|
95
106
|
): Promise<{ sessionId?: string | null }> {
|
|
96
107
|
const terminal = getTerminalStreams();
|
|
@@ -101,16 +112,16 @@ export async function launchCodexCLI(
|
|
|
101
112
|
throw new Error(`Worktree path does not exist: ${worktreePath}`);
|
|
102
113
|
}
|
|
103
114
|
|
|
104
|
-
|
|
105
|
-
|
|
115
|
+
writeTerminalLine(chalk.blue("🚀 Launching Codex CLI..."));
|
|
116
|
+
writeTerminalLine(chalk.gray(` Working directory: ${worktreePath}`));
|
|
106
117
|
|
|
107
118
|
const args: string[] = [];
|
|
108
119
|
const model = options.model ?? DEFAULT_CODEX_MODEL;
|
|
109
120
|
const reasoningEffort =
|
|
110
121
|
options.reasoningEffort ?? DEFAULT_CODEX_REASONING_EFFORT;
|
|
111
122
|
|
|
112
|
-
|
|
113
|
-
|
|
123
|
+
writeTerminalLine(chalk.green(` 🎯 Model: ${model}`));
|
|
124
|
+
writeTerminalLine(chalk.green(` 🧠 Reasoning: ${reasoningEffort}`));
|
|
114
125
|
|
|
115
126
|
const resumeSessionId =
|
|
116
127
|
options.sessionId && options.sessionId.trim().length > 0
|
|
@@ -124,36 +135,36 @@ export async function launchCodexCLI(
|
|
|
124
135
|
case "continue":
|
|
125
136
|
if (resumeSessionId) {
|
|
126
137
|
args.push("resume", resumeSessionId);
|
|
127
|
-
|
|
138
|
+
writeTerminalLine(
|
|
128
139
|
chalk.cyan(
|
|
129
140
|
` ⏭️ Resuming specific Codex session: ${resumeSessionId}`,
|
|
130
141
|
),
|
|
131
142
|
);
|
|
132
143
|
} else {
|
|
133
144
|
args.push("resume", "--last");
|
|
134
|
-
|
|
145
|
+
writeTerminalLine(chalk.cyan(" ⏭️ Resuming last Codex session"));
|
|
135
146
|
}
|
|
136
147
|
break;
|
|
137
148
|
case "resume":
|
|
138
149
|
if (resumeSessionId) {
|
|
139
150
|
args.push("resume", resumeSessionId);
|
|
140
|
-
|
|
151
|
+
writeTerminalLine(
|
|
141
152
|
chalk.cyan(` 🔄 Resuming Codex session: ${resumeSessionId}`),
|
|
142
153
|
);
|
|
143
154
|
} else {
|
|
144
155
|
args.push("resume");
|
|
145
|
-
|
|
156
|
+
writeTerminalLine(chalk.cyan(" 🔄 Resume command"));
|
|
146
157
|
}
|
|
147
158
|
break;
|
|
148
159
|
case "normal":
|
|
149
160
|
default:
|
|
150
|
-
|
|
161
|
+
writeTerminalLine(chalk.green(" ✨ Starting new session"));
|
|
151
162
|
break;
|
|
152
163
|
}
|
|
153
164
|
|
|
154
165
|
if (options.bypassApprovals) {
|
|
155
166
|
args.push("--yolo");
|
|
156
|
-
|
|
167
|
+
writeTerminalLine(chalk.yellow(" ⚠️ Bypassing approvals and sandbox"));
|
|
157
168
|
}
|
|
158
169
|
|
|
159
170
|
if (options.extraArgs && options.extraArgs.length > 0) {
|
|
@@ -164,13 +175,11 @@ export async function launchCodexCLI(
|
|
|
164
175
|
|
|
165
176
|
args.push(...codexArgs);
|
|
166
177
|
|
|
167
|
-
|
|
178
|
+
writeTerminalLine(chalk.gray(` 📋 Args: ${args.join(" ")}`));
|
|
168
179
|
|
|
169
180
|
terminal.exitRawMode();
|
|
170
181
|
resetTerminalModes(terminal.stdout);
|
|
171
182
|
|
|
172
|
-
const childStdio = createChildStdio();
|
|
173
|
-
|
|
174
183
|
const env = Object.fromEntries(
|
|
175
184
|
Object.entries({
|
|
176
185
|
...process.env,
|
|
@@ -179,22 +188,53 @@ export async function launchCodexCLI(
|
|
|
179
188
|
(entry): entry is [string, string] => typeof entry[1] === "string",
|
|
180
189
|
),
|
|
181
190
|
);
|
|
191
|
+
const captureOutput = shouldCaptureAgentOutput(env);
|
|
192
|
+
const childStdio = captureOutput ? null : createChildStdio();
|
|
182
193
|
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
+
// Auto-detect locally installed codex command
|
|
195
|
+
const codexLookup = await findCommand("codex");
|
|
196
|
+
|
|
197
|
+
const execChild = async (child: Promise<unknown>) => {
|
|
198
|
+
try {
|
|
199
|
+
await child;
|
|
200
|
+
} catch (execError: unknown) {
|
|
201
|
+
// Treat SIGINT/SIGTERM as normal exit (user pressed Ctrl+C)
|
|
202
|
+
const signal = (execError as { signal?: unknown })?.signal;
|
|
203
|
+
if (signal === "SIGINT" || signal === "SIGTERM") {
|
|
204
|
+
return;
|
|
205
|
+
}
|
|
206
|
+
throw execError;
|
|
207
|
+
}
|
|
208
|
+
};
|
|
209
|
+
// Treat SIGHUP (1), SIGINT (2), SIGTERM (15) as normal exit signals
|
|
210
|
+
// SIGHUP can occur when the PTY closes, SIGINT/SIGTERM are user interrupts
|
|
211
|
+
const isNormalExitSignal = (signal?: number | null) =>
|
|
212
|
+
signal === 1 || signal === 2 || signal === 15;
|
|
213
|
+
const runCommand = async (command: string, commandArgs: string[]) => {
|
|
214
|
+
if (captureOutput) {
|
|
215
|
+
const result = await runAgentWithPty({
|
|
216
|
+
command,
|
|
217
|
+
args: commandArgs,
|
|
218
|
+
cwd: worktreePath,
|
|
219
|
+
env,
|
|
220
|
+
agentId: "codex-cli",
|
|
221
|
+
});
|
|
222
|
+
if (isNormalExitSignal(result.signal)) {
|
|
223
|
+
return;
|
|
194
224
|
}
|
|
195
|
-
|
|
225
|
+
if (result.exitCode !== null && result.exitCode !== 0) {
|
|
226
|
+
throw new Error(
|
|
227
|
+
`Codex CLI exited with code ${result.exitCode ?? "unknown"}`,
|
|
228
|
+
);
|
|
229
|
+
}
|
|
230
|
+
return;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
if (!childStdio) {
|
|
234
|
+
return;
|
|
235
|
+
}
|
|
196
236
|
|
|
197
|
-
const child = execa(
|
|
237
|
+
const child = execa(command, commandArgs, {
|
|
198
238
|
cwd: worktreePath,
|
|
199
239
|
stdin: childStdio.stdin,
|
|
200
240
|
stdout: childStdio.stdout,
|
|
@@ -202,12 +242,50 @@ export async function launchCodexCLI(
|
|
|
202
242
|
env,
|
|
203
243
|
});
|
|
204
244
|
await execChild(child);
|
|
245
|
+
};
|
|
246
|
+
|
|
247
|
+
// Determine execution strategy based on version selection
|
|
248
|
+
// FR-063b: "installed" option only appears when local command exists
|
|
249
|
+
const requestedVersion = options.version ?? "latest";
|
|
250
|
+
let selectedVersion = requestedVersion;
|
|
251
|
+
|
|
252
|
+
if (requestedVersion === "installed" && !codexLookup.path) {
|
|
253
|
+
writeTerminalLine(
|
|
254
|
+
chalk.yellow(
|
|
255
|
+
" ⚠️ Installed codex command not found. Falling back to latest.",
|
|
256
|
+
),
|
|
257
|
+
);
|
|
258
|
+
selectedVersion = "latest";
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
// Log version information (FR-072)
|
|
262
|
+
if (selectedVersion === "installed") {
|
|
263
|
+
writeTerminalLine(chalk.green(` 📦 Version: installed`));
|
|
264
|
+
} else {
|
|
265
|
+
writeTerminalLine(chalk.green(` 📦 Version: @${selectedVersion}`));
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
try {
|
|
269
|
+
if (selectedVersion === "installed" && codexLookup.path) {
|
|
270
|
+
// FR-066: Use locally installed command when "installed" is selected
|
|
271
|
+
// FR-063b guarantees local command exists when this option is shown
|
|
272
|
+
writeTerminalLine(
|
|
273
|
+
chalk.green(" ✨ Using locally installed codex command"),
|
|
274
|
+
);
|
|
275
|
+
await runCommand(codexLookup.path, args);
|
|
276
|
+
} else {
|
|
277
|
+
// FR-067, FR-068: Use bunx with version suffix for latest/specific versions
|
|
278
|
+
const packageWithVersion = `${CODEX_CLI_PACKAGE}@${selectedVersion}`;
|
|
279
|
+
writeTerminalLine(chalk.cyan(` 🔄 Using bunx ${packageWithVersion}`));
|
|
280
|
+
|
|
281
|
+
await runCommand("bunx", [packageWithVersion, ...args]);
|
|
282
|
+
}
|
|
205
283
|
} finally {
|
|
206
|
-
childStdio
|
|
284
|
+
childStdio?.cleanup();
|
|
207
285
|
}
|
|
208
286
|
|
|
209
287
|
// File-based session detection only - no stdout capture
|
|
210
|
-
// Use only
|
|
288
|
+
// Use only file inspection with a short wait to avoid hanging
|
|
211
289
|
let capturedSessionId: string | null = null;
|
|
212
290
|
const finishedAt = Date.now();
|
|
213
291
|
try {
|
|
@@ -217,6 +295,10 @@ export async function launchCodexCLI(
|
|
|
217
295
|
preferClosestTo: finishedAt,
|
|
218
296
|
windowMs: 10 * 60 * 1000,
|
|
219
297
|
cwd: worktreePath,
|
|
298
|
+
branch: options.branch ?? null,
|
|
299
|
+
worktrees: options.branch
|
|
300
|
+
? [{ path: worktreePath, branch: options.branch }]
|
|
301
|
+
: null,
|
|
220
302
|
});
|
|
221
303
|
const detectedSessionId = latest?.id ?? null;
|
|
222
304
|
// When we explicitly resumed a specific session, keep that ID as the source of truth.
|
|
@@ -226,14 +308,25 @@ export async function launchCodexCLI(
|
|
|
226
308
|
} catch {
|
|
227
309
|
capturedSessionId = usedExplicitSessionId ? resumeSessionId : null;
|
|
228
310
|
}
|
|
311
|
+
const shouldSkipWait =
|
|
312
|
+
typeof process !== "undefined" &&
|
|
313
|
+
(process.env?.NODE_ENV === "test" || Boolean(process.env?.VITEST));
|
|
314
|
+
if (!capturedSessionId && !shouldSkipWait) {
|
|
315
|
+
capturedSessionId = await waitForCodexSessionId({
|
|
316
|
+
startedAt,
|
|
317
|
+
timeoutMs: 15_000,
|
|
318
|
+
pollIntervalMs: 1_000,
|
|
319
|
+
cwd: worktreePath,
|
|
320
|
+
});
|
|
321
|
+
}
|
|
229
322
|
|
|
230
323
|
if (capturedSessionId) {
|
|
231
|
-
|
|
232
|
-
|
|
324
|
+
writeTerminalLine(chalk.cyan(`\n 🆔 Session ID: ${capturedSessionId}`));
|
|
325
|
+
writeTerminalLine(
|
|
233
326
|
chalk.gray(` Resume command: codex resume ${capturedSessionId}`),
|
|
234
327
|
);
|
|
235
328
|
} else {
|
|
236
|
-
|
|
329
|
+
writeTerminalLine(
|
|
237
330
|
chalk.yellow(
|
|
238
331
|
"\n ℹ️ Could not determine Codex session ID automatically.",
|
|
239
332
|
),
|
|
@@ -250,19 +343,25 @@ export async function launchCodexCLI(
|
|
|
250
343
|
: `Failed to launch Codex CLI: ${details || "Unknown error"}`;
|
|
251
344
|
|
|
252
345
|
if (platform() === "win32") {
|
|
253
|
-
|
|
254
|
-
|
|
346
|
+
writeTerminalLine(
|
|
347
|
+
chalk.red("\n💡 Windows troubleshooting tips:"),
|
|
348
|
+
"stderr",
|
|
349
|
+
);
|
|
350
|
+
writeTerminalLine(
|
|
255
351
|
chalk.yellow(
|
|
256
352
|
" 1. Confirm that Bun is installed and bunx is available",
|
|
257
353
|
),
|
|
354
|
+
"stderr",
|
|
258
355
|
);
|
|
259
|
-
|
|
356
|
+
writeTerminalLine(
|
|
260
357
|
chalk.yellow(
|
|
261
358
|
' 2. Run "bunx @openai/codex@latest -- --help" to verify the setup',
|
|
262
359
|
),
|
|
360
|
+
"stderr",
|
|
263
361
|
);
|
|
264
|
-
|
|
362
|
+
writeTerminalLine(
|
|
265
363
|
chalk.yellow(" 3. Restart your terminal or IDE to refresh PATH"),
|
|
364
|
+
"stderr",
|
|
266
365
|
);
|
|
267
366
|
}
|
|
268
367
|
|
|
@@ -278,12 +377,12 @@ export async function launchCodexCLI(
|
|
|
278
377
|
*/
|
|
279
378
|
export async function isCodexAvailable(): Promise<boolean> {
|
|
280
379
|
try {
|
|
281
|
-
await execa("bunx", [CODEX_CLI_PACKAGE
|
|
380
|
+
await execa("bunx", [`${CODEX_CLI_PACKAGE}@latest`, "--help"]);
|
|
282
381
|
return true;
|
|
283
382
|
} catch (error: unknown) {
|
|
284
383
|
const err = error as NodeJS.ErrnoException;
|
|
285
384
|
if (err.code === "ENOENT") {
|
|
286
|
-
|
|
385
|
+
writeTerminalLine(chalk.yellow("\n⚠️ bunx command not found"), "stderr");
|
|
287
386
|
}
|
|
288
387
|
return false;
|
|
289
388
|
}
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import { describe, it, expect, beforeEach, afterEach } from "bun:test";
|
|
2
|
+
import { mkdir, rm } from "fs/promises";
|
|
3
|
+
import { join } from "path";
|
|
4
|
+
import { tmpdir } from "os";
|
|
5
|
+
import { saveSession, loadSession } from "../index.js";
|
|
6
|
+
|
|
7
|
+
describe("saveSession", () => {
|
|
8
|
+
let testDir: string;
|
|
9
|
+
let testRepoRoot: string;
|
|
10
|
+
|
|
11
|
+
beforeEach(async () => {
|
|
12
|
+
// Create a unique temporary directory for each test
|
|
13
|
+
testDir = join(
|
|
14
|
+
tmpdir(),
|
|
15
|
+
`gwt-test-${Date.now()}-${Math.random().toString(36).slice(2)}`,
|
|
16
|
+
);
|
|
17
|
+
testRepoRoot = join(testDir, "test-repo");
|
|
18
|
+
await mkdir(testRepoRoot, { recursive: true });
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
afterEach(async () => {
|
|
22
|
+
// Clean up temporary directory
|
|
23
|
+
try {
|
|
24
|
+
await rm(testDir, { recursive: true, force: true });
|
|
25
|
+
} catch {
|
|
26
|
+
// Ignore cleanup errors
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
it("should save toolVersion to session history", async () => {
|
|
31
|
+
// Arrange
|
|
32
|
+
const sessionData = {
|
|
33
|
+
lastWorktreePath: testRepoRoot,
|
|
34
|
+
lastBranch: "feature/test",
|
|
35
|
+
lastUsedTool: "claude-code",
|
|
36
|
+
toolLabel: "Claude Code",
|
|
37
|
+
mode: "normal" as const,
|
|
38
|
+
model: "opus",
|
|
39
|
+
reasoningLevel: "high",
|
|
40
|
+
skipPermissions: false,
|
|
41
|
+
toolVersion: "2.1.1",
|
|
42
|
+
timestamp: Date.now(),
|
|
43
|
+
repositoryRoot: testRepoRoot,
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
// Act
|
|
47
|
+
await saveSession(sessionData);
|
|
48
|
+
const loaded = await loadSession(testRepoRoot);
|
|
49
|
+
|
|
50
|
+
// Assert
|
|
51
|
+
expect(loaded).not.toBeNull();
|
|
52
|
+
expect(loaded?.history).toHaveLength(1);
|
|
53
|
+
expect(loaded?.history?.[0]?.toolVersion).toBe("2.1.1");
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
it("should save latest toolVersion when not provided", async () => {
|
|
57
|
+
// Arrange
|
|
58
|
+
const sessionData = {
|
|
59
|
+
lastWorktreePath: testRepoRoot,
|
|
60
|
+
lastBranch: "feature/test",
|
|
61
|
+
lastUsedTool: "claude-code",
|
|
62
|
+
toolLabel: "Claude Code",
|
|
63
|
+
mode: "normal" as const,
|
|
64
|
+
model: "opus",
|
|
65
|
+
timestamp: Date.now(),
|
|
66
|
+
repositoryRoot: testRepoRoot,
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
// Act
|
|
70
|
+
await saveSession(sessionData);
|
|
71
|
+
const loaded = await loadSession(testRepoRoot);
|
|
72
|
+
|
|
73
|
+
// Assert
|
|
74
|
+
expect(loaded).not.toBeNull();
|
|
75
|
+
expect(loaded?.history).toHaveLength(1);
|
|
76
|
+
expect(loaded?.history?.[0]?.toolVersion).toBe("latest");
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
it("should preserve toolVersion across multiple saves", async () => {
|
|
80
|
+
// Arrange - first save with version 1.0.0
|
|
81
|
+
await saveSession({
|
|
82
|
+
lastWorktreePath: testRepoRoot,
|
|
83
|
+
lastBranch: "feature/test",
|
|
84
|
+
lastUsedTool: "claude-code",
|
|
85
|
+
toolLabel: "Claude Code",
|
|
86
|
+
toolVersion: "1.0.0",
|
|
87
|
+
timestamp: Date.now() - 1000,
|
|
88
|
+
repositoryRoot: testRepoRoot,
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
// Act - second save with version 2.0.0
|
|
92
|
+
await saveSession({
|
|
93
|
+
lastWorktreePath: testRepoRoot,
|
|
94
|
+
lastBranch: "feature/test",
|
|
95
|
+
lastUsedTool: "claude-code",
|
|
96
|
+
toolLabel: "Claude Code",
|
|
97
|
+
toolVersion: "2.0.0",
|
|
98
|
+
timestamp: Date.now(),
|
|
99
|
+
repositoryRoot: testRepoRoot,
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
const loaded = await loadSession(testRepoRoot);
|
|
103
|
+
|
|
104
|
+
// Assert - should have 2 entries with different versions
|
|
105
|
+
expect(loaded?.history).toHaveLength(2);
|
|
106
|
+
// History is stored oldest first (newest at the end)
|
|
107
|
+
expect(loaded?.history?.[0]?.toolVersion).toBe("1.0.0");
|
|
108
|
+
expect(loaded?.history?.[1]?.toolVersion).toBe("2.0.0");
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
it("should not add to history when skipHistory is true", async () => {
|
|
112
|
+
// Arrange - first save
|
|
113
|
+
await saveSession({
|
|
114
|
+
lastWorktreePath: testRepoRoot,
|
|
115
|
+
lastBranch: "feature/test",
|
|
116
|
+
lastUsedTool: "claude-code",
|
|
117
|
+
toolLabel: "Claude Code",
|
|
118
|
+
toolVersion: "1.0.0",
|
|
119
|
+
timestamp: Date.now(),
|
|
120
|
+
repositoryRoot: testRepoRoot,
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
// Act - second save with skipHistory
|
|
124
|
+
await saveSession(
|
|
125
|
+
{
|
|
126
|
+
lastWorktreePath: testRepoRoot,
|
|
127
|
+
lastBranch: "feature/test",
|
|
128
|
+
lastUsedTool: "claude-code",
|
|
129
|
+
toolLabel: "Claude Code",
|
|
130
|
+
toolVersion: "2.0.0",
|
|
131
|
+
timestamp: Date.now(),
|
|
132
|
+
repositoryRoot: testRepoRoot,
|
|
133
|
+
},
|
|
134
|
+
{ skipHistory: true },
|
|
135
|
+
);
|
|
136
|
+
|
|
137
|
+
const loaded = await loadSession(testRepoRoot);
|
|
138
|
+
|
|
139
|
+
// Assert - should still have only 1 entry
|
|
140
|
+
expect(loaded?.history).toHaveLength(1);
|
|
141
|
+
expect(loaded?.history?.[0]?.toolVersion).toBe("1.0.0");
|
|
142
|
+
});
|
|
143
|
+
});
|