mirror of
https://github.com/stablyai/orca.git
synced 2026-10-18 00:03:20 +00:00
119 lines
3.7 KiB
JavaScript
119 lines
3.7 KiB
JavaScript
#!/usr/bin/env node
|
|
import {
|
|
findCommandSpec,
|
|
isCommandGroup,
|
|
normalizeCommandPositionals,
|
|
parseArgs,
|
|
resolveHelpPath,
|
|
validateCommandAndFlags
|
|
} from './args'
|
|
import { dispatch } from './dispatch'
|
|
import { reportCliError } from './format'
|
|
import { printHelp } from './help'
|
|
import { RuntimeClient } from './runtime-client'
|
|
import { COMMAND_SPECS } from './specs'
|
|
|
|
export { COMMAND_SPECS } from './specs'
|
|
export { buildCurrentWorktreeSelector, normalizeWorktreeSelector } from './selectors'
|
|
|
|
function shouldIgnoreRemoteSelection(commandPath: string[]): boolean {
|
|
return (
|
|
commandPath[0] === 'environment' ||
|
|
commandPath[0] === 'serve' ||
|
|
commandPath[0] === 'agent' ||
|
|
(commandPath[0] === 'relay' && commandPath[1] === 'serve')
|
|
)
|
|
}
|
|
|
|
export async function main(argv = process.argv.slice(2), cwd = process.cwd()): Promise<void> {
|
|
const parsed = normalizeCommandPositionals(COMMAND_SPECS, parseArgs(argv))
|
|
const helpPath = resolveHelpPath(parsed)
|
|
if (helpPath !== null) {
|
|
printCliHelp(helpPath)
|
|
if (
|
|
helpPath.length > 0 &&
|
|
!findCommandSpec(COMMAND_SPECS, helpPath) &&
|
|
!isCommandGroup(helpPath) &&
|
|
!isSpecBackedCommandGroup(helpPath)
|
|
) {
|
|
process.exitCode = 1
|
|
}
|
|
return
|
|
}
|
|
if (parsed.commandPath.length === 0) {
|
|
printCliHelp([])
|
|
return
|
|
}
|
|
const json = parsed.flags.has('json')
|
|
|
|
try {
|
|
// Why: CLI syntax and flag errors should be reported before any runtime
|
|
// lookup so users do not get misleading "Orca is not running" failures for
|
|
// simple command typos or unsupported flags.
|
|
validateCommandAndFlags(COMMAND_SPECS, parsed)
|
|
const ignoreRemoteSelection = shouldIgnoreRemoteSelection(parsed.commandPath)
|
|
const pairingCode = ignoreRemoteSelection ? null : parsed.flags.get('pairing-code')
|
|
const environmentSelector = ignoreRemoteSelection ? null : parsed.flags.get('environment')
|
|
// Why: pass `null` (not `undefined`) when remote selection is suppressed
|
|
// so the RuntimeClient default parameter does not re-activate the
|
|
// ORCA_PAIRING_CODE / ORCA_ENVIRONMENT env-var fallback for commands
|
|
// that must run locally.
|
|
const client = new RuntimeClient(
|
|
undefined,
|
|
undefined,
|
|
typeof pairingCode === 'string' ? pairingCode : ignoreRemoteSelection ? null : undefined,
|
|
typeof environmentSelector === 'string'
|
|
? environmentSelector
|
|
: ignoreRemoteSelection
|
|
? null
|
|
: undefined
|
|
)
|
|
await dispatch(parsed.commandPath, {
|
|
flags: parsed.flags,
|
|
client,
|
|
cwd,
|
|
json
|
|
})
|
|
} catch (error) {
|
|
reportCliError(error, json)
|
|
process.exitCode = 1
|
|
}
|
|
}
|
|
|
|
if (require.main === module) {
|
|
void main()
|
|
}
|
|
|
|
function printCliHelp(commandPath: string[]): void {
|
|
if (isSpecBackedCommandGroup(commandPath)) {
|
|
console.log(formatSpecBackedGroupHelp(commandPath[0]))
|
|
return
|
|
}
|
|
printHelp(COMMAND_SPECS, commandPath)
|
|
if (commandPath.length === 0) {
|
|
console.log(
|
|
[
|
|
'',
|
|
'Relay:',
|
|
' relay serve Start a self-hosted Orca runtime relay server'
|
|
].join('\n')
|
|
)
|
|
}
|
|
}
|
|
|
|
function isSpecBackedCommandGroup(commandPath: string[]): boolean {
|
|
return (
|
|
commandPath.length === 1 &&
|
|
COMMAND_SPECS.some((spec) => spec.path.length > 1 && spec.path[0] === commandPath[0])
|
|
)
|
|
}
|
|
|
|
function formatSpecBackedGroupHelp(group: string): string {
|
|
const lines = [`orca ${group}`, '', `Usage: orca ${group} <command> [options]`, '', 'Commands:']
|
|
for (const spec of COMMAND_SPECS.filter((entry) => entry.path[0] === group)) {
|
|
lines.push(` ${spec.path.slice(1).join(' ').padEnd(18)} ${spec.summary}`)
|
|
}
|
|
lines.push('', `Run \`orca ${group} <command> --help\` for command-specific usage.`)
|
|
return lines.join('\n')
|
|
}
|