Dev runs
When tesser dev restarts the server
tesser dev reuses the box for this worktree and service. On a box whose
server is already running, it only syncs, and prints when the server started
and that its inputs are unchanged. It starts the server again when:
- the server is not running, or its app crashed under a file watcher
- the manifest or the env changed
- a file
setupordevdepends on changed:- the env files the manifest lists
- any
package.json, lockfile, or toolchain pin such as.nvmrc - a
Dockerfileor compose file - any file the
setupcommand names - any shell script the
devcommand names (a.sh,.bashor.zshfile, or one with no extension) - every file in the manifest’s directory except
.mdfiles and the other services’ manifests
node_modules/.bin/... never forces a restart. A source file
the dev command names, such as src/server.ts in
bun --hot src/server.ts, does not count either, because the server reloads
it.
While tesser dev waits
- It prints the last line of the server’s log every 30 seconds. When the health check keeps returning the same 5xx status, the line says for how long.
- When
setupprints nothing new for 5 minutes, it prints a warning with the last line and keeps waiting. Raise[health] timeoutonly when that line still shows progress.
A service name instead of a box id
tesser status, tesser logs, tesser sync, and tesser wait take a
service name for this worktree’s box of that service.
- When the worktree has no box for it,
status,logs, andwaituse the service’s shared instance, andstatusandlogssay so on stderr. syncnever falls back to the shared instance. It fails and suggeststesser dev <service>.- For a script,
tesser status <service> --json | jq -r .boxIdprints the box id.
Dependencies and shared instances
A dependency with nothing behind it
-
dev,make <service>, andmake --ensure-runningstill start the box, and print one line per such port on stderr: -
When this worktree has a manifest for
api, the line first namestesser dev apiin this worktree, which backs the dependency even when it starts after this box (see Your own box from the same worktree). -
When a
make api --ensure-runninghas started a new shared instance but not switched over yet, that instance is staged, and the line names it:The dependency reaches the new instance as soon as that command finishes, with no wire. If the command is no longer running, running it again with the same commit finishes the switch. -
devprints these lines when it returns: after the service is serving, or just before the error when the run fails, so they come at the end of its output. With--detach, it prints them when the box starts.tesser wait, andtesser sync --restartwithout--detach, print them when they return. Each check reads the box’s current wiring, so a port wired in the meantime is not reported. -
On the box, every connection to that port is reset. While the service runs,
the box notes the reset in the dev log (
tesser logs), at most once a minute per port. On the laptop, the request gets a 503 naming thetesser wirecommand that fixes it.
Your own box from the same worktree
-
A dependency with no wire and no shared instance reaches your own dev box
of that service from the same worktree, if one exists. The worktree is the
folder that
tesser devran in. -
Only boxes you started with
tesser devfrom your own login count. A teammate’s box, a box from another worktree, and a box started with a service-account or CI token never do. - With several such boxes, the newest one wins. Removing it moves the dependency to the next one, or to nothing.
-
A wire or a shared instance always takes precedence over this fallback.
tesser wire <box_id> api --sharedwith no shared instance running says the dependency routes to the same-worktree box instead. -
When a shared instance takes precedence over your own box of that service
from this worktree,
devsays so and prints the wire that routes the dependency to your box:If the box that depends on it started first,dev apiprints the same advice when it returns:Both lines appear only when both boxes are yours. -
devprints the fallback on stderr when it returns: -
tesser wire <box_id>lists such a dependency asapi -> <box_id> (same worktree). -
If another box from the worktree was already running when this one began
backing its dependency,
devprints: - Handing a box to another member clears its worktree, so it stops backing your other boxes.
Waking dependencies
devstarts only the requested services. It wakes the dependencies you own and the shared instances it depends on, and once its own server is ready it waits for them to serve, printing which ones it is waiting on.- If a dependency is removed, its server exits, it is still asleep after 15
seconds, or it does not come up in time,
devreports that it is not serving and finishes anyway.tesser status <box_id>shows where that box is. devnever creates missing dependencies.make --ensure-runningcreates shared instances.
make --ensure-running
- It creates a box, checks out the commit, runs
setupanddev, waits for the health check, and makes the box the org’s shared instance. - With the same commit again, it does nothing and prints the same box id,
unless the shared instance is unhealthy, in which case it runs
setupanddevagain on the same box. With a new commit, it starts a new box, waits until it is healthy, switches over, and removes the old box. - From a worktree that already has its own box of the service, when no shared
instance runs that commit yet, that box becomes the shared instance and
keeps its warm build. This applies only when the box is the size the
manifest sets, is not kept, and has no
--sleep-afterof its own; otherwise a new box is created. The CLI resets the box to the commit, deletes files git neither tracks nor ignores (installs and build output stay), runssetupanddevagain with the org’s env values, waits for the health check, and switches over. The box then belongs to the org, and the worktree’s nexttesser devof the service starts a new box. --restartrunssetupanddevagain on the same box even while the health check passes, for a server that is stuck but still answers it. On a staged or draining instance it fails and changes nothing, and on the current one it does not switch the org over again.- A shared instance belongs to the org, so it cannot be synced to. Its env
comes from
tesser env setand the committed files in the manifest’senv.load.
During a switch
- Both boxes run
dev: the new one from whenmakestarts it, the old one, if awake, until it is removed 60 seconds after the switch. - Both see
TESSER_SLOT=pinned, so a queue keyed onTESSER_SLOThas workers on both commits, and the old commit can take jobs meant for the new one. Removal kills any job still running on the old box. Make jobs safe to retry and to run on either commit. - If a job’s producer and workers run on the same box, key the queue on
TESSER_BOX_IDinstead. Jobs still in the old box’s queue when it is removed never run.
tesser service show
Prints one service’s repo and, for each shared instance, the full commit sha,
the box id, and a tesser ssh command that prints the manifest it runs. That
reads the file on the box, which can differ from the copy committed at that
sha. --json prints the same as JSON.
tesser wire
- It refuses a target that is not a box in your org, has been removed, or runs a different service than the dependency names.
-
After saving, it waits until this laptop’s daemon routes the change. If the
daemon has not loaded the wire after 70 seconds, the command fails, but the
wire stays saved.
tesser daemon stopthentesser userestarts the daemon. -
A wire changes where new connections go but restarts nothing. If the box’s
server ran while the dependency had nothing behind it, its client may have
given up, and requests can hang even after the wire. Then
wireprints: -
A wire names a box and stays put. If that box is removed, the dependency
fails loud instead of falling back to the shared instance. Re-wire it or
return it to
--shared. - A wire connects boxes, whichever worktree or repository they came from.
-
The panel marks a branch
custom wiringwhen a laptop port reaches a different box than the box’s own dependency on that port, and names any route that is failing. Laptop focus can override subtrees without changing wires. -
tesser devreuses the box for a worktree and service, so each simultaneous frontend-plus-backend test needs its own frontend worktree. In a monorepo, run the frontend from the backend change’s worktree. - When both a dashboard and its backend depend on a third service, wire both to the copy meant for the test. Focusing the dashboard brings every reachable service to localhost, but does not fix inconsistent wiring on the boxes.
tesser exec --deps-of
The workbench gets that service’s dependency ports for as long as the command
runs. They resolve exactly as for that service’s box in this worktree, wires
included. --in <service> on its own only changes the working directory to
the service’s root.