Conversation
There was a problem hiding this comment.
Thank you very much for this and sorry for the late reply. Somehow I wasn't receiving notifications for PRs opened here....
Code Review
Overall: Well-structured PR. The implementation follows codebase patterns closely, the externalWorktree flag is properly threaded through close/merge/persistence paths, and the backend worktree parsing is solid. Security is handled correctly (path validation, array-form exec, preload allowlist).
Important Issues
1. Misleading close message in TilingLayout.tsx:117-119
The force-close confirmation says "The worktree and branch will be deleted" for external worktrees, which is incorrect — they're intentionally kept. This file wasn't updated in the PR:
// Current (incorrect for external worktrees):
const msg = task.directMode
? 'Close this task? Running agents and shells will be stopped.'
: 'Close this task? The worktree and branch will be deleted.';
// Suggested:
const msg = task.directMode || task.externalWorktree
? 'Close this task? Running agents and shells will be stopped.'
: 'Close this task? The worktree and branch will be deleted.';2. No duplicate import guard in createImportedTask (src/store/tasks.ts)
The UI filters already-tracked paths via trackedWorktreePaths, but createImportedTask itself has no guard against importing the same worktree path twice. A rapid double-click or programmatic call could create duplicates. Compare with createDirectTask which has the hasDirectModeTask() guard at line 144. Suggestion:
const allTaskIds = [...store.taskOrder, ...store.collapsedTaskOrder];
if (allTaskIds.some((id) => store.tasks[id]?.worktreePath === worktree.path)) {
throw new Error('Worktree is already tracked as a task');
}Minor Notes
- Partial import failure (
ImportWorktreesDialog.tsx): Sequential import means if one fails mid-batch, earlier ones are already created. The dialog shows the error but doesn't indicate how many succeeded (e.g. "2 of 5 imported"). Works correctly on reopen though (filters out already-tracked). - File length:
ImportWorktreesDialog.tsxis 364 lines vs. the 300-line guideline. TheStatusBadgehelper at the bottom could be extracted.
What's done well
externalWorktreeflag correctly propagated through all persistence layers (types, save, restore, autosave)- Close task properly skips git cleanup for external worktrees
- Merge dialog defaults
initialCleanup: falsefor imports - Backend:
validatePathon IPC, array-formexec,safeRealpathfallback - Auto-import prompt on project add is a nice UX touch
Summary