Detailed setup instructions for WhipCode: the whipcode CLI and WHIP Desktop.
main is the default/stable source; development is the alpha integration branch.
There is one supported CLI distribution, not a separate alpha product.
For a pre-reset internal installation, use the manual reset checklist;
these instructions describe fresh installations, not a migration.
For the recommended Desktop beta quickstart, see the project README.
The standalone installer requires curl, Python 3, and sha256sum or shasum.
Choose a release from GitHub Releases
and use its pinned installation command. For releases with the two-script split,
substitute its tag below; no version environment variable is needed:
curl -fsSL https://github.com/context-labs/whip/releases/download/<tag>/install.sh | shThat release's install.sh installs its exact version. Its latest.sh always
selects the newest complete stable v1+ release, even when downloaded from an
alpha release. It fails clearly until a stable release exists, never falling back
to an alpha or legacy version. These policies ignore inherited version/channel
selection variables; destination and authentication controls are unchanged.
Both install whipcode into ~/.local/bin by default; add that directory to your
PATH if needed. WHIPCODE_BIN_DIR selects another destination. Older immutable
release installers keep their original behavior. For current source-installer
behavior and explicit prerelease discovery, this command remains available:
curl -fsSL https://raw.githubusercontent.com/context-labs/whip/main/install.sh | WHIPCODE_CHANNEL=prerelease shOr build the packaged CLI from source with Go 1.27+, Node 24, and Task:
git clone --branch main https://github.com/context-labs/whip.git
cd whip
npm ci
task build # ./whipcode, including the embedded renderer/native helper
task install # install into GOBIN or GOPATH/binOn macOS, the native helper also requires Xcode command-line tools. Bare
go install .../cmd/whip@latest is not the supported product build: it names the
wrong executable and omits required packaged assets. Local builds use dev
unless WHIPCODE_VERSION is explicitly supplied.
Day-to-day integration uses development once provisioned; trusted operators may
push directly, with PRs optional. Follow the branch, promotion and backmerge policy.
Then run whipcode in your project folder. The TUI opens directly, without a
folder-trust prompt. Tool approvals follow the session's saved permission level.
Whip detects supported credentials on the execution host and uses your selected
model when it is ready. Otherwise, a provider dialog opens over the composer:
choose Inference.net (recommended), OpenRouter, OpenAI (API key or ChatGPT
subscription) to connect and automatically use the recommended model. Other
providers open a model picker; selecting a model returns directly to the composer.
First-time onboarding saves your choice for new sessions.
Press Esc to close the dialog and draft in the normal composer. /connect,
/auth, or submitting an unconfigured draft reopens it. Type in its focused
search field to filter providers; arrow keys select and Enter connects. Keys
stay in a separate masked field. Connecting preserves your draft; press Enter to send when ready.
Known providers already have their API URLs: choose one and paste its key.
A ✓ marks available credentials; it does not certify inference access.
OpenAI groups API billing and ChatGPT subscription choices without combining their
credentials. Whip recognizes supported environment keys and explicitly configured
local key files. Daemon startup and opening setup save missing provider entries
that reference those keys; secret values stay in their original source.
See local key discovery for file configuration.
Choose Custom endpoint to configure an OpenAI-compatible endpoint in
the TUI through compact steps for its name, API root URL, and API key, host
environment-variable name, or explicit No authentication. Whip discovers models; Enter model
manually… covers endpoints without model discovery. ctrl+e on a provider
opens connection management. Changes persist in the execution host's existing
configuration files, including across restarts.
Legacy /auth provider key also opens masked confirmation. Existing session
choices remain intact. Fresh installations leave external Claude/Codex MCP
imports off and the repository's .mcp.json source off; enable them
explicitly later if wanted.
The web and desktop welcome screen lets you draft first, connect a provider, choose a project folder and send. Ask is the initial tool permission level; changing it applies to the session you create. Credentials and defaults belong to the selected execution host. Custom OpenAI-compatible endpoints are supported through provider configuration; create them in the TUI, then use them from either application.
To reuse a secrets file, add its path to the execution host's ~/.whipcode/config.json:
{
"providerKeySources": {
"envFiles": ["~/.secrets/providers.env"],
"keyFiles": {"CEREBRAS_API_KEY": "~/.secrets/cerebras.key"}
}
}For example, providers.env can contain OPENROUTER_API_KEY=your-key; the Cerebras
file contains only its key. Open /connect or refresh Providers & models to
discover them. Whip saves apiKeyEnv references, never copies these file values
into its configuration, and does not search arbitrary folders or read OpenCode
credentials. File changes are read on discovery and new client creation; reload
an existing session after rotating a key. Newly exported environment variables
require whipcode daemon restart.
The CLI can also validate a named file reference with whipcode auth openrouter --env.
Known-provider metadata is bundled from Models.dev. Maintainers can run
task models:update to refresh the reviewed subset and task models:check to
check generated files offline. Live provider model lists remain authoritative.
For a noninteractive API-key setup:
whipcode auth openrouter
whipcode run -p openrouter -m moonshotai/kimi-k3 "inspect this repository and explain its architecture"Select an execution language once when creating a session:
whipcode --rlm-engine quickjs
whipcode run --rlm-engine quickjs --permission-mode automatic --max-cost 2 --max-tokens 50000 --effort high "inspect this repository"Select an agent definition the same way. coding is the default; the
deliberately limited junior-developer edits and runs tests but cannot
delegate, reach MCP servers, or drive a browser:
whipcode --agent junior-developer
whipcode run --agent junior-developer --permission-mode automatic "add a unit test for the parser"--resume ID --agent NAME asserts the session's definition and rejects a
conflict. starlark remains the default language; configure rlm.defaultEngine
to change the preference for new sessions. JavaScript runs in bundled QuickJS/WASM, without
Node.js or npm. Children inherit their root's language. Forks preserve it;
--resume ID --rlm-engine NAME asserts the existing selection and rejects a
conflict. Headless --max-cost (USD) and --max-tokens cap the entire session
model ledger, including descendants; --permission-mode automatic explicitly
selects the existing Full Access policy for a new session.
Drop a .mcp.json in a repository to make its servers available through the
selected execution language’s mcp module. Use /mcp for connection status and /agents for the
durable recursive tree.
Manage the local runtime daemon directly when testing or upgrading a checkout:
whipcode daemon status [--json]
whipcode daemon start
whipcode daemon stop [--timeout 10s] [--force]
whipcode daemon restart [--timeout 10s] [--force]
whipcode daemon logs [-f] [-n 200]restart replaces the running daemon with the currently invoked whipcode
binary. Normal stop and restart checkpoint durable state first; --force is
only a fallback for an unresponsive daemon.
The next train is v1.0.1-alpha.N (N is the existing workflow run number), then
approved stable v1.0.1. Development pushes can publish alpha after enablement;
main pushes run CI only, with stable manually approved. See release operations
for dispatch rules and rollout acceptance requirements. Raw CLI assets are
whipcode-<linux|darwin>-<x64|arm64>; Desktop downloads are
whipcode-desktop-darwin-arm64.dmg and .zip. Versions live in the release tag
and CDN directory, not these basenames.
whipcode update
whipcode daemon start
whipcode webThe daemon opens only its Unix socket by default. whipcode web requires that
daemon to be running, starts a separate foreground gateway, opens the browser,
and waits; --no-open skips the browser but still stays running. Ctrl+C stops
the gateway without stopping daemon work. WHIPCODE_NETWORK=1 explicitly opts
into managed gateway startup; WHIPCODE_LISTEN alone does not. See
web access for fixed ports,
open-existing --url mode, compatibility, and trusted proxy configuration.
whipcode update replaces the invoked standalone installation and requests only
its daemon's restart. An alpha build follows CLI channel prerelease; a stable
build follows stable. WHIPCODE_CHANNEL can explicitly select either.
Prerelease discovery chooses the highest eligible SemVer and permits graduation
to stable: 1.0.1-alpha.N sorts above 1.0.0, but below stable 1.0.1.
Desktop-owned backends refuse independent CLI updates.
To choose a destination for an exact release, replace <tag> with its published
tag. A pinned installer can roll back executable bytes; it does not make newer
saved state compatible with an older backend:
curl -fsSL https://github.com/context-labs/whip/releases/download/<tag>/install.sh \
| WHIPCODE_BIN_DIR="$HOME/.local/bin" shTo request the newest stable instead, change install.sh to latest.sh. An old
snapshot of latest.sh still resolves the stable version dynamically; it does not
update its own installer implementation.
The installer verifies a complete platform asset set and SHA-256 checksums before atomic replacement. Old CLI tags and Desktop tags are not candidates.
Alpha still installs Whip Beta / Desktop channel beta. New Beta builds use
https://whipcode-alpha-releases.inference.net; stable downloads/updates do not change.
Track release/update verification separately in the acceptance checklist.
Existing Beta testers: after the first new alpha is published, quit Whip Beta
and manually install that release's signed
whipcode-desktop-darwin-arm64.dmg from GitHub Releases once. Keep local data;
do not run the pre-reset cleanup just to switch feeds. Old Beta apps retain their
embedded old feed, which stays readable but stops advancing after cutover; there
is no transparent redirect. The newly signed app embeds the isolated feed for
subsequent updates. This does not migrate incompatible saved state or silently
replace a standalone/remote daemon. Follow the ownership and restart rules below.
Every macOS desktop release, including betas, bundles its matching whipcode backend. It uses that bundled build for installation and managed upgrades; it does not fetch an independently updated standalone CLI binary. Desktop and CLI artifacts share a release version, but the app owns its bundled backend updates. Copying the app into Applications alone does not replace an existing binary.
On a clean Mac, choose Set up this Mac on the welcome screen. It installs the
verified bundled backend (default: ~/.local/bin/whipcode), connects, and opens
provider setup. An existing compatible installation is reused. Desktop and
terminal share that executable and its daemon under ~/.whipcode.
For manual setup, open Settings → Servers → This Mac → Local server settings
to choose an existing executable (for example, /usr/local/bin/whipcode) or use
Install whipcode. Test Connection reports status without starting work.
Diagnostics, explicit restart, and remote host controls remain available there.
Backend upgrades depend on how the installation is managed:
- Installed through Desktop: Install whipcode records the executable as desktop-managed. After an app upgrade, Desktop updates that same executable to the bundled build and brings its daemon to the matching version. Use Desktop updates to upgrade this installation.
- Existing or manually selected executable: Desktop uses it if compatible, but does not automatically replace or update it. Continue using its standalone installer/update command or source-build workflow. Installing a beta does not automatically enroll an existing binary in desktop-managed updates.
- Remote SSH or URL backend: Update the backend explicitly on the remote machine; upgrading Desktop does not upgrade remote hosts.
Downloading an app update leaves running work alone. Restart and update approves the backend restart as well; after a manual app upgrade, Desktop asks before interrupting a running daemon. A restart can interrupt active work from Desktop, terminal, web, or mobile, while sessions and configuration remain on disk. Stable and beta installations cannot silently take over each other's managed backend.
Desktop uses the private Unix socket and needs no web listener. To add a fixed
web endpoint to its running daemon without a restart, run
WHIPCODE_LISTEN=127.0.0.1:8080 whipcode web. Without an explicit bind the
gateway tries 127.0.0.1:4444, falling back to an ephemeral loopback port only
if occupied. See the desktop guide for packaging, setup, and
backend upgrade details.
For an already-installed post-reset app on an Apple Silicon Mac, use the commands below. This is not the clean-project reset or a migration from old builds:
task update:local
# Equivalent without Task:
npm run update:localThis updates the existing /Applications/Whip.app and its saved whipcode
executable (falling back to /usr/local/bin/whipcode). It runs npm ci, builds
the web UI, Swift helper, Go backend and desktop app from the current working
tree, including uncommitted changes, then signs and verifies the package.
It does not pull Git changes. Run git pull yourself first if desired.
Signing failures stop packaging immediately and report the signer error, before
the installed app or daemon is changed. Vite's large-chunk warning is nonfatal.
Once the build passes verification, the command quits Whip normally, retains the previous app and executable, installs the new app and its exact bundled backend, restarts the shared daemon, checks its build ID and reopens Whip. Running this command interrupts active agent work across connected clients. Sessions, configuration, credentials and app settings stay in place. If Whip has unsaved attachments, resolve its normal quit dialog; the script never force-quits it. macOS may report “User canceled (-128)” while Whip saves drafts asynchronously; the updater waits up to 30 seconds for the app to exit before replacing it. If you cancel the quit dialog or Whip stays open, the update stops with the installed app and backend unchanged. An already open browser tab may need a reload to load the new web UI.
Requirements: Node 24, Go 1.27+, Xcode/Swift and a Developer ID Application signing
identity in your keychain. The script automatically selects the sole identity
matching the installed app's signing team. If there are multiple identities, set
WHIP_DESKTOP_SIGN_IDENTITY to the certificate name or SHA-1; use
WHIP_DESKTOP_TEAM_ID when explicitly choosing another team. There is no sudo
step: the existing app and executable directories must be writable by your user.
The installed app's version and channel are retained by default. Each run gets a
unique local-<timestamp>-<commit> backend build ID. WHIP_DESKTOP_VERSION and
WHIPCODE_VERSION can override these values. Local builds have release updates
disabled. Notarization is optional: set WHIP_DESKTOP_NOTARIZE=1 and
WHIP_DESKTOP_NOTARY_PROFILE to your saved notarytool keychain profile, or use
the API credentials supported by desktop packaging.
# Choose another installed app; its saved executable and channel are respected.
task update:local -- --app "/Applications/Whip Beta.app"
# Explicit backend path must match Desktop's saved choice, if one exists.
task update:local -- --executable "$HOME/.local/bin/whipcode"
task update:local -- --helpThe normal runtime home is ~/.whipcode; WHIPCODE_HOME remains supported.
The daemon inherits your shell's runtime environment. Ordinary startup is
socket-only; WHIPCODE_NETWORK=1 explicitly opts into an owned gateway child,
and WHIPCODE_LISTEN alone does not. Export any custom runtime environment
before invoking the command. A foreground whipcode web can serve a compatible
running daemon without another restart.
The command prints a .whip-local-update-* directory beside the installed app
containing previous.app and whipcode.previous. These copies are retained until
you remove them. Build or staging failures leave the installed app and daemon
untouched. If a later step fails, fix the reported error and rerun the command;
do not automatically restore an older backend after a database schema upgrade.
Concurrent runs from the same checkout are refused. If an interrupted run leaves
apps/desktop/.update-local.lock, inspect its pid file and remove the lock
directory only after that process has exited. Test the workflow without touching
your installation with task test:update-local.
From the checkout you want to test, run:
task onboarding:docker
# Equivalent without Task:
node scripts/onboarding-docker.mjsThis builds your current working files, including uncommitted and untracked
source, opens a clean TUI in the current terminal, and serves the production web
app at http://localhost:4000. Both clients share one daemon inside the container.
Provider setup in either client becomes available to the other. Ordinary checkouts
and linked Git worktrees both work; no commit, local Go installation, or host
npm ci is required.
Requirements: Node 24, Git, an interactive terminal, a running local Linux Docker engine (such as OrbStack or Docker Desktop), and an available port 4000. Dependencies and compilers are installed during the image build. The first run downloads them; later runs reuse Docker's dependency and compilation caches while rebuilding changed source. Each invocation checks the build before starting the container.
The container starts with no saved providers or sessions and no inherited host
credentials. Its test project is a disposable Git repository at /workspace.
The TUI opens directly to its normal composer with the provider connection
dialog. Esc closes the dialog; /connect reopens it.
Your installed Whip, normal daemon, and source files are separate from this test
environment. Quitting the TUI removes the container, its credentials, sessions,
and test files. Run the command again for another clean start; cached builds
remain available. The web app runs for the lifetime of that TUI.
For a clean web onboarding test, use a new private browser session and close the previous private session between runs. Resetting the container does not clear your browser's saved state. To compare initial TUI and web onboarding independently, start a fresh container for each; configuring one client also configures the other.
For Inference.net or OpenAI device login, open the displayed URL on your Mac and approve the code. No additional callback port is needed. Automatic host browser opening, native clipboard integration, and macOS computer tools are unavailable inside this Linux environment.
The launcher prints its unique container name. While it is running, inspect it from another terminal:
docker exec <container-name> whipcode daemon logs -n 60
docker exec <container-name> whipcode daemon status --json
# Stop this test environment from another terminal:
docker stop <container-name>Run task test:onboarding-docker for the launcher and renderer provenance tests.
Container source metadata is explicitly marked local; release builds retain their
normal Git provenance checks and reject artifacts using that local override.