Machine commands
The polaris commands on every Machine, the tools Machines come with, and how to write setup scripts.
Every Machine has a polaris command that connects it to Polaris: it opens
Previews, shares screenshots, gives commands your variables, keeps long jobs
running and gets cloud credentials. The agent already knows these commands and
runs them when you ask, so you rarely need them yourself. Use this page to run
one in the Terminal, to write setup scripts, or to see what you
can ask the agent for.
Some commands act for a Session, so they work only in the agent’s shell and
refuse in a Terminal you open: polaris port (except url and logs),
polaris services start, polaris share, polaris feedback,
polaris notify and polaris session. Ask the agent to run those.
Run polaris --help on a Machine to list its commands. If a Machine doesn’t
know a command on this page, start a new Session to get a new Machine. The CLI
on your own computer is a different tool; see Polaris CLI.
Previews
| Command | What it does |
|---|---|
polaris port announce <port> |
Opens the web server on that port as a Preview and prints its link. Add --label "<name>" to show a name instead of the port. |
polaris port announce <port> -- <command> |
Also keeps the server running: Polaris starts the command, starts it again if it fails, and starts it again each time the Machine wakes. After five failures within five minutes it stops trying; fix the command, run polaris port retire <port>, then announce it again. |
polaris port check <port> [path] |
Checks that the Preview loads end to end and shows the kept-running server’s state. |
polaris port logs <port> |
Shows the end of a kept-running server’s output. |
polaris port url <port> |
Prints the Preview link without opening it, so you can configure your app before it starts. |
polaris port retire <port> |
Closes the Preview and stops its kept-running server. |
polaris services list |
Lists the dev servers in the repository’s .agents/services.yaml, with their ports and commands. Names the first problem in a file Polaris can’t read. |
polaris services start <name> |
Starts one of those servers and keeps it running, as polaris port announce <port> --label "<label>" -- <command> would from its folder, and prints its link. |
- The server must listen on
0.0.0.0. Make it fail rather than move to another port if the port is taken, for example with Vite’s--strictPort. - A kept-running server gets the Project’s
variables,
PORTset to its port andPOLARIS_PREVIEW_ORIGINset to its Preview link. Use the link where your app writes its own address, such as an OAuth redirect. - To change a kept-running server’s command, retire the port first.
Share images and videos
polaris share <path>
Polaris checks the file, then prints a public link, markdown to paste into
a pull request or issue, and when the file expires. If it says the file is
still processing, run polaris share --status <file id> <attempt id> with the
IDs it printed. Shared files also appear in the Session’s
Artifacts tab.
| Type | Formats | Largest |
|---|---|---|
| Images | PNG, JPEG, GIF, WebP | 10 MB |
| Videos | MP4, WebM | 100 MB and 10 minutes |
Anyone with the link can open the file without signing in, so don’t share anything that shows secrets or private data. Organization admins turn sharing on or off and choose how long files are kept (Keep files for, 1 year by default) in Settings → General → Shared files. Turning sharing off stops existing links from working.
Common messages:
this file type isn't supported: share a PNG, JPEG, GIF, WebP, MP4 or WebM.this video format isn't supported: export it again as MP4 (H.264) or WebM (VP9).sharing is turned off for this organization: ask an organization admin to turn it on.this organization reached today's 1 GB sharing limit: try again after midnight UTC, or share a smaller file.
Environment variables
| Command | What it does |
|---|---|
polaris env list |
Lists the names of the Project’s variables and whether each is Config or a Secret, without values. |
polaris env run -- <command> |
Runs a command with the Project’s current variables. |
The agent’s own shell and Terminal shells don’t get the Project’s
variables on their own. Start a command with
polaris env run -- to give it them:
polaris env run -- pnpm test:integration
Each command gets the current values when it starts; a command that is already running keeps the values it started with. A key kept off the Machine arrives as a placeholder, and Polaris adds the real key when the request leaves the Machine.
Workspace setup
| Command | What it does |
|---|---|
polaris setup status |
Shows each setup script’s state, with a failure’s reason and exit code, and whether the first Turn waited for setup. |
polaris setup log |
Shows the output of the Project setup script and .agents/setup. |
polaris setup log resume |
Shows the output of the latest .agents/resume run. |
polaris setup log --tail 50 |
Shows only the last 50 lines. Works with resume too. |
polaris setup status prints one line per script:
Project setup script: absent
.agents/setup: succeeded
.agents/resume: succeeded
setup mode: the first Turn does not wait for setup
Logs hide known secret values and keep the first 5 MB of output. Each resume run replaces the previous resume log.
When scripts run
| Script | When it runs |
|---|---|
| Project setup script | First, on a new Machine. It’s saved in Project settings, not in the repository. |
.agents/setup |
Once, on a new Machine, after the Project setup script. |
.agents/resume |
After setup on a new Machine, whether setup succeeded or failed, and first on every wake. Messages don’t wait for it unless Start Turns during resume is off; then a message waits for it for at most 10 seconds. |
Polaris never runs setup again on the same Machine, not even after a failure. Scripts have no time limit, but Polaris keeps the Machine awake for setup for only 60 minutes, so keep setup well under an hour.
Writing setup scripts
-
Start with a shebang, such as
#!/usr/bin/env bash, followed byset -euo pipefail. -
Make each script safe to run twice. Check what is already installed or running before you change it, and test it twice from the repository root.
-
Expect a short
PATH. Scripts run from the repository root as your Machine user, with no terminal and no input.PATHis/usr/local/polaris/bin:/usr/local/bin:/usr/bin:/bin, so call a tool installed elsewhere, such as under~/.local/bin, by its full path. -
sudoworks on most Machines. Use it to install system packages. On some Machinessudoasks for a password, so a script that needs it fails there; keep that setup in user space, or start a new Session to get a new Machine. -
Commit the executable bit. A script without it fails with Not executable.
chmod +x .agents/setup .agents/resume git add .agents/setup .agents/resume -
Keep secrets out of setup. The Project setup script and
.agents/setupget no Project variables. Sign in to registries and start tunnels in.agents/resume, which gets them. If the variables can’t be loaded, resume doesn’t run and shows Project variables unavailable. -
Install in setup, start services in resume. Processes that setup leaves running stop when it ends. Processes that resume starts keep running, so send their output to their own log file, for example
nohup node worker.js > "$HOME/worker.log" 2>&1 &. Don’t install dependencies in resume. -
Run a script by hand only when it isn’t running. Check with
polaris setup statusfirst. To run resume with the Project’s variables, runpolaris env run -- .agents/resumefrom the repository root.
Keep a command running
The agent ends its Turn while waiting for work outside the Machine, such as a review or deployment. Where available, check-ins let it return later. Keep-awake holds are for commands running on the Machine.
The Machine stays awake while the agent works or waits on a command. A command left running in the background with nobody waiting for it doesn’t keep the Machine awake, so it pauses when the Machine sleeps. To keep the Machine awake until a long job finishes:
polaris keep-awake run -- pnpm test:e2e
polaris keep-awake run --for 2h -- python train.py
| Command | What it does |
|---|---|
polaris keep-awake run -- <command> |
Keeps the Machine awake until the command ends. Polaris confirms the hold before the command starts. |
polaris keep-awake run --for <time> -- <command> |
Keeps it awake for at most that long, such as 20m, 2h or 1d. When the time runs out, the command keeps running but no longer holds the Machine awake. |
polaris keep-awake list |
Lists the holds on this Machine, with when each ends. A hold someone started from a Preview isn’t listed, and the agent can’t end it. |
polaris keep-awake release <id> |
Ends one hold. It doesn’t stop its command. |
Keep the job in the foreground inside keep-awake run: when it exits, the hold
ends. If the hold isn’t confirmed, the command doesn’t start.
Cloud access
These commands use the services an admin connected in Cloud access. No long-lived cloud key is stored on the Machine.
Check Tailscale
| Command | What it does |
|---|---|
polaris tailnet status |
Shows this Machine’s tailnet name, tags, MagicDNS suffix, and the online or offline state of peers visible to it. It reads status without changing the connection. |
If the Machine hasn’t joined or the command can’t read status, see Tailscale setup and troubleshooting.
Use an AWS profile
Each AWS role assigned to the Project is an AWS profile on its Machines, such
as polaris-logs-reader. Choose it with --profile or AWS_PROFILE.
Polaris profiles set no region, so pass --region or set AWS_REGION:
aws sts get-caller-identity --profile polaris-logs-reader --region eu-west-1
AWS_PROFILE=polaris-logs-reader AWS_REGION=eu-west-1 aws sts get-caller-identity
- Credentials renew on their own; there is nothing to sign in to or rotate.
- Polaris rewrites the part of
~/.aws/configbetween# BEGIN POLARIS MANAGED CLOUD ACCESS PROFILESand# END POLARIS MANAGED CLOUD ACCESS PROFILES. Keep your own profiles outside it. If you define a profile with the same name, yours wins. - The profiles get credentials from
polaris aws credentials. You don’t run it yourself.
Request access to a role that needs approval
polaris access request polaris-admin --for 30m --reason "Delete the old staging stack" --wait
--fortakes a whole number followed bys,morh, up to24h. A request above the role’s Longest approval asks for that limit and tells you the duration it requested.- On current CLIs,
--waitreturns within about 90 seconds. Older CLIs can wait longer. Approval exits with code 0 and prints the approval end time, duration, approver and profile to use. Denial, cancellation, invalidation or expiry exits nonzero with its reason. Without--wait, the command returns as soon as it sends the request. If a Machine’spolarisrejects--wait, run the command without it. If a request is already waiting for the same role, the command tells you when it was sent; its duration and reason stay unchanged. - Requesting an active role asks for an extension. Approval starts a fresh window from the approval time; it does not add time to the old window.
- At the wait limit, the command prints the exact command to check it:
polaris access status <grantId>. Status prints whether that request is pending, approved (with its end time) or ended. Reaching the wait limit leaves the request open until the printed approval deadline. - Use the profile name shown in the Machine’s Cloud access notes. Those notes include the role’s limit. When access ends, the next AWS call prints a new request command using that profile and its current limit.
- Ask from a Session: the request appears in its transcript, where approvers decide. A request from a shell Polaris can’t match to a Session appears in no transcript.
Get an identity token
polaris id-token --audience https://vault.example.com
The command prints only the token, for a service connected as Other service. A token is valid for 5 minutes, so get a new one each time instead of saving it. An audience isn’t a secret: every Machine in your organization can get a token for every connected service, so have the service also check the Project or Machine in the token.
Tokens are signed with RS256. Services find the keys at
https://plrs.sh/oidc/org/<org id>/.well-known/openid-configuration. Each
token has these claims:
| Claim | Value |
|---|---|
iss |
https://plrs.sh/oidc/org/<org id> |
sub |
org:<org id>:project:<project id>:workspace:<Machine id> |
aud |
The service’s audience, exactly as connected |
iat, exp |
Issue and expiry times, 5 minutes apart |
jti |
A unique token ID |
org_id, project_id, workspace_id |
The organization, Project and Machine. org, project and workspace repeat them. |
To find the IDs, look at addresses in Polaris. A Session’s address has the form
https://plrs.sh/workspaces/<Machine id>/sessions/…?orgId=<org id>. The address
of a Project’s page in Settings → Projects contains its ID, which starts
with project_. A Machine keeps its ID when it sleeps and wakes.
What an AWS role trusts
A role that Polaris sets up trusts only tokens from your organization’s issuer,
https://plrs.sh/oidc/org/<org id>, with the audience sts.amazonaws.com and
the subject for that one role:
| Mode | Subject the role trusts |
|---|---|
| Always available | org:<org id>:access:<access profile id>:mode:always:project:* |
| Needs approval | org:<org id>:access:<access profile id>:mode:approval |
Polaris checks the role’s Projects, and any approval, each time it issues a
token. Tokens from polaris id-token can’t assume these roles. In CloudTrail,
each session’s source identity, m- followed by 32 characters, identifies the
Machine.
Report a problem
polaris feedback draft < report.json
Drafts a report about Polaris from a JSON file. The draft waits in the Session
until you review and send it; see Report a problem. Run
polaris feedback --help for the fields.
CI notifications
| Command | What it does |
|---|---|
polaris notify ci --pr <number> |
Gets the CI result for the pull request’s current commit back in this Session. The agent runs it after it pushes, then ends its Turn. The result arrives when the checks finish, or after an hour; see Wait for CI. |
Common messages:
CI notification armed for <commit>; deadline <time>. End your Turn to wait.: Polaris sends the result for that commit when the checks finish.CI result already sent for <commit>. No new notification armed.: Polaris already sent the result for that commit. Push a new commit to get a new one.CI notification not armed (not_linked); reconnect GitHub in Polaris.: the Session owner’s GitHub account isn’t connected. They connect GitHub, then the agent runs the command again.CI notification not armed (reauthorization_required); reconnect GitHub in Polaris.: the Session owner’s GitHub sign-in expired. They select Reconnect GitHub; see Troubleshooting.CI notification not armed (...); try again shortly.orCI notification was not confirmed; retry.: Polaris couldn’t arm it right now. The agent runs the command again.
Session
| Command | What it does |
|---|---|
polaris session rename "<title>" |
Renames the Session. |
polaris session url |
Prints a link to the Session, for example for a pull request description. |
polaris session snooze --for 2h |
Moves the Session to Snoozed for a number of minutes, hours or days, such as 30m, 2h or 1d. |
polaris session snooze --until <date and time> |
Snoozes it until a date and time with its time zone offset, such as 2026-11-02T09:00+01:00. |
polaris session unsnooze |
Brings a snoozed Session back. |
The agent snoozes a Session only when you ask it to.
Desktop
| Command | What it does |
|---|---|
polaris desktop start |
Starts the Machine’s Desktop if it isn’t running and waits until it is ready. |
polaris desktop status |
Says whether the Desktop is ready. |
Docker
Docker isn’t preinstalled. When you ask the agent to add it to Workspace setup, it uses this tested script, which keeps Docker’s images, containers and volumes on the same disk as your code. It then starts Docker and your containers again each time the Machine wakes. Docker needs root on the Machine; where a Machine doesn’t allow it, the agent tells you.
#!/usr/bin/env bash
set -euo pipefail
mountpoint -q /opt/polaris/workload
sudo apt-get update
sudo apt-get install -y ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/debian/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc
printf '%s\n' 'deb [signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/debian bookworm stable' |
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo install -d /etc/docker /etc/containerd /opt/polaris/workload/docker /opt/polaris/workload/containerd
if ! sudo test -e /etc/containerd/config.toml; then
printf '%s\n' 'version = 2' 'root = "/opt/polaris/workload/containerd"' 'disabled_plugins = ["io.containerd.grpc.v1.cri"]' |
sudo tee /etc/containerd/config.toml > /dev/null
fi
for service in containerd docker; do
sudo install -d "/etc/systemd/system/$service.service.d"
printf '%s\n' '[Unit]' 'ConditionPathIsMountPoint=/opt/polaris/workload' |
sudo tee "/etc/systemd/system/$service.service.d/project-disk.conf" > /dev/null
done
sudo systemctl daemon-reload
if ! sudo test -e /etc/docker/daemon.json; then
printf '%s\n' '{"data-root":"/opt/polaris/workload/docker"}' |
sudo tee /etc/docker/daemon.json > /dev/null
fi
sudo apt-get update
sudo apt-get install -y --no-upgrade -o Dpkg::Options::=--force-confold \
docker-ce docker-ce-cli containerd.io docker-compose-plugin
sudo systemctl enable --now docker
Preinstalled tools
Every Machine runs Debian 12 with these tools installed, so you and the agent use the same versions. A Machine keeps the versions it started with.
| Tool | Version | What you use it for |
|---|---|---|
| Node.js and npm | 24 | Running and installing JavaScript and TypeScript projects. |
| pnpm | 11.1 | Installing and running pnpm projects. |
| Yarn | 4.18 | Installing and running Yarn projects. |
| Bun | 1.3 | Running and installing Bun projects. |
| Python | 3.11 | Running Python projects and scripts. |
| uv | 0.12 | Fast Python environments and dependency installs. |
| pip | 23.0 | Installing Python packages. |
| Git | 2.39 | Branches, commits, history, and diffs on your checkout. |
AWS CLI (aws) |
2.31 | Uses the roles connected through Cloud access. |
GitHub CLI (gh) |
2.101 | Pull requests, issues, checks, and releases from the Machine. |
ripgrep (rg) |
15.1 | Searching a large checkout quickly. |
| fd | 8.6 | Finding files by name. |
| jq | 1.6 | Reading and reshaping JSON output. |
| tmux | 3.3 | Keeping long-running commands in a session. |
| Compilers and build tools | GCC 12, make 4.3 | Building projects with native code. |
| curl | 7.88 | Fetching URLs and calling APIs from the Machine. |
| OpenSSH client | 9.2 | Connecting to hosts your project needs. |
| zip, unzip, zstd, less, file | — | Everyday archive and file handling. |
| Build headers and libraries | — | Building packages that link against PostgreSQL, MySQL, SQLite, OpenSSL, XML, YAML, or ImageMagick. |
| Mercurial and Subversion | 6.3, 1.14 | Working with repositories that do not use Git. |
Machines also have Chromium, which the agent uses for the
Browser. git and gh act as you on GitHub; see
GitHub. Docker isn’t preinstalled; see
Docker. For anything else, ask the agent
to install it, and to add it to your setup if every new Machine should have it.