Skip to content

feat(worktree): add git worktree pool management for parallel agents#289

Open
whitelonng wants to merge 2 commits into
KunAgent:developfrom
whitelonng:feat/git-worktree
Open

feat(worktree): add git worktree pool management for parallel agents#289
whitelonng wants to merge 2 commits into
KunAgent:developfrom
whitelonng:feat/git-worktree

Conversation

@whitelonng

Copy link
Copy Markdown
Contributor

Summary

Adds a Git worktree pool (max 3) so multiple agents can work on the same repository on isolated branches without interfering with each other. This PR delivers the infrastructure + management UI; agent-runtime auto-integration (acquire on task start, release on task end, conflict dialog) is intentionally left for a follow-up to keep this PR reviewable.

Architecture

All git operations use the git CLI (no git2/nodegit dependency) via Kun's existing runGit() helper, which is now exported from git-service.ts.

Settings UI (settings-section-worktree.tsx)
  → window.kunGui.acquireWorktree / mergeWorktree / ...
    → ipcRenderer.invoke('worktree:xxx')
      → ipcMain.handle → worktree-service.ts
        → runGit() → git CLI

What's included

Main process (src/main/services/worktree-service.ts — new):

  • acquireWorktree — create or force-reset (git reset --hard + git clean -ffd) a pool worktree. Emits a WORKTREE_HAS_CHANGES:{poolIndex}:{count} error if the worktree is dirty and force is not set — the renderer parses this to show a confirmation dialog.
  • listWorktrees / removeWorktree / getWorktreeChanges / commitWorktree
  • mergeWorktreeToMain — fast-forward first, then merge commit, with conflict detection (git diff --name-only --diff-filter=U)
  • syncWorktreeFromMain — rebase from main with auto-stash (git stash pushgit rebasegit stash pop), conflict detection
  • abortMerge / continueMerge / abortRebase / cleanupWorktrees / findAvailablePoolIndex
  • In-memory task ownership tracking (replaces the Rust WORKTREE_TASK_MAP)

IPC layer: 12 ipcMain.handle channels with zod-validated payloads (worktree:acquire, worktree:release, worktree:list, worktree:remove, worktree:changes, worktree:commit, worktree:merge, worktree:abort-merge, worktree:continue-merge, worktree:sync, worktree:abort-rebase, worktree:cleanup, worktree:find-available)

Preload + kun-gui-api.ts: full type-safe bridge with shared types in src/shared/worktree.ts.

Renderer:

  • Zustand store (worktree-store.ts)
  • Dedicated Worktrees settings section with:
    • Pool overview (main branch, in-use count, pool directory)
    • Per-pool cards showing status (in-use / idle / empty), uncommitted change count, and actions (create / release / merge / sync / remove)
    • Merge/sync result feedback with conflicted file listing
    • Cleanup-all button
  • 21 i18n keys (en/zh)

Key design decisions

  1. runGit exported, not duplicated — Kun's existing runGit() already handles C-locale forcing (critical for parsing git output) and timeout/buffer limits. Worktree reuses it directly.
  2. reset --hard before clean -ffd — order matters: reset turns staged-new files back into untracked, then clean removes them. Reversed order leaves staged files behind.
  3. WORKTREE_HAS_CHANGES as a string protocol — matches the source project's approach; the error message is parsed by the renderer to show a "N uncommitted changes, force reset?" confirmation.
  4. Pool directory: ~/.kun/{project-basename}/pool-{i} by default, configurable via worktreeRoot.
  5. Agent-runtime integration deferred — this PR only provides the management surface. A follow-up will hook into the agent task lifecycle to auto-acquire/release and show a conflict-resolution dialog.

Verification

  • npm run typecheck passes
  • npm run lint — 0 errors (9 pre-existing warnings unchanged)
  • npx vitest run src/renderer/src/components — 262/262 passed

Notes

  • No new npm dependencies (all git operations via CLI).
  • The worktree pool is compatible with Kun's existing findNearestGitRoot (which already handles .git files for worktrees/submodules).

Adds a Git worktree pool (max 3) so multiple agents can work on the
same repository on isolated branches without interfering with each
other. This is the infrastructure layer: pool management + Settings UI.
Agent-runtime integration (auto acquire/release on task lifecycle) is
left for a follow-up.

Main process (src/main/services/worktree-service.ts):
- acquireWorktree: create or reset (git reset --hard + git clean -ffd)
  a pool worktree; emits WORKTREE_HAS_CHANGES error if dirty and not
  forced (matches TalkCody's protocol)
- listWorktrees / removeWorktree / getWorktreeChanges / commitWorktree
- mergeWorktreeToMain (ff-first, then merge commit, conflict detection)
- syncWorktreeFromMain (rebase with auto-stash)
- abortMerge / continueMerge / abortRebase / cleanupWorktrees
- findAvailablePoolIndex
- Reuses Kun's runGit() (now exported) for all git invocation; no
  git2/nodegit dependency, pure git CLI

IPC layer: 12 ipcMain.handle channels (worktree:acquire/release/list/
remove/changes/commit/merge/abort-merge/continue-merge/sync/abort-rebase/
cleanup/find-available) with zod-validated payloads.

Preload + kun-gui-api: full type-safe bridge.

Renderer:
- Zustand store (worktree-store.ts)
- Settings section with pool overview, per-pool cards (create/release/
  merge/sync/remove), conflict file listing, and cleanup-all
- 21 i18n keys (en/zh)
…tash warnings

Three safety fixes from code review:

1. mergeWorktreeToMain: refuse to checkout main in the user's main repo.
   Previously it silently switched the user's current branch to main and
   never switched back. Now it checks if the user is already on main; if
   not, returns an error instructing them to switch first.

2. acquireWorktree force path: clean -ffd → clean -fd. The double -f
   would delete nested git repos (submodules, CMake deps), which is
   destructive and surprising. Single -f removes untracked files/dirs
   only.

3. syncWorktreeFromMain: stash pop conflicts and non-conflict failures
   now return informative messages telling the user the stash is still
   on the stack and they need to run `git stash pop` manually.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant