What does my skill's shell see?
In a local session the shell your skill runs commands in is sealed: environment variables you set on the host do not reach it, and neither do exports written by hooks. The inline shell-execution syntax some skills use in their instructions does not run there, and whether it runs elsewhere depends on the sandbox and on how the skill was installed. The local shell tool is also not the same tool as the CLI's (in the remote sandbox it is), so branching on which tools you have is a more reliable signal than branching on environment variables.
Do not treat the home directory as a private place that outlives the session.
In the local sandbox the home directory is the session directory itself, not a separate per-user home, and it goes away with the session. Writing there is fine for scratch, but nothing put there is delivered, carried to the next session, or visible to anyone. Deliverables belong in the outputs location.
As of the 2026-08-05 capture · Desktop 1.25927.0 · not individually re-checked since this rule last changed
Do not depend on the inline shell-execution syntax in skill instructions; whether it runs depends on the sandbox, on how the skill was installed, on whether the command needs approval and on when in the conversation it is used.
The syntax that lets a skill embed a command in its own instructions and have the output substituted does not run in a local session: each command is replaced by a notice that shell execution is disabled by policy. Where it is not switched off, each command first goes through the same permission check as a shell command: one that is allowed runs and its output is substituted; one that needs approval, in auto mode, is not run but rewritten into an instruction asking the model to run it, which the model may or may not do; in any other mode such a command makes the skill fail to load. In the remote sandbox, a skill used before the conversation's session exists, for example as its first message, is expanded outside the agent and keeps its commands as raw text whichever way it was installed; once the session exists the agent runs them, and a command the skill allows that then fails when it runs leaves a typed slash command with no reply and no error and makes the model's own invocation fail to load (a failing command the skill does not allow was not tested). In the command-line tool a plugin's skills go through that check, but a skill the user uploaded to their account has its commands left as raw text. Apart from the failed load and that hang, none of these cases raises an error, so a skill that gathers context this way carries on with the notice, the raw command or the instruction in place of the output.
Re-read from the shipped code 2026-09-28 · Desktop 2.9939.2 · agent 2.1.281
Do not rely on arbitrary outbound network access from shell commands.
Outbound access from the shell is filtered by destination rather than absent: some hosts answer and others do not, and the session carries a URL allowlist. Fetching is also available as a dedicated capability with its own routing. Write skills that use the fetch capability when it exists and state a clear limitation when it does not, rather than shelling out to a network client and assuming any host is reachable.
As of the 2026-08-05 capture · Desktop 1.25927.0 · not individually re-checked since this rule last changed
Prefer what is preinstalled, and never install globally. A user-scoped or project-local install works, but treat it as a fallback.
Check what is already there first: the local sandbox ships Python 3.10 with a large preinstalled set, including pandas, numpy, Pillow and openpyxl. If you do need something else, a user-scoped Python install (pip install --user) and a project-local Node install (npm install) both succeed, and the package imports normally afterwards. A global install does not take effect — npm install -g in particular leaves nothing behind. Which package sources are reachable is session configuration that has changed between releases, so put any install on a path that degrades gracefully rather than making it a prerequisite.
As of the 2026-08-05 capture · Desktop 1.25927.0 · not individually re-checked since this rule last changed
Do not assume the sandbox has no third-party libraries. It ships a large preinstalled stack.
On the local lane, the environment your shell commands run in ships Python 3.10 with a large set of packages already installed — pandas, numpy, Pillow and openpyxl among them, alongside other data, document and imaging libraries, and command-line tools for OCR, PDF rendering and office conversion. Skills have shipped workarounds and portability warnings for a scarcity that is not there. Check for what you need at runtime before vendoring it or degrading: the exact set belongs to the shipped image and can change with it, so test rather than rely on this list.
Re-read from the shipped code 2026-09-27 · Desktop 2.9939.2
Do not expect to read or write anything outside your own session, and do not rely on the identity your shell runs as.
In the local sandbox each session runs as its own operating-system user: sibling sessions are visible by name but their contents are refused, and the session namespace holds hundreds of entries. In the remote sandbox there is no per-session user at all and commands run as root. Either way, anything your skill needs must be inside the session or fetched into it — but identity itself is not a stable thing to branch on.
As of the 2026-09-05 capture · Desktop 1.46388.4 · not individually re-checked since this rule last changed
Do not pass configuration to your skill's shell commands through the environment.
The shell your commands run in does not inherit the host environment: variables set in user or managed settings do not appear there, and neither do exports written by a hook. Only a couple of CLAUDE_* variables are present. Pass configuration one of three ways instead — put the value literally in the command string, write it to a file and have the command read that file, or pass it as an argument to a script your skill invokes.
As of the 2026-08-05 capture · Desktop 1.25927.0 · not individually re-checked since this rule last changed
Do not assume the shell tool has the same name it has in the CLI.
The tool your skill uses to run commands in Cowork is a different tool from the CLI's, with a different name. This matters if your skill's instructions name tools explicitly, and it is also useful: the tool surface is a more reliable indicator of where you are running than the environment is.
As of the 2026-08-05 capture · Desktop 1.25927.0 · not individually re-checked since this rule last changed
What is not established
- Network egress is allowed through a fetch capability rather than arbitrary outbound sockets, and the routing has changed across releases. Assume fetch works and arbitrary sockets do not, and degrade gracefully rather than probing.