Boujot
Code on the go — control AI coding agents from your mobile device.
Open source. Code anywhere.
Installation
npm install -g @boujot/happy-coder
Upgrading to 0.14.99
0.14.99 changes what a machine runs before it starts any session. Read this before you upgrade.
- A machine without the isolation service (for example a Mac) starts no session until its
user opts in on that machine. Run
boujot machine-settings run-sessions-here onin a terminal and typeyes(the command reads the answer from the terminal). Sessions then run as that user, not isolated. Turning it off stops the sessions the daemon started there. - An isolated Linux machine needs the service's required file/process capabilities. Current releases require the 0.4.2 protections; project operations additionally need the reviewed network policy and live evidence supplied by 0.5.0. CLI 0.17.0 ships the locked Rust source and installer. npm does not install a root service. Drain chats and stop the daemon and root services before upgrading; existing configurations are preserved. Follow the service release procedure.
- Shell and files, and SSH, are separate switches and off by default
(
boujot machine-settings shell-and-files|ssh on|off). While shell and files is off:- a remote start may set only the settings that
src/daemon/remoteStartSettings.tslists; a program path,PATH,CODEX_HOME, a proxy, a certificate or an unknown name is refused; - a model gateway address needs its own provider's key in the same request; this machine's login, profile and tmux are never used for a gateway start;
${NAME}in a request is filled only from a small set with no secret;- readiness and model lists answer "Not checked" for a gateway;
- a Claude session in an Agent Plane session folder loads only the user's settings and the
servers checked at the start; the folder's
CLAUDE.mdis passed in the system prompt.
- a remote start may set only the settings that
- Downgrading: 0.14.96 and older do not read
run-sessions-hereand give this machine's login to a gateway. Stop the daemon before a downgrade and keep it stopped (on Linux also disable its service unit) until you choose the older behaviour.
Known limits: a running Claude process keeps what it loaded until its next start; a switch
request ends the turn of a daemon-started session instead of switching to local mode; the
switches do not isolate anything from code that already runs as the machine's user.
Messages during a response
Agent Plane can send text and images to the current Claude or Codex response, including while a Claude background job is running. The input keeps the original turn's model, permissions and authority. Image references are downloaded and checked before native delivery; a failed download is reported as not sent. Caller-acknowledged RPC identities prevent a lost receipt or a retried request from injecting the same message twice.
Claude uses streaming user input with UUID receipts and result correlation (qualified with Claude Code 2.1.318). An earlier result cannot close the process while later input is queued. Updating Boujot takes effect in newly started runtime children; drain existing children before restarting the daemon through its supported childless stop/start procedure.
Background work in Agent Plane
A Claude response can finish before its background jobs. Boujot keeps that Agent Plane turn open while those jobs and their completion responses run, so their output and later tool permissions reach the same conversation. Stop and the turn's authority deadline still apply. The turn finishes only after the pending results are consumed and its Claude process ends.
This uses Claude Code's native background-task events and completion run_id / origin.runId
correlation, verified with Claude Code 2.1.318. Native delivery receipts also acknowledge
completions absorbed into an ongoing response; foreground commands do not add background
continuations. These receipts do not create duplicate owner messages. Older versions that report a completion without
its run ID fail with an update message instead of silently dropping the continuation.
Reconnecting Agent Plane replays recorded output; it does not start another copy of the job.
Usage
Claude (default)
boujot
This will:
- Start a Claude Code session
- Display a QR code to connect from your mobile device
- Allow real-time session sharing between Claude Code and your mobile app
Gemini
boujot gemini
Start a Gemini CLI session with remote control capabilities.
First time setup: log in with the Gemini CLI itself on this machine (gemini), or set GEMINI_API_KEY.
Boujot does not store a provider login on its server.
Architecture & Dependencies
Boujot has five core pieces:
happy-app(mobile app)- Metro (only when developing
happy-app) @boujot/happy-coder(boujotcommand)boujot daemon(background mode of the CLI)- Boujot server (
HAPPY_SERVER_URL)
How they depend on each other:
- The server is the shared source of truth for account, sessions, and machines.
boujot daemonis the process that keeps your computer registered as an online machine and routes work to local agent processes.boujotinteractive sessions (Claude/Codex/Gemini) also sync via the server, which is why they appear in the app.- The app talks to the server, selects a machine, and sends actions that are handled by the daemon on that machine.
- Metro is only needed for app development/hot reload; it is not part of production runtime and not required for CLI/daemon operation.
Minimal end-to-end requirements (app controlling your machine):
- Server reachable
- CLI authenticated (
boujot auth login) - Daemon running (
boujot daemon start) - App authenticated to the same account
- Machine selected in the app
Commands
Main Commands
boujot– Start Claude Code session (default)boujot gemini– Start Gemini CLI sessionboujot codex– Start Codex mode
Utility Commands
boujot auth– Manage authenticationboujot notify– Send a push notification to your devicesboujot daemon– Manage background serviceboujot doctor– System diagnostics & troubleshooting
Gemini Subcommands
boujot gemini # Start Gemini session
boujot gemini model set <model> # Set default model
boujot gemini model get # Show current model
boujot gemini project set <id> # Set Google Cloud Project ID (for Workspace accounts)
boujot gemini project get # Show current Google Cloud Project ID
Available models: gemini-2.5-pro, gemini-2.5-flash, gemini-2.5-flash-lite
Options
Claude Options
-m, --model <model>- Claude model to use (default: sonnet)-p, --permission-mode <mode>- Permission mode: auto, default, or plan--claude-env KEY=VALUE- Set environment variable for Claude Code--claude-arg ARG- Pass additional argument to Claude CLI
Global Options
-h, --help- Show help-v, --version- Show version
Environment Variables
CLI Configuration
HAPPY_SERVER_URL- Required for every command except--version. Server URL; there is no default.HAPPY_WEBAPP_URL- Required to log in with a browser (auth login, Web Browser). Address of the web app,httpsonly (httpfor localhost); there is no default.HAPPY_HOME_DIR- Folder for login keys, settings, daemon state and logs (default: ~/.boujot)HAPPY_FLAVOR- Set toboujotfor Boujot naming when running from a checkout (an install detects it from its path)HAPPY_DISABLE_CAFFEINATE- Disable macOS sleep prevention (set totrue,1, oryes)HAPPY_EXPERIMENTAL- Enable experimental features (set totrue,1, oryes)
Gemini Configuration
GEMINI_MODEL- Override default Gemini modelGOOGLE_CLOUD_PROJECT- Google Cloud Project ID (required for Workspace accounts)
Gemini Authentication
Personal Google Account
Log in one time with the Gemini CLI on this machine, then start a session:
gemini
boujot gemini
Google Workspace Account
Google Workspace (organization) accounts require a Google Cloud Project:
- Create a project in Google Cloud Console
- Enable the Gemini API
- Set the project ID:
boujot gemini project set your-project-id
Or use environment variable:
GOOGLE_CLOUD_PROJECT=your-project-id boujot gemini
Guide: https://goo.gle/gemini-cli-auth-docs#workspace-gca
Contributing
Interested in contributing? See CONTRIBUTING.md for development setup and guidelines.
Dev Testing
Run yarn build, then test your build in one of two ways:
- Next to the installed CLI:
npm run dev:daemon:startandnpm run dev:variant <command>run this checkout with its own data folder, login and daemon. The installedboujotkeeps working. - In place of the installed CLI:
yarn dev:deploycopies this build into the installed@boujot/happy-coder. Then restart its daemon:boujot daemon stop && boujot daemon start.
Details are in CONTRIBUTING.md. Running the whole stack (backend, daemon, mobile app, Metro) is in docs/dev-bringup.md.
Boujot Fork: Branches and Releases
master is the one development line and is already branded @boujot/happy-coder. Work happens
on short-lived feat/* or fix/* branches merged into master. Each release is a version commit
on master with a tag, boujot-cli-v<version>. master only moves forward, so no push is ever
forced.
To release from an up-to-date master:
npm run release:boujot -- 0.14.86
git push sn1994 master boujot-cli-v0.14.86
# Drone builds and tests the tag once, then publishes 0.14.86 under latest.
Notes:
- The helper refuses anything but a clean
master. - CLI 0.17.0 packages isolator 0.5.0 source, Cargo lockfile, installer and probes. Drone builds and tests that Linux source before npm publication and checks the actual package list. Root deployment remains a separate childless installation step; no privileged npm hook runs.
- It runs
yarn rebrandas a check: onmasterit must change nothing. If it would, the release stops before committing or tagging. - It bumps the version, runs the build (unless skipped), commits, and tags. It runs no tests, never pushes and never publishes.
- Drone tests and publishes (
.drone.yml). The tag's build runs the tests once and publishes the version underlatestand points the dist-tagbetaat it too (no beta releases: the owner, 28 October 2026); a tag that does not namepackage.json's version is refused. The release commit's own master build skips the tests (it is the tested commit before it plus a version).npm-lateston a version already on npm moveslatestback to it (no new build, no new publish).npm-checkdoes everything but the publish;npm-tokenonly asks npm who the token belongs to. An agent with Software Delivery tools promotes withdrone_build_promote, where itsrepo_writegrant allows. - The npm token is the Drone secret
npm_publish_token, kept by Software Delivery's Credentials page (credentialboujot): it shows the expiry, warns 14 days before, and replaces the token in Vault and Drone at once. No token is kept on a developer machine. - Releases up to 0.14.71 were cut as
boujot-cli-release/<version>branches; those stay as they are.
Adopting Upstream Changes
Upstream is happy-coder, in the packages/happy-cli folder of
slopus/happy. The older slopus/happy-cli repository is archived.
Don't merge upstream into this fork. Instead:
- Review the upstream changes you want.
- Apply them on a
feat/*branch frommaster, by hand or with an agent. - Run
yarn rebrand. It converts upstream names (package, command, data folder) to Boujot; commit what it changes. - Build, test, and merge into
masteras usual.
Requirements
- Node.js >= 20.0.0
For Claude
- Claude CLI installed & logged in (
claudecommand available in PATH)
For Gemini
- Gemini CLI installed (
npm install -g @google/gemini-cli) - Gemini CLI logged in on this machine with your Google account, or
GEMINI_API_KEYset
License
MIT