mirror of
https://github.com/stablyai/orca.git
synced 2026-10-31 09:07:40 +00:00
* fix(native-chat): a host admits structured sessions by client capability, not its own chat setting A host's experimentalStructuredNativeChat decided whether any paired client could reach agentSession.* at all, and whether session.tabs.* showed it structured tabs. That setting is the host user's own launch preference: whether a new agent opens as a chat or a terminal is decided by whoever launches it. Using it as admission control meant a client whose own preference was "structured chat" was refused on a host whose preference was "terminal", and chats opened while the setting was on were withheld from mobile once it was turned off. The gate now asks one thing: did the client advertise agent-session.structured.v1 (in-process callers negotiate nothing and are always admitted). Tab projection and restore follow the same rule. With the setting no longer gating anything, the separate cleanup gate (close, cancel, unsubscribe, release), which existed only so those kept working after the setting was switched off, is identical to the main gate and is folded into it. The settings listener that republished tabs when the setting changed is removed, since projection no longer depends on it. The host setting still picks the default for launches that start on the host itself (agent.launch from mobile, orchestration worker-start). * fix(native-chat): negotiate client-chosen launch mode so released phones and old servers keep terminals Hosts advertise agent-session.structured.client-launch-mode.v1: they admit structured sessions by client capability alone. A remote client that does not advertise it (phones released before agent.launch) asks createSupport to pick the launch mode, so the host keeps answering that with its own setting, exactly as before. Cleanup methods keep their own named gate so a future admission condition cannot make close or cancel refusable. * chore(native-chat): justify the two type assertions this change's lines touch * fix(native-chat): chats that already exist keep showing whatever the chat setting says The structured chat setting decides only what new agents open as. With it off, this machine's structured chats used to be hidden while the host, which no longer reads the setting, still reported them to the workspace activation gate, so a workspace holding only a chat opened empty. The local chat mirror and its startup restore now run whatever the setting says, the continue-after-restart offer follows the chats that exist, and the setting's copy says it applies to new agents. * test(native-chat): pin that a host advertises the client-chosen launch mode * fix(native-chat): mirror this machine's chats only where it holds them Round 1 ran the local chat mirror for everyone so existing chats show whatever the setting says. That gave every desktop a permanent session-tabs listener, which turns on the runtime's phone replication paths, plus two full session-tab censuses at startup, and made the browser client mirror its remote host a second time. The runtime now says whether it holds structured chats: its structured host is built only when saved chats were restored at startup or a client created one here, and it announces the moment one is built. The mirror, the startup restore and the continue-after-restart offer run only when the setting launches chats or the host holds some, and never in the browser client. A chat a paired client creates here with the setting off still appears at once. The chat behaviour settings show wherever chats exist, and the setting's copy says it picks what new agents open as. The toggle-off teardown this made dead is removed. * test(native-chat): record install listeners without a cast * fix(native-chat): mirror this machine's chats only once it holds one, not once its host is built Session history, resume preparation, terminal resume commands and replay-safe phone launches all build the structured host for users who never had a chat, which turned on the chat mirror and the structured-only settings rows until the next restart. The signal is now derived from the host's records (or a records file still owed its import) and pushed when the first chat is restored or created. A throwing listener no longer fails the install that fired it. * feat(native-chat): createSupport reports the saved selection a new chat on this host starts with A chat on a paired server starts with the server's saved model and options, which the desktop could not read, so its picker showed a guess. createSupport's answer, which the desktop already waits for before a paired launch, now also carries that seed as a new optional field (older clients ignore it). Create and createSupport read it through one resolver so they cannot drift. * refactor(protocol): move the Electron remote client capability list into its own module Merging main left protocol-version.ts one line over the max-lines limit on this branch. The list of capabilities the desktop advertises to a paired host moves, unchanged, into electron-remote-runtime-client-capabilities.ts, the module the next PR in the stack already uses for it; importers point there. * test(cross-version): stub the launch seed resolver createSupport now reads * fix(native-chat): the desktop tells its own host it picks each launch mode, so retrying an existing chat works with the setting off * docs(native-chat): name the real exit for the released-phone createSupport rule * test(cross-version): a released client still gets the host-setting createSupport answer; a launch-mode client gets supported plus the seed
99 lines
5.6 KiB
TypeScript
99 lines
5.6 KiB
TypeScript
import type { AppIdentity } from '../../shared/app-identity'
|
|
import type { E2EConfig } from '../../shared/e2e-config'
|
|
import type { ExecutionHostId } from '../../shared/execution-host'
|
|
import type {
|
|
WriteTerminalRenderDesyncEvidenceArgs,
|
|
WriteTerminalRenderDesyncEvidenceResult
|
|
} from '../../shared/terminal-render-desync-evidence'
|
|
import type { MacCapturedDigitRowChord } from '../../shared/macos-symbolic-hotkeys'
|
|
import type { MarkdownDocument } from '../../shared/filesystem-entry-types'
|
|
import type { PersistedUIState } from '../../shared/persisted-ui-state-types'
|
|
import type { FloatingTerminalCwdRequest } from '../../shared/ui-chrome-types'
|
|
import type { WorkspaceSessionState } from '../../shared/workspace-session-state-types'
|
|
import type { KeyboardLayoutSnapshot } from '../../shared/keyboard-layout-snapshot'
|
|
import type { KeyboardLayoutChangeEvent } from '../../shared/keyboard-layout-events'
|
|
|
|
export type AppApi = {
|
|
/** Returns the app identity currently exposed to native chrome and the titlebar. */
|
|
getIdentity: () => Promise<AppIdentity>
|
|
/** Returns a URL base for feature-wall assets. In dev this is Vite /@fs;
|
|
* in packaged builds this is file:// resources. Renderer appends filenames. */
|
|
getFeatureWallAssetBaseUrl: () => Promise<string>
|
|
/** Relaunches the app (app.relaunch() + app.exit(0)) for settings that need a full restart to apply. */
|
|
relaunch: () => Promise<void>
|
|
/** Restarts Orca through the normal quit pipeline so daemon-backed terminal
|
|
* sessions survive and can reattach after the new process starts. */
|
|
restart: () => Promise<void>
|
|
/** Reloads the current app renderer through main so expected renderer
|
|
* teardown can be classified before Electron emits process-gone events. */
|
|
reload: () => Promise<void>
|
|
/** Stages the renderer's final state synchronously before unload. */
|
|
stageBeforeUnloadSync: (args: {
|
|
sessions: { state: WorkspaceSessionState; hostId?: ExecutionHostId }[]
|
|
ui: Partial<PersistedUIState>
|
|
}) => void
|
|
/** Resolves once the last staged checkpoint is durably written; rejects if that
|
|
* write failed, so a reload/restart can abort instead of losing the snapshot. */
|
|
awaitBeforeUnloadCheckpoint: () => Promise<void>
|
|
/** Resolves when the daemon PTY provider and hook receiver have either
|
|
* started or failed open for the first BrowserWindow. */
|
|
awaitFirstWindowStartupServices: () => Promise<void>
|
|
/** Resolves when host Git can run: shell-PATH generation is published and the
|
|
* managed WSL CLI registration has reconciled. Does not wait on PTY services. */
|
|
awaitGitEnvironmentStartupBarrier: () => Promise<void>
|
|
/** Inventories retained PTYs and restores durable structured ownership before renderer adoption. */
|
|
prepareTerminalStartupRestoration: () => Promise<void>
|
|
/** Whether this machine's runtime holds a structured chat, saved or live. */
|
|
holdsStructuredAgentSessions: () => Promise<boolean>
|
|
/** Fires when that answer changes, e.g. when a paired client creates the first chat here. */
|
|
onStructuredAgentSessionsHeldChanged: (callback: (held: boolean) => void) => () => void
|
|
/** Reconciles legacy worker authority around persisted terminal reconnect. */
|
|
recoverLegacyWorkerTerminalsForRendererStartup: () => Promise<void>
|
|
/** Emits a startup benchmark marker when ORCA_STARTUP_DIAGNOSTICS is enabled. */
|
|
startupDiagnostic: (event: string, details?: Record<string, unknown>) => Promise<void>
|
|
/** macOS active input mode, or layout ID when no IME is selected (e.g. `com.apple.keylayout.PolishPro`).
|
|
* Distinguishes CJK IMEs and Option-layer-composing layouts that look like US QWERTY (issue #1205).
|
|
* Returns null on non-Darwin or when the defaults read fails. */
|
|
getKeyboardInputSourceId: () => Promise<string | null>
|
|
/** Physical Mission Control chords before layout resolution. */
|
|
getMacCapturedDigitRowChords: () => Promise<MacCapturedDigitRowChord[]>
|
|
/** Active macOS layout characters without Option, or null off macOS or when the native probe fails. */
|
|
getKeyboardLayoutSnapshot: () => Promise<KeyboardLayoutSnapshot | null>
|
|
/** Subscribes to active macOS input-source changes. No-op in the browser fallback. */
|
|
onKeyboardLayoutChanged: (callback: (event: KeyboardLayoutChangeEvent) => void) => () => void
|
|
/** Updates the macOS Dock unread badge. No-op on Windows/Linux. */
|
|
setUnreadDockBadgeCount: (count: number) => Promise<void>
|
|
/** Resolves the launch directory for global Floating Terminal tabs. */
|
|
getFloatingTerminalCwd: (args?: FloatingTerminalCwdRequest) => Promise<string>
|
|
/** Resolves Orca's app-owned directory for auto-created Floating Workspace
|
|
* markdown notes. */
|
|
getFloatingMarkdownDirectory: () => Promise<string>
|
|
/** Opens a native picker for markdown documents, rooted in the floating
|
|
* workspace, and authorizes the selected file for editor reads/writes. */
|
|
pickFloatingMarkdownDocument: () => Promise<MarkdownDocument | null>
|
|
/** Opens a native directory picker and authorizes the selected directory
|
|
* for Floating Workspace markdown file creation. */
|
|
pickFloatingWorkspaceDirectory: () => Promise<string | null>
|
|
/** Persists flag-gated terminal render evidence under app-owned userData. */
|
|
writeTerminalRenderDesyncEvidence: (
|
|
args: WriteTerminalRenderDesyncEvidenceArgs
|
|
) => Promise<WriteTerminalRenderDesyncEvidenceResult>
|
|
}
|
|
|
|
/** Panel contribution as surfaced by the main-process plugin service. */
|
|
|
|
export type PlatformApi = {
|
|
get: () => {
|
|
platform: NodeJS.Platform
|
|
osRelease: string
|
|
arch: string
|
|
/** Login shell or ComSpec when available. */
|
|
shell: string
|
|
displayServer: 'wayland' | 'x11' | null
|
|
}
|
|
}
|
|
|
|
export type E2EApi = {
|
|
getConfig: () => E2EConfig
|
|
}
|