test: remove capability inventories and projection receipts (#36018)

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
This commit is contained in:
OrcaWin
2026-10-29 10:39:21 -07:00
committed by GitHub
co-authored by OrcaWin
parent d61b37cbca
commit f4d19ca710
11 changed files with 0 additions and 799 deletions
-3
View File
@@ -3141,7 +3141,6 @@
"src/main/ipc/repos/repo-creation-git-availability.test.ts": 124,
"src/main/ipc/repos/repo-ipc-wsl-move-fence.test.ts": 2855,
"src/main/ipc/repos/repo-remove-for-host-teardown.test.ts": 423,
"src/main/ipc/runtime-agent-launch-capability.test.ts": 1720,
"src/main/ipc/runtime-environments/orcad-delta-move-handlers.test.ts": 949,
"src/main/ipc/runtime-environments/orcad-runtime-conversion-handlers.test.ts": 569,
"src/main/ipc/runtime-environments/orcad-runtime-lifecycle-handlers.test.ts": 32,
@@ -3989,7 +3988,6 @@
"src/main/opencode/overlay-dir-gc-lifecycle.test.ts": 67,
"src/main/opencode/overlay-dir-gc.test.ts": 81,
"src/main/opencode/overlay-source-ownership.test.ts": 78,
"src/main/opencode/status-plugin-shared-server-capability.test.ts": 42,
"src/main/opencode2/status-plugin-setup-lifetime.test.ts": 110,
"src/main/orca-profiles/other-profile-workspace-catalog.test.ts": 377,
"src/main/orca-profiles/profile-active-transfer-worker.test.ts": 2010,
@@ -5459,7 +5457,6 @@
"src/main/runtime/rpc/methods/orchestration/worker/worker-start-prompt-contract.test.ts": 3293,
"src/main/runtime/rpc/methods/orchestration/worker/worker-start-readiness-settlement.test.ts": 541,
"src/main/runtime/rpc/methods/orchestration/worker/worker-start-turn-observation.test.ts": 43,
"src/main/runtime/rpc/methods/orchestration/worker/worker-stop-capability.test.ts": 478,
"src/main/runtime/rpc/methods/orchestration/worker/worker-stop-exit-race.test.ts": 3668,
"src/main/runtime/rpc/methods/orchestration/worker/worker-stop-liveness-verdict.test.ts": 3343,
"src/main/runtime/rpc/methods/orchestration/worker/worker-terminal-custody-at-creation.test.ts": 3239,
@@ -1,143 +0,0 @@
/** Exercise advertised IPC capabilities through the real host gate, including the local-renderer launch path. */
import { beforeEach, describe, expect, it, vi } from 'vitest'
import type { RuntimeCapability } from '../../shared/protocol-version'
import { AGENT_LAUNCH_RUNTIME_CAPABILITY } from '../../shared/agent-launch-runtime-capability'
import {
resolveRpcCallerIdentity,
rpcCallerOperationKey,
type RpcCallerIdentity
} from '../runtime/rpc/rpc-caller-identity'
type AdvertisedClient = {
clientKind?: 'mobile' | 'runtime'
clientCapabilities?: readonly RuntimeCapability[]
caller?: RpcCallerIdentity
pairedDeviceId?: string
}
const { handlers, advertised } = vi.hoisted(
(): {
handlers: Map<string, (event: unknown, args?: unknown) => unknown>
advertised: { unary: AdvertisedClient[]; streaming: AdvertisedClient[] }
} => ({
handlers: new Map(),
advertised: { unary: [], streaming: [] }
})
)
vi.mock('electron', () => ({
BrowserWindow: { fromWebContents: vi.fn() },
ipcMain: {
handle: vi.fn((channel: string, handler: (event: unknown, args?: unknown) => unknown) => {
handlers.set(channel, handler)
}),
on: vi.fn(),
removeAllListeners: vi.fn(),
removeHandler: vi.fn()
}
}))
vi.mock('../runtime/rpc/dispatcher', () => ({
RpcDispatcher: class {
dispatch(_request: unknown, options: AdvertisedClient): Promise<unknown> {
advertised.unary.push(options)
return Promise.resolve({ ok: true, result: {} })
}
dispatchStreaming(
_request: unknown,
_emit: (response: string) => void,
options: AdvertisedClient
): Promise<void> {
advertised.streaming.push(options)
// Keep streaming open; the handler attaches only a cleanup callback.
return new Promise<void>(() => {})
}
}
}))
const { registerRuntimeHandlers } = await import('./runtime')
const { supportsAgentLaunch } = await import('../runtime/rpc/methods/agent-launch')
const { agentLaunchOperationCallerKey } = await import('../runtime/rpc/methods/agent-launch-replay')
function rendererEvent() {
const mainFrame = {}
return {
sender: { id: 1, mainFrame, on: vi.fn(), once: vi.fn(), isDestroyed: () => false },
senderFrame: mainFrame
}
}
function invoke(channel: string, args: unknown): void {
const handler = handlers.get(channel)
if (!handler) {
throw new Error(`no handler registered for ${channel}`)
}
void handler(rendererEvent(), args)
}
/** Missing dispatch must fail rather than pass the gate via undefined clientKind. */
function onlyAdvertisedClient(records: readonly AdvertisedClient[]): AdvertisedClient {
const client = records[0]
if (!client) {
throw new Error('the handler dispatched nothing')
}
return client
}
function withoutLaunchCapability(client: AdvertisedClient): AdvertisedClient {
return {
clientKind: client.clientKind,
clientCapabilities: client.clientCapabilities?.filter(
(capability) => capability !== AGENT_LAUNCH_RUNTIME_CAPABILITY
)
}
}
describe('desktop renderer reaching agent.launch on its own main process', () => {
beforeEach(() => {
handlers.clear()
advertised.unary.length = 0
advertised.streaming.length = 0
// oxlint-disable-next-line typescript/consistent-type-assertions -- SAFETY: registerRuntimeHandlers reaches only the sender-lifecycle cleanup on this path; any other runtime method it called would throw here rather than read a wrong value.
registerRuntimeHandlers({ cleanupSubscriptionsForConnection: vi.fn() } as never)
})
it('advertises the launch capability on the unary path', () => {
invoke('runtime:call', {
method: 'agent.launch',
params: { agent: 'claude', target: { kind: 'existing', worktree: 'id:wt-7' } }
})
const client = onlyAdvertisedClient(advertised.unary)
expect(client.clientKind).toBe('runtime')
expect(supportsAgentLaunch(client)).toBe(true)
expect(supportsAgentLaunch(withoutLaunchCapability(client))).toBe(false)
})
it('advertises the same set on the streaming path', () => {
invoke('runtime:call', { method: 'status.get' })
invoke('runtime:subscribe', { subscriptionId: 'sub-1', method: 'session.tabs.watch' })
const streaming = onlyAdvertisedClient(advertised.streaming)
expect(streaming.clientCapabilities).toEqual(
onlyAdvertisedClient(advertised.unary).clientCapabilities
)
expect(supportsAgentLaunch(streaming)).toBe(true)
})
it('names the desktop as its caller on both paths, so its launches replay under one identity', () => {
invoke('runtime:call', { method: 'status.get' })
invoke('runtime:subscribe', { subscriptionId: 'sub-1', method: 'session.tabs.watch' })
for (const client of [advertised.unary, advertised.streaming].map(onlyAdvertisedClient)) {
const caller = resolveRpcCallerIdentity(client)
expect(caller).toEqual({ kind: 'desktop' })
expect(agentLaunchOperationCallerKey({ caller })).toBe('trusted-local:desktop')
}
const { caller: _named, ...unnamed } = onlyAdvertisedClient(advertised.unary)
expect(resolveRpcCallerIdentity(unnamed)).toBeUndefined()
expect(rpcCallerOperationKey({ kind: 'local-cli' })).toBe('trusted-local:runtime')
})
})
@@ -1,53 +0,0 @@
import { afterEach, describe, expect, it, vi } from 'vitest'
import { getStatusPluginPostSource } from './status-plugin-post-source'
import { getStatusPluginRuntimeStateSource } from './status-plugin-runtime-state-source'
afterEach(() => {
vi.unstubAllEnvs()
vi.unstubAllGlobals()
vi.restoreAllMocks()
})
describe('generated shared-server capability without a test-only environment flag', () => {
it.each([
{ argv: ['opencode', 'serve'], major: 0, capability: '1', expected: true },
{
argv: ['opencode', '/embedded/cli.js', '--log-level', 'none', 'serve'],
major: 0,
capability: '1',
expected: true
},
{
argv: ['opencode', '--log-level', 'serve', 'run', 'serve'],
major: 0,
capability: '1',
expected: false
},
{ argv: ['opencode', 'run', '--', 'serve'], major: 0, capability: '1', expected: false },
{ argv: ['opencode', '--', 'serve'], major: 0, capability: '1', expected: false },
{ argv: ['opencode', 'serve'], major: 2, capability: '1', expected: false },
{ argv: ['opencode', 'serve'], major: 0, capability: '', expected: false }
])(
'recognizes only an opted-in legacy serve context: %j',
async ({ argv, major, capability, expected }) => {
vi.stubEnv('ORCA_PANE_KEY', 'tab-a:aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa')
vi.stubEnv('ORCA_OPENCODE_PLUGIN_API', undefined)
vi.spyOn(process, 'argv', 'get').mockReturnValue(argv)
const posts: Record<string, unknown>[] = []
vi.stubGlobal('fetch', async (_input: unknown, init: RequestInit) => {
posts.push(JSON.parse(String(init.body)))
return new Response('{}', { status: 200 })
})
const source = [
...getStatusPluginRuntimeStateSource(),
...getStatusPluginPostSource('/hook/opencode'),
`reportingOpenCodeMajor = ${major};`,
'return post("SessionBusy", { sessionID: "ses_test" });'
].join('\n')
const run = new Function('resolveHookCoords', source)
await run(() => ({ port: 12345, token: 'fixture', openCodeTui: capability }))
expect(posts).toHaveLength(1)
expect(posts[0].opencodeSharedServer === 1).toBe(expected)
expect(posts[0].opencodeMajor).toBe(major || undefined)
}
)
})
@@ -1,42 +0,0 @@
import { describe, expect, it } from 'vitest'
import { pluginMarketplaceListingSchema } from '../../../shared/plugins/catalog/plugin-marketplace'
import { pluginMarketplaceListing } from './plugin-marketplace-projection'
describe('pluginMarketplaceListing trust', () => {
const listing = (catalogUrl: string, pluginKey: string) => {
const source = { kind: 'git' as const, url: catalogUrl, ref: 'main' }
const marketplace = pluginMarketplaceListingSchema.parse({
name: 'Orca Plugins',
owner: 'stablyai',
plugins: [
{
id: pluginKey,
source: { kind: 'git', url: 'https://github.com/stablyai/orca-plugins.git', ref: 'v1' }
}
]
})
return pluginMarketplaceListing({
source: { id: 'a'.repeat(32), source, addedAt: 0 },
snapshot: {
schemaVersion: 2,
sourceId: 'a'.repeat(32),
source,
marketplaceCommit: 'b'.repeat(40),
fetchedAt: 0,
marketplace
},
entry: marketplace.plugins[0]!,
hostVersion: null,
blocked: null
})
}
it('marks official what the official catalog lists, whatever the id', () => {
const official = 'https://github.com/stablyai/orca-plugins.git'
expect(listing(official, 'stablyai.spreadsheet').official).toBe(true)
expect(listing(official, 'stablyai.orca-gleam').official).toBe(true)
expect(
listing('https://github.com/acme/orca-plugins.git', 'stablyai.orca-gleam').official
).toBe(false)
})
})
@@ -67,89 +67,7 @@ function serviceWith(
} as unknown as PluginService
}
describe('buildPluginList contribution icons', () => {
it('projects editor and new-file icons as installed image URLs, and new files without paths', async () => {
const drawManifest = pluginManifestSchema.parse({
manifestVersion: 2,
execution: 'sandboxed-ui',
id: 'draw',
publisher: 'samples',
name: 'Draw',
version: '1.0.0',
engines: { orca: '>=1.4.245' },
contributes: {
customEditors: [
{ id: 'draw', title: 'Draw', extensions: ['.draw'], entry: 'e.html', icon: 'tab.png' }
],
newFiles: [
{ id: 'drawing', title: 'New drawing', extension: '.draw', template: 'empty.draw' }
]
}
})
const hash = 'c'.repeat(64)
const [entry] = await buildPluginList(
serviceWith({
pluginKey: 'samples.draw',
rootDir: join(tmpdir(), 'plugins', 'draw'),
manifest: drawManifest,
consentFingerprint: 'sha256-current',
consentContentHash: hash,
contentHash: hash,
isDev: false
}),
emptyPluginLockfile()
)
expect(entry?.customEditors?.[0]?.icon).toBe(
`orca-plugin-image://installed/samples.draw/${hash}/editor-0`
)
// Why no template path: clients ask main for the text, never for a file.
expect(entry?.newFiles).toEqual([{ id: 'drawing', title: 'New drawing', extension: '.draw' }])
})
})
describe('buildPluginList consent identity', () => {
it('projects the exact current fingerprint for an optimistic consent write', async () => {
const plugin: ValidDiscoveredPlugin = {
pluginKey: 'samples.demo',
rootDir: join(tmpdir(), 'plugins', 'demo'),
manifest,
consentFingerprint: 'sha256-current',
contentHash: null,
isDev: true
}
expect((await buildPluginList(serviceWith(plugin), emptyPluginLockfile()))[0]).toMatchObject({
pluginKey: plugin.pluginKey,
consentFingerprint: 'sha256-current',
status: 'pending',
// Why declarative: a capability makes it more than content, with no worker in sight.
execution: 'declarative'
})
})
it('projects supervised backoff as restarting instead of running', async () => {
const plugin: ValidDiscoveredPlugin = {
pluginKey: 'samples.demo',
rootDir: join(tmpdir(), 'plugins', 'demo'),
manifest,
consentFingerprint: 'sha256-current',
contentHash: null,
isDev: true
}
expect(
(
await buildPluginList(
serviceWith(plugin, {
activation: 'approved',
worker: { state: 'restarting', restarts: 2 }
}),
emptyPluginLockfile()
)
)[0]
).toMatchObject({ status: 'restarting', restarts: 2 })
})
it('does not attribute a shadowing dev plugin to the installed source', async () => {
const plugin: ValidDiscoveredPlugin = {
pluginKey: 'samples.demo',
@@ -193,104 +111,6 @@ describe('buildPluginList consent identity', () => {
expect(projected.name).toBe('invalid-development-plugin-1')
expect(JSON.stringify(projected)).not.toContain(invalid.rootDir)
})
it('projects exact VM lifecycle commands for declarative consent', async () => {
const recipeManifest = pluginManifestSchema.parse({
...manifest,
contributes: { vmRecipes: [{ path: 'recipes/cloud.json' }] }
})
const plugin: ValidDiscoveredPlugin = {
pluginKey: 'samples.demo',
rootDir: join(tmpdir(), 'plugins', 'demo'),
manifest: recipeManifest,
consentFingerprint: 'sha256-current',
consentContentHash: 'a'.repeat(64),
contentHash: null,
isDev: true
}
expect(
(
await buildPluginList(
serviceWith(plugin, {
vmRecipes: [
{
pluginKey: plugin.pluginKey,
recipe: {
id: 'cloud',
name: 'Cloud',
create: './create.sh',
destroyDisabled: true
}
}
]
}),
emptyPluginLockfile()
)
)[0]?.vmRecipes
).toEqual([
{
id: 'cloud',
name: 'Cloud',
commands: [
{ phase: 'create', command: './create.sh' },
{ phase: 'destroy', command: 'none' }
]
}
])
})
it('projects command handlers and normalized keybindings for consent and dispatch', async () => {
const commandManifest = pluginManifestSchema.parse({
...manifest,
contributes: {
commands: [
{ id: 'tasks', title: 'Open Tasks', context: 'workspace', action: 'view.tasks' }
],
keybindings: [{ command: 'tasks', key: 'mod+alt+t' }]
}
})
const plugin: ValidDiscoveredPlugin = {
pluginKey: 'samples.demo',
rootDir: join(tmpdir(), 'plugins', 'demo'),
manifest: commandManifest,
consentFingerprint: 'sha256-current',
consentContentHash: 'a'.repeat(64),
contentHash: null,
isDev: true
}
const [entry] = await buildPluginList(serviceWith(plugin), emptyPluginLockfile())
// Why: a worker-less commands plugin still runs instructions, so the page must not say content only.
expect(entry).toMatchObject({ hasWorker: false, execution: 'declarative' })
expect(
(
await buildPluginList(
serviceWith(plugin, {
commands: [
{
pluginKey: plugin.pluginKey,
id: 'tasks',
title: 'Open Tasks',
context: 'workspace',
handler: { type: 'built-in', action: 'view.tasks' },
keybindings: [{ key: 'Mod+Alt+T', when: 'workspace' }]
}
]
}),
emptyPluginLockfile()
)
)[0]?.commands
).toEqual([
{
id: 'tasks',
title: 'Open Tasks',
context: 'workspace',
handler: { type: 'built-in', action: 'view.tasks' },
keybindings: [{ key: 'Mod+Alt+T', when: 'workspace' }]
}
])
})
})
describe('buildPluginList I/O', () => {
@@ -320,41 +140,4 @@ describe('buildPluginList I/O', () => {
expect(entry?.source?.kind).toBe('git')
expect(fsCalls.count).toBe(0)
})
it('reports the catalog ref a marketplace install came from', async () => {
const plugin: ValidDiscoveredPlugin = {
pluginKey: 'samples.demo',
rootDir: join(tmpdir(), 'plugins', 'samples.demo', 'a'.repeat(64)),
manifest,
consentFingerprint: 'sha256-current',
contentHash: 'a'.repeat(64),
isDev: false
}
const lock = emptyPluginLockfile()
lock.plugins[plugin.pluginKey] = {
pluginKey: plugin.pluginKey,
version: '1.0.0',
source: {
kind: 'marketplace',
marketplace: {
url: 'https://github.com/acme/catalog.git',
ref: 'stable',
resolvedCommit: 'f'.repeat(40)
},
plugin: { url: 'https://github.com/samples/demo.git', ref: 'main' }
},
resolvedCommit: 'c'.repeat(40),
contentHash: 'a'.repeat(64),
consentFingerprint: 'sha256-current',
installedAt: 1
}
const [entry] = await buildPluginList(serviceWith(plugin), lock)
expect(entry?.source?.marketplace).toEqual({
reference: 'https://github.com/acme/catalog.git',
ref: 'stable',
resolvedCommit: 'f'.repeat(40)
})
})
})
@@ -1,60 +0,0 @@
import { mkdtempSync, rmSync, writeFileSync } from 'node:fs'
import { tmpdir } from 'node:os'
import { join } from 'node:path'
import { afterEach, describe, expect, it } from 'vitest'
import { createRuntime } from '../orca-runtime-test-fixtures.spec'
import { resetBundledMobileWebBundleCacheForTests } from '../bundled-mobile-web-bundle'
import {
installMobileWebBundleAppPath,
writeSyntheticMobileWebBundle
} from '../rpc/methods/mobile-web-bundle.test-fixture'
import { MOBILE_WEB_BUNDLE_CAPABILITY } from '../../../shared/mobile-web-bundle/mobile-web-bundle-capability'
// The aggregate shares this process cache; each fixture must restore it.
function statusCapabilitiesForInstall(appPath: string): readonly string[] {
resetBundledMobileWebBundleCacheForTests()
installMobileWebBundleAppPath(appPath)
const { capabilities } = createRuntime().getStatus()
if (!capabilities) {
// A missing capability list would make absence assertions pass vacuously.
throw new Error('status.get answered no capability list')
}
return capabilities
}
function withInstallRoot(prefix: string, run: (install: string) => void): void {
const install = mkdtempSync(join(tmpdir(), prefix))
try {
run(install)
} finally {
rmSync(install, { recursive: true, force: true })
}
}
describe('OrcaRuntimeService mobile web bundle capability', () => {
afterEach(() => {
resetBundledMobileWebBundleCacheForTests()
})
it('omits the mobile web bundle capability where the install carries no bundle', () => {
withInstallRoot('orca-mobile-web-absent-', (install) => {
expect(statusCapabilitiesForInstall(install)).not.toContain(MOBILE_WEB_BUNDLE_CAPABILITY)
})
})
it('advertises the mobile web bundle capability where the install carries one', () => {
withInstallRoot('orca-mobile-web-present-', (install) => {
writeSyntheticMobileWebBundle(join(install, 'out', 'mobile-web'), 4)
expect(statusCapabilitiesForInstall(install)).toContain(MOBILE_WEB_BUNDLE_CAPABILITY)
})
})
it('omits the capability where the bundle manifest does not parse', () => {
withInstallRoot('orca-mobile-web-unparseable-', (install) => {
const root = join(install, 'out', 'mobile-web')
writeSyntheticMobileWebBundle(root, 5)
writeFileSync(join(root, 'manifest.json'), '{"schemaVersion":2}', 'utf8')
expect(statusCapabilitiesForInstall(install)).not.toContain(MOBILE_WEB_BUNDLE_CAPABILITY)
})
})
})
-1
View File
@@ -12,7 +12,6 @@ await import('./orca-runtime-tests/paired-settings.spec')
await import('./orca-runtime-tests/runtime-availability.spec')
await import('./orca-runtime-tests/browser-capabilities.spec')
await import('./orca-runtime-tests/browser-capabilities-part-02.spec')
await import('./orca-runtime-tests/mobile-web-bundle-capability.spec')
await import('./orca-runtime-tests/managed-server-capability.spec')
await import('./orca-runtime-tests/window-authority.spec')
await import('./orca-runtime-tests/terminal-handles.spec')
@@ -1,59 +0,0 @@
import { describe, expect, it, vi } from 'vitest'
import { ORCHESTRATION_CONTRACT_RUNTIME_CAPABILITY } from '../../../../../../shared/protocol-version'
import type { OrcaRuntimeService } from '../../../../orca-runtime'
import type { OrchestrationDb } from '../../../../orchestration/db'
import { ORCHESTRATION_WORKER_STOP_METHODS } from './worker-stop'
describe('federated worker stop capability', () => {
it('does not trust a legacy server stop receipt', async () => {
const markWorkerStopUnknown = vi.fn((_dispatchId: string, reason: string) => ({
state: 'stop_unknown',
last_error: reason
}))
const db = {
getFederatedDispatch: vi.fn(() => ({
dispatch_id: 'ctx_remote',
environment_id: 'environment_linux',
environment_name: 'linux',
peer_fingerprint: 'peer-linux'
})),
beginWorkerStop: vi.fn(() => ({ disposition: 'started' })),
markWorkerStopUnknown
} as unknown as OrchestrationDb
const callOrchestrationWorkerServer = vi.fn(async (_environmentId, method) => {
if (method === 'status.get') {
return { capabilities: [ORCHESTRATION_CONTRACT_RUNTIME_CAPABILITY] }
}
return { state: 'stopped', processAction: 'closed_agent_terminal' }
})
const runtime = {
getOrchestrationDb: () => db,
getRuntimeId: () => 'runtime_current',
resolveOrchestrationWorkerServer: () => ({
environmentId: 'environment_linux',
name: 'linux',
peerFingerprint: 'peer-linux'
}),
callOrchestrationWorkerServer
} as unknown as OrcaRuntimeService
const method = ORCHESTRATION_WORKER_STOP_METHODS[0]!
await expect(
method.handler(method.params!.parse({ dispatch: 'ctx_remote' }), {
runtime,
orchestrationMutation: {
callerFingerprint: 'coordinator',
requestId: 'request_stop',
method: 'orchestration.workerStop',
payloadHash: 'hash'
}
})
).resolves.toMatchObject({ state: 'stop_unknown', processAction: 'none' })
expect(db.beginWorkerStop).toHaveBeenCalledWith('ctx_remote', 'runtime_current')
expect(markWorkerStopUnknown).toHaveBeenCalledWith(
'ctx_remote',
'Connected server linux cannot prove the worker stop outcome.'
)
expect(callOrchestrationWorkerServer).toHaveBeenCalledTimes(1)
})
})
@@ -1,129 +0,0 @@
import { readFileSync } from 'node:fs'
import { join } from 'node:path'
import { describe, expect, it } from 'vitest'
import { ALL_RPC_METHODS } from './methods'
import { buildRegistry } from './core'
import { ACCOUNT_METHODS } from './methods/accounts'
import { resolveOrcadFeatureRequirement, type OrcadFeature } from './orcad-feature-readiness'
// Every method's declared needs for these params; param-level ones read them.
const REGISTRY = buildRegistry(ALL_RPC_METHODS)
const requiresOf = (name: string, params: unknown = {}): readonly OrcadFeature[] => {
const method = REGISTRY.get(name)
expect(method, name).toBeDefined()
return resolveOrcadFeatureRequirement(method?.requires, params)
}
// Launches that start an agent (and so read its account home); a terminal create is one only with an agent.
const AGENT_LAUNCHES = [
'terminal.createAgentSession',
'agentSession.create',
'git.generateCommitMessage',
'orchestration.workerStart',
'orchestration.federationAttachStart'
]
const PARAM_GATED_LAUNCHES = [
'terminal.ensureAgentSession',
'terminal.create',
'session.tabs.createTerminal',
'agent.launch',
'agent.launchReplay'
]
describe('which RPC methods wait for an orcad startup phase', () => {
it('gates the account services, search index, orchestration and orphan adoption', () => {
for (const method of ALL_RPC_METHODS) {
const expected: OrcadFeature[] = []
// Claude/Codex account services only; usage credentials and Antigravity live elsewhere.
if (
ACCOUNT_METHODS.some((account) => account.name === method.name) &&
method.name !== 'accounts.setHostLaunchEnv' &&
method.name !== 'accounts.unsubscribe'
) {
expected.push('accounts')
}
if (AGENT_LAUNCHES.includes(method.name)) {
expected.push('accounts')
}
if (method.name.startsWith('orchestration.')) {
expected.push('orchestration')
}
if (/^aiVault\.(searchSessions|searchStatus|setSearchEnabled)$/.test(method.name)) {
expected.push('sessionSearch')
}
if (method.name === 'terminal.adoptOrphans') {
expected.push('unshownPlacement')
}
if (PARAM_GATED_LAUNCHES.includes(method.name)) {
expect(typeof method.requires, method.name).toBe('function')
continue
}
expect({ name: method.name, requires: requiresOf(method.name) }).toEqual({
name: method.name,
requires: expected
})
}
})
it('gates a terminal create only when it starts an agent; plain shells stay ungated', () => {
for (const name of ['terminal.create', 'session.tabs.createTerminal']) {
expect(requiresOf(name, {}), name).toEqual([])
expect(requiresOf(name, { command: 'ls -la' }), name).toEqual([])
expect(requiresOf(name, { command: 'claude --resume' }), name).toEqual(['accounts'])
expect(requiresOf(name, { command: 'codex' }), name).toEqual(['accounts'])
expect(requiresOf(name, { launchAgent: 'claude' }), name).toEqual(['accounts'])
expect(requiresOf(name, { launchConfig: { agentArgs: '', agentEnv: {} } }), name).toEqual([
'accounts'
])
expect(requiresOf(name, { resumeProviderSession: { id: 's' } }), name).toEqual(['accounts'])
}
expect(requiresOf('session.tabs.createTerminal', { agent: 'claude' })).toEqual(['accounts'])
})
it('gates only an explicit ensureAgentSession; an attach is restore latency', () => {
expect(requiresOf('terminal.ensureAgentSession', { kind: 'explicit' })).toEqual(['accounts'])
expect(requiresOf('terminal.ensureAgentSession', { kind: 'automatic' })).toEqual([])
})
it('gates agent.launch unless it reuses a live terminal', () => {
for (const name of ['agent.launch', 'agent.launchReplay']) {
expect(requiresOf(name, {}), name).toEqual(['accounts'])
expect(requiresOf(name, { reuseTerminal: { handle: 'h' } }), name).toEqual([])
}
})
it('never gates what every client calls at connect', () => {
for (const name of [
'status.get',
'repo.list',
'session.tabs.subscribe',
'terminal.list',
'worktree.teardownMissingTerminals',
'accounts.setHostLaunchEnv'
]) {
expect(ALL_RPC_METHODS.some((method) => method.name === name)).toBe(true)
expect(requiresOf(name)).toEqual([])
}
})
// No behavior change yet: orcad opens every latch before RPC starts accepting calls.
it('opens every latch before orcad starts RPC', () => {
const read = (file: string): string =>
readFileSync(join(__dirname, '../../orcad', file), 'utf8')
const entry = read('orcad-entry.ts')
const restore = read('orcad-restored-terminal-authority.ts')
const rpcStart = entry.indexOf("await timed('rpc', () => rpc.start())")
const restored = entry.indexOf('await restoreOrcadTerminalAuthority(')
expect(rpcStart).toBeGreaterThan(0)
expect(restored).toBeGreaterThan(0)
expect(restored).toBeLessThan(rpcStart)
for (const feature of ['accounts', 'sessionSearch']) {
const opened = entry.indexOf(`featureReadiness.open('${feature}')`)
expect(opened, feature).toBeGreaterThan(0)
expect(opened, feature).toBeLessThan(rpcStart)
}
for (const feature of ['orchestration', 'unshownPlacement']) {
expect(restore).toContain(`readiness.open('${feature}')`)
}
})
})
@@ -1,6 +1,5 @@
import { vi } from 'vitest'
import './runtime-client-settings-linear-team-projection.spec'
import './runtime-client-settings-source-control-projection.spec'
vi.mock('../claude/agent-view-service', () => ({
getClaudeAgentViewService: () => ({ reconcile: async () => {} })
@@ -1,91 +0,0 @@
import { describe, expect, it } from 'vitest'
import { RuntimeClientSettingsController } from './runtime-client-settings'
import { createGlobalSettingsFixture } from '../../shared/global-settings-test-fixture'
import type { GlobalSettings } from '../../shared/global-settings-types'
import { SourceControlAiSettings } from '../../shared/rpc-contract/git-params'
import { liftActionPermissionArgs } from '../../shared/source-control-action-permission-lift'
import { getDefaultSourceControlAiSettings } from '../../shared/source-control-ai'
// settings.get is an allowlist: omitted per-action agent recipes look unsaved to paired AI buttons.
function projectionOf(settings: Partial<GlobalSettings>) {
// oxlint-disable-next-line typescript/consistent-type-assertions -- SAFETY: get() reads nothing but store.getSettings(); every other RuntimeStore member is unreachable from that path.
return new RuntimeClientSettingsController({ getSettings: () => settings } as never).get()
}
function hostSettings(sourceControlAi: GlobalSettings['sourceControlAi']): Partial<GlobalSettings> {
return { ...createGlobalSettingsFixture({ workspaceDir: '/w' }), sourceControlAi }
}
describe('RuntimeClientSettingsController source control launch recipes', () => {
it('publishes the recipe saved for a launch action', () => {
const recipe = liftActionPermissionArgs({
agentId: 'codex' as const,
agentArgs: '-c model=o3 --fast',
launchPreferences: {
agentId: 'claude',
permissionMode: 'ask',
modelSelection: {
base: 'inherit',
options: { effort: { agentId: 'codex', value: null } }
}
}
})
const source = { ...getDefaultSourceControlAiSettings(), actions: { fixChecks: recipe } }
expect(SourceControlAiSettings.parse(source).actions?.fixChecks).toEqual(recipe)
const projected = projectionOf(hostSettings(source))
expect(projected.sourceControlAi.actions.fixChecks?.launchPreferences).toEqual(
recipe.launchPreferences
)
expect(projected.sourceControlAi.actions.fixChecks).toMatchObject({
agentId: 'codex',
agentArgs: '--fast',
argumentChoices: { syntaxAgent: 'codex', nodes: [{ at: 0, text: '-c model=o3' }] }
})
})
it('publishes a recipe saved under the legacy launch defaults key', () => {
const projected = projectionOf(
hostSettings({
...getDefaultSourceControlAiSettings(),
actions: undefined,
launchActionDefaults: { resolveConflicts: { agentId: 'claude' } }
})
)
expect(projected.sourceControlAi.actions.resolveConflicts).toMatchObject({ agentId: 'claude' })
})
it('publishes launch actions only, not the text generation recipes', () => {
const projected = projectionOf(hostSettings(getDefaultSourceControlAiSettings()))
expect(Object.keys(projected.sourceControlAi.actions).sort()).toEqual([
'fixChecks',
'fixCommitFailure',
'fixPushFailure',
'resolveComments',
'resolveConflicts'
])
})
})
describe('RuntimeClientSettingsController source control list order', () => {
it('publishes the group order so paired clients list changes the same way', () => {
expect(projectionOf({ sourceControlGroupOrder: 'staged-first' }).sourceControlGroupOrder).toBe(
'staged-first'
)
expect(projectionOf({}).sourceControlGroupOrder).toBe('changes-first')
})
it('publishes the compare base and whitespace choices desktop diffs use', () => {
const projected = projectionOf({
sourceControlCompareAgainstUpstream: true,
diffShowWhitespace: true
})
expect(projected).toMatchObject({
sourceControlCompareAgainstUpstream: true,
diffShowWhitespace: true
})
expect(projectionOf({})).toMatchObject({
sourceControlCompareAgainstUpstream: false,
diffShowWhitespace: false
})
})
})