Docs

Local Dev Setup

This is a start-to-finish runbook for building and launching Tranquil Studio from source on macOS. It is written to be executed top to bottom — you can follow it yourself, or point an LLM agent harness (e.g. Claude Code) at this page and let it run each step.

Tranquil Studio (tranquil-client) is a fork of Pulsar (an Atom/Electron editor). Its owned features live in eleven sibling packages that are symlinked into the app for live editing. This runbook clones all twelve repos, wires them together, and launches the real Electron GUI.

Prerequisites

Before starting, make sure the shell has:

  • git, with access to the private tranquillabs/* repos — an SSH key or a token that can clone them. All the git clone commands below fail without it.
  • Node via nvm — each repo pins its version in .nvmrc, so nvm use selects it. Node ≥ 18 (nvm typically resolves to 20.x here).
  • Yarn 1 (classic)yarn --version should report 1.x. Yarn 1’s link: feature is what creates the live sibling symlinks; Yarn 2+ won’t work.

Everything is cloned under one workspace root. This runbook uses ~/Documents/Tranquil/Repos — substitute your own path consistently if you prefer another.

Clone the repos

Clone tranquil-client (the app) plus its eleven owned packages as siblings in the same directory. They must sit next to each other — the link:../ paths in tranquil-client/package.json resolve relative to the repo root.

mkdir -p ~/Documents/Tranquil/Repos
cd ~/Documents/Tranquil/Repos

git clone https://github.com/tranquillabs/tranquil-client.git
git clone https://github.com/tranquillabs/tranquil-rpc.git
git clone https://github.com/tranquillabs/tranquil-automations.git
git clone https://github.com/tranquillabs/tranquil-browser.git
git clone https://github.com/tranquillabs/tranquil-config.git
git clone https://github.com/tranquillabs/tranquil-drag-drop.git
git clone https://github.com/tranquillabs/tranquil-window-color.git
git clone https://github.com/tranquillabs/tranquil-tips.git
git clone https://github.com/tranquillabs/tranquil-theme-icons.git
git clone https://github.com/tranquillabs/tranquil-business-dark.git
git clone https://github.com/tranquillabs/tranquil-business-light.git
git clone https://github.com/tranquillabs/tranquil-examples.git

The resulting layout:

~/Documents/Tranquil/Repos/
  tranquil-client/          ← main app (Pulsar fork)
  tranquil-rpc/             ← guest↔host RPC layer (Cap'n Web)
  tranquil-automations/     ← automation runner + tree-view/tab UI
  tranquil-browser/         ← embedded Chromium browser
  tranquil-config/          ← config, defaults, and the settings tab
  tranquil-drag-drop/       ← drag tabs to the tree to save .url files
  tranquil-window-color/    ← per-window accent color
  tranquil-tips/            ← background tips when no editors are open
  tranquil-theme-icons/     ← semantic file-type icons
  tranquil-business-dark/   ← default dark UI theme
  tranquil-business-light/  ← default light UI theme
  tranquil-examples/        ← first-run guided sample project

All repos are on the main branch.

Install dependencies

Install tranquil-client, initialize the ppm submodule, then install each sibling package that has its own dependencies. The per-sibling installs matter: a symlinked package resolves its own require()s from its real path, so it needs a local node_modules/ to find them.

cd ~/Documents/Tranquil/Repos/tranquil-client
source ~/.nvm/nvm.sh && nvm use
yarn install
git submodule update --init ppm
cd ppm && yarn install && cd ..

# Install deps inside each sibling package that has its own (so it can resolve them)
cd ../tranquil-rpc && yarn install
cd ../tranquil-automations && yarn install
cd ../tranquil-browser && yarn install
cd ../tranquil-config && yarn install
cd ../tranquil-tips && yarn install
cd ../tranquil-client

Verify the sibling symlinks resolved — each should point at ../../tranquil-*:

ls -la node_modules/tranquil-rpc 
        node_modules/tranquil-automations 
        node_modules/tranquil-browser 
        node_modules/tranquil-config 
        node_modules/tranquil-business-dark 
        node_modules/tranquil-theme-icons

Configure tranquil-config

tranquil-config supplies API keys through a generated file that is never committed. The app won’t start until that file exists. For a first launch you don’t need real keys — write a stub:

cd ~/Documents/Tranquil/Repos/tranquil-config
echo '{"github_token": ""}' > config.json
node generate.js
cd ../tranquil-client

When you need real keys later, copy .env.example to .env, fill it in, then run node write_config.js --staging (or --production) followed by node generate.js. Re-run generate.js whenever keys change.

Launch

Start the app. This opens a real Electron GUI:

cd ~/Documents/Tranquil/Repos/tranquil-client
source ~/.nvm/nvm.sh && nvm use
yarn start

Launching from an agent shell

yarn start works from an agent/IDE shell as well as a terminal — background it so the agent keeps control:

cd ~/Documents/Tranquil/Repos/tranquil-client && source ~/.nvm/nvm.sh && nvm use && yarn start

The ELECTRON_RUN_AS_NODE gotcha. An agent/IDE shell (e.g. the VSCode extension host Claude runs inside) exports ELECTRON_RUN_AS_NODE=1. If that leaks into the environment Electron is spawned with, the binary runs as a plain Node interpreter instead of a GUI app, rejects the Chromium flags, and dies in ~0.3s with bad option: --no-sandbox. Tranquil’s scripts/dev.js strips the variable from the child env before spawning, so yarn start works from any shell — no env -u wrapper needed. If you ever see that error, confirm the binary’s mode directly:

electron --version                          # Node's version (e.g. v20.x) → running as Node
env -u ELECTRON_RUN_AS_NODE electron --version   # Electron's version (e.g. v30.x)

Prefer a throwaway instance — yarn verify. For agent work that shouldn’t touch your real window layout or open your actual source tree, yarn verify launches a fully isolated instance (its own --user-data-dir and ATOM_HOME seeded from ~/.tranquil, opening the dedicated tranquil-test-suite repo instead of tranquil-client) and holds it open:

yarn verify   # background this; override the project with: yarn verify <path>

Stop either one by stopping the backgrounded launcher — scripts/dev.js forwards SIGINT/ SIGTERM to the Electron child, so the whole app tears down with no orphans.

Verify it’s running

The dev build exposes the Chromium DevTools Protocol on localhost:9222. Confirm a live GUI without touching the UI:

curl -s http://localhost:9222/json/version

A running instance returns the Electron/Chrome versions and a Tranquil/<version> user agent. To go further — list every renderer/webview target and evaluate JavaScript inside a specific tab — see Agent Debugging.

Next steps

For deeper reference on how the pieces fit together:

  • Multi-Repo Setup — the symlink model, link: mechanics, and how to add a new owned package.
  • ppm and Core Packages — how ppm and the bundled Pulsar core packages load in a dev build.
  • Agent Debugging — inspect and script a live instance over CDP, and know what a reload actually reloads.