mirror of
https://github.com/stablyai/orca.git
synced 2026-10-30 00:27:39 +00:00
* Provide the Orca CLI automatically in managed WSL terminals * Simplify managed WSL CLI provisioning Never block a shell on CLI availability, keep the shared WSL login-shell builder unchanged, provision from PTY env assembly only, drop the error variable and command probing, and reuse the existing WSLENV helper. * Scope the managed WSL CLI to WSL terminals Provision only for WSL panes and publish the directory through addOrcaWslInteropEnv, so daemon terminals keep inherited WSLENV entries and non-WSL builds never see the variable. Write the bridge with a UTF-8 BOM so Windows PowerShell 5.1 keeps non-ASCII user-data paths, give the dev bridge the dev launcher's app-launch env, and drop the unused skill-setup wiring and runtime capability. * Tighten the managed WSL CLI bridge and setup Launch the bridge child exactly like the registered bridge (no hidden window or output relay; verified through WSL with Node and Electron), give the dev bridge the dev launcher's NODE_OPTIONS stash, clear the guest-only directory before starting Windows processes, collapse setup into one function, warn once, and guard WSL env routing with tests. * Harden managed WSL CLI quoting and inheritance PowerShell also ends single-quoted strings at typographic quotes, so a user-data path such as O'Brien with a curly apostrophe broke the managed bridge. Fix the shared quotePowerShellLiteral and reuse it. Drop an inherited ORCA_WSL_CLI_DIR on the daemon path, remove the unreachable PATH dedupe, and cover failed setup with a stale caller value. * Cover the managed WSL CLI in zsh and on POSIX CI Add a live zsh case that reaches a real prompt, a POSIX test that runs the PATH restore snippet in bash and zsh under set -u, and a null result for unwritable user data. Say what a failed write actually costs, and document per-spawn write logging and older-daemon behaviour. * Keep system bashrc out of the PATH restore test CI runners make bash -c read /etc/bash.bashrc, which fails under set -u. --------- Co-authored-by: Orca Worker <orca-worker@localhost>
54 lines
2.4 KiB
TypeScript
54 lines
2.4 KiB
TypeScript
import { createHash } from 'node:crypto'
|
|
import { existsSync } from 'node:fs'
|
|
import { join } from 'node:path'
|
|
import { getAppEnvironment } from '../../shared/app-environment'
|
|
import { windowsPowerShellPath } from '../../shared/child-process/windows-system-binary'
|
|
import { writeShellWrapperFiles } from '../shell-wrapper-file-writer'
|
|
import { getBundledLauncherPath, LINUX_CLI_COMMAND_NAME } from './bundled-cli-launcher-path'
|
|
import { DEV_COMMAND_NAME } from './cli-install-constants'
|
|
import { buildColocatedWslLauncher, buildWslBridgeScript } from './wsl-cli-scripts'
|
|
|
|
/** Packaged builds share `orca-ide` with guest registration; dev builds get their own name. */
|
|
export function getWslCliCommandName(isPackaged: boolean): string {
|
|
return isPackaged ? LINUX_CLI_COMMAND_NAME : DEV_COMMAND_NAME
|
|
}
|
|
|
|
let warnedMissingRuntime = false
|
|
|
|
/**
|
|
* Directory holding this app's WSL launcher and bridge, or null when the CLI runtime is
|
|
* missing or unwritable. Content-addressed like shell-ready wrappers: builds sharing userData
|
|
* never overwrite each other, and a present file is complete because each one lands by rename.
|
|
*/
|
|
export function getManagedWslCliDir(opts: {
|
|
isPackaged: boolean
|
|
userDataPath: string
|
|
resourcesPath?: string
|
|
}): string | null {
|
|
const cliEntryPath = opts.isPackaged
|
|
? undefined
|
|
: join(getAppEnvironment().getAppPath(), 'out', 'cli', 'index.js')
|
|
const launcherPath = opts.isPackaged
|
|
? opts.resourcesPath && getBundledLauncherPath('win32', opts.resourcesPath)
|
|
: process.execPath
|
|
if (!launcherPath || !existsSync(cliEntryPath ?? launcherPath)) {
|
|
if (!warnedMissingRuntime) {
|
|
warnedMissingRuntime = true
|
|
console.warn('[WSL CLI] Orca CLI runtime is missing; WSL terminals will not provide it.')
|
|
}
|
|
return null
|
|
}
|
|
const launcher = buildColocatedWslLauncher(launcherPath, windowsPowerShellPath())
|
|
const bridge = buildWslBridgeScript({ userDataPath: opts.userDataPath, cliEntryPath })
|
|
const digest = createHash('sha256').update(launcher).update(bridge).digest('hex').slice(0, 20)
|
|
const directory = join(opts.userDataPath, 'wsl-managed-cli', digest)
|
|
const files = [
|
|
[join(directory, getWslCliCommandName(opts.isPackaged)), launcher],
|
|
[join(directory, 'orca-wsl-bridge.ps1'), bridge]
|
|
] as const
|
|
const ready =
|
|
files.every(([path]) => existsSync(path)) ||
|
|
writeShellWrapperFiles(files, '[WSL CLI]', 'WSL terminals will start without the Orca CLI')
|
|
return ready ? directory : null
|
|
}
|