# How to Contribute to the OpenWork Project: A Complete Guide to the Monorepo Architecture

> Learn how to contribute to the OpenWork project. Follow this guide to set up the monorepo architecture, install dependencies, and submit pull requests for the open source AI initiative.

- Repository: [Different AI/openwork](https://github.com/different-ai/openwork)
- Tags: how-to-guide
- Published: 2026-08-13

---

**Fork the repository, install dependencies with `pnpm install`, run `pnpm dev` to start the development environment, and submit pull requests against the `dev` branch with accompanying slow specs.**

OpenWork is a modular, open-source platform developed by **different-ai** that combines a desktop Electron client, a Node-based backend server, and a cloud-hosted control plane called **OpenWork Den**. To effectively contribute to the OpenWork project, you must understand its monorepo structure organized around **pnpm workspaces** and its three-tier **client-server-control-plane** architecture. This guide walks you through the codebase organization, development workflow, and testing requirements needed to submit high-quality contributions.

## Understanding the OpenWork Architecture

The codebase follows a strict separation of concerns across four primary areas. Each layer has distinct entry points and responsibilities that determine where your changes should live.

### Desktop UI Layer

The **Electron client** renders React components from `packages/ui` and provides the main user experience. Key entry points include:

- [`packages/ui/src/react/platform-detect.ts`](https://github.com/different-ai/openwork/blob/main/packages/ui/src/react/platform-detect.ts) – Detects OS and CPU architecture for platform-specific behavior
- [`apps/ui-demo/vite.config.ts`](https://github.com/different-ai/openwork/blob/main/apps/ui-demo/vite.config.ts) – Configures the UI development server

The desktop application loads the UI via HTTP and communicates with the local server for workspace operations.

### Server API Layer

The **Node/TypeScript backend** persists workspaces, manages plugins, and exposes the **MCP (Multi-Capability Protocol)** for AI agents. Critical files include:

- [`apps/server/src/server.ts`](https://github.com/different-ai/openwork/blob/main/apps/server/src/server.ts) – Boots the HTTP server and wires routes
- [`apps/server/src/workspaces.ts`](https://github.com/different-ai/openwork/blob/main/apps/server/src/workspaces.ts) – Implements workspace CRUD operations

This layer handles local data persistence and skill execution before forwarding remote calls to the Den.

### OpenWork Den Control Plane

**OpenWork Den** is the cloud-side orchestration service handling model provisioning, team management, and policy enforcement. The server communicates with Den via:

- [`apps/server/src/cloud-plugins.ts`](https://github.com/different-ai/openwork/blob/main/apps/server/src/cloud-plugins.ts) – Bridges server-side plugins to the Den control plane

Den exposes a single MCP endpoint at `https://api.openworklabs.com/mcp/agent` that any AI agent can consume.

### Testing Infrastructure

End-to-end validation relies on **@openwork/testkit** and **slow specs** that guarantee full-stack functionality:

- `evals/specs/*.slow.test.ts` – Full-stack scenario tests covering first-run experiences, model access, and MCP interactions
- [`scripts/dev-headless-web.ts`](https://github.com/different-ai/openwork/blob/main/scripts/dev-headless-web.ts) – Launches headless Electron for CI environments

## Setting Up Your Development Environment

Follow these steps to configure your local machine for OpenWork development.

1. **Fork and clone** the repository from `different-ai/openwork` to your GitHub account, then clone your fork locally.

2. **Install dependencies** at the repository root:

   ```bash
   pnpm install
   ```

   pnpm automatically links workspace packages across the UI and server.

3. **Start the development server**:

   ```bash
   pnpm dev
   ```

   This command starts the Vite UI on `http://localhost:5173` and Electron with the Chrome DevTools Protocol (CDP) on `http://127.0.0.1:9223`. Look for the console banner: `[openwork] dev profile=… cdp=http://127.0.0.1:9223`.

   For isolated feature branch development, use:

   ```bash
   pnpm dev:worktree
   ```

   This creates a separate dev profile to avoid conflicts with your main worktree.

4. **Verify the environment** by checking that the Electron client loads and can connect to the local server instance.

## Implementing New Features

Code changes must align with the architectural boundaries of the monorepo.

### Modifying the Desktop UI

Edit React components under `packages/ui/src/…`. Use [`platform-detect.ts`](https://github.com/different-ai/openwork/blob/main/platform-detect.ts) as a reference for implementing cross-platform TypeScript logic that handles OS-specific behavior.

### Extending Server Capabilities

Add routes or database models under `apps/server/src/…`. The [`workspaces.ts`](https://github.com/different-ai/openwork/blob/main/workspaces.ts) file demonstrates how to implement CRUD operations with proper TypeScript typing.

### Adding MCP Skills

New capabilities must be registered as skills in the MCP framework. Define your skill in [`apps/server/src/skills.ts`](https://github.com/different-ai/openwork/blob/main/apps/server/src/skills.ts):

```typescript
// apps/server/src/skills.ts
export const myNewSkill = {
  name: "my-new-skill",
  description: "Does something useful",
  execute: async (input: any) => {
    // your logic here
    return { result: "done" };
  },
};

```

Then register it in the server entry point:

```typescript
// apps/server/src/server.ts
import { myNewSkill } from "./skills";

mcp.registerSkill(myNewSkill);

```

## Writing End-to-End Tests

All contributions must include **slow specs** that validate the full stack. Create test files in `evals/specs/` following the naming convention `*.slow.test.ts`:

```typescript
// evals/specs/my-new-skill.slow.test.ts
import { test, expect } from "@openwork/testkit";

test("my-new-skill works end-to-end", async ({ client }) => {
  const result = await client.executeCapability("my-new-skill", { foo: "bar" });
  expect(result).toMatchObject({ result: "done" });
});

```

Run the test suite before submitting:

```bash
pnpm test        # Unit tests

pnpm test:slow   # Full-stack specs (uses Daytona when available)

```

## Submitting Your Contribution

Push your branch to your fork and open a pull request against the **`dev`** branch. The CI pipeline automatically executes the test suite and generates a **testkit evidence tape**. Ensure this tape is attached to your PR description for human verification.

## Summary

- **OpenWork** uses a monorepo structure with pnpm workspaces separating the Electron UI, Node server, and cloud Den control plane
- Run `pnpm dev` to start the shared development environment with CDP access on port 9223
- Implement UI changes in `packages/ui/src/`, server logic in `apps/server/src/`, and MCP skills via [`skills.ts`](https://github.com/different-ai/openwork/blob/main/skills.ts)
- All features require corresponding slow specs in `evals/specs/` to validate end-to-end functionality
- Target the `dev` branch for pull requests and ensure CI generates the evidence tape

## Frequently Asked Questions

### What branch should I target for pull requests?

Always open pull requests against the **`dev`** branch rather than `main`. The `dev` branch serves as the integration point for all new features before they are promoted to production releases.

### How do I test my changes locally?

Use `pnpm test` for fast unit tests during development, and `pnpm test:slow` before committing to validate full-stack interactions. The slow specs require a running development environment and optionally use Daytona for containerized testing.

### What is the MCP in OpenWork?

The **Multi-Capability Protocol (MCP)** is the standardized interface that allows AI agents to discover and execute skills. The local server exposes MCP endpoints for immediate capabilities, while the Den control plane provides remote MCP access at `https://api.openworklabs.com/mcp/agent` for cloud-hosted features.

### How does the workspace isolation work for development?

The `pnpm dev:worktree` command creates an isolated development profile using a separate worktree configuration. This prevents conflicts between different feature branches by maintaining distinct state directories and process ports, allowing you to run multiple OpenWork instances simultaneously on the same machine.