Skills
Machine session management and driving guidance.
Machine-core ships two skills and one always-active rule. They follow the
standard skill protocol and
contribution model: visibility inherits
the caller's feature grants, so an agent whose caller lacks machine.read
never sees any of this surface.
manage-machine-sessions
A script-backed skill (requires machine.read) that wraps the session
lifecycle routes for explicit, owner-level control over the Webtop container.
Day-to-day driving does not need it — machine_use ensures a session
implicitly — but it is the right tool for checking health, pre-warming a
machine, or stopping one deliberately.
| Action | Route | Script |
|---|---|---|
| Get current session info (probes liveness) | GET /sessions | list.sh |
| List every machine you can see and what you may do to it | GET /sessions/overview | list.sh with ALL=true |
| Start / ensure the session is running | POST /sessions | start.sh |
| Stop the machine (the container is kept) | DELETE /sessions | stop.sh |
Delete the container (PURGE=true also destroys the profile of a stopped machine) | DELETE /sessions/container | delete.sh |
| Per-source running map + Docker health | GET /health | health.sh |
The scripts authenticate with the per-stream session ticket like every internal skill call — see sessions. Two environment variables steer them:
SOURCE— the machine source slug (defaults to the first configured machine source; required fordelete.sh).ALL— settrueonlist.shto list every machine instead of one.PURGE— settrueondelete.shto also destroy the persisted profile volume; the machine must be stopped first (a running one answers409). Onstop.shit is refused, because a stop never purges.
webtop-1 is a placeholder — the real slug comes from list.sh. The block
below starts a machine and stops the same one, so it leaves it as it found it:
a stop keeps the container and everything installed into it.
ALL=true bash ${SKILL_DIR}/scripts/list.sh
SOURCE=webtop-1 bash ${SKILL_DIR}/scripts/start.sh
SOURCE=webtop-1 bash ${SKILL_DIR}/scripts/stop.shDeleting is the consequential half. delete.sh removes the container:
packages installed into the container layer and files outside /config are
lost, while the /config profile and its proot-apps installs stay. PURGE=true
additionally destroys the profile volume — the desktop profile, browser logins,
and anything saved inside the machine's home — with no undo. It needs a stopped
machine: while the machine runs the purge answers 409, so run stop.sh first.
SOURCE=webtop-1 bash ${SKILL_DIR}/scripts/delete.sh
SOURCE=webtop-1 PURGE=true bash ${SKILL_DIR}/scripts/delete.sh # only when you mean to wipe the profileThe session key is derived host-side from the project, source, and container scope — the model only ever chooses the source slug.
machine-driving
A reference skill (requires machine.drive, manual activation) that teaches
agents how to compose machine_use, URI-selected execute, and fs_* machine://
well. Its core prescriptions:
- Observe between actions. The golden pattern is
goto → read_* / screenshot → think → click / type → read_* → …. Never chain two drive actions without a snapshot in between — the page or desktop state changed, and blind acting misses modals, redirects, and errors. - Selector strategy (browser). Prefer text matchers
(
text="Save changes"), then accessibility selectors (role=button[name="…"]), thendata-testid, and CSS selectors only as a last resort. - Anchor desktop clicks to a screenshot. Desktop mode has no selector engine — clicks are pixel coordinates, and coordinates only make sense relative to the screenshot just taken. Re-screenshot after every drive action.
- Know when not to use the machine. Plain HTML content is cheaper through the regular web tools; the machine is for client-rendered apps, logged-in sessions, visual tasks, desktop applications, and commands that must run in a specific Linux userspace.
- Escape hatches. Stop and hand back to the user on repeated identical observations, repeated action errors, or any captcha / 2FA / payment form.
The machine-safety rule
rules/machine-safety.md is an always-active rule injected whenever
the machine package’s automatic contributions are enabled for the caller. It covers
machine_use and Webtop shell through execute. It encodes the
safe-driving floor:
- Credentials. The agent must never type passwords, API keys, card numbers, or OTP codes — in a web form, a desktop app, or a shell command — unless the user pasted the value in the current turn. Login flows are handed to the user inside the Machine widget; secrets are never echoed into the shell or saved anywhere.
- Phishing. Before navigating to anything that looks like a major brand, the agent verifies the exact registrable domain and refuses obvious typosquats.
- Logged-in side effects. The browser and desktop apps may be signed into real accounts. Destructive-looking actions (Send / Delete / Pay / Submit / Overwrite) require a stop-summarize-confirm step first.
- Denylist discipline. Blocked key combos, blocked shell commands, and blocked app launches must be surfaced to the user, never retried through a workaround.
- Bounded capture and output. Recording is bounded in both duration and
file size — 30 seconds and 25 MB by default, each adjustable by an admin —
and goes only through the
recordaction, which writes the clip to disk and returns a URI; large shell output is piped to a file and read back through the filesystem tools. - The
/configsecret-path floor.fs_read,fs_listandfs_searchon a machine source cannot reach the browser profiles and their caches, the container's own TLS key, the NSS certificate store, or the dotfile credential trees. The rule tells the agent the denial is immutable, that it applies to the person who attached the source too, and that content surfacing from one of those paths is leaked credential material to report rather than repeat. - Downloads and file writes. No unasked downloads, no dragging workspace
files into the widget, and nothing throw-away-secret written under
/config/— files created there are visible to the user and tofs_list. - Audit awareness. Every call is logged with caller identity and arguments. The rule's framing: write tool calls as if they were commits.
Rules outrank convenience
The safety rule is injected as an always-on contribution, not opt-in guidance: it explicitly outranks user hints that contradict it, and it inherits the package enable state and the caller's feature grants like every other contribution.