mirror of
https://github.com/stablyai/orca.git
synced 2026-10-31 09:07:40 +00:00
* [comment audit] Align legacy failure-read counts with cached display * [comment audit] Condense shared provider lifecycle and browser recovery comments [skip ci] * [comment audit] Condense shared generation, path and preview comments [skip ci] * [comment audit] Condense host, file and Git contract rationale [skip ci] * [comment audit] Tighten Git lifecycle and provider contract comments [skip ci] * [comment audit] Clarify shared host authority and launch isolation [skip ci] * [comment audit] simplify local access mobile and native chat contracts [skip ci] * [comment audit] simplify native chat presentation and state contracts [skip ci] * [comment audit] simplify native runtime and provider contracts [skip ci] * [comment audit] simplify migration and orchestration contracts [skip ci] * [comment audit] simplify plugin trust and process capture rationale [skip ci] * [comment audit] simplify terminal delivery and remote compatibility rationale [skip ci] * [comment audit] clarify remote recovery and launch wire rationale [skip ci] * [comment audit] shorten shared RPC compatibility and runtime evidence comments [skip ci] * [comment audit] simplify secure storage shell startup and sidebar rationale [skip ci] * [comment audit] clarify sidebar, skill and SSH invariants [skip ci] * [comment audit] condense structured chat delivery and timing rationale [skip ci] * [comment audit] condense terminal replay and telemetry invariants [skip ci] * [comment audit] clarify launch permission and terminal delivery rationale [skip ci] * [comment audit] clarify workspace ownership and layout contracts [skip ci] * [comment audit] wait for fitted and painted SSH terminal links * [comment audit] clarify layout persistence and session ownership [skip ci] * [comment audit] clarify host routing and workspace lifecycle contracts [skip ci] * [comment audit] clarify startup persistence and app lifetime comments [skip ci] * [comment audit] clarify recovery and activity boundaries [skip ci] * [comment audit] condense activity and artifact invariants [skip ci] * [comment audit] condense automation authority contracts [skip ci] * [comment audit] simplify automation scheduling and history contracts [skip ci] * [comment audit] clarify browser chrome and annotation lifecycles [skip ci] * [comment audit] clarify browser routing and retained guest ownership [skip ci] * [comment audit] clarify browser recovery and document ownership comments [skip ci] * [comment audit] restore hosted runners required by native IME fixtures * [comment audit] shorten preview, palette and dashboard invariants [skip ci] * [comment audit] clarify terminal preview, dashboard and retention comments [skip ci] * [comment audit] clarify diff-note recovery and editor lifecycle comments [skip ci] * [comment audit] shorten rich-text and combined-diff ownership comments [skip ci] * [comment audit] shorten autosave, draft recovery and model ownership comments [skip ci] * [comment audit] shorten save-queue, notebook and Markdown constraints [skip ci] * [comment audit] shorten Monaco, PDF and rich Markdown safeguards [skip ci] * [comment audit] clarify rich Markdown source and selection safeguards [skip ci] * [comment audit] clarify editor loading and emulator stream lifetimes [skip ci] * [comment audit] trim emulator and feature tour narration [skip ci] * [comment audit] clarify floating workspace and GitHub cache ownership [skip ci] * [comment audit] trim provider controls and Linear filter explanations [skip ci] * [comment audit] clarify pairing and chat resume lifetimes [skip ci] * [comment audit] clarify chat delivery and transcript lifetimes [skip ci] * [comment audit] clarify session options and host-owned status [skip ci] * [comment audit] clarify draft durability and live-status precedence [skip ci] * [comment audit] Trim chat send and model ownership explanations [skip ci] * [comment audit] Shorten transcript ownership and send recovery comments [skip ci] * [comment audit] Simplify native chat composer and transcript hook comments [skip ci] * [comment audit] Shorten native chat scroll and structured session explanations [skip ci] * [comment audit] Trim workspace picker and onboarding commentary [skip ci] * [comment audit] Simplify pet rendering, review cache and quick open comments [skip ci] * [comment audit] Trim sidebar and session history explanations [skip ci] * [comment audit] Condense session resume and review checks comments [skip ci] * [comment audit] Shorten checks state and file explorer refresh comments [skip ci] * [comment audit] Trim plugin bridge and source-control action rationale [skip ci] * [comment audit] Trim source-control listing and review rationale [skip ci] * [comment audit] Shorten sidebar lifecycle and explorer safeguards [skip ci] * [comment audit] Condense Settings account and appearance rationale [skip ci] * [comment audit] Trim pairing and repository Settings explanations [skip ci] * [comment audit] Condense Settings search SSH and terminal safeguards [skip ci] * [comment audit] Shorten Settings voice and provider ownership comments [skip ci] * [comment audit] Condense Settings draft persistence and host-state rationale [skip ci] * [comment audit] Trim Settings hooks and sidebar setup rationale [skip ci] * [comment audit] Condense sidebar deletion and board-filter safeguards [skip ci] * [comment audit] Condense worktree cards, host ownership and Markdown contracts [skip ci] * [comment audit] Condense sidebar drag, folder and filtering contracts [skip ci] * [comment audit] Condense sidebar parity, sleep and host ownership contracts [skip ci] * [comment audit] Prune focus-read baseline after comment cleanup * [comment audit] Clarify sidebar visibility, board drops and agent evidence [skip ci] * [comment audit] Tighten sidebar listing, drag and reveal contracts [skip ci] * [comment audit] Clarify viewport geometry and skill update safeguards [skip ci] * [comment audit] Tighten skill inventory, usage and host status comments [skip ci] * [comment audit] Clarify usage ownership and resource kill safeguards [skip ci] * [comment audit] Tighten tab selection, rename and search contracts [skip ci] * [comment audit] Tighten tab-strip geometry and drag ownership comments [skip ci] * [comment audit] Tighten Tasks recovery, pagination and mutation comments [skip ci] * [comment audit] Tighten provider loading and terminal recovery comments [skip ci] * [comment audit] Tighten completion, cadence and PTY ownership comments [skip ci] * [comment audit] Clarify terminal restore and parked-pane boundaries [skip ci] * [comment audit] Tighten PTY startup and replay explanations [skip ci] * [comment audit] Clarify PTY identity and delivery ownership [skip ci] * [comment audit] Shorten remote reconnect and input replay rationale [skip ci] * [comment audit] Condense terminal parking clipboard and file link comments [skip ci] * [comment audit] Clarify IME ownership and trim trace history [skip ci] * [comment audit] Shorten pane recovery and parked watcher explanations [skip ci] * [comment audit] Condense snapshot replay and visibility recovery rationale [skip ci] * [comment audit] Shorten terminal parking and keyboard ownership rationale [skip ci] * [comment audit] Trim renderer lifecycle and menu rationale [skip ci] * [comment audit] Condense workspace cleanup ownership and settlement notes [skip ci] * [comment audit] Clarify renderer hook evidence and source ownership [skip ci] * [comment audit] Tighten IPC ownership and reconnect explanations [skip ci] * [comment audit] Trim renderer focus, paste and attention comments [skip ci] * [comment audit] Shorten scroll, locale and agent lifecycle comments [skip ci] * [comment audit] Trim agent launch, resume and ownership commentary [skip ci] * [comment audit] Shorten account, browser and editor comments [skip ci] * [comment audit] Clarify host-mirror waits, previews and input ownership [skip ci] * [comment audit] Condense launch recovery and editor tokenization comments [skip ci] * [comment audit] Condense workspace selection and terminal pane rationale [skip ci] * [comment audit] Condense terminal fitting and rendering recovery comments [skip ci] * [comment audit] Condense terminal input and host routing explanations [skip ci] * [comment audit] Condense ownership and sleeping-session recovery rationale [skip ci] * [comment audit] Condense structured launch and terminal link explanations [skip ci] * [comment audit] Condense terminal ownership and workspace file routing rationale [skip ci] * [comment audit] Condense session persistence and workspace activation rationale [skip ci] * [comment audit] Condense workspace routing and browser ownership rationale [skip ci] * [comment audit] Condense mirror recovery and layout authority rationale [skip ci] * [comment audit] Condense runtime transport and file safety rationale [skip ci] * [comment audit] Condense runtime graph and structured session rationale [skip ci] * [comment audit] Condense browser creation and remote tab recovery rationale [skip ci] * [comment audit] Condense snapshot authority and publisher recovery rationale [skip ci] * [comment audit] Condense frame, startup and provider cache rationale [skip ci] * [comment audit] Condense host twin and agent lifecycle rationale [skip ci] * [comment audit] Condense browser authority and editor cleanup rationale [skip ci] * [comment audit] Condense editor buffer identity and review cache rationale [skip ci] * [comment audit] Condense provider lifetime and repository ownership rationale [skip ci] * [comment audit] Condense reconnect, hydration and terminal retirement rationale [skip ci] * [comment audit] Condense recovery, reconciliation and persistence rationale [skip ci] * [comment audit] Condense cleanup ownership and listing admission rationale [skip ci] * [comment audit] Condense teardown ordering and terminal ownership rationale [skip ci] * [comment audit] Condense recovery ledger and web host-boundary rationale [skip ci] * [comment audit] Condense web reconnect and credential lifecycle rationale [skip ci] * [comment audit] Condense cloud rollout and assignment safety rationale [skip ci] * [comment audit] Condense relay session and database recovery rationale [skip ci] * [comment audit] Condense relay placement and protocol compatibility rationale [skip ci] * [comment audit] Condense build and packaging constraints [skip ci] * [comment audit] Condense CI gates and validation isolation rationale [skip ci] * [comment audit] Condense catalog identity and browser validation rationale [skip ci] * [comment audit] Condense mobile browser and frame-budget rationale [skip ci] * [comment audit] Shorten mobile route and browser test explanations [skip ci] * [comment audit] Condense editor and session seam test rationale [skip ci] * [comment audit] Trim session and terminal closure history [skip ci] * [comment audit] Shorten terminal browser and census explanations [skip ci] * [comment audit] Preserve root-only E2E diagnostic baseline * [comment audit] Condense mobile seam and HTML preview test rationale [skip ci] * [comment audit] Condense preview instrumentation and render harness rationale [skip ci] * [comment audit] Condense bundle contracts and native-build constraints [skip ci] * [comment audit] Shorten native packaging and CI routing rationale [skip ci] * [comment audit] Condense release tooling and benchmark constraints [skip ci] * [comment audit] Condense packaging and platform gate rationale [skip ci] * [comment audit] Shorten mobile route and history rationale [skip ci] * [comment audit] Condense mobile browser and component rationale [skip ci] * [comment audit] Shorten drawer and workspace-form rationale [skip ci] * [comment audit] Trim mobile review and editor-document explanations [skip ci] * [comment audit] Condense editor lifecycle and Markdown explanations [skip ci] * [comment audit] Trim mobile file, diagnostics and dictation commentary [skip ci] * [comment audit] Simplify mobile host-list and workspace-view explanations [skip ci] * [comment audit] Clarify mobile shell lifetime and bridge delivery constraints [skip ci] * [comment audit] Condense bridge stream, native request and audio rationale [skip ci] * [comment audit] Reduce bridge schema and page-client commentary [skip ci] * [comment audit] Tighten mobile page bridge contracts [skip ci] * [comment audit] Clarify mobile cache and session constraints [skip ci] * [comment audit] Condense mobile route and lifecycle rationale [skip ci] * [comment audit] Tighten mobile shell hook timing rationale [skip ci] * [comment audit] Clarify route handoff and notification compatibility [skip ci] * [comment audit] Clarify push registration and dictation cleanup constraints [skip ci] * [comment audit] Condense keyboard geometry and native media ownership rationale [skip ci] * [comment audit] Tighten mobile chat scroll and composer concurrency rationale [skip ci] * [comment audit] Condense mobile reply compatibility and upload ownership rationale [skip ci] * [comment audit] Condense optimistic echo and scroll ownership rationale [skip ci] * [comment audit] Tighten stream replay and queued session ownership rationale [skip ci] * [comment audit] Condense mobile composer and reply-schema constraints [skip ci] * [comment audit] Clarify mobile transcript recovery and session ownership [skip ci] * [comment audit] Clarify mobile queue and source-control compatibility [skip ci] * [comment audit] Condense storage and task launch constraints [skip ci] * [comment audit] Clarify task schemas and terminal document ownership [skip ci] * [comment audit] Tighten terminal input and viewport rationale [skip ci] * [comment audit] Shorten terminal and RPC recorder contracts [skip ci] * [comment audit] Condense recorder engine and connection contracts [skip ci] * [comment audit] Shorten host credential and relay recovery comments [skip ci] * [comment audit] Tighten pairing recovery and bundle transport rationale [skip ci] * [comment audit] Clarify RPC delivery and workspace catalog boundaries [skip ci] * [comment audit] Condense catalog and relay entry contracts [skip ci] * [comment audit] Shorten shutdown and SSH relay delivery contracts [skip ci] * [comment audit] Condense WSL relay and E2E regression rationale [skip ci] * [comment audit] Shorten cross-version harness and renderer fixture explanations [skip ci] * [comment audit] Condense paired-host and E2E lifecycle rationale [skip ci] * [comment audit] Shorten layout oracle and regression explanations [skip ci] * [comment audit] Condense paired recovery and ownership regression contracts [skip ci] * [comment audit] Shorten restart, sidebar and SSH lifecycle contracts [skip ci] * [comment audit] Condense terminal rendering and IME regression rationale [skip ci] * [comment audit] Shorten terminal recovery and benchmark contracts [skip ci] * [comment audit] Condense tooling and Windows lifecycle proof rationale [skip ci] * [comment audit] Condense workflow routing and release rationale [skip ci] * [comment audit] Condense mobile security and installer contracts [skip ci] * [comment audit] Shorten native rationale and stylesheet workarounds [skip ci] * [comment audit] Shorten Windows visibility probe rationale [skip ci] * [comment audit] Condense embedded release and signing rationale [skip ci] * [comment audit] Retain current main test behavior in final reconciliation [skip ci] * [comment audit] Complete final comment review across current source inventory * [comment audit] Handle consolidated audit reports before final CI * [comment audit] Preserve credential storage census detail [skip ci] * [comment audit] Scale broad changed E2E selections with verified timing shards * [comment audit] Align E2E assertions with browser close and settled session metadata * [comment audit] Match existing E2Es to current resource and windowing contracts * [comment audit] Observe the shared server outage notice in reconnect coverage * [comment audit] Make existing renderer probes measure settled tab and PTY work * [comment audit] Align palette E2E selector with task search * [comment audit] Refresh remaining palette search selectors * [comment audit] Keep selector correction within selected audit specs * [comment audit] Await emoji fixture settings inside renderer evaluation * [comment audit] Cancel fixture fit retries between terminal tests --------- Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
279 lines
11 KiB
TypeScript
279 lines
11 KiB
TypeScript
import { quotePosixShellUnlessPlainNoAt } from './shell-argument-quoting'
|
||
import { encodePowerShellCommand } from './powershell-command-encoding'
|
||
import { getPosixCodexShellLaunchPreflight } from './codex-shell-function'
|
||
import { getPosixClaudeShellFunction } from './claude-shell-function'
|
||
import {
|
||
nativeWindowsPathToPosixShellPath,
|
||
resolveSetupRunnerCommand,
|
||
type SetupRunnerCommandPlatform,
|
||
type SetupRunnerShell
|
||
} from './setup-runner-command'
|
||
import { createNonSecureContextUuid } from './non-secure-context-uuid'
|
||
import { quotePowerShellLiteral } from './powershell-native-argument'
|
||
|
||
const DEFAULT_WAIT_TIMEOUT_SECONDS = 2 * 60 * 60
|
||
export const SETUP_COMPLETE_MESSAGE = 'Setup finished; starting agent.'
|
||
export const SETUP_AGENT_SEQUENCE_STARTUP_COMMAND_ENV = 'ORCA_SEQUENCED_STARTUP_COMMAND'
|
||
export const SETUP_AGENT_SEQUENCE_STARTUP_SCRIPT_ENV = 'ORCA_SEQUENCED_STARTUP_SCRIPT'
|
||
|
||
export type SequencedSetupAgentCommands = {
|
||
setupCommand: string
|
||
startupCommand: string
|
||
startupEnv?: Record<string, string>
|
||
}
|
||
|
||
export function resolveSetupAgentSequenceLaunchCommand(
|
||
env: Record<string, string | undefined>,
|
||
fallbackCommand: string | undefined
|
||
): string | undefined {
|
||
const sequencedStartup = env[SETUP_AGENT_SEQUENCE_STARTUP_COMMAND_ENV]?.trim()
|
||
return sequencedStartup || fallbackCommand
|
||
}
|
||
|
||
export function createSetupAgentSequenceNonce(): string {
|
||
return createNonSecureContextUuid()
|
||
}
|
||
|
||
export function createSequencedSetupAgentCommands(args: {
|
||
runnerScriptPath: string
|
||
startupCommand: string
|
||
platform: SetupRunnerCommandPlatform
|
||
shell?: SetupRunnerShell
|
||
nonce?: string
|
||
waitTimeoutSeconds?: number
|
||
}): SequencedSetupAgentCommands {
|
||
const nonce = args.nonce ?? createSetupAgentSequenceNonce()
|
||
const resolution = resolveSetupRunnerCommand(args.runnerScriptPath, args.platform, args.shell)
|
||
// startupCommand is already quoted for the pane: Git Bash needs a bash gate even for batch runners,
|
||
// which still launch through resolution.command. PowerShell cannot parse the POSIX escaping.
|
||
const posixGateForWindowsRunner = resolution.shell === 'windows' && args.shell?.family === 'posix'
|
||
const markerBasePath = posixGateForWindowsRunner
|
||
? nativeWindowsPathToPosixShellPath(resolution.runnerScriptPathForShell)
|
||
: resolution.runnerScriptPathForShell
|
||
// Use distinct markers for overlapping launches of one setup runner.
|
||
const markerPath = `${markerBasePath}.${nonce}.done`
|
||
const waitTimeoutSeconds = args.waitTimeoutSeconds ?? DEFAULT_WAIT_TIMEOUT_SECONDS
|
||
|
||
if (resolution.shell === 'windows' && !posixGateForWindowsRunner) {
|
||
return {
|
||
setupCommand: buildWindowsSetupCommand(
|
||
resolution.runnerScriptPathForShell,
|
||
markerPath,
|
||
nonce
|
||
),
|
||
startupCommand: buildWindowsStartupCommand(markerPath, nonce, waitTimeoutSeconds),
|
||
startupEnv: {
|
||
[SETUP_AGENT_SEQUENCE_STARTUP_COMMAND_ENV]: args.startupCommand
|
||
}
|
||
}
|
||
}
|
||
|
||
const startupScript = buildPosixStartupScript(
|
||
args.startupCommand,
|
||
markerPath,
|
||
nonce,
|
||
waitTimeoutSeconds
|
||
)
|
||
return {
|
||
setupCommand: buildPosixSetupCommand(resolution.command, markerPath, nonce),
|
||
// Why: long worktree paths can push the gate past a PTY's canonical input cap and drop its submit byte.
|
||
startupCommand: `bash -lc 'eval "$${SETUP_AGENT_SEQUENCE_STARTUP_SCRIPT_ENV}"'`,
|
||
startupEnv: {
|
||
[SETUP_AGENT_SEQUENCE_STARTUP_COMMAND_ENV]: args.startupCommand,
|
||
[SETUP_AGENT_SEQUENCE_STARTUP_SCRIPT_ENV]: startupScript
|
||
}
|
||
}
|
||
}
|
||
|
||
function buildPosixSetupCommand(setupCommand: string, markerPath: string, nonce: string): string {
|
||
const marker = quotePosixShellUnlessPlainNoAt(markerPath)
|
||
const tmp = quotePosixShellUnlessPlainNoAt(`${markerPath}.tmp`)
|
||
const nonceValue = quotePosixShellUnlessPlainNoAt(nonce)
|
||
|
||
const script = [
|
||
`rm -f ${marker} ${tmp} 2>/dev/null`,
|
||
`( ${setupCommand} )`,
|
||
'status=$?',
|
||
`printf '%s:%s\\n' ${nonceValue} "$status" > ${tmp}`,
|
||
`mv -f ${tmp} ${marker}`,
|
||
'exit "$status"'
|
||
].join('; ')
|
||
|
||
return `bash -lc ${quotePosixShellUnlessPlainNoAt(script)}`
|
||
}
|
||
|
||
function buildPosixStartupScript(
|
||
startupCommand: string,
|
||
markerPath: string,
|
||
nonce: string,
|
||
waitTimeoutSeconds: number
|
||
): string {
|
||
const marker = quotePosixShellUnlessPlainNoAt(markerPath)
|
||
const tmp = quotePosixShellUnlessPlainNoAt(`${markerPath}.tmp`)
|
||
const nonceValue = quotePosixShellUnlessPlainNoAt(nonce)
|
||
const timeout = Math.max(1, Math.floor(waitTimeoutSeconds))
|
||
const startupSuccessCommand = buildPosixStartupSuccessCommand(startupCommand)
|
||
// Keep the interactive wrapper one line to avoid visible quote-continuation prompts.
|
||
const script = [
|
||
`deadline=$((SECONDS + ${timeout}));`,
|
||
'echo "Waiting for setup to finish before starting agent..." >&2;',
|
||
'while :; do',
|
||
`if [ -f ${marker} ]; then`,
|
||
`IFS=: read -r seen status < ${marker} || true;`,
|
||
`if [ "$seen" = ${nonceValue} ]; then`,
|
||
`rm -f ${marker} ${tmp} 2>/dev/null;`,
|
||
// Announce success so “Waiting for setup...” does not linger. Install launch functions only after setup
|
||
// may have supplied codex; fresh bash -lc does not read Orca’s wrapper.
|
||
`if [ "$status" = "0" ]; then echo ${quotePosixShellUnlessPlainNoAt(SETUP_COMPLETE_MESSAGE)} >&2;\n${getPosixCodexShellLaunchPreflight() + getPosixClaudeShellFunction()}if [ -n "\${${SETUP_AGENT_SEQUENCE_STARTUP_COMMAND_ENV}:-}" ]; then eval "\$${SETUP_AGENT_SEQUENCE_STARTUP_COMMAND_ENV}"; exit "$?"; else ${startupSuccessCommand}; fi; fi;`,
|
||
'echo "Setup failed; skipping agent startup." >&2;',
|
||
'exit "${status:-1}";',
|
||
'fi;',
|
||
'fi;',
|
||
'if [ "$SECONDS" -ge "$deadline" ]; then',
|
||
'echo "Timed out waiting for setup before starting agent." >&2;',
|
||
'exit 124;',
|
||
'fi;',
|
||
'sleep 1;',
|
||
'done'
|
||
].join(' ')
|
||
|
||
return script
|
||
}
|
||
|
||
function buildPosixStartupSuccessCommand(startupCommand: string): string {
|
||
if (
|
||
hasUnquotedPosixCommandSeparator(startupCommand) ||
|
||
hasLeadingPosixEnvAssignment(startupCommand)
|
||
) {
|
||
return `eval ${quotePosixShellUnlessPlainNoAt(startupCommand)}; exit "$?"`
|
||
}
|
||
return `exec ${startupCommand}`
|
||
}
|
||
|
||
function hasLeadingPosixEnvAssignment(command: string): boolean {
|
||
return /^[A-Za-z_][A-Za-z0-9_]*=/.test(command.trimStart())
|
||
}
|
||
|
||
function hasUnquotedPosixCommandSeparator(command: string): boolean {
|
||
let quote: "'" | '"' | null = null
|
||
let escaped = false
|
||
for (const char of command) {
|
||
if (escaped) {
|
||
escaped = false
|
||
continue
|
||
}
|
||
if (char === '\\') {
|
||
escaped = true
|
||
continue
|
||
}
|
||
if (quote) {
|
||
if (char === quote) {
|
||
quote = null
|
||
}
|
||
continue
|
||
}
|
||
if (char === "'" || char === '"') {
|
||
quote = char
|
||
continue
|
||
}
|
||
if (char === ';' || char === '&' || char === '|' || char === '\n' || char === '\r') {
|
||
return true
|
||
}
|
||
}
|
||
return false
|
||
}
|
||
|
||
function buildWindowsSetupCommand(
|
||
runnerScriptPath: string,
|
||
markerPath: string,
|
||
nonce: string
|
||
): string {
|
||
// Why: delayed expansion keeps path metacharacters as data when cmd invokes the batch runner.
|
||
const script = [
|
||
`$runner = ${quotePowerShellLiteral(runnerScriptPath)}`,
|
||
`$marker = ${quotePowerShellLiteral(markerPath)}`,
|
||
'$tmp = $marker + ".tmp"',
|
||
`$nonce = ${quotePowerShellLiteral(nonce)}`,
|
||
'Remove-Item -LiteralPath $marker, $tmp -Force -ErrorAction SilentlyContinue',
|
||
'$processInfo = [System.Diagnostics.ProcessStartInfo]::new()',
|
||
'$processInfo.FileName = $env:ComSpec',
|
||
'$processInfo.Arguments = \'/d /s /v:on /c ""!ORCA_SETUP_RUNNER!""\'',
|
||
'$processInfo.UseShellExecute = $false',
|
||
'$processInfo.EnvironmentVariables["ORCA_SETUP_RUNNER"] = $runner',
|
||
'$process = [System.Diagnostics.Process]::Start($processInfo)',
|
||
'$process.WaitForExit()',
|
||
'$setupStatus = $process.ExitCode',
|
||
'$utf8 = [System.Text.UTF8Encoding]::new($false)',
|
||
'[System.IO.File]::WriteAllText($tmp, ($nonce + ":" + $setupStatus + [Environment]::NewLine), $utf8)',
|
||
'Move-Item -LiteralPath $tmp -Destination $marker -Force',
|
||
'exit $setupStatus'
|
||
].join('; ')
|
||
|
||
return encodePowerShellInvocation(script)
|
||
}
|
||
|
||
function buildWindowsStartupCommand(
|
||
markerPath: string,
|
||
nonce: string,
|
||
waitTimeoutSeconds: number
|
||
): string {
|
||
const timeout = Math.max(1, Math.floor(waitTimeoutSeconds))
|
||
// Use PowerShell for safe bounded marker polling; native Windows runners still launch through cmd.
|
||
const script = [
|
||
// User startup may invoke policy-gated .ps1; apply relief in-payload to avoid the flagged command-line switch.
|
||
// Silence/restore module-autoload progress so stderr stays clean. Stop routes nonterminating autoload errors
|
||
// to a reporting catch; never rethrow and abort startup over a broken security module.
|
||
"$orcaProgress = $ProgressPreference; $ProgressPreference = 'SilentlyContinue'",
|
||
'try { Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass -Force -ErrorAction Stop } ' +
|
||
'catch { [Console]::Error.WriteLine("Orca: could not relax the execution policy for this " + ' +
|
||
'"session (" + $_.FullyQualifiedErrorId + "). A startup command that runs a .ps1 " + ' +
|
||
'"may be blocked.") }',
|
||
'$ProgressPreference = $orcaProgress',
|
||
`$marker = ${quotePowerShellLiteral(markerPath)}`,
|
||
'if ([string]::IsNullOrWhiteSpace($marker)) {',
|
||
' [Console]::Error.WriteLine("Missing setup marker path.")',
|
||
' exit 1',
|
||
'}',
|
||
'$tmp = $marker + ".tmp"',
|
||
`$nonce = ${quotePowerShellLiteral(nonce)}`,
|
||
`$deadline = (Get-Date).AddSeconds(${timeout})`,
|
||
'[Console]::Error.WriteLine("Waiting for setup to finish before starting agent...")',
|
||
'while ($true) {',
|
||
' if (Test-Path -LiteralPath $marker) {',
|
||
' $content = Get-Content -LiteralPath $marker -TotalCount 1',
|
||
' if ($content -match "^([0-9A-Za-z_-]+):([0-9]+)$" -and $Matches[1] -eq $nonce) {',
|
||
' $setupStatus = [int]$Matches[2]',
|
||
' Remove-Item -LiteralPath $marker, $tmp -Force -ErrorAction SilentlyContinue',
|
||
' if ($setupStatus -ne 0) {',
|
||
' [Console]::Error.WriteLine("Setup failed; skipping agent startup.")',
|
||
' exit $setupStatus',
|
||
' }',
|
||
` $startup = $env:${SETUP_AGENT_SEQUENCE_STARTUP_COMMAND_ENV}`,
|
||
' if ([string]::IsNullOrWhiteSpace($startup)) {',
|
||
' [Console]::Error.WriteLine("Missing sequenced startup command.")',
|
||
' exit 1',
|
||
' }',
|
||
` [Console]::Error.WriteLine(${quotePowerShellLiteral(SETUP_COMPLETE_MESSAGE)})`,
|
||
' Invoke-Expression $startup',
|
||
' if ($global:LASTEXITCODE -ne $null) { exit $global:LASTEXITCODE }',
|
||
' if (-not $?) { exit 1 }',
|
||
' exit 0',
|
||
' }',
|
||
' }',
|
||
' if ((Get-Date) -ge $deadline) {',
|
||
' [Console]::Error.WriteLine("Timed out waiting for setup before starting agent.")',
|
||
' exit 124',
|
||
' }',
|
||
' Start-Sleep -Seconds 1',
|
||
'}'
|
||
].join('; ')
|
||
|
||
return encodePowerShellInvocation(script)
|
||
}
|
||
|
||
// EncodedCommand is not policy-gated; omit the EDR-heavy ExecutionPolicy Bypass switch.
|
||
// Keep base64 because terminal panes reparse the command.
|
||
function encodePowerShellInvocation(script: string): string {
|
||
return `powershell.exe -NoProfile -NonInteractive -EncodedCommand ${encodePowerShellCommand(script)}`
|
||
}
|