# Key Data Structures in OpenWork: Type-Safe Contracts for Desktop, Server, and Runtime

> Explore OpenWorks key data structures like WorkspaceWire and OpenworkContextSnapshot for type-safe contracts across desktop, server, and runtime environments. Improve your development.

- Repository: [Different AI/openwork](https://github.com/different-ai/openwork)
- Tags: internals
- Published: 2026-08-02

---

**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`](https://github.com/different-ai/openwork/blob/main/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 of `WorkspaceWire` objects with selection metadata, serving as the response shape for commands like `workspaceBootstrap` and `workspaceSetSelected`.
- **`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`](https://github.com/different-ai/openwork/blob/main/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`](https://github.com/different-ai/openwork/blob/main/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`](https://github.com/different-ai/openwork/blob/main/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:

```typescript
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`](https://github.com/different-ai/openwork/blob/main/packages/types/src/desktop-ipc.ts).

### Creating Remote Workspaces

The `workspaceCreateRemote` command demonstrates how input types flow to output structures:

```typescript
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:

```typescript
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:

```typescript
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

- **`WorkspaceWire`** defines the canonical workspace record exchanged between server and desktop in [`packages/types/src/workspace.ts`](https://github.com/different-ai/openwork/blob/main/packages/types/src/workspace.ts).
- **`DesktopCommandMap`** provides type-safe IPC command definitions in [`packages/types/src/desktop-ipc.ts`](https://github.com/different-ai/openwork/blob/main/packages/types/src/desktop-ipc.ts), supported by `DesktopCommandHandlers` and `DesktopCommandInvokers`.
- **`OpenworkContextSnapshot`** captures full UI state for persistence and MCP context sharing in [`packages/types/src/openwork-context.ts`](https://github.com/different-ai/openwork/blob/main/packages/types/src/openwork-context.ts).
- **`OpenworkAffordanceDescriptor`** and related request/result types enable typed skill execution in [`packages/types/src/openwork-affordance.ts`](https://github.com/different-ai/openwork/blob/main/packages/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`](https://github.com/different-ai/openwork/blob/main/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`](https://github.com/different-ai/openwork/blob/main/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.