Skip to content

Commit e2ca9b9

Browse files
committed
fix(worktree): LOW polish — selector, button style, timeout config (WT-16/17/18)
- PaneTopbar: narrow selector to single project instead of all (WT-16) - ConfirmDialog: distinct accent-colored style for extra action button (WT-17) - GitPort: configurable timeout via createWslGitPort({ timeoutMs }) (WT-18) - WT-19 (prune parallelization) not worth the complexity for startup-only op Co-Authored-By: Rooty
1 parent d923509 commit e2ca9b9

4 files changed

Lines changed: 40 additions & 17 deletions

File tree

src/main/git-port.ts

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { toWslPath } from './wsl-utils'
55

66
const log = createLogger('git-port')
77

8-
const EXEC_TIMEOUT_MS = 15_000
8+
const DEFAULT_EXEC_TIMEOUT_MS = 15_000
99

1010
// ─── Interface ────────────────────────────────────────────────────────────────
1111

@@ -77,11 +77,11 @@ export function makeBranchName(projectId: string, sessionId: string, suffix?: nu
7777
* Runs `wsl.exe git <args>` in the given working directory.
7878
* Resolves with trimmed stdout; rejects with a descriptive Error on non-zero exit.
7979
*/
80-
function wslExec(args: string[], cwd?: string): Promise<string> {
80+
function wslExec(args: string[], cwd?: string, timeoutMs?: number): Promise<string> {
8181
return new Promise((resolve, reject) => {
8282
const opts: ExecFileOptions & { encoding: 'utf8' } = {
8383
encoding: 'utf8',
84-
timeout: EXEC_TIMEOUT_MS,
84+
timeout: timeoutMs ?? DEFAULT_EXEC_TIMEOUT_MS,
8585
...(cwd !== undefined ? { cwd } : {}),
8686
}
8787
execFile('wsl.exe', ['git', ...args], opts, (err, stdout, stderr) => {
@@ -106,23 +106,26 @@ function ensureWslPath(p: string): string {
106106
/**
107107
* Creates a GitPort that shells out to `wsl.exe git ...` for all operations.
108108
*/
109-
export function createWslGitPort(): GitPort {
109+
export function createWslGitPort(options?: { timeoutMs?: number }): GitPort {
110+
const t = options?.timeoutMs
111+
const git = (args: string[]): Promise<string> => wslExec(args, undefined, t)
112+
110113
return {
111114
async isGitRepo(path: string): Promise<boolean> {
112115
try {
113-
await wslExec(['-C', ensureWslPath(path), 'rev-parse', '--git-dir'])
116+
await git(['-C', ensureWslPath(path), 'rev-parse', '--git-dir'])
114117
return true
115118
} catch {
116119
return false
117120
}
118121
},
119122

120123
async getRepoRoot(path: string): Promise<string> {
121-
return wslExec(['-C', ensureWslPath(path), 'rev-parse', '--show-toplevel'])
124+
return git(['-C', ensureWslPath(path), 'rev-parse', '--show-toplevel'])
122125
},
123126

124127
async addWorktree(repoRoot: string, worktreePath: string, branch: string): Promise<void> {
125-
await wslExec([
128+
await git([
126129
'-C',
127130
ensureWslPath(repoRoot),
128131
'worktree',
@@ -135,7 +138,7 @@ export function createWslGitPort(): GitPort {
135138
},
136139

137140
async removeWorktree(repoRoot: string, worktreePath: string): Promise<void> {
138-
await wslExec([
141+
await git([
139142
'-C',
140143
ensureWslPath(repoRoot),
141144
'worktree',
@@ -147,16 +150,16 @@ export function createWslGitPort(): GitPort {
147150
},
148151

149152
async pruneWorktrees(repoRoot: string): Promise<void> {
150-
await wslExec(['-C', ensureWslPath(repoRoot), 'worktree', 'prune'])
153+
await git(['-C', ensureWslPath(repoRoot), 'worktree', 'prune'])
151154
},
152155

153156
async deleteBranch(repoRoot: string, branch: string): Promise<void> {
154-
await wslExec(['-C', ensureWslPath(repoRoot), 'branch', '-D', branch])
157+
await git(['-C', ensureWslPath(repoRoot), 'branch', '-D', branch])
155158
log.info('branch deleted', { repoRoot, branch })
156159
},
157160

158161
async status(path: string): Promise<{ hasChanges: boolean }> {
159-
const output = await wslExec([
162+
const output = await git([
160163
'-C',
161164
ensureWslPath(path),
162165
'status',
@@ -168,7 +171,7 @@ export function createWslGitPort(): GitPort {
168171
},
169172

170173
async aheadCount(path: string, baseOid: string): Promise<number> {
171-
const output = await wslExec([
174+
const output = await git([
172175
'-C',
173176
ensureWslPath(path),
174177
'rev-list',
@@ -179,11 +182,11 @@ export function createWslGitPort(): GitPort {
179182
},
180183

181184
async currentOid(path: string): Promise<string> {
182-
return wslExec(['-C', ensureWslPath(path), 'rev-parse', 'HEAD'])
185+
return git(['-C', ensureWslPath(path), 'rev-parse', 'HEAD'])
183186
},
184187

185188
async gitVersion(): Promise<{ major: number; minor: number }> {
186-
const output = await wslExec(['version'])
189+
const output = await git(['version'])
187190
return parseGitVersion(output)
188191
},
189192
}

src/renderer/components/SplitView/PaneTopbar.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,11 @@ export const PaneTopbar = memo(function PaneTopbar({
1515
}: PaneTopbarProps): React.JSX.Element {
1616
const status = useAppStore((s) => s.sessions[sessionId]?.status ?? 'exited')
1717
const projectId = useAppStore((s) => s.sessions[sessionId]?.projectId)
18-
const projects = useAppStore((s) => s.projects)
18+
const project = useAppStore((s) =>
19+
projectId ? s.projects.find((p) => p.id === projectId) : undefined,
20+
)
1921
const worktreeInfo = useAppStore((s) => s.worktreePaths[sessionId])
2022
const restartSession = useAppStore((s) => s.restartSession)
21-
const project = projectId ? projects.find((p) => p.id === projectId) : undefined
2223

2324
const isTerminal = !projectId
2425
const accentColor = project?.identity?.accentColor ?? undefined

src/renderer/components/shared/ConfirmDialog.css

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,25 @@
6969
border-color: var(--border-bright);
7070
}
7171

72+
.confirm-dialog-btn-extra {
73+
font-family: var(--font-mono);
74+
font-size: 12px;
75+
padding: 6px 16px;
76+
background: transparent;
77+
color: var(--accent);
78+
border: 1px solid var(--accent-border);
79+
border-radius: var(--r);
80+
cursor: pointer;
81+
transition:
82+
color 0.12s,
83+
border-color 0.12s;
84+
}
85+
86+
.confirm-dialog-btn-extra:hover {
87+
color: var(--text0);
88+
border-color: var(--accent);
89+
}
90+
7291
.confirm-dialog-btn-confirm {
7392
font-family: var(--font-mono);
7493
font-size: 12px;

src/renderer/components/shared/ConfirmDialog.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ export function ConfirmDialog({
7575
{extraAction && (
7676
<button
7777
type="button"
78-
className="confirm-dialog-btn-cancel"
78+
className="confirm-dialog-btn-extra"
7979
onClick={extraAction.onClick}
8080
>
8181
{extraAction.label}

0 commit comments

Comments
 (0)