Files
orca/src/main/ipc/cli.ts
T
Jinjing 6729f683f6 Fix Orca CLI path resolution and improve registration UI (#6484)
* fix Orca CLI path resolution and improve registration UI

- Hydrate the shell PATH before running installer actions on macOS to
  match the user's terminal instead of launchd.
- Resolve the active macOS command path dynamically against shell PATH
  candidates, ignoring broken symlinks and non-executable files.
- Detect and report conflicts with unmanaged executables shadowing the
  configured command path.
- Add "Preparing..." and "Registering..." loading states to the settings
  and setup panels during preflight checks.

* Fix Orca CLI detection and installation path conflict checks

- Allow detecting a managed Orca command located later in PATH when the
  default path entry is missing or non-executable.
- Avoid raising installation conflicts for unmanaged commands located
  after the default install path, as they will be safely shadowed.
- Translate terminal setup and Orca CLI registration strings for
  Spanish, Japanese, Korean, and Chinese locales.

* Only open terminal when pre-install checks succeed

Prevent the terminal from opening and setting the terminal command if
onBeforeOpenTerminal or refreshPreInstallNotice throws an error.
2026-06-27 02:05:23 -07:00

60 lines
2.0 KiB
TypeScript

import { ipcMain } from 'electron'
import type { CliInstallStatus } from '../../shared/cli-install-types'
import { CliInstaller } from '../cli/cli-installer'
import { WslCliInstaller } from '../cli/wsl-cli-installer'
import { hydrateShellPath, mergePathSegments } from '../startup/hydrate-shell-path'
function normalizeWslCliDistro(args?: { distro?: string | null }): string | undefined {
return args?.distro?.trim() || undefined
}
async function hydrateLocalShellPathForCli(force = false): Promise<void> {
if (process.platform === 'win32') {
return
}
// Why: CLI registration must match `which orca` in the user's terminal, not
// the sparse PATH a GUI-launched Electron process inherited from launchd.
const hydration = await hydrateShellPath(force ? { force: true } : undefined)
if (hydration.ok) {
mergePathSegments(hydration.segments)
}
}
export function registerCliHandlers(): void {
ipcMain.handle('cli:getInstallStatus', async (): Promise<CliInstallStatus> => {
await hydrateLocalShellPathForCli()
return new CliInstaller().getStatus()
})
ipcMain.handle('cli:install', async (): Promise<CliInstallStatus> => {
await hydrateLocalShellPathForCli(true)
return new CliInstaller().install()
})
ipcMain.handle('cli:remove', async (): Promise<CliInstallStatus> => {
await hydrateLocalShellPathForCli()
return new CliInstaller().remove()
})
ipcMain.handle(
'cli:getWslInstallStatus',
async (_event, args?: { distro?: string | null }): Promise<CliInstallStatus> => {
return new WslCliInstaller({ distro: normalizeWslCliDistro(args) }).getStatus()
}
)
ipcMain.handle(
'cli:installWsl',
async (_event, args?: { distro?: string | null }): Promise<CliInstallStatus> => {
return new WslCliInstaller({ distro: normalizeWslCliDistro(args) }).install()
}
)
ipcMain.handle(
'cli:removeWsl',
async (_event, args?: { distro?: string | null }): Promise<CliInstallStatus> => {
return new WslCliInstaller({ distro: normalizeWslCliDistro(args) }).remove()
}
)
}