diff --git a/src/App.tsx b/src/App.tsx index e0c201a..bd06718 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -348,6 +348,12 @@ const GIT_PUSH_AGENT_ACTIONS: Array<{ }, ]; +type GitPushMenuTarget = { + branch: string | null | undefined; + cwd: string; + worktreePath?: string; +}; + function buildGitPushAgentPrompt( template: string, task: string, @@ -1960,6 +1966,7 @@ const ProjectWorkspace = forwardRef< const [worktreePanelStatus, setWorktreePanelStatus] = useState(null); const [gitPushMenuPosition, setGitPushMenuPosition] = useState<{ + target?: GitPushMenuTarget; x: number; y: number; } | null>(null); @@ -3687,6 +3694,25 @@ const ProjectWorkspace = forwardRef< [handleOpenTerminalAt], ); + const handleOpenWorktreePushMenu = useCallback( + (worktree: GitWorktreeStatus, anchor: { x: number; y: number }) => { + setGitPushMenuPosition((current) => + current?.target?.worktreePath === worktree.path + ? null + : { + x: anchor.x, + y: anchor.y, + target: { + branch: worktree.branch, + cwd: worktree.path, + worktreePath: worktree.path, + }, + }, + ); + }, + [], + ); + const handleOpenGitEntry = useCallback( (entry: GitChangeEntry) => { // Untracked files have no diff to show; open them directly. Everything @@ -4771,7 +4797,7 @@ const ProjectWorkspace = forwardRef< ); const launchGitPushAgent = useCallback( - (action: GitPushAgentAction) => { + (action: GitPushAgentAction, target?: GitPushMenuTarget) => { setGitPushMenuPosition(null); const config = settings.gitPushAgent; @@ -4799,7 +4825,7 @@ const ProjectWorkspace = forwardRef< const prompt = buildGitPushAgentPrompt( config.prompt, actionMeta.task, - gitPanelStatus?.branch, + target ? target.branch : gitPanelStatus?.branch, ); const command = buildGitPushAgentCommand( config.provider, @@ -4808,7 +4834,7 @@ const ProjectWorkspace = forwardRef< ); void addTerminal({ - cwd: project.rootFolder, + cwd: target?.cwd ?? project.rootFolder, title: 'Push agent', initialInput: command, }); @@ -4822,7 +4848,7 @@ const ProjectWorkspace = forwardRef< ); const launchQuickPush = useCallback( - async (action: GitPushAgentAction) => { + async (action: GitPushAgentAction, target?: GitPushMenuTarget) => { setGitPushMenuPosition(null); if (settings.gitPushAgent.provider === 'disabled') { @@ -4835,18 +4861,20 @@ const ProjectWorkspace = forwardRef< return; } - // Operate on the active terminal's working directory so Quick Push - // targets the branch the user is actually on (e.g. a worktree), - // falling back to the project root. - let cwd = project.rootFolder; - const activeSessionId = getActiveSessionId(); - if (activeSessionId) { - try { - cwd = - (await window.terminay.getTerminalCwd(activeSessionId)) ?? - project.rootFolder; - } catch { - cwd = project.rootFolder; + let cwd = target?.cwd ?? project.rootFolder; + if (!target) { + // Operate on the active terminal's working directory so Quick Push + // targets the branch the user is actually on (e.g. a worktree), + // falling back to the project root. + const activeSessionId = getActiveSessionId(); + if (activeSessionId) { + try { + cwd = + (await window.terminay.getTerminalCwd(activeSessionId)) ?? + project.rootFolder; + } catch { + cwd = project.rootFolder; + } } } @@ -7068,7 +7096,8 @@ const ProjectWorkspace = forwardRef< + + + {collapsed ? null : worktree.errorMessage ? (
{worktree.errorMessage}
) : worktree.isBare ? ( diff --git a/src/components/git-panel/gitPanel.css b/src/components/git-panel/gitPanel.css index f71a50e..e9f1b59 100644 --- a/src/components/git-panel/gitPanel.css +++ b/src/components/git-panel/gitPanel.css @@ -259,7 +259,6 @@ } .worktrees-panel__worktree-header { - all: unset; box-sizing: border-box; min-height: 48px; display: flex; @@ -277,7 +276,20 @@ background: rgba(255, 255, 255, 0.05); } -.worktrees-panel__worktree-header:focus-visible { +.worktrees-panel__worktree-toggle { + all: unset; + box-sizing: border-box; + flex: 1 1 auto; + min-width: 0; + min-height: 40px; + display: flex; + align-items: center; + gap: 6px; + cursor: pointer; +} + +.worktrees-panel__worktree-toggle:focus-visible, +.worktrees-panel__push-button:focus-visible { background: rgba(255, 255, 255, 0.08); outline: 1px solid rgba(87, 183, 255, 0.5); outline-offset: -1px; @@ -356,12 +368,6 @@ padding-left: 22px; } -.worktrees-panel__spacer { - flex: 1 1 auto; - min-width: 0; -} - -.worktrees-panel__branch, .worktrees-panel__pill { flex: 0 1 auto; display: inline-flex; @@ -385,6 +391,35 @@ color: #57b7ff; } +.worktrees-panel__push-button { + all: unset; + box-sizing: border-box; + flex: 0 0 auto; + display: inline-flex; + align-items: center; + justify-content: center; + width: 28px; + height: 28px; + border-radius: 6px; + color: rgba(220, 226, 240, 0.64); + cursor: pointer; + transition: + background 100ms ease, + color 100ms ease; +} + +.worktrees-panel__push-button:hover, +.worktrees-panel__push-button--active { + background: rgba(87, 183, 255, 0.12); + color: #57b7ff; +} + +.worktrees-panel__push-button:disabled { + background: transparent; + color: rgba(220, 226, 240, 0.24); + cursor: default; +} + .worktrees-panel__delta { flex: 0 0 auto; font-variant-numeric: tabular-nums;