mirror of
https://github.com/stablyai/orca.git
synced 2026-10-01 00:02:10 +00:00
The relay CLI shim on SSH remotes rejected every orchestration/mutation command with 'Unsupported SSH Orca CLI command' because the host handled relay CLI requests with a hand-rolled allowlist of five read-only-ish commands. The host now runs the real bundled orca CLI entry (same entry as the local shell command, via ELECTRON_RUN_AS_NODE) as a captured subprocess, so remote invocations get the full command surface by construction. Remote cwd is carried via ORCA_CLI_CWD so cwd-based selectors (--worktree active) resolve against the caller's remote directory; only Orca terminal-context env vars cross the bridge. Host-interactive commands (serve, claude-teams, agent-teams-tmux) get a targeted error, and the legacy in-process switch remains as a fallback when the host CLI entry cannot be launched. Relay-side request timeouts are raised to fit mutation and long-poll (--wait/--timeout-ms) commands, and stdin forwarding now covers *-stdin payload flags. Fixes #7716 Co-authored-by: Orca <help@stably.ai>
51 lines
1.6 KiB
TypeScript
51 lines
1.6 KiB
TypeScript
export function shouldReadRemoteCliStdin(argv: string[]): boolean {
|
|
if (argv.includes('--help') || argv.includes('-h')) {
|
|
return false
|
|
}
|
|
// Why: computer-use style flags (`--text-stdin`, ...) declare a stdin
|
|
// payload directly in the flag name; the full-CLI bridge (#7716) must
|
|
// forward stdin for them the same way local shells provide it.
|
|
if (argv.some((part) => /^--[a-z0-9][a-z0-9-]*-stdin(?:=|$)/.test(part))) {
|
|
return true
|
|
}
|
|
const commandPath = parseRemoteCliCommandPath(argv)
|
|
if (!isLinearBodyWriteCommand(commandPath)) {
|
|
return false
|
|
}
|
|
return argv.some((part, index) => {
|
|
if (part === '--body-file') {
|
|
return argv[index + 1] === '-'
|
|
}
|
|
return part === '--body-file=-'
|
|
})
|
|
}
|
|
|
|
const REMOTE_STDIN_BOOLEAN_FLAGS = new Set(['current', 'help', 'json', 'parent-current'])
|
|
|
|
function parseRemoteCliCommandPath(argv: string[]): string[] {
|
|
const commandPath: string[] = []
|
|
for (let index = 0; index < argv.length; index += 1) {
|
|
const token = argv[index]
|
|
if (!token.startsWith('--')) {
|
|
commandPath.push(token)
|
|
continue
|
|
}
|
|
const assignment = token.slice(2)
|
|
if (assignment.includes('=')) {
|
|
continue
|
|
}
|
|
const next = argv[index + 1]
|
|
if (!REMOTE_STDIN_BOOLEAN_FLAGS.has(assignment) && next && !next.startsWith('--')) {
|
|
index += 1
|
|
}
|
|
}
|
|
return commandPath
|
|
}
|
|
|
|
function isLinearBodyWriteCommand(commandPath: string[]): boolean {
|
|
if (commandPath[0] !== 'linear') {
|
|
return false
|
|
}
|
|
return (commandPath[1] === 'comment' && commandPath[2] === 'add') || commandPath[1] === 'create'
|
|
}
|