# How to Use Orca's IPC Handlers for Worktrees: A Complete Developer Guide

> Master Orca's IPC handlers for worktrees. This guide shows developers how to list, create, and manage worktree metadata using `ipcRenderer.invoke` for local and remote Git repositories.

- Repository: [Stably/orca](https://github.com/stablyai/orca)
- Tags: how-to-guide
- Published: 2026-05-25

---

**Orca exposes Git worktree operations through a centralized IPC layer in [`src/main/ipc/worktrees.ts`](https://github.com/stablyai/orca/blob/main/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`](https://github.com/stablyai/orca/blob/main/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 from `listRepoWorktrees` or SSH provider calls with folder workspaces.
- **`worktrees:list`** – Returns worktrees for a single repository identified by `repoId`, using the same logic as `listAll` but scoped to one repo.
- **`worktrees:listDetected`** – Returns detected worktrees with an authority flag, building a `DetectedWorktreeListResult` containing `authoritative` and `source` fields.

### Creation and Branch Resolution

- **`worktrees:create`** – Creates new worktrees locally, remotely, or as folder workspaces by delegating to `createLocalWorktree`, `createRemoteWorktree`, or `createFolderWorkspace`.
- **`worktrees:resolvePrBase`** – Resolves the base branch for GitHub PRs using `resolveGitHubPrStartPoint`.
- **`worktrees:resolveMrBase`** – Resolves the base branch for GitLab MRs via runtime RPC `resolveManagedMrBase`.

### Metadata and Lineage Management

- **`worktrees:updateMeta`** – Persists partial metadata updates like `isUnread` or `sortOrder` by calling `store.setWorktreeMeta` directly; no UI notification fires because the renderer applies optimistic updates.
- **`worktrees:listLineage`** – Reads parent-child relationships by calling `runtime.hydrateInferredWorktreeLineage`.
- **`worktrees:updateLineage`** – Modifies worktree lineage through `runtime.updateManagedWorktreeMeta`.
- **`worktrees:persistSortOrder`** – Batch-persists UI-driven ordering by writing descending timestamps via `store.setWorktreeMeta`.

### Removal and Hook Operations

- **`worktrees:remove`** – Deletes worktrees with optional force-deletion and archive hook execution, managing concurrency via `worktreeRemovalsInFlight`.
- **`hooks:*`** – Channels for inspecting, reading, writing, or creating hook scripts associated with repositories using the `hooks` module (`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`](https://github.com/stablyai/orca/blob/main/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.

```typescript
// 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`](https://github.com/stablyai/orca/blob/main/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`](https://github.com/stablyai/orca/blob/main/src/main/git/worktree.ts)** – Low-level Git helpers including `listWorktrees`, `removeWorktree`, and `assertWorktreeCleanForRemoval`.
- **[`src/main/ipc/worktree-logic.ts`](https://github.com/stablyai/orca/blob/main/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`](https://github.com/stablyai/orca/blob/main/src/main/ipc/worktree-remote.ts)** – Creation and cleanup logic for remote worktrees including push-target handling.
- **[`src/main/repo-worktrees.ts`](https://github.com/stablyai/orca/blob/main/src/main/repo-worktrees.ts)** – `listRepoWorktrees` wrapper around `git worktree list` for local repositories.
- **`src/main/persistence/*`** – `Store` API implementation for fetching repos, worktree metadata, and settings.
- **[`src/main/runtime/orca-runtime.ts`](https://github.com/stablyai/orca/blob/main/src/main/runtime/orca-runtime.ts)** – Runtime services providing `clearOptimisticReconcileToken` and MR base resolution.
- **`src/main/hooks/*`** – Hook discovery, [`orca.yaml`](https://github.com/stablyai/orca/blob/main/orca.yaml) parsing, and execution helpers.
- **[`src/main/worktree-removal-safety.ts`](https://github.com/stablyai/orca/blob/main/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.ts`](https://github.com/stablyai/orca/blob/main/src/main/ipc/worktrees.ts) via `registerWorktreeHandlers`, 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 `connectionId` status.
- **Safety First**: Concurrent deletions are prevented through `worktreeRemovalsInFlight` maps, while `assertWorktreeCleanForRemoval` enforces clean working directories unless `force` is 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`](https://github.com/stablyai/orca/blob/main/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.