Skein

Scripts

Define project and global scripts, run them in a workspace, and invoke them across a domain.

Add a project script

Open a project and click the ⚙ next to its name (Project settings). In the Scripts section, click + Add script and choose Shell step or Copy-files step — the dialog opens as New script (or New copy-files step).

Fill in:

  • Name
  • Kind — setup (auto-runs on create/unarchive), run, or custom.
  • Command — the shell command to run. Wrap a placeholder in double braces, e.g. bun run test -- --grep "{{pattern}}", to prompt for a value each time the script runs (see Run a script in a workspace).
  • Ports (0–16) — how many SKEIN_PORT_* slots to lease for this script's pane (see Environment variables).
  • Allow multiple instances — "Launch a new pane each time instead of focusing the running one." Off by default, so re-running a script refocuses its existing pane.

Copy-files steps

A setup-kind script can use Copy files instead of Shell — a toggle further down the dialog, below the Globally invokable checkbox. It copies files into the workspace instead of running a command, and skips the Command, Ports, and argument fields.

Run a script in a workspace

In a workspace, click the tab strip's + button and pick New terminal, or open the Scripts submenu below it to pick a script by name. Each entry shows a [kind] tag for a project script or a Global badge for a global script, plus a port count when the script leases any.

Running a script opens a new tab in the strip (marked with a ⚡ icon) with its own output pane, just like a regular terminal.

If the script's command has a {{placeholder}}, running it opens a Run "<name>" dialog first, with one field per placeholder. A placeholder's field renders as:

  • a plain text input, for a free-text argument;
  • a combobox of options, for a manual list or a generated list (with a refresh button to re-run the generator); picking Other… switches it to a text input with a ← back to options link;
  • a plain text input, if the generator failed or timed out — this emergency input always renders, even when the free-text fallback isn't allowed.

Click Run script to submit.

Setup scripts run automatically

A setup-kind script runs automatically when a workspace is created or unarchived — no need to trigger it from the Scripts submenu. Its output appears as an ordinary terminal pane in that workspace, tagged with the same ⚡ icon as a manually-run script.

While setup scripts run, the workspace's row in the project's workspace list shows a status badge next to its name: setup: running N/M while scripts are in flight, setup: ✓ once they all succeed, setup: failed or setup: timed out if one doesn't, or setup: cancelled. A failure aborts the remaining chain — later setup scripts don't run.

Environment variables

Every script's pane gets these variables, built from the project and (for a workspace-scoped run) the workspace it's running in:

VariableSet whenValue
SKEIN_DOMAINalwaysthe domain's name
SKEIN_PROJECTalwaysthe project's name
SKEIN_PROJECT_PATHalwaysthe project's checkout path
SKEIN_WORKSPACErun in a workspacethe workspace's name
SKEIN_WORKSPACE_PATHrun in a workspacethe workspace's worktree path
SKEIN_GH_LOGINdomain has a GitHub accountthat account's login
SKEIN_PORT_1 … SKEIN_PORT_Nthe script's Ports is > 0one leased port per slot
SKEIN_ARG_<NAME>the script has a {{name}} placeholderthat placeholder's argument value
CLAUDE_CONFIG_DIRdomain sets a Claude config dirthat directory
GH_TOKEN, GITHUB_TOKENdomain has a GitHub account with a tokenthat account's token

Running a script from a project's main checkout (not a workspace) sets SKEIN_PROJECT_PATH but not SKEIN_WORKSPACE or SKEIN_WORKSPACE_PATH.

A {{name}} placeholder's value is available two ways: substituted directly into the command, and separately as SKEIN_ARG_<NAME> — the placeholder name, uppercased, with any - replaced by _ (so {{db-name}} becomes SKEIN_ARG_DB_NAME).

Global scripts

Settings → Scripts always leads with a predefined Claude entry (badged Predefined) that launches claude right away with no run dialog — it can't be edited, reordered, or deleted. Skein still appends any Claude launch flags set at Settings → Issues (see Issue trackers → Set issue-open defaults). Below it are your own personal scripts, available in every workspace regardless of project. Click New global script — the dialog has Name, Command, Kind, Ports, and Working directory (blank defaults to the workspace root; ~ expands to your home directory, and a relative path resolves against the workspace root). A global script is always a shell script, and it's always runnable everywhere — there's no project picker and no globally-invokable toggle to set.

A workspace's Scripts submenu shows global scripts in their own Global section below the project's own scripts.

Settings → Scripts showing the predefined Claude entry and a list of global scripts available in every workspace

Globally invokable scripts

A project script's edit dialog has a Globally invokable checkbox: "Show this script in the domain Scripts view and command palette." Turn it on and the script also shows up outside its own project.

Once at least one project has a globally invokable script, a Scripts link appears in the sidebar under that domain, opening /domains/<id>/scripts. That page groups those project scripts by project, each with a Run button. Running one from there opens the same argument dialog described above; on success a toast reads "Started <script> in <project>" with a Show output action that jumps to the project's main checkout with that pane focused.

The same page also lists your global scripts (badged Global) below the per-project ones, for reference only — they have no Run button there, since a global script is already runnable from inside any workspace (see Global scripts).

On this page