mirror of
https://github.com/stablyai/orca.git
synced 2026-10-26 00:03:55 +00:00
* fix(daemon): detect severed macOS TCC attribution and surface daemon-restart remedy (STA-3491) macOS pins the detached PTY daemon's TCC responsible process to the app binary that forked it. Once that binary is deleted (packaged updates replace the bundle), Accessibility/Automation grants on Orca silently stop covering every daemon-hosted terminal: osascript/System Events fails with -25211 no matter what the user grants. - record spawnerExecPath in the daemon pid file at fork - adoption checks it: severed + 0 live sessions -> replace the daemon (reason severed_tcc_attribution); live sessions are preserved - Settings (Developer Permissions + Manage Sessions) show a visible banner pointing at Manage Sessions -> Restart while severed * fix(daemon): harden TCC attribution recovery
64 lines
2.5 KiB
TypeScript
64 lines
2.5 KiB
TypeScript
import { DaemonServer, type DaemonServerOptions } from './daemon-server'
|
|
import type { DaemonFileLog } from './daemon-file-log'
|
|
|
|
export type DaemonStartOptions = {
|
|
socketPath: string
|
|
tokenPath: string
|
|
pidPath?: string
|
|
launchNonce?: string
|
|
startedAtMs?: number
|
|
publishEndpointOwnership?: DaemonServerOptions['publishEndpointOwnership']
|
|
entryPath?: string
|
|
appVersion?: string
|
|
spawnerExecPath?: string
|
|
/** Direct-construction seam for versioned protocol fixtures; never CLI/env configured. */
|
|
protocolVersion?: number
|
|
spawnSubprocess: DaemonServerOptions['spawnSubprocess']
|
|
preparePtySpawn?: DaemonServerOptions['preparePtySpawn']
|
|
onPtySessionExit?: DaemonServerOptions['onPtySessionExit']
|
|
onAuthenticatedClientPair?: DaemonServerOptions['onAuthenticatedClientPair']
|
|
log?: DaemonFileLog
|
|
onIdleShutdown?: () => void
|
|
onRpcShutdown?: () => void
|
|
initialAdoptionTestConfig?: DaemonServerOptions['initialAdoptionTestConfig']
|
|
}
|
|
|
|
export type DaemonHandle = {
|
|
shutdown(): Promise<void>
|
|
}
|
|
|
|
export async function startDaemon(opts: DaemonStartOptions): Promise<DaemonHandle> {
|
|
const server = new DaemonServer({
|
|
socketPath: opts.socketPath,
|
|
tokenPath: opts.tokenPath,
|
|
...(opts.pidPath ? { pidPath: opts.pidPath } : {}),
|
|
...(opts.launchNonce ? { launchNonce: opts.launchNonce } : {}),
|
|
...(opts.startedAtMs ? { startedAtMs: opts.startedAtMs } : {}),
|
|
...(opts.publishEndpointOwnership
|
|
? { publishEndpointOwnership: opts.publishEndpointOwnership }
|
|
: {}),
|
|
...(opts.entryPath ? { entryPath: opts.entryPath } : {}),
|
|
...(opts.appVersion ? { appVersion: opts.appVersion } : {}),
|
|
...(opts.spawnerExecPath ? { spawnerExecPath: opts.spawnerExecPath } : {}),
|
|
...(opts.protocolVersion !== undefined ? { protocolVersion: opts.protocolVersion } : {}),
|
|
spawnSubprocess: opts.spawnSubprocess,
|
|
...(opts.preparePtySpawn ? { preparePtySpawn: opts.preparePtySpawn } : {}),
|
|
...(opts.onPtySessionExit ? { onPtySessionExit: opts.onPtySessionExit } : {}),
|
|
...(opts.onAuthenticatedClientPair
|
|
? { onAuthenticatedClientPair: opts.onAuthenticatedClientPair }
|
|
: {}),
|
|
...(opts.log ? { log: opts.log } : {}),
|
|
...(opts.onIdleShutdown ? { onIdleShutdown: opts.onIdleShutdown } : {}),
|
|
...(opts.onRpcShutdown ? { onRpcShutdown: opts.onRpcShutdown } : {}),
|
|
...(opts.initialAdoptionTestConfig
|
|
? { initialAdoptionTestConfig: opts.initialAdoptionTestConfig }
|
|
: {})
|
|
})
|
|
|
|
await server.start()
|
|
|
|
return {
|
|
shutdown: () => server.shutdown()
|
|
}
|
|
}
|