Files
orca/src/preload/api/app-api.ts
T
Neil b00ec20731 perf(startup): stop an unreachable SSH host from gating local terminal restore (#18164)
* perf(startup): stop an unreachable SSH host from gating local terminal restore

An asleep or unreachable SSH target held the terminal-restoration gate for the
full 15s reconnect timeout, so no terminal restored — local ones included.
Startup now awaits only the target that owns the active workspace's tabs and
lets the rest connect in the background, folded into the existing deferred path
that reattaches their PTYs on tab focus.

Also splits the renderer's git-environment fence out of the first-window PTY
services barrier: worktree hydration needs shell-PATH generation and the managed
WSL CLI registration, not a daemon PTY spawn or a hook-server bind. Terminal
restoration still fences on the first-window services via
app:prepareTerminalStartupRestoration.

Measured with tests/tools/benchmarks/startup-time-bench.mjs (382 restored tabs,
28k-file profile, medians of 3):
  unreachable SSH host: 17.27s -> 1.34s to renderer-startup-hydration-done
  all-local:             1.98s -> 1.33s

* fix(startup): restore the startup-ordering oracle and keep a connected background SSH target undeferred

app-startup-routing.test.ts pinned the old step names, so the two ordering cases
went vacuous-then-red when the barrier split. Repoint them at the steps that now
carry the same fences: 'git-environment-barrier-await' (shell PATH + managed WSL,
the fence host Git needs) before hydration worktrees, and
'prepare-terminal-startup-restoration' (which awaits firstWindowStartupServicesReady
in main) before terminal reconnect. Both still fail against main's hydration source.

Also: the timed-out-eager rewrite of the deferred list re-added background targets
that had already connected, undoing removeDeferredSshReconnectTarget and sending
fresh panes on a reachable host down the cold-restore path.
2026-09-02 13:10:02 -07:00

95 lines
5.3 KiB
TypeScript

import type { AppIdentity } from '../../shared/app-identity'
import type { E2EConfig } from '../../shared/e2e-config'
import type { ExecutionHostId } from '../../shared/execution-host'
import type {
WriteTerminalRenderDesyncEvidenceArgs,
WriteTerminalRenderDesyncEvidenceResult
} from '../../shared/terminal-render-desync-evidence'
import type { MacCapturedDigitRowChord } from '../../shared/macos-symbolic-hotkeys'
import type { MarkdownDocument } from '../../shared/filesystem-entry-types'
import type { PersistedUIState } from '../../shared/persisted-ui-state-types'
import type { FloatingTerminalCwdRequest } from '../../shared/ui-chrome-types'
import type { WorkspaceSessionState } from '../../shared/workspace-session-state-types'
import type { KeyboardLayoutSnapshot } from '../../shared/keyboard-layout-snapshot'
import type { KeyboardLayoutChangeEvent } from '../../shared/keyboard-layout-events'
export type AppApi = {
/** Returns the app identity currently exposed to native chrome and the titlebar. */
getIdentity: () => Promise<AppIdentity>
/** Returns a URL base for feature-wall assets. In dev this is Vite /@fs;
* in packaged builds this is file:// resources. Renderer appends filenames. */
getFeatureWallAssetBaseUrl: () => Promise<string>
/** Relaunches the app (app.relaunch() + app.exit(0)) for settings that need a full restart to apply. */
relaunch: () => Promise<void>
/** Restarts Orca through the normal quit pipeline so daemon-backed terminal
* sessions survive and can reattach after the new process starts. */
restart: () => Promise<void>
/** Reloads the current app renderer through main so expected renderer
* teardown can be classified before Electron emits process-gone events. */
reload: () => Promise<void>
/** Stages the renderer's final state synchronously before unload. */
stageBeforeUnloadSync: (args: {
sessions: { state: WorkspaceSessionState; hostId?: ExecutionHostId }[]
ui: Partial<PersistedUIState>
}) => void
/** Resolves once the last staged checkpoint is durably written; rejects if that
* write failed, so a reload/restart can abort instead of losing the snapshot. */
awaitBeforeUnloadCheckpoint: () => Promise<void>
/** Resolves when the daemon PTY provider and hook receiver have either
* started or failed open for the first BrowserWindow. */
awaitFirstWindowStartupServices: () => Promise<void>
/** Resolves when host Git can run: shell-PATH generation is published and the
* managed WSL CLI registration has reconciled. Does not wait on PTY services. */
awaitGitEnvironmentStartupBarrier: () => Promise<void>
/** Inventories retained PTYs and restores durable structured ownership before renderer adoption. */
prepareTerminalStartupRestoration: () => Promise<void>
/** Reconciles legacy worker authority around persisted terminal reconnect. */
recoverLegacyWorkerTerminalsForRendererStartup: () => Promise<void>
/** Emits a startup benchmark marker when ORCA_STARTUP_DIAGNOSTICS is enabled. */
startupDiagnostic: (event: string, details?: Record<string, unknown>) => Promise<void>
/** macOS active input mode, or layout ID when no IME is selected (e.g. `com.apple.keylayout.PolishPro`).
* Distinguishes CJK IMEs and Option-layer-composing layouts that look like US QWERTY (issue #1205).
* Returns null on non-Darwin or when the defaults read fails. */
getKeyboardInputSourceId: () => Promise<string | null>
/** Physical Mission Control chords before layout resolution. */
getMacCapturedDigitRowChords: () => Promise<MacCapturedDigitRowChord[]>
/** Active macOS layout characters without Option, or null off macOS or when the native probe fails. */
getKeyboardLayoutSnapshot: () => Promise<KeyboardLayoutSnapshot | null>
/** Subscribes to active macOS input-source changes. No-op in the browser fallback. */
onKeyboardLayoutChanged: (callback: (event: KeyboardLayoutChangeEvent) => void) => () => void
/** Updates the macOS Dock unread badge. No-op on Windows/Linux. */
setUnreadDockBadgeCount: (count: number) => Promise<void>
/** Resolves the launch directory for global Floating Terminal tabs. */
getFloatingTerminalCwd: (args?: FloatingTerminalCwdRequest) => Promise<string>
/** Resolves Orca's app-owned directory for auto-created Floating Workspace
* markdown notes. */
getFloatingMarkdownDirectory: () => Promise<string>
/** Opens a native picker for markdown documents, rooted in the floating
* workspace, and authorizes the selected file for editor reads/writes. */
pickFloatingMarkdownDocument: () => Promise<MarkdownDocument | null>
/** Opens a native directory picker and authorizes the selected directory
* for Floating Workspace markdown file creation. */
pickFloatingWorkspaceDirectory: () => Promise<string | null>
/** Persists flag-gated terminal render evidence under app-owned userData. */
writeTerminalRenderDesyncEvidence: (
args: WriteTerminalRenderDesyncEvidenceArgs
) => Promise<WriteTerminalRenderDesyncEvidenceResult>
}
/** Panel contribution as surfaced by the main-process plugin service. */
export type PlatformApi = {
get: () => {
platform: NodeJS.Platform
osRelease: string
arch: string
/** Login shell or ComSpec when available. */
shell: string
displayServer: 'wayland' | 'x11' | null
}
}
export type E2EApi = {
getConfig: () => E2EConfig
}