Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions src/main/orcad/orcad-entry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
*/
import process from 'node:process'
import { setAppEnvironment, type AppEnvironment } from '../../shared/app-environment'
import { HEADLESS_RUNTIME_WINDOW_ID } from '../../shared/runtime-session-contracts'
import { setSecretStore, type SecretStore } from '../../shared/secret-store'
import type { ServeReadiness } from '../server/serve-readiness'
import { resolveOrcadInstallRoot, resolveOrcadPath, resolveUserDataPath } from './orcad-app-paths'
Expand Down Expand Up @@ -291,6 +292,10 @@ async function startOrcadRuntime(
// Recovery binds terminal and dispatch identities; only now can startup observations be fenced.
observedStatusCapture.attach(runtime)

// Why: nothing else publishes a graph on this host, so `graphStatus` would stay 'unavailable'
// and every graph-gated RPC — terminal create, tab inventory — would fail or hang forever.
runtime.syncWindowGraph(HEADLESS_RUNTIME_WINDOW_ID, { tabs: [], leaves: [] })

const bindHost = resolveOrcadBindHost(options.bind)
rpc = new OrcaRuntimeRpcServer({
runtime,
Expand Down
14 changes: 14 additions & 0 deletions src/main/startup/headless-pty-hydration-ordering.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,20 @@ describe('headless PTY registry hydration ordering', () => {
expect(readiness).toBeGreaterThan(rpc)
})

it('publishes the orcad headless graph after PTY registration and before RPC', () => {
const source = readFileSync(join(process.cwd(), 'src/main/orcad/orcad-entry.ts'), 'utf8')
const handlersAndHydration = source.indexOf('await registerHeadlessPtyRuntime(')
const sentinel = source.indexOf(
'runtime.syncWindowGraph(HEADLESS_RUNTIME_WINDOW_ID, { tabs: [], leaves: [] })',
handlersAndHydration
)
const rpc = source.indexOf('rpc = new OrcaRuntimeRpcServer({', sentinel)

expect(handlersAndHydration).toBeGreaterThanOrEqual(0)
expect(sentinel).toBeGreaterThan(handlersAndHydration)
expect(rpc).toBeGreaterThan(sentinel)
})

it('starts the orcad hook owner after Store hydration and before daemon PTY recovery', () => {
const source = readFileSync(join(process.cwd(), 'src/main/orcad/orcad-entry.ts'), 'utf8')
const cleanup = source.indexOf('registerCleanup(async () => {')
Expand Down
Loading