mirror of
https://github.com/stablyai/orca.git
synced 2026-10-07 16:02:29 +00:00
* fix(memory): bound session and lifecycle registries * fix(memory): bound transient filesystem registries * fix(memory): cap path and locale caches * fix(memory): bound runtime recovery registries * fix(memory): bound host mirror gap verdicts * fix(memory): bound shell startup env cache * fix(memory): bound gitlab host context cache * fix(memory): release removed ssh generations * fix(memory): expire cloud refresh replay guards * fix(memory): release retired plugin generations * fix(memory): bound plugin log key retention * fix(memory): bound automation authority generations * fix(memory): bound native chat enrichment cache * fix(memory): bound web session tracking generations * fix(memory): bound codex credential absence paths * fix(memory): bound WSL canonical path cache * fix(memory): bound sparse checkout cache * fix(memory): bound shared directory cache * fix(memory): bound advertised URL scan snapshots * fix(memory): bound automation manager cache * fix(memory): bound web session reorder intents * fix(memory): bound web session focus intents * fix(memory): bound web session handoffs * fix(memory): bound automation dispatch tokens * fix(memory): bound host mirror waiters * fix(memory): bound retained session activity * fix(memory): bound retained session activity * fix(memory): bound web session close intents * fix(memory): bound cloud session cache * fix(memory): bound WSL home cache * fix(memory): bound SSH capability cache * fix(memory): bound trust grant cooldowns * fix(memory): bound WSL auth drain state * fix(memory): bound Linear workspace credential cache * fix(memory): bound local Git capability cache * fix(memory): bound WSL Git environment cache * fix(memory): bound WSL Git environment cache * fix(memory): bound WSL preflight cache * fix(memory): keep hot cache entries warm * fix(memory): preserve generation fences across eviction * fix(memory): close remaining eviction fences * fix(memory): align evicted upstream generations * fix(memory): trim successful capability probes * fix(auth): retain expired refresh replay evidence --------- Co-authored-by: m4air <m4air@Mac.localdomain>
69 lines
2.6 KiB
TypeScript
69 lines
2.6 KiB
TypeScript
import type { SshTarget } from '../../shared/ssh-types'
|
|
import { CapabilityProbeCache } from '../../shared/capability-probe-cache'
|
|
|
|
/**
|
|
* Whether a Windows host can take a file write over the sftp subsystem, and whether it has a
|
|
* PowerShell 7 to fall back to. Both are host facts, so they are cached per execution host rather
|
|
* than per transfer — a hardened host with `Subsystem sftp` removed must not be re-probed on every
|
|
* file of a multi-file upload.
|
|
*/
|
|
export type WindowsRemoteWriteCapability = 'sftp-subsystem' | 'pwsh'
|
|
|
|
// Why re-probe at all: an admin can enable the subsystem, or install PowerShell 7, without the
|
|
// user restarting Orca. Long enough that a hardened host costs one failed probe per half hour.
|
|
export const WINDOWS_WRITE_CAPABILITY_RETRY_INTERVAL_MS = 30 * 60_000
|
|
const MAX_WINDOWS_WRITE_CAPABILITY_HOSTS = 256
|
|
|
|
const capabilitiesByExecutionHost = new Map<
|
|
string,
|
|
CapabilityProbeCache<WindowsRemoteWriteCapability>
|
|
>()
|
|
|
|
function rememberCapabilityCache(
|
|
key: string,
|
|
cache: CapabilityProbeCache<WindowsRemoteWriteCapability>
|
|
): CapabilityProbeCache<WindowsRemoteWriteCapability> {
|
|
capabilitiesByExecutionHost.delete(key)
|
|
capabilitiesByExecutionHost.set(key, cache)
|
|
while (capabilitiesByExecutionHost.size > MAX_WINDOWS_WRITE_CAPABILITY_HOSTS) {
|
|
const oldest = capabilitiesByExecutionHost.keys().next().value
|
|
if (oldest === undefined) {
|
|
break
|
|
}
|
|
capabilitiesByExecutionHost.delete(oldest)
|
|
}
|
|
return cache
|
|
}
|
|
|
|
/**
|
|
* Keyed by the endpoint that executes, not by target id: two Orca targets pointing at one host
|
|
* describe the same sshd, and a target re-created under a new id has not changed what that host
|
|
* supports. A config alias is its own key because ssh_config, not Orca, resolves where it lands.
|
|
*/
|
|
export function getWindowsRemoteWriteExecutionHostKey(target: SshTarget): string {
|
|
if (target.configHost) {
|
|
return `config:${target.configHost}`
|
|
}
|
|
const port = target.port ?? 22
|
|
return target.username
|
|
? `host:${target.username}@${target.host}:${port}`
|
|
: `host:${target.host}:${port}`
|
|
}
|
|
|
|
export function getWindowsRemoteWriteCapabilities(
|
|
target: SshTarget
|
|
): CapabilityProbeCache<WindowsRemoteWriteCapability> {
|
|
const key = getWindowsRemoteWriteExecutionHostKey(target)
|
|
let cache = capabilitiesByExecutionHost.get(key)
|
|
if (!cache) {
|
|
cache = new CapabilityProbeCache<WindowsRemoteWriteCapability>(
|
|
WINDOWS_WRITE_CAPABILITY_RETRY_INTERVAL_MS
|
|
)
|
|
}
|
|
return rememberCapabilityCache(key, cache)
|
|
}
|
|
|
|
export function clearWindowsRemoteWriteCapabilitiesForTests(): void {
|
|
capabilitiesByExecutionHost.clear()
|
|
}
|