Key Data Structures in OpenWork: Type-Safe Contracts for Desktop, Server, and Runtime
OpenWork's architecture relies on TypeScript wire contracts—including WorkspaceWire, DesktopCommandMap, and OpenworkContextSnapshot—to enforce type safety across Electron IPC, server APIs, and UI state management.
The OpenWork project (different-ai/openwork) implements a contract-first data model that governs how information flows between the desktop application, server endpoints, and the OpenWork runtime. These TypeScript definitions serve as the single source of truth for data exchange, persistence, and rendering, eliminating type leaks across process boundaries.
WorkspaceWire: The Canonical Workspace Record
The WorkspaceWire type defines the shape of workspace records as emitted by the server or bridged through Electron IPC. This structure accommodates both local and remote workspaces, encapsulating authentication tokens, sandbox information, and optional Opencode credentials.
Key fields include identifiers for local versus remote workspaces, authentication context, and sandbox configuration. In packages/types/src/workspace.ts, WorkspaceWire acts as the foundational type that the server exposes via the /workspaces API and that the desktop augments with fields like openworkClientToken before passing to the renderer.
DesktopCommandMap and IPC Type Contracts
The DesktopCommandMap type (along with DesktopCommandName, DesktopCommandArgs, and DesktopCommandResult) enumerates every command available over the openwork:desktop IPC channel. This mapping defines the argument tuples and expected result types for each operation, enabling type-safe remote procedure calls from the renderer to the main process.
Supporting structures include:
WorkspaceList: Wraps an array ofWorkspaceWireobjects with selection metadata, serving as the response shape for commands likeworkspaceBootstrapandworkspaceSetSelected.DesktopCommandHandlers: A typed map binding command names to their main process implementations.DesktopCommandInvokers: Provides async functions in the renderer that guarantee compile-time parity with server-side handlers.
These types reside in packages/types/src/desktop-ipc.ts and ensure that IPC communication remains strongly typed without any leaks.
OpenworkContextSnapshot: Capturing UI State
The OpenworkContextSnapshot type records the complete UI state for session persistence and remote MCP context sharing. Defined in packages/types/src/openwork-context.ts, this structure includes the active screen, conversation layout, side-panel status, available resources, and the list of current affordances.
This snapshot supports versioned schema evolution through OPENWORK_CONTEXT_SCHEMA_VERSION, allowing the platform to migrate persisted state safely across updates.
OpenworkAffordanceDescriptor and Execution Types
Affordances represent skills or commands that users can invoke within the OpenWork environment. The OpenworkAffordanceDescriptor type describes these capabilities with rich metadata:
- Affordance ID and kind (query, command, or guidance)
- Provider reference and argument schema
- UI effects and confirmation policies
- Availability conditions and executor definitions
When executing affordances, the system uses OpenworkAffordanceRequest and OpenworkAffordanceResult to handle the request/response cycle. The request carries arguments and optional revision data, while the result encodes success or failure states, side effects, and revision metadata. All affordance-related types live in packages/types/src/openwork-affordance.ts.
Practical Examples: Working with OpenWork Types
Fetching Workspaces via the Desktop Bridge
Use the generated invoker to retrieve workspace state through the type-safe IPC bridge:
import { desktopBridge } from "apps/app/src/app/lib/desktop";
async function listWorkspaces() {
// Calls the IPC command workspaceBootstrap defined in DesktopCommandMap
const workspaceList = await desktopBridge.workspaceBootstrap();
console.log("Available workspaces:", workspaceList.workspaces);
}
listWorkspaces();
This code relies on DesktopCommandMap and returns a WorkspaceList as defined in packages/types/src/desktop-ipc.ts.
Creating Remote Workspaces
The workspaceCreateRemote command demonstrates how input types flow to output structures:
import { desktopBridge } from "apps/app/src/app/lib/desktop";
async function createRemoteWorkspace() {
const input = {
baseUrl: "https://api.openworklabs.com",
remoteType: "openwork",
displayName: "My Cloud Workspace",
};
const updatedList = await desktopBridge.workspaceCreateRemote({ input });
console.log("Created remote workspace:", updatedList.workspaces.find(w => w.displayName === "My Cloud Workspace"));
}
This example utilizes WorkspaceCreateRemoteInput and receives an updated WorkspaceList containing the new WorkspaceWire record.
Invoking Affordances
Accessing and executing affordances requires referencing the context snapshot and affordance descriptors:
import { desktopBridge } from "apps/app/src/app/lib/desktop";
async function runSearchAffordance() {
// Access the context snapshot containing available affordances
const ctx = await desktopBridge.getUiControlBridgeInfo();
const searchAffordance = ctx?.availableAffordances?.find(a => a.id === "search");
if (!searchAffordance) return;
const request = {
id: searchAffordance.id,
args: { query: "OpenWork architecture" },
};
// Execution would dispatch OpenworkAffordanceRequest and await OpenworkAffordanceResult
const result = await desktopBridge.importSkill(/* request details */);
console.log("Affordance result:", result);
}
Persisting UI Snapshots
Capture and store application state for session restoration:
import { desktopBridge } from "apps/app/src/app/lib/desktop";
import { writeFile } from "fs/promises";
async function captureSnapshot() {
// Returns OpenworkContextSnapshot
const snapshot = await desktopBridge.getUiControlBridgeInfo();
await writeFile("snapshot.json", JSON.stringify(snapshot, null, 2));
}
Summary
WorkspaceWiredefines the canonical workspace record exchanged between server and desktop inpackages/types/src/workspace.ts.DesktopCommandMapprovides type-safe IPC command definitions inpackages/types/src/desktop-ipc.ts, supported byDesktopCommandHandlersandDesktopCommandInvokers.OpenworkContextSnapshotcaptures full UI state for persistence and MCP context sharing inpackages/types/src/openwork-context.ts.OpenworkAffordanceDescriptorand related request/result types enable typed skill execution inpackages/types/src/openwork-affordance.ts.- These structures enable contract-first architecture with strong typing across server, desktop, and renderer boundaries.
Frequently Asked Questions
What is WorkspaceWire used for?
WorkspaceWire serves as the canonical TypeScript interface for workspace records flowing between the OpenWork server and desktop application. It standardizes fields for authentication tokens, sandbox configuration, and remote workspace metadata, ensuring consistency whether data originates from the /workspaces API or the Electron IPC bridge.
How does DesktopCommandMap ensure type safety across process boundaries?
DesktopCommandMap acts as a centralized registry in packages/types/src/desktop-ipc.ts that maps command names to their specific argument and return types. This allows the renderer process to call desktopBridge.workspaceBootstrap() with compile-time guarantees that the arguments and results match the main process implementation, eliminating runtime type mismatches in IPC communication.
What information does OpenworkContextSnapshot capture?
OpenworkContextSnapshot stores the complete UI state including the active screen identifier, conversation layout configuration, side-panel visibility, available resources, and the list of OpenworkAffordanceDescriptor objects currently available to the user. This snapshot enables session restoration and provides context to remote MCPs (Model Context Protocol servers) for enhanced AI assistance.
How are affordances defined and executed in OpenWork?
Affordances are defined using OpenworkAffordanceDescriptor in packages/types/src/openwork-affordance.ts, which specifies the skill ID, argument schema, UI effects, and execution policy. When invoked, the system constructs an OpenworkAffordanceRequest containing the arguments and optional revision data, then returns an OpenworkAffordanceResult encoding success status, side effects, and updated revision metadata.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →