How to Use Orca's IPC Handlers for Worktrees: A Complete Developer Guide
Orca exposes Git worktree operations through a centralized IPC layer in src/main/ipc/worktrees.ts, allowing renderer processes to invoke handlers via ipcRenderer.invoke for listing, creating, removing, and managing worktree metadata across local and remote repositories.
The stablyai/orca repository implements a robust Electron-based Git worktree manager that bridges the main process and renderer through typed IPC channels. Developers can interact with Orca IPC handlers for worktrees by calling registerWorktreeHandlers during app initialization, which registers channels like worktrees:list and worktrees:create for UI components to manage repository workspaces safely.
Understanding the IPC Architecture
All worktree-related IPC handlers are centralized in src/main/ipc/worktrees.ts and registered through the registerWorktreeHandlers function. This function accepts the main window, persistence store, and runtime services as dependencies, establishing the bridge between Electron's main process and the renderer.
The registration process follows a defensive pattern to prevent duplicate listeners during app re-activation. According to the source code, handlers first remove any previously registered handler (lines 37-50) before attaching new listeners via ipcMain.handle. Each handler validates input, looks up the repository in the persisted Store, communicates with either the local Git binary or an SSH-based Git provider, and returns a JSON-serializable response to the renderer.
Available Worktree IPC Channels
Orca organizes worktree operations into distinct IPC channels that the renderer invokes using ipcRenderer.invoke. These channels cover the full lifecycle of worktree management.
Listing and Detection
worktrees:listAll– Lists all visible worktrees across every repository in parallel, merging results fromlistRepoWorktreesor SSH provider calls with folder workspaces.worktrees:list– Returns worktrees for a single repository identified byrepoId, using the same logic aslistAllbut scoped to one repo.worktrees:listDetected– Returns detected worktrees with an authority flag, building aDetectedWorktreeListResultcontainingauthoritativeandsourcefields.
Creation and Branch Resolution
worktrees:create– Creates new worktrees locally, remotely, or as folder workspaces by delegating tocreateLocalWorktree,createRemoteWorktree, orcreateFolderWorkspace.worktrees:resolvePrBase– Resolves the base branch for GitHub PRs usingresolveGitHubPrStartPoint.worktrees:resolveMrBase– Resolves the base branch for GitLab MRs via runtime RPCresolveManagedMrBase.
Metadata and Lineage Management
worktrees:updateMeta– Persists partial metadata updates likeisUnreadorsortOrderby callingstore.setWorktreeMetadirectly; no UI notification fires because the renderer applies optimistic updates.worktrees:listLineage– Reads parent-child relationships by callingruntime.hydrateInferredWorktreeLineage.worktrees:updateLineage– Modifies worktree lineage throughruntime.updateManagedWorktreeMeta.worktrees:persistSortOrder– Batch-persists UI-driven ordering by writing descending timestamps viastore.setWorktreeMeta.
Removal and Hook Operations
worktrees:remove– Deletes worktrees with optional force-deletion and archive hook execution, managing concurrency viaworktreeRemovalsInFlight.hooks:*– Channels for inspecting, reading, writing, or creating hook scripts associated with repositories using thehooksmodule (loadHooks,hasHooksFile, etc.).
Handling Remote vs. Local Repositories
Orca's IPC handlers automatically route Git commands based on repository configuration. Local repositories (without a connectionId) execute native Git CLI commands using gitExecFileAsync, listRepoWorktrees, and removeWorktree. SSH repositories (with a connectionId) route all operations through an SSH provider accessed via getSshGitProvider and requireSshGitProvider.
The code paths are guarded at each step (lines 667-692, 704-728), ensuring that remote operations use the appropriate SSH transport while local operations use direct file system access.
Concurrency and Safety Mechanisms
Orca implements strict safety controls to prevent data corruption during concurrent operations. A Map<string, WorktreeRemovalInFlight> (lines 993-1015) guarantees that only one deletion runs per worktree; concurrent requests either share the same promise or throw an error.
Before removal, assertWorktreeCleanForRemoval validates that the worktree contains no untracked files unless the force parameter is set. Orphaned worktrees undergo cleanup through logic in src/main/worktree-removal-safety.ts (lines 1030-1065). The system also executes defined archive hooks before tearing down worktrees via runRemoteArchiveHook or runHook (lines 983-995).
Implementing Renderer-Side Calls
The renderer process communicates with these handlers through ipcRenderer.invoke. All calls return plain JSON-serializable objects, with errors throwing exceptions catchable via try…catch blocks.
// List worktrees for a specific repository
const worktrees = await ipcRenderer.invoke('worktrees:list', {
repoId: 'repo-123'
});
// Returns: DetectedWorktree[]
// Create a new local worktree from main branch
const result = await ipcRenderer.invoke('worktrees:create', {
repoId: 'repo-123',
name: 'feature-xyz',
baseBranch: 'main',
displayName: 'Feature XYZ',
telemetrySource: 'menu-create'
});
// Returns: { worktree: Worktree }
// Force delete a worktree with archive hook
await ipcRenderer.invoke('worktrees:remove', {
worktreeId: 'repo-123::/path/to/wt',
force: true,
skipArchive: false
});
// Optimistically update read status
await ipcRenderer.invoke('worktrees:updateMeta', {
worktreeId: 'repo-123::/path/to/wt',
updates: { isUnread: false }
});
// Persist drag-and-drop ordering
await ipcRenderer.invoke('worktrees:persistSortOrder', {
orderedIds: [
'repo-123::/wt1',
'repo-123::/wt2',
'repo-123::/wt3'
]
});
// Resolve PR base branch for GitHub integration
const prInfo = await ipcRenderer.invoke('worktrees:resolvePrBase', {
repoId: 'repo-123',
prNumber: 42,
headRefName: 'feature-xyz',
isCrossRepository: false
});
// Returns: { baseBranch: 'main', pushTarget?: GitPushTarget } | { error: string }
Key Implementation Files
Understanding the handler architecture requires familiarity with these core modules:
src/main/ipc/worktrees.ts– Central registration of all worktree IPC handlers including listing, creation, removal, metadata, lineage, and sort order operations.src/main/git/worktree.ts– Low-level Git helpers includinglistWorktrees,removeWorktree, andassertWorktreeCleanForRemoval.src/main/ipc/worktree-logic.ts– Helper functions for parsing IDs, merging worktree data, and handling remote-vs-local edge cases.src/main/ipc/worktree-remote.ts– Creation and cleanup logic for remote worktrees including push-target handling.src/main/repo-worktrees.ts–listRepoWorktreeswrapper aroundgit worktree listfor local repositories.src/main/persistence/*–StoreAPI implementation for fetching repos, worktree metadata, and settings.src/main/runtime/orca-runtime.ts– Runtime services providingclearOptimisticReconcileTokenand MR base resolution.src/main/hooks/*– Hook discovery,orca.yamlparsing, and execution helpers.src/main/worktree-removal-safety.ts– Safety checks for orphaned worktree directories and safe removal logic.
Summary
- Centralized Registration: All worktree IPC handlers are registered in
src/main/ipc/worktrees.tsviaregisterWorktreeHandlers, with duplicate listener prevention built-in. - Channel Coverage: The architecture supports listing (
worktrees:list,worktrees:listAll), creation (worktrees:create), deletion (worktrees:remove), and metadata management (worktrees:updateMeta,worktrees:persistSortOrder). - Transport Abstraction: Handlers automatically choose between local Git CLI and SSH providers based on the repository's
connectionIdstatus. - Safety First: Concurrent deletions are prevented through
worktreeRemovalsInFlightmaps, whileassertWorktreeCleanForRemovalenforces clean working directories unlessforceis specified. - Renderer Integration: UI components invoke these handlers through
ipcRenderer.invoke, receiving typed responses for optimistic updates and error handling.
Frequently Asked Questions
How do I register worktree IPC handlers in the main process?
During Electron app startup, import and call registerWorktreeHandlers(mainWindow, store, runtime) from src/main/ipc/worktrees.ts. This function attaches all handlers to their respective channels and ensures previous listeners are removed to prevent duplicates during window reloads.
What is the difference between worktrees:list and worktrees:listAll?
The worktrees:list channel accepts a repoId parameter and returns worktrees for a single repository, while worktrees:listAll queries every configured repository in parallel, merging results from both local Git operations and SSH providers into a unified list of detected worktrees.
How does Orca handle concurrent worktree deletion requests?
Orca maintains a Map<string, WorktreeRemovalInFlight> that tracks in-progress deletions by worktree ID. When worktrees:remove is invoked, the system checks this map; if a removal is already running for that worktree, concurrent requests either await the same promise or receive an error, preventing duplicate deletion attempts and filesystem conflicts.
Can I skip archive hooks when removing a worktree?
Yes. When invoking worktrees:remove, set the skipArchive parameter to true to bypass execution of defined archive hooks. However, the force parameter only controls whether untracked files block deletion, while archive hooks run independently unless explicitly skipped.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →