Files
orca/src/main/ssh/ssh-remote-linear-cli.ts
T
Jinjing 52388c1ab7 Fix worker done pane identity (#8473)
* fix(orchestration): bind lifecycle sends to dispatched pane

* fix(orchestration): bind injected worker messaging

* Fix worker_done pane identity gating and rename SSH linear CLI files

- Lifecycle reconciliation now returns an explicit `rejected` action
  (instead of `ignored`) for persisted sender_not_assignee markers, and
  only treats a payload's `_orcaLifecycleRejection` as trusted state
  when it exactly matches that reserved shape, preventing caller-
  supplied markers from spoofing a rejected send as success.
- SSH legacy fallback CLI now fails closed with
  `no_active_sender_terminal` when a worker_done/heartbeat send has no
  resolvable sender identity, rejects mixed raw/structured payload
  flags, and reconstructs structured lifecycle payload fields
  (task/dispatch id, files-modified, report-path, phase) instead of
  dropping them — extracted into ssh-remote-orchestration-send.ts.
- Renamed ssh-remote-linear-argument-error.ts to
  ssh-remote-cli-argument-error.ts since RemoteCliArgumentError is now
  shared beyond the Linear CLI.

* Add re-read logging for already-converted lifecycle rejections

Send-path reconcile converts worker_done/heartbeat rejections with a
no-op logger, so the coordinator's later re-read is the only chance
to surface the rejection message. Log it there instead of dropping it.
2026-07-12 22:45:33 -07:00

49 lines
1.6 KiB
TypeScript

import type { RpcDispatcher } from '../runtime/rpc/dispatcher'
import type { RpcResponse } from '../runtime/rpc/core'
import { getRemoteLinearReadHelp } from './ssh-remote-linear-read-help'
import { tryDispatchRemoteLinearReadCli } from './ssh-remote-linear-read-cli'
import type { ParsedRemoteCli } from './ssh-remote-cli-argument-error'
import {
getRemoteLinearWriteHelp,
tryDispatchRemoteLinearWriteCli
} from './ssh-remote-linear-write-cli'
export function getRemoteLinearHelp(parsed: ParsedRemoteCli): string | null {
const helpPath = remoteLinearHelpPath(parsed)
if (!helpPath) {
return null
}
const readHelp = getRemoteLinearReadHelp(helpPath)
if (readHelp) {
return readHelp
}
return getRemoteLinearWriteHelp({ ...parsed, commandPath: helpPath })
}
function remoteLinearHelpPath(parsed: ParsedRemoteCli): string[] | null {
if (parsed.commandPath[0] === 'help' && parsed.commandPath[1] === 'linear') {
return parsed.commandPath.slice(1)
}
if (parsed.flags.has('help') && parsed.commandPath[0] === 'linear') {
return parsed.commandPath
}
return null
}
export async function tryDispatchRemoteLinearCli(
dispatcher: RpcDispatcher,
parsed: ParsedRemoteCli,
env: Record<string, string>,
stdin?: string
): Promise<RpcResponse | null> {
const readResponse = await tryDispatchRemoteLinearReadCli(dispatcher, parsed, env)
if (readResponse) {
return readResponse
}
const writeResponse = await tryDispatchRemoteLinearWriteCli(dispatcher, parsed, env, stdin)
if (writeResponse) {
return writeResponse
}
return null
}