# Shared types reference

> Core exported interfaces: Session, ChatMessage, RoutingDecision, OrchestrationPlan, Harness, PermissionRequest, MCP types, and message-queue HarnessCapabilities.

- Repository: Parcha-ai/build
- GitHub: https://github.com/Parcha-ai/build
- Human docs: https://grok-wiki.com/public/docs/parcha-ai-build-bea5702b371b
- Complete Markdown: https://grok-wiki.com/public/docs/parcha-ai-build-bea5702b371b/llms-full.txt

## Source Files

- `src/shared/types/index.ts`
- `src/shared/types/message-queue.ts`
- `src/shared/utils/message-recovery.ts`
- `src/shared/utils/prompt-truncation.ts`
- `src/main/services/harness-capabilities.ts`

---

---
title: "Shared types reference"
description: "Core exported interfaces: Session, ChatMessage, RoutingDecision, OrchestrationPlan, Harness, PermissionRequest, MCP types, and message-queue HarnessCapabilities."
---

Build’s Electron main and renderer processes share a single TypeScript contract under `src/shared/`. Domain models (`Session`, `ChatMessage`, Auto Build routing shapes, MCP registry types) live in `src/shared/types/index.ts`; per-harness queue behavior is typed in `src/shared/types/message-queue.ts` and enforced at runtime by `getHarnessCapabilities()` in `src/main/services/harness-capabilities.ts`. IPC payloads, Zustand stores, and services import these symbols directly so both sides agree on field names, unions, and optional metadata without duplicating schemas.

## Module layout

```text
src/shared/
├── types/
│   ├── index.ts          # Primary barrel: sessions, chat, routing, MCP, settings
│   ├── message-queue.ts  # QueuedMessage, QueueState, HarnessCapabilities
│   └── audio.ts          # Voice/TTS settings (re-exported from index)
├── utils/
│   ├── message-recovery.ts   # PersistedChatMessage, dedupe/merge helpers
│   └── prompt-truncation.ts  # Long-prompt middle truncation
└── constants/channels.ts     # IPC channel strings (separate reference page)

src/main/services/
└── harness-capabilities.ts   # Runtime HarnessCapabilities map per Harness
```

<Note>
`AppSettings`, `AutoRouterConfig`, and git/browser helpers are defined in `index.ts` but documented in depth on the settings and feature pages. This page focuses on session, chat, routing, agent dialogs, MCP, and the message queue.
</Note>

## Import pattern

Both processes import from the same paths:

```typescript
import type { Session, ChatMessage, RoutingDecision } from '../../shared/types';
import type { QueuedMessage, HarnessCapabilities } from '../../shared/types/message-queue';
```

Renderer stores (`session.store.ts`, `audio.store.ts`) and main services (`claude.service.ts`, `auto-router.service.ts`, `message-queue.service.ts`) depend on these types for IPC serialization and UI state.

```mermaid
classDiagram
  class Session {
    +string id
    +SessionStatus status
    +string repoPath
    +Harness model prefix via picker
  }
  class ChatMessage {
    +string id
    +role user|assistant|system
    +Harness harness
    +ToolCall[] toolCalls
  }
  class RoutingDecision {
    +TaskTier tier
    +string resolvedModel
    +OrchestrationPlan orchestration
  }
  class OrchestrationPlan {
    +mode single|lead-with-delegates|sequential
    +OrchestrationStage[] stages
  }
  class QueuedMessage {
    +string sessionId
    +string text
  }
  class HarnessCapabilities {
    +boolean supportsAsyncInjection
    +number minTurnGapMs
  }
  Session --> ChatMessage : messages per session
  RoutingDecision --> OrchestrationPlan : optional
  QueuedMessage --> HarnessCapabilities : drain timing via harness
```

## Harness identifier

<ParamField body="Harness" type="'claude' | 'codex' | 'cursor' | 'gemini' | 'opencode' | 'custom'" required>
Union of supported agent backends. Stored on `ChatMessage.harness` and resolved from model picker strings.
</ParamField>

Model strings use prefixed forms for non-Claude harnesses. `harnessFromModel()` in `message-recovery.ts` maps:

| Model prefix | Harness |
|--------------|---------|
| (none / default) | `claude` |
| `codex:` | `codex` |
| `cursor:` | `cursor` |
| `gemini:` | `gemini` |
| `opencode:` | `opencode` |
| `custom:` | `custom` |
| `auto` | Resolved at runtime to `resolvedModel` from `RoutingDecision` |

When `model === 'auto'`, `withFallbackHarness()` may attach the resolved harness to assistant messages after routing completes.

## Session

`Session` is the persisted workspace record (electron-store `claudette-sessions`) and the in-memory object passed through session IPC.

### Core fields

| Field | Type | Role |
|-------|------|------|
| `id` | `string` | Stable session identifier |
| `name` | `string` | Display name |
| `repoPath` | `string` | Primary repository path |
| `worktreePath` | `string` | Active git worktree |
| `branch` | `string` | Checked-out branch |
| `status` | `SessionStatus` | Lifecycle gate for UI and services |
| `ports` | `PortAllocation` | `web`, `api`, `debug` port triple |
| `createdAt` / `updatedAt` | `Date` | Timestamps |
| `setupScript` | `string` | Worktree/bootstrap script |
| `model` | `string?` | Selected model for the session |

### SessionStatus

```text
creating → starting → setup → running → stopping → stopped
                                    ↘ error
```

`SetupProgressEvent` reports worktree/SSH setup progress with `status: 'running' | 'completed' | 'error'`.

### Execution modes (optional blocks)

<ParamField body="sshConfig" type="SSHConfig">
Remote execution: host, port (default 22), username, `privateKeyPath`, `remoteWorkdir`, optional `passphrase`, `worktreeScript`, `syncSettings`.
</ParamField>

<ParamField body="openclawConfig" type="OpenClawConfig">
OpenClaw Gateway: `gatewayUrl`, `gatewayPassword` (Bearer token).
</ParamField>

<ParamField body="isDevMode" type="boolean">
Local dev session without Docker container.
</ParamField>

<ParamField body="containerId" type="string">
Docker-backed session when not dev mode.
</ParamField>

### Transcript and fork metadata

| Field | Purpose |
|-------|---------|
| `sdkSessionId` | Claude Agent SDK session for transcript resume |
| `relatedSessionIds` | Alternate local/SDK IDs for same conversation |
| `continuedFromSessionId` | Prior Build session this one resumed |
| `isWorktree` / `parentRepoPath` / `forkName` | Git worktree fork from parent repo |
| `parentSessionId` / `childSessionIds` / `forkPoint` | Conversation fork tree (distinct from git worktree) |
| `isRoot` / `forkCreatedAt` / `aiGeneratedName` | Fork tab labeling |
| `teleportedFrom` / `downloadedFrom` / `isTeleported` | Teleport/import provenance |
| `isStarred` / `starredAt` | Favorites ordering |
| `gstackMode` | Active GStack skill id (`GStackMode` is `string`) |
| `tabHidden` | User-closed tab persistence |
| `htmlRenderMode` | `'md' \| 'html'` per-session rendering |

`SavedSSHConfig` is the electron-store-safe SSH preset (no passphrase). `SSHResumeCandidate` lists resumable remote transcripts. `DownloadSessionConfig` configures reverse teleport (SSH → local).

## ChatMessage and streaming artifacts

`ChatMessage` is the canonical chat timeline unit in the renderer and transcript merge logic.

<ParamField body="id" type="string" required>
Message id (UUID in queue; SDK/transcript ids when recovered).
</ParamField>

<ParamField body="role" type="'user' | 'assistant' | 'system'" required>
Speaker role.
</ParamField>

<ParamField body="content" type="string" required>
Combined text for search and backwards compatibility.
</ParamField>

<ParamField body="contentBlocks" type="ContentBlock[]">
Ordered `text` / `tool_use` blocks for interleaved UI; `toolCallId` references `toolCalls`.
</ParamField>

<ParamField body="toolCalls" type="ToolCall[]">
SDK tool invocations with `status: 'pending' | 'running' | 'completed' | 'error'`.
</ParamField>

<ParamField body="harness" type="Harness">
Which backend produced or received the message.
</ParamField>

<ParamField body="metadata" type="object">
Optional workflow hints, e.g. `workflowCompletedScope: TaskTier`, `workflowFailures[]` with harness/model/error.
</ParamField>

### ToolCall and multi-agent UI

`ToolCall` carries `input`, `result`, `error`, timestamps, and optional `agentId` (SDK `parent_tool_use_id` for teammates). `AgentInfo` pairs `id`, optional `name`, and a color from `AGENT_COLORS`. `ContentBlock.agentId` attributes blocks to lead vs delegate agents.

### Attachments and browser context

`Attachment` types: `file`, `image`, `dom_element` with optional `screenshot`. `DOMElementContext` captures inspector payloads (selector, HTML, computed styles, `boundingRect`). `BrowserSnapshot` is url + screenshot + html + timestamp.

### Persistence helper

`PersistedChatMessage` = `ChatMessage` with `timestamp: string` (ISO). Use `serializeCompletedStreamMessage()` / `normalizeCompletedStreamMessage()` when writing or reading stored transcripts.

<Warning>
Recovery utilities (`mergeRecoveredStreamMessages`, `isDuplicateStreamMessage`, `filterInternalPromptEchoes`) implement deduplication windows (60s default, 5s for close content duplicates). Do not change signatures without updating both transcript reload and live stream merge paths.
</Warning>

## Auto Build routing types

Auto Build (intelligent model routing) types cluster around `TaskTier`, `RoutingDecision`, and `OrchestrationPlan`. `auto-router.service.ts` builds decisions; `claude.service.ts` consumes `orchestration` for staged handoffs and emits `IPC_CHANNELS.CLAUDE_AUTO_ROUTE_DECISION` to the renderer.

### TaskTier and TaskDomain

| TaskTier | Typical use |
|----------|-------------|
| `plan` | Planning / spec work |
| `build` | Implementation |
| `verify` | Tests, lint, validation |
| `refine` | Fix-up after failure |

`TaskDomain` narrows routing: `copy`, `frontend`, `backend`, `fullstack`, `debug`, `ops`, `docs`, `data`, `general`.

### MetaHarnessPolicy and extensions

Shared optional knobs on tiers, categories, and stages:

| Field | Values |
|-------|--------|
| `effort` | Provider-specific effort string |
| `speed` | `MetaHarnessSpeed`: `auto`, `standard`, `fast` |
| `workflow` | `MetaWorkflowMode`: `auto`, `single`, `lead-with-delegates`, `sequential`, `dynamic` |
| `verification` | `MetaVerificationMode`: `auto`, `none`, `optional`, `required` |
| `budgetUsd` | Spend cap hint |

`MetaMissionControlPolicy` adds `controllerHarness: 'meta'`, `requestedTier`, `leadTier`, `leadHarness`, `leadModel`, and optional category labels for Flue/meta controller routes.

### RoutingDecision

<ResponseField name="RoutingDecision" type="object">
Auto Build output attached to a user turn and analytics.
</ResponseField>

| Field | Description |
|-------|-------------|
| `tier` | Resolved `TaskTier` for this turn |
| `domain` | Optional `TaskDomain` |
| `resolvedModel` | Model id sent to the harness |
| `resolvedHarness` | Backend when distinct from model prefix |
| `resolvedEffort` / `resolvedSpeed` / `workflow` / `budgetUsd` / `verification` | Applied policy |
| `confidence` | Router confidence score |
| `reason` | Human-readable routing explanation |
| `method` | `'heuristic' \| 'controller'` |
| `enableGoals` / `goal` | `GoalOrchestration` from `/goal` or Ralph loop |
| `missionControl` | `MetaMissionControlPolicy` when meta controller leads |
| `orchestration` | Multi-stage `OrchestrationPlan` when workflow ≠ single |

`SessionPhase` tracks `lastTierUsed`, `hasPlanContext`, `hasBuildContext`, and `recentTiers[]` for follow-up routing. `AutoRouterConfig` (in settings store) supplies per-tier models, efforts, workflows, verification modes, `categories[]`, and `costAware` / `costThresholdPercent`.

### OrchestrationPlan and OrchestrationStage

```typescript
interface OrchestrationPlan {
  mode: 'single' | 'lead-with-delegates' | 'sequential';
  leadHarness: Harness;
  leadModel: string;
  stages: OrchestrationStage[];
  contextPolicy: {
    includeTranscript: boolean;
    includeTranscriptReferences: boolean;
    includePlanFileReference: boolean;
    avoidBulkContextOnHandoff: boolean;
    maxHandoffConversationChars: number;
    includeProjectInstructions: boolean;
    includeSkills: boolean;
    includeAgents: boolean;
    includeMemories: boolean;
  };
  handoffPrompt: string;
}
```

Each `OrchestrationStage` includes `tier`, `harness`, `model`, optional `fallbackModels`, `purpose`, `required`, and `trigger`:

| trigger | Meaning |
|---------|---------|
| `now` | Run immediately with lead |
| `after-plan` | After plan stage completes |
| `after-build` | After build stage completes |
| `on-failure` | After a failed lead (often refine) |
| `manual-follow-up` | User-triggered follow-up |

Stages inherit `MetaHarnessPolicy` fields for per-stage effort/speed/verification.

## Agent interaction types

These structs cross the preload bridge when the Agent SDK blocks on user input.

### PermissionRequest / PermissionResponse

<ParamField body="PermissionRequest" type="object" required>
`sessionId`, `requestId`, `toolName`, `toolInput`, optional `message`.
</ParamField>

<ParamField body="PermissionResponse" type="object" required>
`requestId`, `approved`, optional `modifiedInput`, `alwaysApprove` (persist pattern to project settings).
</ParamField>

### QuestionRequest / QuestionResponse

`Question` contains `question`, `header`, `options: QuestionOption[]`, and `multiSelect`. `QuestionRequest` bundles `questions[]` with session/request ids; `QuestionResponse` returns `answers: Record<string, string>`.

### PlanApprovalRequest / PlanApprovalResponse

Used with ExitPlanMode: `planContent`, optional `planFilePath`, `allowedPrompts[]`. Response: `approved`, optional `feedback` on reject.

### CompactionStatus / CompactionComplete

Smart Compact events: `isCompacting`, optional model switch metadata, `preTokens` / `postTokens`, `trigger: 'manual' | 'auto'`.

## MCP and marketplace types

Runtime-installed servers use `MCPServerInfo`:

| Field | Notes |
|-------|-------|
| `id`, `name`, `description`, `version` | Identity |
| `status` | `active`, `inactive`, `error` |
| `type` | `sdk`, `stdio`, `http`, `sse` |
| `tools` | `MCPServerTool[]` (`name`, `description`) |
| `projectEnabled` | Per-project toggle |

Registry/marketplace browsing uses `MarketplaceMCPServer` with `packages[]` (`MCPRegistryPackage`), `remotes[]` (`MCPRegistryRemote`), and `authFields[]` (`MCPRegistryAuthField`). Plugin marketplaces add `PluginMarketplace`, `InstalledPlugin`, `MarketplacePlugin`, and `PopularMarketplace`.

## Message queue types

Defined in `message-queue.ts` and driven by `message-queue.service.ts` in the main process.

### QueuedMessage

| Field | Type | Notes |
|-------|------|-------|
| `id` | `string` | UUID at enqueue |
| `sessionId` | `string` | Owning session |
| `text` | `string` | Prompt body |
| `attachments` | `unknown[]?` | Opaque attachment payload |
| `timestamp` | `number` | `Date.now()` at enqueue |
| `model` | `string?` | Model active when queued |
| `suppressUserMessage` | `boolean?` | Hide user bubble (e.g. continue) |

### QueueState

`messages`, `isProcessing`, optional `activeHarness` — emitted on `state-changed` events for the session switcher UI.

### HarnessCapabilities

Interface consumed by `getHarnessCapabilities(harness?)`:

<ParamField body="supportsAsyncInjection" type="boolean">
`true` only for `claude` — can accept messages mid-stream.
</ParamField>

<ParamField body="supportsMultiTurn" type="boolean">
`true` for `claude` and `cursor` — conversation state across turns.
</ParamField>

<ParamField body="minTurnGapMs" type="number">
Delay after `onStreamEnd` before dequeuing next message (`0` for Claude, `500` for others).
</ParamField>

<ParamField body="maxCoalesceWindowMs" type="number">
Declared coalesce window (3000 ms for all harnesses); reserved for rapid-send batching.
</ParamField>

| Harness | Async injection | Multi-turn | minTurnGapMs |
|---------|-----------------|------------|--------------|
| `claude` | yes | yes | 0 |
| `cursor` | no | yes | 500 |
| `codex`, `gemini`, `opencode`, `custom` | no | no | 500 |

Unknown harness strings fall back to the default row (same as non-Claude backends). Today `message-queue.service.ts` applies `minTurnGapMs` on drain; other flags are part of the contract for UI and future coalescing.

## Prompt truncation utility

`truncateMiddlePreservingTail(value, maxChars, options?)` in `prompt-truncation.ts` shortens oversized prompts while keeping the tail (default 70% tail ratio). Used by `claude.service.ts` and `codex.service.ts` when context exceeds harness limits.

<ParamField body="marker" type="string">
Inserted middle marker; default `[... middle truncated due to length ...]`.
</ParamField>

<ParamField body="tailRatio" type="number">
Fraction of `maxChars` reserved for tail; clamped 0.1–0.9, default 0.7.
</ParamField>

## Audio types (re-export)

`index.ts` re-exports `src/shared/types/audio.ts`: `AudioState`, `TranscriptionStatus`, `TranscriptionResult`, `TTSState`, `TTSRequest`, `VoiceSettings`, `AudioSettings`, and `DEFAULT_AUDIO_SETTINGS`. Voice IPC uses these alongside `AppSettings` API key fields documented on the settings page.

## Quick reference: other index exports

| Group | Types |
|-------|-------|
| Git / GitHub | `Commit`, `Branch`, `FileChange`, `GitHubUser`, `GitHubRepo` |
| Focus mode | `FocusTask`, `FocusSubtask` |
| Settings | `AppSettings`, `CustomModelConfig` |
| Extensions | `Command`, `Skill`, `AgentDefinition` |
| Containers | `ContainerStats`, `PortAllocation` |
| Legacy GStack | `GSTACK_MODE_META` color/shortName map for known skill ids |

## Related pages

<CardGroup>
  <Card title="Sessions and workspaces" href="/sessions-and-workspaces">
    Session lifecycle, persistence keys, SSH/OpenClaw fields, and transcript resume.
  </Card>
  <Card title="Auto Build routing" href="/auto-build-routing">
    How RoutingDecision and OrchestrationPlan are produced and executed.
  </Card>
  <Card title="Harnesses and models" href="/harnesses-and-models">
    Harness identifiers, model prefixes, and capability limits in the UI.
  </Card>
  <Card title="IPC and preload bridge" href="/ipc-bridge">
    How typed payloads cross main/renderer via electronAPI.
  </Card>
  <Card title="Manage coding sessions" href="/manage-sessions">
    Message queue UX, permission dialogs, and session fork/rewind flows.
  </Card>
  <Card title="MCP servers" href="/mcp-servers">
    MCPServerInfo storage, marketplace install, and harness sync.
  </Card>
</CardGroup>
