Workspaces
How a project's toolchain gets onto the computer with Nix, where it is kept, and why there is no apt or sudo.
A guide to Hotline Computer · Reviewed 2026-11-02 · Markdown
The image has a desktop, a browser and Nix, and no language toolchains: a
project names what it needs, and the computer prepares it in that project's
workspace. The agent's state guide has the full manifest format; this is
how it works underneath.
Preparing
Start a session with state info and state guide. The guide and its
SHA-256 come from the running binary, so every client gets instructions that
match its image. Then prepare the packages the repository needs:
{"action":"prepare","packages":["nodejs","pnpm"],"workspace":"/home/agent/src/project"}
Or use the repository's own flake, including a named dev shell:
{"action":"prepare","flake":".#dev","workspace":"/home/agent/src/project"}
Package names are Nixpkgs attribute paths. Without packages or flake, the
saved definition is reused, or a root flake.nix is found on first use.
There are no language or framework presets. state catalog lists the inputs
and the default Nixpkgs pin.
Preparation returns a managed job, or ready:true when the packages are
cached. Once it succeeds, jobs whose cwd is inside the workspace get the
exported environment, and a job's own env wins. A failed preparation keeps
the previous environment.
Storage
The workspace owns .hotline/environment-spec.json, and .hotline/nix/
holds the generated flake and lock. A package definition keeps its Nixpkgs
revision across Computer upgrades. Shared caches live under
~/.cache/hotline/environments, keyed by recipe and architecture rather
than by Computer version.
The image keeps nothing of its own in the home: its terminal configuration,
bash rc and Chromium policy live under /etc. So a home on a volume carries
the prepared environments, their cache, the jobs and their output, the shell
history and the browser profile across a recreate, for an upgrade or a
restart.
Flakes
A repository flake is evaluated again on each preparation, reusing Nix's
store. An existing lock is never updated silently; first use may create one.
Shell hooks run during preparation and their exported variables are kept.
Aliases, functions and hooks that must run for every command need an
explicit nix develop --command …. To change a package environment, edit its
generated flake and prepare with "flake":".hotline/nix".
Software
Nothing runs as root, nothing can elevate, and the image has no apt or
sudo. Software comes in this order: what the computer prepares, then Nix by
hand (nix shell nixpkgs#<name> for one tool), then what the image already
has. A .deb or a system-wide install belongs in an image build.
An AppImage runs without FUSE, which a container cannot offer: the image sets
APPIMAGE_EXTRACT_AND_RUN=1 and carries every library on the AppImage
exclude list, so an AppImage built anywhere finds what it expects.
Artifacts
files download takes a URL or a GitHub release asset, with an optional
SHA-256 check; an asset pattern must match exactly one file. extract needs
a new destination and refuses traversal, links, special files and archives
that expand past 1 GiB. run runs bash, sh and python3 scripts. All three
are managed jobs, with the same status, progress and cancellation as shell
commands.