For contributors and developers building from source. For the product overview see the root README; for the roadmap and progress see the ROADMAP.
This directory (
docs/development/) is the development track: this guide is the entry point, alongside Packaging & release (incl. CI) and macOS build & release. Module / subsystem design lives in../arch/.
The codebase uses the neutral codename meebox throughout (npm scope
@meebox/*); the public brand is Code Meeseeks. The data directory is~/.code-meeseeks/. Upstream pr-agent is a third-party dependency and is out of the renaming scope.
| Dependency | Version | Notes |
|---|---|---|
| Node.js | ≥ 20 (22 for development) | See the root package.json engines |
| npm | ≥ 10 | Uses workspaces — do not use pnpm/yarn |
| Git | Any recent version | Repo mirroring + diff go through system git |
Packaging also needs (already installed as devDependencies, no system-level install required): the embedded-runtime download goes through undici + tar, so no system curl / python / docker is needed.
Proxy:
prepare:pragentdownloads python-build-standalone from GitHub. On a restricted network, set theHTTPS_PROXYenvironment variable, or pass--proxy http://host:portto the script.
git clone <repo-url>
cd <repo>
npm ci # install all workspace dependenciesThe repo tracks icons / images with Git LFS (see the root .gitattributes). If images show up as pointer text after cloning:
git lfs pullThe app defaults to the embedded strategy: a bundled relocatable CPython + a pinned pr-agent version. Assemble it before starting in dev mode:
npm --prefix apps/desktop run prepare:pragent- The output lands in
apps/desktop/vendor/pragent/(gitignored, ~600+ MB). - Idempotent: skipped if already assembled;
--forceforces a rebuild. - Auto-detects the platform: Windows x64 / macOS arm64 (see Packaging & release).
- This script needs Node 22+ (uses newer built-ins); the other dev commands work on Node 20.
npm --prefix apps/desktop run dev # electron-vite dev (HMR)The first launch automatically creates the ~/.code-meeseeks/ working directory + a default config.yaml. Configure a code platform connection and an LLM provider on the Settings page or by editing that file directly.
After changing main-process / workspace-package code, HMR may not apply — restart
dev. Renderer code hot-reloads normally.
The repo is orchestrated with Nx; the root scripts apply to all packages:
npm run build # nx run-many -t build
npm run typecheck # type-check all packages
npm run test # vitest (nx run-many -t test)
npm run lint # eslint
npm run format # prettier write
npm run graph # nx dependency graphTarget a single package with the nx prefix, e.g.:
npx nx typecheck @meebox/desktop
npx nx test @meebox/poller# Windows: produce an NSIS installer into apps/desktop/release/
npm --prefix apps/desktop run dist
# Only produce the unpacked directory (a faster smoke test, no installer)
npm --prefix apps/desktop run packdist = prepare:pragent + electron-vite build + electron-builder.
- Icons: sources in
assets/icons/, referenced explicitly by electron-builder (win.iconpoints aticon.ico). To regenerate the.icosee assets/README. - macOS: signing / notarization / the free ad-hoc route are covered in macOS build & release.
- CI release: pushing a
v*tag triggers automatic Windows + macOS(arm64) builds attached to the Release. The unified build / signing / CI design is in Packaging & release (workflow: .github/workflows/release.yml).
.
├── apps/
│ └── desktop/ # Electron app (main / preload / renderer)
│ ├── scripts/ # embedded-runtime assembly script + sitecustomize shim
│ ├── build-resources/ # packaging resources (entitlements / afterPack hooks)
│ └── vendor/pragent/ # embedded runtime (gitignored, generated by prepare:pragent)
├── packages/
│ ├── shared/ # cross-process shared types / IPC contract / config schema
│ ├── config/ # config loading and validation
│ ├── logger/ # pino logging
│ ├── platform-bitbucket-server/ # Bitbucket Server platform adapter
│ ├── poller/ # PR polling discovery + draft pool
│ ├── pr-agent-bridge/ # pr-agent invocation (embedded / local-cli strategies)
│ ├── repo-mirror/ # repo mirroring (partial clone + diff/blame)
│ ├── rules/ # rules directory loading and matching
│ └── state-store/ # JSON state storage (atomic writes)
├── docs/ # ROADMAP / arch design / development track
├── assets/ # brand / icon assets (LFS)
└── tools/ # helper scripts (icon gen, third-party notices, CLI install)
App data lives at a fixed ~/.code-meeseeks/ (consistent across OSes):
~/.code-meeseeks/
├── config.yaml # all config: connections / LLM / repos_dir etc. (plaintext credentials, tightened permissions)
├── state/ # PR metadata / comment cache / review runs / drafts (per-PR directories)
├── logs/ # rolling logs
└── repos/ # repo mirrors (default location; repos_dir can point at another disk)
For the data model and fault-tolerance design see arch · State storage & data model.
- Put a new package's tests in its
tests/directory, importing from'../src/...'(legacy packages with tests still undersrc/are not forced to migrate). - Run
npm run typecheck && npm run testbefore committing.
The onboarding wizard only appears when there is "no valid active connection". Once a connection is configured, to debug the wizard repeatedly, use a localStorage flag (doesn't touch config, toggles freely):
While the app is running, open DevTools (Settings page "Open DevTools", or the main-process menu) and run in the Console:
localStorage.setItem('meebox.forceOnboarding', '1'); location.reload();After reloading you enter the wizard. Completing it (clicking "Enter the app") automatically clears the flag and returns to the main UI; you can also clear it manually:
localStorage.removeItem('meebox.forceOnboarding'); location.reload();The onboarding wizard has no menu / status-bar entry. On the welcome page (step 1), click the logo 7 times in a row (each within < 800 ms) to open DevTools, for troubleshooting during the wizard stage.
A dev build is usually higher than the online latest, so it won't naturally trigger the update prompt. Simulate it in the DevTools Console to verify the status-bar chip:
window.dispatchEvent(new CustomEvent('meebox:debug-update')); // shows v9.9.9
window.dispatchEvent(new CustomEvent('meebox:debug-update', { detail: { latestVersion: '1.2.3' } })); // custom version
window.dispatchEvent(new CustomEvent('meebox:debug-update', { detail: null })); // clear