tesser --help and every
tesser <command> --help, regenerated from the CLI at each release, so what
your agent reads on the box is what you read here.
tesser
Usage: tesser [options] [command]
persistent cloud boxes for dev servers, tests, and builds; the code stays local
Options:
-v, --version output the version number
-h, --help display help for command
Commands:
version print the CLI version
licenses show bundled rsync's license and extract its complete source
login [options] [target] sign in through the browser or through a grant, and make the chosen org the default
logout revoke the saved token and forget it
whoami [options] the signed-in email, where the org and token came from, and when the token expires
org the org every command runs against
member the org's members (admins only)
grant rules that let an agent platform or CI job sign in as a service account (admins only)
cloud [options] run the org's boxes in your own AWS account
gateway [options] serve shared boxes at <box>.<host>:<port> from inside the org's own AWS account
skill the agent skill: a few lines that point at --help
boxd the agent tesser runs on each box
daemon [options] run the local proxy in the foreground: <box_id>.localhost, bare localhost for focused boxes, the panel, and the tunnels
use [options] [box_id...] focus boxes, last one on top: bare localhost:<port> shows their ports
make [options] [service] create a box and print its id: a workbench, or an instance box for a service
pool boxes kept warm, with a repo's install, for an hour after the last make so make takes seconds
ls|list [options] list the org's boxes, a sortable table in a terminal
top the org's boxes and wiring, live, in a terminal UI
status [options] [box_id] one box in detail; with no id, the current worktree's box
usage [options] the org's meter: credit left, what is awake, and time by size and service
spend-limit [options] [dollars] the most usage past what the plan includes that a month may bill; bare form shows it
update [options] [version] install the latest CLI release, then restart a running daemon on it
sync [options] [box_id] copy the current worktree to a box; with no id, the current worktree's box
env env files on boxes, and the values held for a service's shared instances
exec [options] [box_id] sync the worktree and run a command on a box (the worktree's workbench when no box is named)
dev [options] [service|box_id] start a service's dev server from the current worktree
logs [options] [box_id] the dev server's last 200 lines; with no id, the current worktree's box
sleep <box_id> power a box down; any command targeting it wakes it
wake <box_id> power a box up and wait until it answers
sleep-after [options] [duration] how long your instance boxes sit idle before they sleep; bare form shows it
keep [options] <box_id> never let a box sleep or expire on its own, for a database or anything that must stay up
ssh <box_id|service> [command line...] an interactive shell in ~/workspace, or one command there (no sync first); a service name means its org default box
rm <box_id> remove a box, its disk, and every wire that pointed at it
share [options] <box_id> a review link for a box and everything it depends on; anyone in the org opens it with tesser review
review <link> open a review link: the box and its deps get addresses on this laptop
wire [options] <box_id> [service] [target_box_id] point a box's <service> dependency at a box, or back to the org's shared instance; bare form shows every dep
service the org's service registrations
nuke [options] remove every box in the org, plus every service registration and shared instance; env values survive
help [command] display help for command
How it works
The code stays on the laptop; the compute is a cloud box. tesser mirrors
the current git worktree to a box's ~/workspace and runs commands there.
Every box has a fixed address on the laptop, http://<box_id>.localhost:<port>,
served by tesserd. `dev`, `use`, and `review` start it in the background
when it is not running. If a box address refuses connections, run
`tesser use` with no arguments: it starts tesserd and reports each route.
`login`, `cloud`, and `daemon install` are the human's to run, never yours.
Each worktree gets a workbench for `exec` (tests, typechecks, builds) and
one instance box per service for `dev`. Boxes persist until `rm` and keep
their node_modules; idle ones sleep, and any command targeting one wakes it
(about a minute); `keep` exempts a box that must stay up, like a database.
`tesser ls` finds a box whose id you lost; its last column is the worktree
each box belongs to. Boxes run Ubuntu with Node, Docker, and passwordless
sudo; install anything else with `exec`.
Start here
tesser exec -- pnpm install workbench: setup, tests, typechecks
tesser exec -- pnpm test
BOX=$(tesser dev web) instance box; tell the human: open http://$BOX.localhost:3000
tesser sync "$BOX" ship edits; HMR picks them up. --restart for a new dependency
tesser logs "$BOX" -f dev server output (Ctrl-C detaches)
tesser rm "$BOX" when the worktree is done
Every command explains itself: tesser <command> --help.
Contracts
`make` and `dev` print the box id as their only stdout; progress goes to
stderr. `exec` and `logs` pass the remote exit code through. Read
commands take --json. Everything after -- is exact argv; no shell parses
it. Chain with -- bash -c 'a && b'.
Give the human the box's own URL printed by `dev`. They choose which box
bare localhost:<port> shows from the panel on every page. `top` and bare
`usage` are terminal UIs for a person, never for an agent.
Never
Edit files on the box. The next sync overwrites them; `ssh` is for looking.
Commit on the box. It is a shallow mirror of the local HEAD; commit locally.
--force past the sync guard. It means the box belongs to another worktree;
`make` a new one.
Let the dev server drift ports. Pin the port in its config so a collision
fails loud instead of breaking routing.
Touch a box you did not make. `dev`, `sync`, `wire`, `sleep`, and `rm`
on someone else's box restart their server or repoint their deps. To use
their box, wire yours to it.
Run `tesser use` unless the human asks. It changes what their localhost
shows; the box URL from `dev` is what you hand them.
`rm` never confirms and is unrecoverable.
tesser version
Usage: tesser version [options]
print the CLI version
Options:
-h, --help display help for command
tesser licenses
Usage: tesser licenses [options]
show bundled rsync's license and extract its complete source
Options:
-h, --help display help for command
tesser login
Usage: tesser login [options] [target]
sign in through the browser or through a grant, and make the chosen org the
default
Arguments:
target oidc to exchange an id token through a grant
Options:
--org <org_id> require this org instead of showing the picker
--token <tsr_api_…> save a token made on the dashboard instead of opening a
browser (needs --org)
--grant <grt_id> with oidc: the grant to exchange through (needs --org);
inside GitHub Actions the CLI mints the id token itself,
elsewhere pass --proof
--proof <command> with oidc: a shell command that prints an id token for
audience <control url>; rerun when the token expires
--no-browser print the sign-in URL instead of opening a browser
--ssh the browser is on another machine: approve there and
paste the code it shows here (the default over ssh)
--no-ssh over ssh, still wait for the browser on this machine (it
reaches 127.0.0.1 here, e.g. through a forwarded port)
-h, --help display help for command
tesser logout
Usage: tesser logout [options]
revoke the saved token and forget it
Options:
-h, --help display help for command
tesser whoami
Usage: tesser whoami [options]
the signed-in email, where the org and token came from, and when the token
expires
Options:
--json
-h, --help display help for command
tesser org
Usage: tesser org [options] [command]
the org every command runs against
Options:
-h, --help display help for command
Commands:
ls|list [options] the orgs this laptop is signed in to
use <org_id> make one of them the default
Every command runs in one org; `login` makes the org it authorized the
default. TESSER_ORG=<id> overrides for one shell.
tesser org ls
Usage: tesser org ls|list [options]
the orgs this laptop is signed in to
Options:
--json
-h, --help display help for command
tesser org use
Usage: tesser org use [options] <org_id>
make one of them the default
Options:
-h, --help display help for command
tesser member
Usage: tesser member [options] [command]
the org's members (admins only)
Options:
-h, --help display help for command
Commands:
ls|list [options] list members
add <email|service:name> [role] invite an email address, or create a service
account service:<name>
role <membership_id> <role> change a member's role
rm|remove <membership_id> remove a member and revoke every token they
hold
alias issuer claims that name a member, so a token
exchanged through a grant is attributed to
them
token tokens held by a service account
Admins only. `member add <email>` invites one address. `member add
service:<name>` makes a service account: a
member that never signs in and holds tokens and grants instead. It is
always a member, never an admin. `member token create <membership_id>
--name ci --expires 30d` mints it a token, printed once; `member token ls`
and `rm` manage them. A human mints their own tokens on the dashboard.
An alias pins an issuer claim to a member: `member alias set <membership_id>
https://app.devin.ai requesting_user_email <email>`. When an agent platform
or CI job signs in through a grant (tesser grant --help), the box it makes
is recorded as made for the member the claim names; an alias is for when
the claim does not already match the member's email.
tesser member ls
Usage: tesser member ls|list [options]
list members
Options:
--json
-h, --help display help for command
tesser member add
Usage: tesser member add [options] <email|service:name> [role]
invite an email address, or create a service account service:<name>
Arguments:
email|service:name
role admin or member (choices: "admin", "member", default:
"member")
Options:
-h, --help display help for command
tesser member role
Usage: tesser member role [options] <membership_id> <role>
change a member's role
Arguments:
membership_id
role admin or member (choices: "admin", "member")
Options:
-h, --help display help for command
tesser member rm
Usage: tesser member rm|remove [options] <membership_id>
remove a member and revoke every token they hold
Options:
-h, --help display help for command
tesser member alias
Usage: tesser member alias [options] [command]
issuer claims that name a member, so a token exchanged through a grant is
attributed to them
Options:
-h, --help display help for command
Commands:
set <membership_id> <issuer> <claim> <value> pin an issuer claim to a member
rm|remove <membership_id> <issuer> <claim> <value> drop one alias
help [command] display help for command
tesser member alias set
Usage: tesser member alias set [options] <membership_id> <issuer> <claim> <value>
pin an issuer claim to a member
Arguments:
membership_id
issuer https://app.devin.ai, token.actions.githubusercontent.com, …
claim requesting_user_email, actor_id, …
value
Options:
-h, --help display help for command
tesser member alias rm
Usage: tesser member alias rm|remove [options] <membership_id> <issuer> <claim> <value>
drop one alias
Options:
-h, --help display help for command
tesser member token
Usage: tesser member token [options] [command]
tokens held by a service account
Options:
-h, --help display help for command
Commands:
create [options] <membership_id> mint a token for a service account;
printed once
ls|list [options] <membership_id> list a member's tokens
rm|revoke <membership_id> <token_id> revoke one token
help [command] display help for command
tesser member token create
Usage: tesser member token create [options] <membership_id>
mint a token for a service account; printed once
Options:
--name <name> what holds it: ci, the machine it lives on
--expires <duration> 30d, 12h, 90m; 1h..365d
--role <role> cap the token below the account's role (choices:
"admin", "member")
-h, --help display help for command
tesser member token ls
Usage: tesser member token ls|list [options] <membership_id>
list a member's tokens
Options:
--json
-h, --help display help for command
tesser member token rm
Usage: tesser member token rm|revoke [options] <membership_id> <token_id>
revoke one token
Options:
-h, --help display help for command
tesser grant
Usage: tesser grant [options] [command]
rules that let an agent platform or CI job sign in as a service account (admins
only)
Options:
-h, --help display help for command
Commands:
create [options] <devin|replicas|github:owner/repo> let an issuer's id tokens be exchanged for a service account's tesser token
ls|list [options] list the org's grants
rm|revoke <grant_id> revoke a grant; no more exchanges
Admins only. A grant is a rule, not a secret: id tokens from one issuer
whose claims match the grant's pins may be exchanged at the control plane
for a tesser token acting as one service account until the grant expires.
Its id can sit in a workflow file or an agent's config. Grants are org-
level and always for a service account (tesser member --help); without
--for, one named after the issuer (devin, replicas, github-actions) is used and made
if missing. A person who wants an agent to act as themselves pastes their
own token instead: tesser login --token, or TESSER_TOKEN.
tesser grant create devin --pin org_id=<devin org id>
tesser grant create replicas --pin organization_id=<replicas org id>
tesser grant create github:acme/web pins repository; add --pin ref=refs/heads/main
The command prints the id and the exact `tesser login oidc --org <org>
--grant <id>` line for that issuer. In a GitHub Actions job with
`permissions: id-token: write` the CLI mints the id token itself; for
Devin and Replicas the line carries `--proof '<command>'`, a command that
prints an id token with the control URL as its audience. Either way the CLI proves
again and exchanges again when the token is within a minute of expiring or
is refused. Boxes an agent session makes show its client and session,
`devin · <session>`, are recorded as made for the person the id token
names, and show in that person's dropdown. `grant rm` stops new
exchanges; tokens already minted last until they expire, an hour at most.
tesser grant create
Usage: tesser grant create [options] <devin|replicas|github:owner/repo>
let an issuer's id tokens be exchanged for a service account's tesser token
Options:
--for <membership_id> the service account to act as; without it, one named
devin, replicas, or github-actions, made if missing
--name <name> a label; defaults to the issuer and pins
--expires <duration> 30d, 12h; 1h..365d (default: "90d")
--pin <claim=value> an extra claim the id token must carry (repeatable)
(default: [])
-h, --help display help for command
tesser grant ls
Usage: tesser grant ls|list [options]
list the org's grants
Options:
--json
-h, --help display help for command
tesser grant rm
Usage: tesser grant rm|revoke [options] <grant_id>
revoke a grant; no more exchanges
Options:
-h, --help display help for command
tesser cloud
Usage: tesser cloud [options] [command]
run the org's boxes in your own AWS account
Options:
--json print JSON
-h, --help display help for command
Commands:
status [options] where the org's boxes run, and AWS errors from
the last 7 days
connect [options] check an AWS account and move the org's boxes
there (flags default to the current config once
connected)
check [options] test the connected account end to end, or a
candidate given with the connect flags, without
storing anything
disconnect return the org to tesser's cloud (once it has no
boxes)
template [options] the IAM policies and network rules the org's AWS
account needs
aws-profile [options] [name] this laptop's ~/.aws profile for the org's SSM
sessions, overriding the org's --aws-profile
Admins only, and only when the human asks. The account is set up with the
Pulumi program in the self-hosting docs (tesser cloud template prints the
policies it holds); once it is applied, tesser cloud connect --account <id>
--region <region> checks the account end to end and moves the org there.
tesser cloud check runs the same checks any time. Self-hosted boxes are
reached only through AWS Session Manager. When `ssh` fails asking for an
AWS profile, no profile is set: the org's default is
tesser cloud connect --aws-profile <name>; a laptop overrides it with
tesser cloud aws-profile <name>.
tesser cloud status
Usage: tesser cloud status [options]
where the org's boxes run, and AWS errors from the last 7 days
Options:
--json print JSON
-h, --help display help for command
tesser cloud connect
Usage: tesser cloud connect [options]
check an AWS account and move the org's boxes there (flags default to the
current config once connected)
Options:
--account <id> the AWS account the Pulumi program ran in; finds
its role, instance profile, subnet, and security
group
--region <region>
--role <arn> IAM role tesser assumes
--subnet <id>
--sg <id> security group
--private reach boxes at their private IP
--instance-profile <name> launch boxes with this IAM instance profile;
laptops reach them through Session Manager
--image <ami> launch your own copy of a tesser image, or `tesser`
for tesser's published one
--aws-profile <name> the ~/.aws profile members' laptops use for Session
Manager, unless a laptop sets its own
--sso-start-url <url> the AWS access portal behind that profile
(https://d-1234567890.awsapps.com/start); laptops
missing the profile get it written
--sso-region <region> the region of that IAM Identity Center
--sso-role <name> the permission set members sign in with in the
org's account
--no-sso forget the SSO portal
--env <store> where `tesser env set` values live: tesser
(default) or parameter-store, your account's
Parameter Store under /tesser/<org id>/
--max-boxes <n> the org's own box cap
--crash-output boxd sends a crashed dev server's last 40 log lines
to tesser so `tesser dev` can print them (the
default)
--no-crash-output keep them on the box; `tesser dev` points at
`tesser logs` instead
--json print JSON
-h, --help display help for command
tesser cloud check
Usage: tesser cloud check [options]
test the connected account end to end, or a candidate given with the connect
flags, without storing anything
Options:
--account <id> the AWS account the Pulumi program ran in; finds
its role, instance profile, subnet, and security
group
--region <region>
--role <arn> IAM role tesser assumes
--subnet <id>
--sg <id> security group
--private reach boxes at their private IP
--instance-profile <name> launch boxes with this IAM instance profile;
laptops reach them through Session Manager
--image <ami> launch your own copy of a tesser image, or `tesser`
for tesser's published one
--aws-profile <name> the ~/.aws profile members' laptops use for Session
Manager, unless a laptop sets its own
--sso-start-url <url> the AWS access portal behind that profile
(https://d-1234567890.awsapps.com/start); laptops
missing the profile get it written
--sso-region <region> the region of that IAM Identity Center
--sso-role <name> the permission set members sign in with in the
org's account
--no-sso forget the SSO portal
--env <store> where `tesser env set` values live: tesser
(default) or parameter-store, your account's
Parameter Store under /tesser/<org id>/
--max-boxes <n> the org's own box cap
--crash-output boxd sends a crashed dev server's last 40 log lines
to tesser so `tesser dev` can print them (the
default)
--no-crash-output keep them on the box; `tesser dev` points at
`tesser logs` instead
--json print JSON
-h, --help display help for command
tesser cloud disconnect
Usage: tesser cloud disconnect [options]
return the org to tesser's cloud (once it has no boxes)
Options:
-h, --help display help for command
tesser cloud template
Usage: tesser cloud template [options]
the IAM policies and network rules the org's AWS account needs
Options:
--account <id> fill in this account id
--region <region> fill in this region
--image <ami> pin the launch policy to your own copy of the image
--box-role <name> the IAM role inside the boxes' instance profile, with its
path if any, when it differs from the profile's name
--json print JSON
-h, --help display help for command
tesser cloud aws-profile
Usage: tesser cloud aws-profile [options] [name]
this laptop's ~/.aws profile for the org's SSM sessions, overriding the org's
--aws-profile
Options:
--clear forget the profile
-h, --help display help for command
tesser gateway
Usage: tesser gateway [options] [command]
serve shared boxes at <box>.<host>:<port> from inside the org's own AWS account
Options:
--json print JSON
-h, --help display help for command
Commands:
set [options] point `tesser share` at a gateway, and trust its IAM role
off stop trusting the gateway; share links stop carrying gateway
urls
serve [options] run the gateway behind its load balancer: opens an HTTPS
listener for every port a shared box declares and proxies to
the box's mesh
Admins only, and only for an org running in its own AWS account. The gateway
is a process in that account's VPC (tesser gateway serve) that makes every
shared box answer at https://box-<id>.<host>:<port>, where <host> is the
gateway url's host and <port> any port the box's service declares. Its
Application Load Balancer terminates TLS with an ACM certificate for *.<host>;
the gateway keeps one listener there per shared port and shows the dev server
the address it has on a laptop, localhost:<port>, rewriting redirects back. It wakes a sleeping box on the first request and keeps it
awake while traffic flows. A box is served only while it has a live share
(tesser share <box>); --revoke or expiry takes it off within 15 seconds.
The gateway authenticates to tesser with its IAM role's AWS web identity
token (the account needs outbound identity federation enabled, and the role
sts:GetWebIdentityToken for the tesser API's audience). It does no user
auth: whoever can reach it reaches every shared box, so put it behind the
VPN or an SSO proxy.
tesser gateway set
Usage: tesser gateway set [options]
point `tesser share` at a gateway, and trust its IAM role
Options:
--url <url> the https base URL boxes hang off, like
https://tesser.example.internal
--role <arn> the IAM role the gateway runs as, in the account the boxes run
in
--json print JSON
-h, --help display help for command
tesser gateway off
Usage: tesser gateway off [options]
stop trusting the gateway; share links stop carrying gateway urls
Options:
-h, --help display help for command
tesser gateway serve
Usage: tesser gateway serve [options]
run the gateway behind its load balancer: opens an HTTPS listener for every port
a shared box declares and proxies to the box's mesh
Options:
--org <id> the org whose shared boxes to serve
--bind <address> the address to listen on (default: "0.0.0.0")
--load-balancer <arn> the gateway's Application Load Balancer, which
terminates TLS
--target-group <arn> the target group every listener forwards to: this
gateway on --port
--certificate <arn> the ACM certificate for *.<host> the listeners serve
--port <port> the plain HTTP port the target group forwards to
(default: "8080")
-h, --help display help for command
tesser skill
Usage: tesser skill [options] [command]
the agent skill: a few lines that point at --help
Options:
-h, --help display help for command
Commands:
install [options] write it to ~/.claude/skills/tesser-cli/SKILL.md, or into a
directory
help [command] display help for command
tesser skill install
Usage: tesser skill install [options]
write it to ~/.claude/skills/tesser-cli/SKILL.md, or into a directory
Options:
--dir <path> install into this directory
-h, --help display help for command
tesser boxd
Usage: tesser boxd [options] [command]
the agent tesser runs on each box
Options:
-h, --help display help for command
Commands:
update <box_id> install the control plane's current agent on a box; its dev
server restarts under the new one
help [command] display help for command
`dev`, `sync`, and `exec` bring the agent on the box they target up to
the control plane's version first, restarting its dev server, and say so on
stderr. `boxd update` does the same for one box on purpose, including a
shared instance (admins only); `tesser status` shows the version a box
runs. If it says boxd did not come back, the update did not land within a
minute and the box is still on its old agent: retry, and if it fails again
tesser ssh <box_id> -- journalctl -u tesser-boxd -n 50 says why.
tesser boxd update
Usage: tesser boxd update [options] <box_id>
install the control plane's current agent on a box; its dev server restarts
under the new one
Options:
-h, --help display help for command
tesser daemon
Usage: tesser daemon [options] [command]
run the local proxy in the foreground: <box_id>.localhost, bare localhost for
focused boxes, the panel, and the tunnels
Options:
--port <n> the daemon's own port (default: 3000)
--host <hostname>
--allow-lan also answer the rest of the local network, not only this
machine and Tailscale peers
-h, --help display help for command
Commands:
install [options] run it as a login service (launchd on macOS, systemd --user
on Linux) that survives reboots and crashes
uninstall remove the login service and stop the daemon it runs
stop stop a foreground or background daemon; a login service
needs uninstall
Nobody has to run this. `dev`, `use`, and `review` start tesserd in the
background when it is not answering, on TESSER_DAEMON_PORT (3000), logging to
<state dir>/daemon.log; `daemon stop` ends it. `daemon install` makes it a
login service instead (launchd on macOS, systemd --user on Linux) that comes
back after reboots and crashes and picks up `tesser update` on its own;
`daemon uninstall` removes it. Bare `tesser daemon` runs it in this
terminal, for watching it.
If something else holds port 3000, --port 3300 moves the viewport and `dev`
says which port to open. A local process already bound to a declared port
wins over the box's door silently: lsof -i :<port>.
tesser daemon install
Usage: tesser daemon install [options]
run it as a login service (launchd on macOS, systemd --user on Linux) that
survives reboots and crashes
Options:
--port <n> the daemon's own port (default: 3000)
--allow-lan also answer the rest of the local network
-h, --help display help for command
tesser daemon uninstall
Usage: tesser daemon uninstall [options]
remove the login service and stop the daemon it runs
Options:
-h, --help display help for command
tesser daemon stop
Usage: tesser daemon stop [options]
stop a foreground or background daemon; a login service needs uninstall
Options:
-h, --help display help for command
tesser use
Usage: tesser use [options] [box_id...]
focus boxes, last one on top: bare localhost:<port> shows their ports
Options:
--off unfocus instead
--json with no box ids, the daemon's routes as JSON
-h, --help display help for command
tesser make
Usage: tesser make [options] [service]
create a box and print its id: a workbench, or an instance box for a service
Options:
--ensure-running <sha> the org's shared instance of the service at this
commit
--size <size> (choices: "small", "standard", "large", "xlarge")
-h, --help display help for command
A workbench (no service) or an instance box for a service. Claims a
prewarmed pool box of its size in seconds when one exists (tesser pool
--help), else cold-boots in about 90s. A brand-new box warms its package
stores from awake org boxes, and its node_modules from one on the same repo;
the first `dev` or `exec` waits for that copy.
--size picks RAM and CPU. Standard is 2 vCPU and 8 GB; each step doubles. A
manifest's `size` sets the default.
--ensure-running <sha> runs the org's shared instance of the service at a
commit (resolved in the current worktree), waits for it to be healthy, and
switches the org over to it. This creates shared instances, not personal
boxes. `tesser service ls` shows every one.
If the org is at its box limit, `tesser rm` an idle box; `tesser sleep`
does not help, since the cap counts boxes, not awake ones.
tesser pool
Usage: tesser pool [options] [command]
boxes kept warm, with a repo's install, for an hour after the last make so make
takes seconds
Options:
-h, --help display help for command
Commands:
target [options] [n] keep N boxes of a size warm with this repo's install; 0
turns them off
ls [options] list unclaimed pool boxes
drain remove every unclaimed pool box
help [command] display help for command
`pool target` run in a repo keeps boxes that already hold that repo's
node_modules, copied from a teammate's box on the same repo, so `make`,
`exec`, and `dev` there skip the copy. Only a make in that repo claims
them. With --any-repo the boxes are blank and any make can claim one.
Unclaimed pool boxes self-destruct an hour after the last make they could
serve, and after 6 hours whatever happens.
tesser pool target
Usage: tesser pool target [options] [n]
keep N boxes of a size warm with this repo's install; 0 turns them off
Arguments:
n 0-8 (default: 2)
Options:
--size <size> (choices: "small", "standard", "large", "xlarge", default:
"standard")
--any-repo blank boxes any make can claim, not this repo's
-h, --help display help for command
tesser pool ls
Usage: tesser pool ls [options]
list unclaimed pool boxes
Options:
--json
-h, --help display help for command
tesser pool drain
Usage: tesser pool drain [options]
remove every unclaimed pool box
Options:
-h, --help display help for command
tesser ls
Usage: tesser ls|list [options]
list the org's boxes, a sortable table in a terminal
Options:
--json
-h, --help display help for command
tesser top
Usage: tesser top [options]
the org's boxes and wiring, live, in a terminal UI
Options:
-h, --help display help for command
tesser status
Usage: tesser status [options] [box_id]
one box in detail; with no id, the current worktree's box
Options:
--json
-h, --help display help for command
Presence is boxd's socket; instance is whether the dev server is actually
up: none, exited, or running on :3000 (healthy). Trust the instance column,
not presence.
tesser usage
Usage: tesser usage [options]
the org's meter: credit left, what is awake, and time by size and service
Options:
--json
-h, --help display help for command
tesser spend-limit
Usage: tesser spend-limit [options] [dollars]
the most usage past what the plan includes that a month may bill; bare form
shows it
Arguments:
dollars 50, 12.50
Options:
--off no limit: bill all usage as you go
-h, --help display help for command
Pro and Team bill usage past what the plan includes. The spend limit caps
that extra, per month: when the org reaches it, its awake boxes sleep and
launches and wakes are refused until an admin raises it or the month resets.
Hobby has no extra to cap; it already stops at its included usage. Admins
only. Do not change it unless the user explicitly asks.
tesser update
Usage: tesser update [options] [version]
install the latest CLI release, then restart a running daemon on it
Arguments:
version a release to install instead of the latest
Options:
--check only say whether a newer release exists
-h, --help display help for command
tesser sync
Usage: tesser sync [options] [box_id]
copy the current worktree to a box; with no id, the current worktree's box
Options:
--restart run the manifest's setup and dev again after the sync
--detach with --restart, return without waiting for the port
--force sync even if it would delete most of the files on the box
-h, --help display help for command
Respects .gitignore, so .env.local never reaches the box on its own. Either
list it under [env] files in the manifest (then every sync ships it) or send
it once with `tesser env push <box_id>`. After a push or an edit:
tesser sync <box_id> --restart.
The guard: syncing worktree B to a box made from worktree A would replace
its whole workspace. Do not --force past it; `make` a new box. A shared
instance's checkout is immutable and refuses sync entirely.
The box's repo is a shallow mirror of the worktree's HEAD. `git status`,
`diff`, and `rev-parse` behave normally; `git log` shows one commit, and
any commit or branch made on the box is wiped by the next sync.
tesser env
Usage: tesser env [options] [command]
env files on boxes, and the values held for a service's shared instances
Options:
-h, --help display help for command
Commands:
push <box_id> [file...] send gitignored .env* files to a box (every one at the worktree root, or the files named)
set [options] <service> [KEY=VALUE...] set values for a service's shared instances
unset <service> <KEY...> drop values
ls <service> the names set, and required names still unset
help [command] display help for command
Two different things. `env push` sends gitignored files from the worktree
to one box (default: every gitignored .env* at the worktree root). `env set`
holds values in the control plane that every `dev` run of that service
gets, dev boxes and shared instances alike; `exec` does not get them.
`env ls` also shows required names still unset. Names that make a shell,
loader, interpreter or package manager run code (PATH, NODE_OPTIONS, LD_*,
GIT_*, npm_config_*, YARN_*, ...) are refused: the box never takes them
from the control plane. Set those in the manifest's run.dev instead, e.g.
dev = "NODE_OPTIONS=--max-old-space-size=4096 pnpm dev".
Keep secrets out of shell history and the process list: a bare KEY reads its
value from stdin, and --from-file takes KEY=VALUE lines (blank lines, #
comments, and a leading export are skipped; a value wrapped in matching
quotes loses them; nothing else is interpreted).
tesser env set api STRIPE_KEY < ~/.stripe-key
tesser env set api --from-file .env.production
tesser env push
Usage: tesser env push [options] <box_id> [file...]
send gitignored .env* files to a box (every one at the worktree root, or the
files named)
Options:
-h, --help display help for command
tesser env set
Usage: tesser env set <service> [KEY=VALUE|KEY...] [--from-file <path>]
set values for a service's shared instances
Arguments:
service
KEY=VALUE a bare KEY reads its value from stdin
Options:
--from-file <path> KEY=VALUE lines (- for stdin); a value in matching quotes
loses them, nothing else is interpreted
-h, --help display help for command
tesser env unset
Usage: tesser env unset [options] <service> <KEY...>
drop values
Options:
-h, --help display help for command
tesser env ls
Usage: tesser env ls [options] <service>
the names set, and required names still unset
Options:
-h, --help display help for command
tesser exec
Usage: tesser exec [options] [box_id] -- <cmd...>
sync the worktree and run a command on a box (the worktree's workbench when no
box is named)
Options:
--in <service> run in the service's root directory
--deps-of <service> give the box the service's dependency ports for the
duration
--force sync even if it would delete most of the files on the box
-h, --help display help for command
Runs on the worktree's workbench when no box is named, creating one the
first time. The workbench never runs a dev server; tests, typechecks,
installs and builds belong there. Syncs the worktree first. The remote exit
code is yours.
--deps-of <service> gives the box that service's dependency ports for one
run. Values held by `tesser env set` are in the environment: a service box
gets its service's, a workbench gets every value its repo's services agree
on (a key two of them set differently is left out).
tesser dev
Usage: tesser dev [options] [service|box_id]
start a service's dev server from the current worktree
Options:
--force sync even if it would delete most of the files on
the box
--detach return without waiting for the port
--sleep-after <duration> the box sleeps after this long idle (30m, 4h), over
your sleep-after
-h, --help display help for command
Runs the manifest's setup, then dev, and waits for the primary port. Reuses
the box for (worktree, service): running it again restarts the server on the
same box, which is also how you recover a crash. Each simultaneous setup of
the same service needs its own worktree.
If the run dies before the port listens, prints the log tail and exits 1.
Usually a missing env var (tesser env --help) or a port that drifted because
the dev server found its port taken. If setup is just slow, raise [health]
timeout in the manifest. A new box takes about 90 seconds to launch and
setup can take many minutes more; do not `rm` a box that only looks hung.
Waits on the box's own port, never its deps'. A box started before the infra
it needs lands against a dead port, and a client that started while nothing
was behind its dep can keep a dead connection (redis loops on EPIPE instead
of reconnecting). Once the dep is up, or after `wire`:
tesser sync <box_id> --restart.
Deps resolve to a wire, else the org's shared instance of that service, else
fail loud. Nothing is ever wired for you, and starting a second service's
box never rewires anything (tesser wire --help). A manifest edit does not
hot-register; re-run `dev` after changing one.
The box runs the manifest it was synced, never a command from anywhere
else; a one-off command is tesser exec. Manifests: tesser service --help.
tesser logs
Usage: tesser logs [options] [box_id]
the dev server's last 200 lines; with no id, the current worktree's box
Options:
-f, --follow keep following
-h, --help display help for command
A 200-line tail of the current run. Each `dev` or restart rotates the log:
~/.tesser/dev.log is this run, dev.log.1 the one before. For a line the tail
has scrolled past: tesser ssh <box_id> -- bash -c 'grep -c "..." ~/.tesser/dev.log'.
tesser sleep
Usage: tesser sleep [options] <box_id>
power a box down; any command targeting it wakes it
Options:
-h, --help display help for command
Idle boxes sleep on their own: workbenches after 10 minutes, instance boxes
after 2 hours (`tesser sleep-after` changes yours). A box asleep for 16 hours is removed. Disk and
id persist through sleep; any command targeting the box wakes it, about a
minute. A running dev server does not count as activity; proxied traffic
does.
tesser wake
Usage: tesser wake [options] <box_id>
power a box up and wait until it answers
Options:
-h, --help display help for command
tesser sleep-after
Usage: tesser sleep-after [options] [duration]
how long your instance boxes sit idle before they sleep; bare form shows it
Arguments:
duration 30m, 4h; 5m to 24h
Options:
--box <box_id> set one box's clock instead, over its owner's
--default back to the default: the org's for you, the owner's for a box
-h, --help display help for command
Your own idle clock, per org: every instance box you own sleeps this long
after its last activity instead of the 2 hour default. Workbenches keep
their 10 minutes. Takes effect on your existing boxes immediately, so a
box already idle longer than the new value sleeps now.
`--box <box_id>` (or `tesser dev --sleep-after`) sets one box's clock, any
class, over its owner's. A pool claim starts a box with none.
tesser keep
Usage: tesser keep [options] <box_id>
never let a box sleep or expire on its own, for a database or anything that must
stay up
Options:
--off back to the idle clock
-h, --help display help for command
A kept box is exempt from the idle clock: it never sleeps on its own and is
never removed for being asleep too long. Use it for a database or anything
the rest of the org depends on. It bills for every second it is awake, so
do not run this unless the user explicitly asks for it.
`keep` wakes the box if it is asleep. `sleep` and `rm` still act
immediately; a kept box put to sleep stays asleep until something targets it.
`keep --off` returns it to the idle clock.
tesser ssh
Usage: tesser ssh <box_id|service> ['<command line>' | -- <cmd...>]
an interactive shell in ~/workspace, or one command there (no sync first); a
service name means its org default box
Options:
-h, --help display help for command
For looking, never editing: the next sync overwrites the box. A quoted
command line runs in the box's shell, as with ssh: tesser ssh <box_id>
'git status'; after --, the words are passed exactly. A service
name instead of a box id lands on that service's org default, the shared
instance any member can run scripts against:
tesser ssh api -- bun run scripts/backfill.ts. One command per ssh;
chained commands often come back empty over Session Manager. If ssh asks
for an AWS profile, the org runs its boxes in its own AWS account and no
profile is set: an admin sets the org's default with
tesser cloud connect --aws-profile, or this laptop names its own with
tesser cloud aws-profile.
tesser rm
Usage: tesser rm [options] <box_id>
remove a box, its disk, and every wire that pointed at it
Options:
-h, --help display help for command
tesser share
Usage: tesser share [options] <box_id>
a review link for a box and everything it depends on; anyone in the org opens it
with tesser review
Options:
--ttl <duration> how long the link works (12h, 7d); default 7d
--revoke end every review link for the box
-h, --help display help for command
tesser review
Usage: tesser review [options] <link>
open a review link: the box and its deps get addresses on this laptop
Arguments:
link the https://tesser.sh/r#... link, or its token
Options:
-h, --help display help for command
tesser wire
Usage: tesser wire <box_id> [<service> <target_box_id|--shared>]
point a box's <service> dependency at a box, or back to the org's shared
instance; bare form shows every dep
Options:
--shared back to the org's shared instance
-h, --help display help for command
How deps resolve
A manifest's [deps] maps loopback ports on the box to other services, so
the app keeps its localhost:… config. Each dep port reaches, in order: the
box it is wired to, else the org's shared instance of that service, else
nothing, and the port fails loud. Nothing is ever wired for you. A
single-service change needs no wiring: `tesser dev web` against the
shared api just works.
Two dev boxes that talk to each other
API=$(tesser dev api) in the backend worktree
WEB=$(tesser dev web) in the frontend worktree
tesser wire "$WEB" api "$API" the human opens http://$WEB.localhost:3000
tesser sync "$WEB" --restart if web started before the wire
tesser wire "$WEB" api --shared done: back to the shared api
When the frontend lives in a repo you are not editing, make a worktree of
it and `dev` from there: git -C ../frontend worktree add /tmp/web-<branch>
origin/main. `dev` reuses the box for (worktree, service), so each
simultaneous setup needs its own worktree.
Bare `tesser wire <box_id>` shows where every dep points. `tesser rm`
removes the wires that pointed at the box; a wire whose target is gone
fails loud, so re-wire it or return it to --shared. The org's shared
instances never point at anyone's dev box.
Browser-testing a backend change
A backend box alone is not a browser test. Run a frontend box of your own
from a worktree of the frontend repo, wire it to your backend box, leave
unchanged deps on their shared instances, and return the frontend's URL
with the wiring. One frontend cannot show two people different backends.
Unit tests and builds alone never need a frontend.
How a box addresses another box
Two ways, for different questions. A wired dep port is 127.0.0.1:<dep port>
on the box and answers whatever Host header is sent: use it when the app's
config names a fixed port and you want to swap what sits behind it.
http://<box_id>.localhost:<port> works from a box too: every box gets a
door for each peer in the org, so one box can name another directly. Use
it when a single box has to reach many targets, which a dep port cannot
express; one dep is one target. The run command sees its own box as
TESSER_BOX_ID and TESSER_BOX_URL (first declared port), so a dev box can
hand its address to a shared service, for webhooks say. It also gets
TESSER_SLOT: which boxes share backing state (queue names, a redis db).
Every shared instance is `pinned`; a dev box is its worktree's folder plus
its owner, so a worktree's cohort shares one slot and nobody else's does,
and a branch switch moves nothing. Key shared-infra names on it, never
on the checkout's branch or sha.
The laptop's proxy serves only boxes this laptop started. A shared
instance's <box_id>.localhost answers 404 (unknown box) from the laptop;
reach those from a box. If <box_id>.localhost resolves to ::1 from a box,
that box's peer doors never installed: `grep box_ /etc/hosts` there
should list every peer in the org, and `journalctl -u tesser-boxd` says
why not. Both boxes need a current agent: `tesser status`, then
`tesser boxd update`.
tesser service
Usage: tesser service [options] [command]
the org's service registrations
Options:
-h, --help display help for command
Commands:
ls|list [options] each service's shared instances; worktree manifests the org
has never seen show as unregistered
rm <name> forget a service: its shared instances and env values
A service is a TOML file at .claude/skills/devboxes/<service>.toml. The file
name is the service name, and names are org-global. Every .toml in that
directory is read as a manifest. .claude/skills/tesser, .agents/skills/devboxes
and .agents/skills/tesser are read too; manifests in two of them is an error. A manifest carries facts only; secret
values live in the control plane (`tesser env set`), never in the file.
root = "apps/web" optional: the service's directory, relative to the repo root
ports = [3000] required; several allowed; first = primary
size = "standard" optional default for make/dev: small|standard|large|xlarge
box_address = true optional: a page opened on bare localhost moves to <box_id>.localhost
[run] required, both keys
setup = "pnpm install" idempotent environment recipe, runs before dev
dev = "pnpm dev" the server; must listen on the primary port
[health] optional
path = "/healthz" probed on the primary port
timeout = "90s" how long dev waits for the port ("500ms", "90s", "2m")
[deps] optional
5001 = "backend" localhost:5001 on this box reaches backend's primary port
9091 = "search:9090" a specific port of a dependency
[env] optional
files = [".env.local"] gitignored files every sync ships, relative to root
required = ["DATABASE_URL"] names `tesser env set <service> KEY=VALUE` must hold
Rules
Own ports and dep ports share the box's loopback, so a dep's local port
cannot be one of the service's own ports. Declared ports may bind
127.0.0.1 or 0.0.0.0; either works, and an all-interfaces bind is not
public. The recipe runs as `exec <cmd>`, so a dev that starts with a
shell builtin dies as `exec: set: not found`; wrap it in a script. A
manifest edit does not hot-register; re-run `dev` after changing one.
`service ls` prints one line per service: ports, the org's default box (-
when none), and each shared instance as state sha power. Manifests in this worktree the
org has never seen show as unregistered. Run it before `dev` when a dep
might have nothing behind it. `service rm <name>` unregisters a service and
removes its shared instances and env; dev boxes stay.
tesser service ls
Usage: tesser service ls|list [options]
each service's shared instances; worktree manifests the org has never seen show
as unregistered
Options:
--json
-h, --help display help for command
tesser service rm
Usage: tesser service rm [options] <name>
forget a service: its shared instances and env values
Options:
-h, --help display help for command
tesser nuke
Usage: tesser nuke [options]
remove every box in the org, plus every service registration and shared
instance; env values survive
Options:
--force skip the confirmation
-h, --help display help for command