# Installation

> macOS release download, from-source prerequisites (Node, npm, Electron native deps), npm install, and environment separation between production and dev user data.

- 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

- `README.md`
- `package.json`
- `forge.config.ts`
- `entitlements.mac.plist`
- `scripts/dev.sh`
- `webpack.main.config.ts`

---

---
title: "Installation"
description: "macOS release download, from-source prerequisites (Node, npm, Electron native deps), npm install, and environment separation between production and dev user data."
---

Build ships as a signed macOS `.app` from GitHub Releases and as an Electron Forge workspace you run with `npm install` plus `./scripts/dev.sh`. Production state lives under `~/Library/Application Support/Build`; development overrides `userData` to `/tmp/grep-build-dev` so settings, sessions, and MCP configs do not collide with a release install.

## macOS release install

<Tabs>
<Tab title="Download release">

<Steps>
<Step title="Download the artifact">

Download the latest macOS build from [GitHub Releases](https://github.com/Parcha-ai/build/releases). Release builds are signed and notarized when Apple credentials are present at package time.

</Step>
<Step title="Install to Applications">

Drag **Build.app** into `/Applications` (or open the DMG/ZIP artifact and move the app bundle).

</Step>
<Step title="Verify the install">

Launch **Build** from Applications. The status bar shows the app version from `package.json` (for example `0.5.27`). No account is required for local-folder mode; API keys are configured after launch.

</Step>
</Steps>

</Tab>
<Tab title="Build locally">

Use `npm run make` when you need a local distributable. Output lands under a versioned directory:

```text
out/v{version}/Build-darwin-arm64/Build.app
```

`./scripts/build.sh` wraps `npm run make`, tags `v{version}`, and opens the built app on macOS.

</Tab>
</Tabs>

<Note>
README notes that **building from source** is supported on macOS, Linux, and Windows; **prebuilt release downloads** target macOS.
</Note>

| Artifact | Typical path |
|----------|----------------|
| Packaged app (arm64) | `out/v{version}/Build-darwin-arm64/Build.app` |
| Forge output root | `out/v{version}/` |
| Bundle ID | `com.parcha.build` |
| Executable name | `build` |

## From-source prerequisites

| Requirement | Version / notes |
|-------------|-----------------|
| **Node.js** | Node **18+** (Electron Forge 7 and dependencies expect modern Node; no `engines` field in root `package.json`) |
| **npm** | Bundled with Node; used for install and scripts |
| **Electron** | `^38.7.2` (devDependency; Forge downloads the matching runtime) |
| **TypeScript** | `~4.5.4` (compile-time only) |
| **macOS toolchain** | Xcode Command Line Tools for native module compile and optional codesign |
| **Git** | Clone and contribution workflow |

### Native and externalized dependencies

Build relies on native Node addons and packages that stay **outside** the webpack bundle:

| Package | Role |
|---------|------|
| `node-pty` | Integrated terminal (PTY) |
| `@anthropic-ai/claude-agent-sdk` (+ platform binary package) | Claude Code harness |
| `@cursor/sdk` (+ platform binary) | Cursor harness |
| `@anthropic-ai/sdk`, `docx`, `monaco-editor` | SDK and editor assets copied at package time |

Webpack **externals** in `webpack.main.config.ts` match the `postPackage` copy list in `forge.config.ts`. `@electron-forge/plugin-auto-unpack-natives` unpacks `.node` binaries into the app layout. `webpack.rules.ts` routes `node-pty` and `@anthropic-ai` through `node-loader` / asset relocator rules instead of bundling them.

<Warning>
Main-process `webPreferences` set `sandbox: false` because **node-pty** and **webview** tags require it. Do not enable sandbox without replacing those subsystems.
</Warning>

### Optional: QMD semantic search bundle

`./scripts/dev.sh` runs `npm run setup-qmd`, which downloads Bun and QMD platform bundles into `resources/qmd/{platform-arch}/`. Production `npm run make` copies the matching bundle into `Build.app/Contents/Resources/qmd` when present; otherwise packaging logs a warning to run `npx ts-node scripts/setup-qmd.ts {platform-arch}`.

## Clone and `npm install`

<CodeGroup>
```bash title="Clone"
git clone https://github.com/Parcha-ai/build.git
cd build
```

```bash title="Install dependencies"
npm install
```
</CodeGroup>

`npm install` pulls Electron Forge, webpack tooling, React, and application dependencies from `package.json`. There is no root `postinstall` script; Forge plugins handle native unpacking on package.

<Tip>
If `node-pty` or SDK binaries fail to load after install, run `npm run make` or `npx electron-rebuild` against the pinned Electron version, then retry `./scripts/dev.sh`.
</Tip>

## Development launch (`./scripts/dev.sh`)

<Warning>
Start development with **`./scripts/dev.sh`**, not `npm run start` alone. The dev script sets instance name, QMD setup, port isolation, userData override, and cleanup of orphaned dev Electron processes.
</Warning>

<Steps>
<Step title="Run the dev script">

```bash
./scripts/dev.sh
```

The script prints a **DEV INSTANCE** name (for example `bouncy-penguin`) used in the status bar to distinguish dev builds.

</Step>
<Step title="What the script configures">

| Variable / action | Value / behavior |
|-------------------|------------------|
| `DEV_INSTANCE_NAME` | Random adjective–noun label |
| `npm run setup-qmd` | Ensures QMD/Bun bundle for current platform |
| Process cleanup | Kills `node_modules/electron` dev instances and `electron-forge`; does **not** kill `out/` production builds |
| `DEV_WEBPACK_PORT` | `9001` (frees port `9000` for production logger) |
| `GREP_DEV_USER_DATA` | `/tmp/grep-build-dev` |
| Settings sync | One-time copy from production dirs if dev files missing |
| Launch | `npm run start` → `electron-forge start` |

</Step>
<Step title="Verify dev is isolated">

Confirm the console line `Using dev userData: /tmp/grep-build-dev` and that DevTools open automatically when `GREP_DEV_USER_DATA` is set.

</Step>
</Steps>

Other common scripts after install:

| Script | Purpose |
|--------|---------|
| `npm run lint` | ESLint across `.ts` / `.tsx` |
| `npm run package` | Forge package without full make |
| `npm run make` | Clean `.webpack` and `out/v{version}`, then `electron-forge make` |
| `npm run setup-qmd` | QMD bundle for current platform only |
| `npm run setup-qmd:all` | QMD bundles for all supported platforms |

## Production vs development user data

Electron persists app state under `app.getPath('userData')`. Build separates environments by **directory**, not by renaming store files in current code (`getSessionStoreName()` returns `claudette-sessions` in both modes; files simply live in different folders).

```text
Production (release .app)
  ~/Library/Application Support/Build/
    claudette-settings.json      # electron-store (API keys, theme, QMD flags, …)
    claudette-sessions.json      # CachedStore session index
    claudette-mcp-servers.json
    claudette-mcp-harness-sync.json
    claudette-identity.json
    claudette-memory.json
    claudette-qmd.json
    main.log                     # production main-process log
    sessions/                    # per-session artifacts
    qmd/                         # copied/runtime QMD files
    Local Storage/               # renderer localStorage

Development (./scripts/dev.sh)
  /tmp/grep-build-dev/           # GREP_DEV_USER_DATA via app.setPath
    (same store filenames)
```

```mermaid
flowchart LR
  subgraph prod["Production Build.app"]
    PUD["~/Library/Application Support/Build"]
  end
  subgraph dev["Dev electron-forge"]
    DEV["/tmp/grep-build-dev"]
  end
  subgraph legacy["Legacy dirs - migrated once"]
    GB["G-Build"]
    GR["Grep Build"]
  end
  legacy -->|migrateFromGrepBuild on first launch| PUD
  GB -.->|dev.sh one-time copy if missing| DEV
  GR -.->|dev.sh one-time copy if missing| DEV
  PUD -.->|dev.sh one-time copy if missing| DEV
```

### How separation is enforced

| Mechanism | Production | Development |
|-----------|------------|-------------|
| `userData` path | Default Electron path for `productName: "Build"` | `GREP_DEV_USER_DATA=/tmp/grep-build-dev` set before `app.ready` |
| CDP remote debugging | Port `9222` (default) | Port `9223` when `DEV_INSTANCE_NAME` or `NODE_ENV=development` |
| Webpack logger port | `9000` (Forge default) | `9001` via `DEV_WEBPACK_PORT` |
| Main log file | `main.log` under userData | Skipped when `DEV_INSTANCE_NAME` is set |
| DevTools | Closed by default | Opened when `GREP_DEV_USER_DATA` is set |

On first production launch, `migrateFromGrepBuild()` copies store files and `Local Storage` from `~/Library/Application Support/G-Build` or `Grep Build` into `Build`, then writes `.migrated-from-grep-build`.

`scripts/dev.sh` sync policy:

- **Settings / MCP**: copy from production only if the dev file does **not** exist (never overwrite dev keys or custom models).
- **Sessions**: copy `claudette-sessions.json` when present (optional convenience).
- **Never symlink** dev → prod; `CachedStore` debounced writes would corrupt production data.

<Info>
Store files retain the `claudette-*` prefix from earlier product names. Paths on disk use **Build**; identifiers in JSON are unchanged for compatibility.
</Info>

### Persistence keys (electron-store)

Settings use `claudette-settings` (`SettingsService`). Sessions and related IPC services use `CachedStore` with name `claudette-sessions`. MCP configuration uses `claudette-mcp-servers` and `claudette-mcp-harness-sync`. All resolve under the active `userData` directory.

## macOS signing and entitlements

Distribution signing in `forge.config.ts` `postPackage` uses `entitlements.plist` (JIT, unsigned executable memory, network client, user-selected read-write). When `APPLE_ID`, `APPLE_PASSWORD`, and `APPLE_TEAM_ID` are set, the hook runs `@electron/osx-sign` and `@electron/notarize`; otherwise it falls back to adhoc `codesign`.

`entitlements.mac.plist` adds microphone access (`com.apple.security.device.audio-input`) for voice mode alongside standard Electron JIT entitlements.

Offline or air-gapped packaging knobs:

| Environment variable | Effect |
|---------------------|--------|
| `GREP_ELECTRON_ZIP_DIR` | Use a local Electron zip (`electronZipDir`) |
| `GREP_ELECTRON_CACHE_ROOT` | Cache root (default `~/Library/Caches/electron`) |
| `GREP_SKIP_ELECTRON_CHECKSUMS=1` | Skip checksum verification on download |

## Environment variables reference

<ParamField body="GREP_DEV_USER_DATA" type="string">
Overrides Electron `userData`. Set by `scripts/dev.sh` to `/tmp/grep-build-dev`.
</ParamField>

<ParamField body="DEV_INSTANCE_NAME" type="string">
Human-readable dev instance label; disables production `main.log` redirection when set.
</ParamField>

<ParamField body="DEV_WEBPACK_PORT" type="number">
Webpack dev server port. Dev script sets `9001` to avoid conflicting with production on `9000`.
</ParamField>

<ParamField body="DEV_WEBPACK_LOGGER_PORT" type="number">
Forge logger port (default `9000` in `forge.config.ts`).
</ParamField>

<ParamField body="ELECTRON_CDP_PORT" type="string">
Chrome DevTools Protocol port override for browser preview / Stagehand.
</ParamField>

<ParamField body="NODE_ENV" type="string">
When `development`, CDP defaults to port `9223` alongside `DEV_INSTANCE_NAME`.
</ParamField>

## Verification checklist

| Check | Expected signal |
|-------|-----------------|
| Release app opens | No Gatekeeper block on notarized builds from Releases |
| Dev script banner | `DEV INSTANCE: {adjective}-{noun}` in terminal |
| Isolated settings | Edits under `/tmp/grep-build-dev` do not change `~/Library/Application Support/Build` |
| Terminal works | PTY sessions start (confirms `node-pty` native module loaded) |
| Status bar version | Matches `package.json` `version` field |

<Warning>
Run only **one** dev Electron instance at a time. `dev.sh` kills prior `node_modules/electron` processes to release the single-instance lock; production apps under `out/` are left running.
</Warning>

## Related pages

<CardGroup>
<Card title="Quickstart" href="/quickstart">
Open a project, store API keys, pick a harness, and send the first agent message after install.
</Card>
<Card title="Electron architecture" href="/electron-architecture">
Main vs renderer boundaries, services layout, webpack output, and userData path behavior in depth.
</Card>
<Card title="Build and release" href="/build-and-release">
Version bumps, `npm run make`, git tags, and GitHub release artifacts.
</Card>
<Card title="Troubleshooting" href="/troubleshooting">
Port conflicts, PATH/node discovery in packaged apps, and log file locations.
</Card>
</CardGroup>
