Files
orca/src/main/ipc/repos.ts
T
Jinwoo Hong bed9734a9d Prevent deleted workspace browser snapshot resurrection (#17779)
* Prevent deleted workspace browser snapshot resurrection

* fix: tear down folder workspace browser tabs

* fix: fence pre-publication browser snapshots

* fix: route folder deletion through runtime cleanup

* chore: retrigger CI

* fix: sweep folder PTYs on runtime deletion

* fix: restore deletion fences after runtime refactor

* test: cover deleted renderer snapshot after recreation

* fix: avoid publishing ambiguous worktree snapshots

* fix: preserve optional worktree index state

* fix: fence paired PTYs on worktree removal

* fix: harden deletion fence and folder-delete teardown

- Folder-group delete no longer fails on a mixed-host group: an ambiguous
  connection skips the PTY sweep instead of rejecting the delete.
- Share one folder-workspace PTY teardown helper between the runtime
  removal path and the project-group controller.
- Simplify the mobile snapshot fence: identity-carrying frames are judged
  against the live catalog instanceId and clear the fence once the
  successor is accepted; identity-less frames are fenced by renderer
  generation. Drops the unbounded epoch bookkeeping.
- A fenced frame no longer triggers a resync request on every sync while
  the renderer still lists it as unchanged.
- Cross-host id collisions publish without an instanceId rather than
  blanking the mobile session for that workspace.
- Folder delete IPC always routes through the runtime; the store-only
  fallback and double notify are gone.
- Drop the redundant rescue-path tombstone check; ownership is purged at
  removal.
- Fence tests drive removeWorktreeMetadataAndHistory + syncWindowGraph
  instead of seeding the fence map, and add accept-after-recreate,
  no-resync, and ambiguous-host folder delete cases.
2026-09-02 00:52:24 -04:00

84 lines
4.1 KiB
TypeScript

import type { BrowserWindow } from 'electron'
import { ipcMain } from 'electron'
import type { Store } from '../persistence'
import { registerRepoCatalogHandlers } from './repos/repo-catalog-handlers'
import { registerProjectHostSetupHandlers } from './repos/project-host-setup-handlers'
import { registerRepoCreationHandlers } from './repos/repo-creation-handlers'
import { registerProjectGroupHandlers } from './repos/project-group-handlers'
import { registerFolderWorkspaceHandlers } from './repos/folder-workspace-handlers'
import { registerNestedRepoImportHandler } from './repos/nested-repo-import-handler'
import { registerRepoUpdateHandler } from './repos/repo-update-handler'
import { registerSparsePresetHandlers } from './repos/sparse-preset-handlers'
import { registerRepoFolderPickerHandlers } from './repos/repo-folder-picker-handlers'
import { registerRepoCloneHandlers } from './repos/repo-clone-lifecycle'
import { registerRepoGitUsernameHandler } from './repos/repo-git-username-handler'
import { registerBaseRefQueryHandlers } from './repos/base-ref-query-handlers'
import type { OrcaRuntimeService } from '../runtime/orca-runtime'
export function registerRepoHandlers(
mainWindow: BrowserWindow,
store: Store,
runtime: OrcaRuntimeService
): void {
// Remove previously registered handlers so we can re-register on macOS app re-activation (new window).
ipcMain.removeHandler('repos:list')
ipcMain.removeHandler('repos:listForExecutionHost')
ipcMain.removeHandler('repos:add')
ipcMain.removeHandler('repos:remove')
ipcMain.removeHandler('repos:removeForHost')
ipcMain.removeHandler('repos:reorder')
ipcMain.removeHandler('repos:reorderForHost')
ipcMain.removeHandler('repos:update')
ipcMain.removeHandler('projects:list')
ipcMain.removeHandler('projects:update')
ipcMain.removeHandler('projectHostSetups:list')
ipcMain.removeHandler('projectHostSetups:create')
ipcMain.removeHandler('projectHostSetups:setupExistingFolder')
ipcMain.removeHandler('projectHostSetups:update')
ipcMain.removeHandler('projectHostSetups:delete')
ipcMain.removeHandler('projectGroups:list')
ipcMain.removeHandler('projectGroups:create')
ipcMain.removeHandler('projectGroups:update')
ipcMain.removeHandler('projectGroups:delete')
ipcMain.removeHandler('projectGroups:moveProject')
ipcMain.removeHandler('projectGroups:scanNested')
ipcMain.removeHandler('projectGroups:cancelNestedScan')
ipcMain.removeHandler('projectGroups:importNested')
ipcMain.removeHandler('folderWorkspaces:list')
ipcMain.removeHandler('folderWorkspaces:create')
ipcMain.removeHandler('folderWorkspaces:update')
ipcMain.removeHandler('folderWorkspaces:delete')
ipcMain.removeHandler('folderWorkspaces:getPathStatus')
ipcMain.removeHandler('repos:pickFolder')
ipcMain.removeHandler('repos:pickFolders')
ipcMain.removeHandler('repos:pickDirectory')
ipcMain.removeHandler('repos:clone')
ipcMain.removeHandler('repos:cloneAbort')
ipcMain.removeHandler('repos:cloneRemote')
ipcMain.removeHandler('repos:isGitAvailable')
ipcMain.removeHandler('repos:getDefaultCreateProjectParent')
ipcMain.removeHandler('repos:getGitUsername')
ipcMain.removeHandler('repos:getBaseRefDefault')
ipcMain.removeHandler('repos:searchBaseRefs')
ipcMain.removeHandler('repos:searchBaseRefDetails')
ipcMain.removeHandler('repos:addRemote')
ipcMain.removeHandler('repos:create')
ipcMain.removeHandler('repos:createRemote')
ipcMain.removeHandler('sparsePresets:list')
ipcMain.removeHandler('sparsePresets:save')
ipcMain.removeHandler('sparsePresets:remove')
registerRepoCatalogHandlers(mainWindow, store)
registerProjectHostSetupHandlers(mainWindow, store)
registerRepoCreationHandlers(mainWindow, store)
registerProjectGroupHandlers(mainWindow, store)
registerFolderWorkspaceHandlers(mainWindow, store, runtime)
registerNestedRepoImportHandler(mainWindow, store)
registerRepoUpdateHandler(mainWindow, store)
registerSparsePresetHandlers(mainWindow, store)
registerRepoFolderPickerHandlers(mainWindow)
registerRepoCloneHandlers(mainWindow, store)
registerRepoGitUsernameHandler(store)
registerBaseRefQueryHandlers(store)
}