Repository navigation
Releases: juscribe/jus-dispatch
Release list
jus-dispatch v0.8.28
Installing jus-dispatch
jus-dispatch is the remote dispatch agent for Juscribe. It connects to the Juscribe server over a WebSocket, runs a coding-agent CLI against your project when a dispatch arrives, and reports the result back to the board.
Platform support: macOS and Linux, amd64 and arm64. Requires the CLI you dispatch to — Claude Code by default.
Install
brew install juscribe/tap/jusThat installs the jus CLI and jus-dispatch together, and brew upgrade jus moves both. Binaries for macOS and Linux, amd64 and arm64, are attached to every release at github.com/juscribe/jus-dispatch/releases and download without authentication.
A container image ships on the same cut, for the docker placement:
docker pull ghcr.io/juscribe/jus-dispatch:latestlinux/amd64 and linux/arm64. --sandbox docker mode that left with it; p188 restored the placement layer and the image came back with it.
To build from a checkout instead:
cd dispatch && make buildThat writes dispatch/bin/jus-dispatch. make build-all cross-compiles all four platforms into the same directory, and make install copies the host build into $GOPATH/bin.
What it does NOT do
The station created a git worktree per dispatch, ran the CLI inside it, and then merged, pushed or left the branch. jus-dispatch leaves the branch and stops there (#4223).
- It creates a worktree, runs the CLI in it, removes the worktree and keeps the branch. The board is told the branch name and how many commits are on it.
- No merge, no push, no pull request, on any path. A person reviews and lands it. A run that committed nothing gets its branch deleted and the board says so rather than naming an empty one.
⚠️ .jus/hooks/worktree-setupruns inside the new worktree first, if your project has one — a git checkout is missing everything you gitignore. A hook that fails or is not executable fails the dispatch rather than handing an agent a broken tree.branch_strategyno longer arrives on the wire at all (#3902), and nothing here reads it. There is one behaviour, so there is nothing to select.
raw / orbstack / docker and the setup-sandbox, setup-orb, setup-docker and auth commands were restored across #4222, #4221, #4220, #4243 and #4245. jus-dispatch init is what chooses between them — the Setup section below records the choice; it does not make it, and this sentence said otherwise until #4292.
What a dispatch is allowed to do
It runs under --permission-mode auto — it can edit files (#4254).
raw there is nothing. Under orbstack and docker only the project directory is mounted, so a write outside it is refused by the kernel; raw is your real machine with an autonomous agent on it. jus-dispatch init prints that difference and takes a typed agree before it will select raw.
dontAsk, then plan after #3970 found that a project's own .claude/settings.json outranked the narrower mode in a trusted checkout. That approach is retired: the boundary is the container now, not the model's own restraint.
One rule still binds under auto, and it is the project's own. permissions.deny in .claude/settings.json is honoured and recorded. Measured on claude 2.1.273: asked for a deny-listed file, the CLI reached for it through cat — not the Read tool — and the rule stopped it anyway. --setting-sources is deliberately never passed, because it would discard exactly that.
--dangerously-skip-permissions is never passed and must not be. An autonomous mode answers the permission system; that flag switches it off, and takes the deny rules with it.
Setup
jus-dispatch initPress Enter to accept a default (shown in brackets):
| Prompt | Default | What it means |
|---|---|---|
| API token | (none — required) | Your Juscribe API token, from Settings → API Tokens. It authenticates the agent with the server. |
| Server URL | wss://app.juscribe.ai/cable |
The WebSocket endpoint for your Juscribe instance. Accept the default unless you have a designated subdomain. |
| Project path | Current directory | Absolute path to the git repository the agent runs in. |
| Sandbox | (none — you are asked) | Where the CLI runs: raw, orbstack or docker. raw is your real machine and requires a typed agree. |
| CLI provider | claude |
Only shown when multi-LLM is enabled for your workspace. |
| Thinking effort | medium |
low, medium, high or max. Claude only. |
| Log level | info |
debug, info, warn or error. Use debug when troubleshooting a connection. |
| Log file | ~/.local/share/jus-dispatch/logs/jus-dispatch.log |
Where the structured log is written, in addition to stderr. |
Config is saved to ~/.config/jus-dispatch/config.toml, or to <project>/.jus/dispatch.toml when the directory has been through jus init.
~/.config/jus-station/ is not read, at any precedence. A frozen station and a new agent can sit on one machine, and sharing a config would have each writing over the other's scope. The station cannot connect either way — the server's protocol floor is past it — but the file is left alone rather than migrated. See Upgrading from jus-station.
Every value can be overridden at runtime by a flag (--token, --server, --project, --log-level, --log-file) or an environment variable (JUSCRIBE_API_TOKEN, JUS_SERVER_URL, JUS_PROJECT_PATH, JUS_LOG_LEVEL, JUS_LOG_FILE, JUS_EFFORT_LEVEL).
Your project's toolchain is yours to install
jus-dispatch initoffers to file this as a chore on your board, with the commands below already filled in for your sandbox — you can decline, and nothing is written to your tracker unless you say yes.
A sandbox gets git, the AI CLI and the jus toolset, and nothing else. It does not get your language runtime, your package manager or your database client — jus-dispatch has no way to know what those are.
Put an executable .jus/hooks/sandbox-setup in your repository. Both setup-orb and setup-docker run it, with your project as the working directory:
#!/usr/bin/env bash
set -euo pipefail
sudo apt-get update
sudo apt-get install -y nodejs npm postgresql-client- No hook is not an error. Most projects need no provisioning and none is invented for them.
- A hook that fails, or exists without an executable bit, fails setup — a sandbox missing the tools it was meant to install is one every dispatch dies in, somewhere that names neither the hook nor its permissions.
- It is not bounded by a timeout. A toolchain install can legitimately run for half an hour; the output streams to your terminal and
Ctrl-Cworks. .jus/hooks/orb-setupstill works. That was the name before the hook reached docker. Both are found, on both placements, andsandbox-setupwins if you have written both.
.jus/hooks/worktree-setup, and the two are not interchangeable. That one runs per dispatch, in a fresh worktree, and restores what you gitignore — typically starting with a dependency install. This one runs once per sandbox and installs the thing that dependency install invokes.
| Placement | What the hook becomes |
|---|---|
orbstack |
A provisioning step inside the orb, run once by setup-orb after git, the CLI and the jus toolset are installed. |
docker |
A build layer. setup-docker builds an image from ghcr.io/juscribe/jus-dispatch with your hook in it, tags it jus-dispatch-<project>-<hash>:latest and points [sandbox] target at that. Every container is `docker run -... |
jus-dispatch v0.8.27
Installing jus-dispatch
jus-dispatch is the remote dispatch agent for Juscribe. It connects to the Juscribe server over a WebSocket, runs a coding-agent CLI against your project when a dispatch arrives, and reports the result back to the board.
Platform support: macOS and Linux, amd64 and arm64. Requires the CLI you dispatch to — Claude Code by default.
Install
brew install juscribe/tap/jusThat installs the jus CLI and jus-dispatch together, and brew upgrade jus moves both. Binaries for macOS and Linux, amd64 and arm64, are attached to every release at github.com/juscribe/jus-dispatch/releases and download without authentication.
A container image ships on the same cut, for the docker placement:
docker pull ghcr.io/juscribe/jus-dispatch:latestlinux/amd64 and linux/arm64. --sandbox docker mode that left with it; p188 restored the placement layer and the image came back with it.
To build from a checkout instead:
cd dispatch && make buildThat writes dispatch/bin/jus-dispatch. make build-all cross-compiles all four platforms into the same directory, and make install copies the host build into $GOPATH/bin.
What it does NOT do
The station created a git worktree per dispatch, ran the CLI inside it, and then merged, pushed or left the branch. jus-dispatch leaves the branch and stops there (#4223).
- It creates a worktree, runs the CLI in it, removes the worktree and keeps the branch. The board is told the branch name and how many commits are on it.
- No merge, no push, no pull request, on any path. A person reviews and lands it. A run that committed nothing gets its branch deleted and the board says so rather than naming an empty one.
⚠️ .jus/hooks/worktree-setupruns inside the new worktree first, if your project has one — a git checkout is missing everything you gitignore. A hook that fails or is not executable fails the dispatch rather than handing an agent a broken tree.branch_strategyno longer arrives on the wire at all (#3902), and nothing here reads it. There is one behaviour, so there is nothing to select.
raw / orbstack / docker and the setup-sandbox, setup-orb, setup-docker and auth commands were restored across #4222, #4221, #4220, #4243 and #4245. jus-dispatch init is what chooses between them — the Setup section below records the choice; it does not make it, and this sentence said otherwise until #4292.
What a dispatch is allowed to do
It runs under --permission-mode auto — it can edit files (#4254).
raw there is nothing. Under orbstack and docker only the project directory is mounted, so a write outside it is refused by the kernel; raw is your real machine with an autonomous agent on it. jus-dispatch init prints that difference and takes a typed agree before it will select raw.
dontAsk, then plan after #3970 found that a project's own .claude/settings.json outranked the narrower mode in a trusted checkout. That approach is retired: the boundary is the container now, not the model's own restraint.
One rule still binds under auto, and it is the project's own. permissions.deny in .claude/settings.json is honoured and recorded. Measured on claude 2.1.273: asked for a deny-listed file, the CLI reached for it through cat — not the Read tool — and the rule stopped it anyway. --setting-sources is deliberately never passed, because it would discard exactly that.
--dangerously-skip-permissions is never passed and must not be. An autonomous mode answers the permission system; that flag switches it off, and takes the deny rules with it.
Setup
jus-dispatch initPress Enter to accept a default (shown in brackets):
| Prompt | Default | What it means |
|---|---|---|
| API token | (none — required) | Your Juscribe API token, from Settings → API Tokens. It authenticates the agent with the server. |
| Server URL | wss://app.juscribe.ai/cable |
The WebSocket endpoint for your Juscribe instance. Accept the default unless you have a designated subdomain. |
| Project path | Current directory | Absolute path to the git repository the agent runs in. |
| Sandbox | (none — you are asked) | Where the CLI runs: raw, orbstack or docker. raw is your real machine and requires a typed agree. |
| CLI provider | claude |
Only shown when multi-LLM is enabled for your workspace. |
| Thinking effort | medium |
low, medium, high or max. Claude only. |
| Log level | info |
debug, info, warn or error. Use debug when troubleshooting a connection. |
| Log file | ~/.local/share/jus-dispatch/logs/jus-dispatch.log |
Where the structured log is written, in addition to stderr. |
Config is saved to ~/.config/jus-dispatch/config.toml, or to <project>/.jus/dispatch.toml when the directory has been through jus init.
~/.config/jus-station/ is not read, at any precedence. A frozen station and a new agent can sit on one machine, and sharing a config would have each writing over the other's scope. The station cannot connect either way — the server's protocol floor is past it — but the file is left alone rather than migrated. See Upgrading from jus-station.
Every value can be overridden at runtime by a flag (--token, --server, --project, --log-level, --log-file) or an environment variable (JUSCRIBE_API_TOKEN, JUS_SERVER_URL, JUS_PROJECT_PATH, JUS_LOG_LEVEL, JUS_LOG_FILE, JUS_EFFORT_LEVEL).
Your project's toolchain is yours to install
jus-dispatch initoffers to file this as a chore on your board, with the commands below already filled in for your sandbox — you can decline, and nothing is written to your tracker unless you say yes.
A sandbox gets git, the AI CLI and the jus toolset, and nothing else. It does not get your language runtime, your package manager or your database client — jus-dispatch has no way to know what those are.
Put an executable .jus/hooks/sandbox-setup in your repository. Both setup-orb and setup-docker run it, with your project as the working directory:
#!/usr/bin/env bash
set -euo pipefail
sudo apt-get update
sudo apt-get install -y nodejs npm postgresql-client- No hook is not an error. Most projects need no provisioning and none is invented for them.
- A hook that fails, or exists without an executable bit, fails setup — a sandbox missing the tools it was meant to install is one every dispatch dies in, somewhere that names neither the hook nor its permissions.
- It is not bounded by a timeout. A toolchain install can legitimately run for half an hour; the output streams to your terminal and
Ctrl-Cworks. .jus/hooks/orb-setupstill works. That was the name before the hook reached docker. Both are found, on both placements, andsandbox-setupwins if you have written both.
.jus/hooks/worktree-setup, and the two are not interchangeable. That one runs per dispatch, in a fresh worktree, and restores what you gitignore — typically starting with a dependency install. This one runs once per sandbox and installs the thing that dependency install invokes.
| Placement | What the hook becomes |
|---|---|
orbstack |
A provisioning step inside the orb, run once by setup-orb after git, the CLI and the jus toolset are installed. |
docker |
A build layer. setup-docker builds an image from ghcr.io/juscribe/jus-dispatch with your hook in it, tags it jus-dispatch-<project>-<hash>:latest and points [sandbox] target at that. Every container is `docker run -... |
jus-dispatch v0.8.26
Installing jus-dispatch
jus-dispatch is the remote dispatch agent for Juscribe. It connects to the Juscribe server over a WebSocket, runs a coding-agent CLI against your project when a dispatch arrives, and reports the result back to the board.
Platform support: macOS and Linux, amd64 and arm64. Requires the CLI you dispatch to — Claude Code by default.
Install
brew install juscribe/tap/jusThat installs the jus CLI and jus-dispatch together, and brew upgrade jus moves both. Binaries for macOS and Linux, amd64 and arm64, are attached to every release at github.com/juscribe/jus-dispatch/releases and download without authentication.
A container image ships on the same cut, for the docker placement:
docker pull ghcr.io/juscribe/jus-dispatch:latestlinux/amd64 and linux/arm64. --sandbox docker mode that left with it; p188 restored the placement layer and the image came back with it.
To build from a checkout instead:
cd dispatch && make buildThat writes dispatch/bin/jus-dispatch. make build-all cross-compiles all four platforms into the same directory, and make install copies the host build into $GOPATH/bin.
What it does NOT do
The station created a git worktree per dispatch, ran the CLI inside it, and then merged, pushed or left the branch. jus-dispatch leaves the branch and stops there (#4223).
- It creates a worktree, runs the CLI in it, removes the worktree and keeps the branch. The board is told the branch name and how many commits are on it.
- No merge, no push, no pull request, on any path. A person reviews and lands it. A run that committed nothing gets its branch deleted and the board says so rather than naming an empty one.
⚠️ .jus/hooks/worktree-setupruns inside the new worktree first, if your project has one — a git checkout is missing everything you gitignore. A hook that fails or is not executable fails the dispatch rather than handing an agent a broken tree.branch_strategyno longer arrives on the wire at all (#3902), and nothing here reads it. There is one behaviour, so there is nothing to select.
raw / orbstack / docker and the setup-sandbox, setup-orb, setup-docker and auth commands were restored across #4222, #4221, #4220, #4243 and #4245. jus-dispatch init is what chooses between them — the Setup section below records the choice; it does not make it, and this sentence said otherwise until #4292.
What a dispatch is allowed to do
It runs under --permission-mode auto — it can edit files (#4254).
raw there is nothing. Under orbstack and docker only the project directory is mounted, so a write outside it is refused by the kernel; raw is your real machine with an autonomous agent on it. jus-dispatch init prints that difference and takes a typed agree before it will select raw.
dontAsk, then plan after #3970 found that a project's own .claude/settings.json outranked the narrower mode in a trusted checkout. That approach is retired: the boundary is the container now, not the model's own restraint.
One rule still binds under auto, and it is the project's own. permissions.deny in .claude/settings.json is honoured and recorded. Measured on claude 2.1.273: asked for a deny-listed file, the CLI reached for it through cat — not the Read tool — and the rule stopped it anyway. --setting-sources is deliberately never passed, because it would discard exactly that.
--dangerously-skip-permissions is never passed and must not be. An autonomous mode answers the permission system; that flag switches it off, and takes the deny rules with it.
Setup
jus-dispatch initPress Enter to accept a default (shown in brackets):
| Prompt | Default | What it means |
|---|---|---|
| API token | (none — required) | Your Juscribe API token, from Settings → API Tokens. It authenticates the agent with the server. |
| Server URL | wss://app.juscribe.ai/cable |
The WebSocket endpoint for your Juscribe instance. Accept the default unless you have a designated subdomain. |
| Project path | Current directory | Absolute path to the git repository the agent runs in. |
| Sandbox | (none — you are asked) | Where the CLI runs: raw, orbstack or docker. raw is your real machine and requires a typed agree. |
| CLI provider | claude |
Only shown when multi-LLM is enabled for your workspace. |
| Thinking effort | medium |
low, medium, high or max. Claude only. |
| Log level | info |
debug, info, warn or error. Use debug when troubleshooting a connection. |
| Log file | ~/.local/share/jus-dispatch/logs/jus-dispatch.log |
Where the structured log is written, in addition to stderr. |
Config is saved to ~/.config/jus-dispatch/config.toml, or to <project>/.jus/dispatch.toml when the directory has been through jus init.
~/.config/jus-station/ is not read, at any precedence. A frozen station and a new agent can sit on one machine, and sharing a config would have each writing over the other's scope. The station cannot connect either way — the server's protocol floor is past it — but the file is left alone rather than migrated. See Upgrading from jus-station.
Every value can be overridden at runtime by a flag (--token, --server, --project, --log-level, --log-file) or an environment variable (JUSCRIBE_API_TOKEN, JUS_SERVER_URL, JUS_PROJECT_PATH, JUS_LOG_LEVEL, JUS_LOG_FILE, JUS_EFFORT_LEVEL).
Your project's toolchain is yours to install
jus-dispatch initoffers to file this as a chore on your board, with the commands below already filled in for your sandbox — you can decline, and nothing is written to your tracker unless you say yes.
A sandbox gets git, the AI CLI and the jus toolset, and nothing else. It does not get your language runtime, your package manager or your database client — jus-dispatch has no way to know what those are.
Put an executable .jus/hooks/sandbox-setup in your repository. Both setup-orb and setup-docker run it, with your project as the working directory:
#!/usr/bin/env bash
set -euo pipefail
sudo apt-get update
sudo apt-get install -y nodejs npm postgresql-client- No hook is not an error. Most projects need no provisioning and none is invented for them.
- A hook that fails, or exists without an executable bit, fails setup — a sandbox missing the tools it was meant to install is one every dispatch dies in, somewhere that names neither the hook nor its permissions.
- It is not bounded by a timeout. A toolchain install can legitimately run for half an hour; the output streams to your terminal and
Ctrl-Cworks. .jus/hooks/orb-setupstill works. That was the name before the hook reached docker. Both are found, on both placements, andsandbox-setupwins if you have written both.
.jus/hooks/worktree-setup, and the two are not interchangeable. That one runs per dispatch, in a fresh worktree, and restores what you gitignore — typically starting with a dependency install. This one runs once per sandbox and installs the thing that dependency install invokes.
| Placement | What the hook becomes |
|---|---|
orbstack |
A provisioning step inside the orb, run once by setup-orb after git, the CLI and the jus toolset are installed. |
docker |
A build layer. setup-docker builds an image from ghcr.io/juscribe/jus-dispatch with your hook in it, tags it jus-dispatch-<project>-<hash>:latest and points [sandbox] target at that. Every container is `docker run -... |
jus-dispatch v0.8.25
Installing jus-dispatch
jus-dispatch is the remote dispatch agent for Juscribe. It connects to the Juscribe server over a WebSocket, runs a coding-agent CLI against your project when a dispatch arrives, and reports the result back to the board.
Platform support: macOS and Linux, amd64 and arm64. Requires the CLI you dispatch to — Claude Code by default.
Install
brew install juscribe/tap/jusThat installs the jus CLI and jus-dispatch together, and brew upgrade jus moves both. Binaries for macOS and Linux, amd64 and arm64, are attached to every release at github.com/juscribe/jus-dispatch/releases and download without authentication.
A container image ships on the same cut, for the docker placement:
docker pull ghcr.io/juscribe/jus-dispatch:latestlinux/amd64 and linux/arm64. --sandbox docker mode that left with it; p188 restored the placement layer and the image came back with it.
To build from a checkout instead:
cd dispatch && make buildThat writes dispatch/bin/jus-dispatch. make build-all cross-compiles all four platforms into the same directory, and make install copies the host build into $GOPATH/bin.
What it does NOT do
The station created a git worktree per dispatch, ran the CLI inside it, and then merged, pushed or left the branch. jus-dispatch leaves the branch and stops there (#4223).
- It creates a worktree, runs the CLI in it, removes the worktree and keeps the branch. The board is told the branch name and how many commits are on it.
- No merge, no push, no pull request, on any path. A person reviews and lands it. A run that committed nothing gets its branch deleted and the board says so rather than naming an empty one.
⚠️ .jus/hooks/worktree-setupruns inside the new worktree first, if your project has one — a git checkout is missing everything you gitignore. A hook that fails or is not executable fails the dispatch rather than handing an agent a broken tree.branch_strategyno longer arrives on the wire at all (#3902), and nothing here reads it. There is one behaviour, so there is nothing to select.
raw / orbstack / docker and the setup-sandbox, setup-orb, setup-docker and auth commands were restored across #4222, #4221, #4220, #4243 and #4245. jus-dispatch init is what chooses between them — the Setup section below records the choice; it does not make it, and this sentence said otherwise until #4292.
What a dispatch is allowed to do
It runs under --permission-mode auto — it can edit files (#4254).
raw there is nothing. Under orbstack and docker only the project directory is mounted, so a write outside it is refused by the kernel; raw is your real machine with an autonomous agent on it. jus-dispatch init prints that difference and takes a typed agree before it will select raw.
dontAsk, then plan after #3970 found that a project's own .claude/settings.json outranked the narrower mode in a trusted checkout. That approach is retired: the boundary is the container now, not the model's own restraint.
One rule still binds under auto, and it is the project's own. permissions.deny in .claude/settings.json is honoured and recorded. Measured on claude 2.1.273: asked for a deny-listed file, the CLI reached for it through cat — not the Read tool — and the rule stopped it anyway. --setting-sources is deliberately never passed, because it would discard exactly that.
--dangerously-skip-permissions is never passed and must not be. An autonomous mode answers the permission system; that flag switches it off, and takes the deny rules with it.
Setup
jus-dispatch initPress Enter to accept a default (shown in brackets):
| Prompt | Default | What it means |
|---|---|---|
| API token | (none — required) | Your Juscribe API token, from Settings → API Tokens. It authenticates the agent with the server. |
| Server URL | wss://app.juscribe.ai/cable |
The WebSocket endpoint for your Juscribe instance. Accept the default unless you have a designated subdomain. |
| Project path | Current directory | Absolute path to the git repository the agent runs in. |
| Sandbox | (none — you are asked) | Where the CLI runs: raw, orbstack or docker. raw is your real machine and requires a typed agree. |
| CLI provider | claude |
Only shown when multi-LLM is enabled for your workspace. |
| Thinking effort | medium |
low, medium, high or max. Claude only. |
| Log level | info |
debug, info, warn or error. Use debug when troubleshooting a connection. |
| Log file | ~/.local/share/jus-dispatch/logs/jus-dispatch.log |
Where the structured log is written, in addition to stderr. |
Config is saved to ~/.config/jus-dispatch/config.toml, or to <project>/.jus/dispatch.toml when the directory has been through jus init.
~/.config/jus-station/ is not read, at any precedence. A frozen station and a new agent can sit on one machine, and sharing a config would have each writing over the other's scope. The station cannot connect either way — the server's protocol floor is past it — but the file is left alone rather than migrated. See Upgrading from jus-station.
Every value can be overridden at runtime by a flag (--token, --server, --project, --log-level, --log-file) or an environment variable (JUSCRIBE_API_TOKEN, JUS_SERVER_URL, JUS_PROJECT_PATH, JUS_LOG_LEVEL, JUS_LOG_FILE, JUS_EFFORT_LEVEL).
Your project's toolchain is yours to install
jus-dispatch initoffers to file this as a chore on your board, with the commands below already filled in for your sandbox — you can decline, and nothing is written to your tracker unless you say yes.
A sandbox gets git, the AI CLI and the jus toolset, and nothing else. It does not get your language runtime, your package manager or your database client — jus-dispatch has no way to know what those are.
Put an executable .jus/hooks/sandbox-setup in your repository. Both setup-orb and setup-docker run it, with your project as the working directory:
#!/usr/bin/env bash
set -euo pipefail
sudo apt-get update
sudo apt-get install -y nodejs npm postgresql-client- No hook is not an error. Most projects need no provisioning and none is invented for them.
- A hook that fails, or exists without an executable bit, fails setup — a sandbox missing the tools it was meant to install is one every dispatch dies in, somewhere that names neither the hook nor its permissions.
- It is not bounded by a timeout. A toolchain install can legitimately run for half an hour; the output streams to your terminal and
Ctrl-Cworks. .jus/hooks/orb-setupstill works. That was the name before the hook reached docker. Both are found, on both placements, andsandbox-setupwins if you have written both.
.jus/hooks/worktree-setup, and the two are not interchangeable. That one runs per dispatch, in a fresh worktree, and restores what you gitignore — typically starting with a dependency install. This one runs once per sandbox and installs the thing that dependency install invokes.
| Placement | What the hook becomes |
|---|---|
orbstack |
A provisioning step inside the orb, run once by setup-orb after git, the CLI and the jus toolset are installed. |
docker |
A build layer. setup-docker builds an image from ghcr.io/juscribe/jus-dispatch with your hook in it, tags it jus-dispatch-<project>-<hash>:latest and points [sandbox] target at that. Every container is `docker run -... |
jus-dispatch v0.8.24
Installing jus-dispatch
jus-dispatch is the remote dispatch agent for Juscribe. It connects to the Juscribe server over a WebSocket, runs a coding-agent CLI against your project when a dispatch arrives, and reports the result back to the board.
Platform support: macOS and Linux, amd64 and arm64. Requires the CLI you dispatch to — Claude Code by default.
Install
brew install juscribe/tap/jusThat installs the jus CLI and jus-dispatch together, and brew upgrade jus moves both. Binaries for macOS and Linux, amd64 and arm64, are attached to every release at github.com/juscribe/jus-dispatch/releases and download without authentication.
A container image ships on the same cut, for the docker placement:
docker pull ghcr.io/juscribe/jus-dispatch:latestlinux/amd64 and linux/arm64. --sandbox docker mode that left with it; p188 restored the placement layer and the image came back with it.
To build from a checkout instead:
cd dispatch && make buildThat writes dispatch/bin/jus-dispatch. make build-all cross-compiles all four platforms into the same directory, and make install copies the host build into $GOPATH/bin.
What it does NOT do
The station created a git worktree per dispatch, ran the CLI inside it, and then merged, pushed or left the branch. jus-dispatch leaves the branch and stops there (#4223).
- It creates a worktree, runs the CLI in it, removes the worktree and keeps the branch. The board is told the branch name and how many commits are on it.
- No merge, no push, no pull request, on any path. A person reviews and lands it. A run that committed nothing gets its branch deleted and the board says so rather than naming an empty one.
⚠️ .jus/hooks/worktree-setupruns inside the new worktree first, if your project has one — a git checkout is missing everything you gitignore. A hook that fails or is not executable fails the dispatch rather than handing an agent a broken tree.branch_strategyno longer arrives on the wire at all (#3902), and nothing here reads it. There is one behaviour, so there is nothing to select.
raw / orbstack / docker and the setup-sandbox, setup-orb, setup-docker and auth commands were restored across #4222, #4221, #4220, #4243 and #4245. jus-dispatch init is what chooses between them — the Setup section below records the choice; it does not make it, and this sentence said otherwise until #4292.
What a dispatch is allowed to do
It runs under --permission-mode auto — it can edit files (#4254).
raw there is nothing. Under orbstack and docker only the project directory is mounted, so a write outside it is refused by the kernel; raw is your real machine with an autonomous agent on it. jus-dispatch init prints that difference and takes a typed agree before it will select raw.
dontAsk, then plan after #3970 found that a project's own .claude/settings.json outranked the narrower mode in a trusted checkout. That approach is retired: the boundary is the container now, not the model's own restraint.
One rule still binds under auto, and it is the project's own. permissions.deny in .claude/settings.json is honoured and recorded. Measured on claude 2.1.273: asked for a deny-listed file, the CLI reached for it through cat — not the Read tool — and the rule stopped it anyway. --setting-sources is deliberately never passed, because it would discard exactly that.
--dangerously-skip-permissions is never passed and must not be. An autonomous mode answers the permission system; that flag switches it off, and takes the deny rules with it.
Setup
jus-dispatch initPress Enter to accept a default (shown in brackets):
| Prompt | Default | What it means |
|---|---|---|
| API token | (none — required) | Your Juscribe API token, from Settings → API Tokens. It authenticates the agent with the server. |
| Server URL | wss://app.juscribe.ai/cable |
The WebSocket endpoint for your Juscribe instance. Accept the default unless you have a designated subdomain. |
| Project path | Current directory | Absolute path to the git repository the agent runs in. |
| Sandbox | (none — you are asked) | Where the CLI runs: raw, orbstack or docker. raw is your real machine and requires a typed agree. |
| CLI provider | claude |
Only shown when multi-LLM is enabled for your workspace. |
| Thinking effort | medium |
low, medium, high or max. Claude only. |
| Log level | info |
debug, info, warn or error. Use debug when troubleshooting a connection. |
| Log file | ~/.local/share/jus-dispatch/logs/jus-dispatch.log |
Where the structured log is written, in addition to stderr. |
Config is saved to ~/.config/jus-dispatch/config.toml, or to <project>/.jus/dispatch.toml when the directory has been through jus init.
~/.config/jus-station/ is not read, at any precedence. A frozen station and a new agent can sit on one machine, and sharing a config would have each writing over the other's scope. The station cannot connect either way — the server's protocol floor is past it — but the file is left alone rather than migrated. See Upgrading from jus-station.
Every value can be overridden at runtime by a flag (--token, --server, --project, --log-level, --log-file) or an environment variable (JUSCRIBE_API_TOKEN, JUS_SERVER_URL, JUS_PROJECT_PATH, JUS_LOG_LEVEL, JUS_LOG_FILE, JUS_EFFORT_LEVEL).
Your project's toolchain is yours to install
jus-dispatch initoffers to file this as a chore on your board, with the commands below already filled in for your sandbox — you can decline, and nothing is written to your tracker unless you say yes.
A sandbox gets git, the AI CLI and the jus toolset, and nothing else. It does not get your language runtime, your package manager or your database client — jus-dispatch has no way to know what those are.
Put an executable .jus/hooks/sandbox-setup in your repository. Both setup-orb and setup-docker run it, with your project as the working directory:
#!/usr/bin/env bash
set -euo pipefail
sudo apt-get update
sudo apt-get install -y nodejs npm postgresql-client- No hook is not an error. Most projects need no provisioning and none is invented for them.
- A hook that fails, or exists without an executable bit, fails setup — a sandbox missing the tools it was meant to install is one every dispatch dies in, somewhere that names neither the hook nor its permissions.
- It is not bounded by a timeout. A toolchain install can legitimately run for half an hour; the output streams to your terminal and
Ctrl-Cworks. .jus/hooks/orb-setupstill works. That was the name before the hook reached docker. Both are found, on both placements, andsandbox-setupwins if you have written both.
.jus/hooks/worktree-setup, and the two are not interchangeable. That one runs per dispatch, in a fresh worktree, and restores what you gitignore — typically starting with a dependency install. This one runs once per sandbox and installs the thing that dependency install invokes.
| Placement | What the hook becomes |
|---|---|
orbstack |
A provisioning step inside the orb, run once by setup-orb after git, the CLI and the jus toolset are installed. |
docker |
A build layer. setup-docker builds an image from ghcr.io/juscribe/jus-dispatch with your hook in it, tags it jus-dispatch-<project>-<hash>:latest and points [sandbox] target at that. Every container is `docker run -... |
jus-dispatch v0.8.23
Installing jus-dispatch
jus-dispatch is the remote dispatch agent for Juscribe. It connects to the Juscribe server over a WebSocket, runs a coding-agent CLI against your project when a dispatch arrives, and reports the result back to the board.
Platform support: macOS and Linux, amd64 and arm64. Requires the CLI you dispatch to — Claude Code by default.
Install
brew install juscribe/tap/jusThat installs the jus CLI and jus-dispatch together, and brew upgrade jus moves both. Binaries for macOS and Linux, amd64 and arm64, are attached to every release at github.com/juscribe/jus-dispatch/releases and download without authentication.
A container image ships on the same cut, for the docker placement:
docker pull ghcr.io/juscribe/jus-dispatch:latestlinux/amd64 and linux/arm64. --sandbox docker mode that left with it; p188 restored the placement layer and the image came back with it.
To build from a checkout instead:
cd dispatch && make buildThat writes dispatch/bin/jus-dispatch. make build-all cross-compiles all four platforms into the same directory, and make install copies the host build into $GOPATH/bin.
What it does NOT do
The station created a git worktree per dispatch, ran the CLI inside it, and then merged, pushed or left the branch. jus-dispatch leaves the branch and stops there (#4223).
- It creates a worktree, runs the CLI in it, removes the worktree and keeps the branch. The board is told the branch name and how many commits are on it.
- No merge, no push, no pull request, on any path. A person reviews and lands it. A run that committed nothing gets its branch deleted and the board says so rather than naming an empty one.
⚠️ .jus/hooks/worktree-setupruns inside the new worktree first, if your project has one — a git checkout is missing everything you gitignore. A hook that fails or is not executable fails the dispatch rather than handing an agent a broken tree.branch_strategyno longer arrives on the wire at all (#3902), and nothing here reads it. There is one behaviour, so there is nothing to select.
raw / orbstack / docker and the setup-sandbox, setup-orb, setup-docker and auth commands were restored across #4222, #4221, #4220, #4243 and #4245. jus-dispatch init is what chooses between them — the Setup section below records the choice; it does not make it, and this sentence said otherwise until #4292.
What a dispatch is allowed to do
It runs under --permission-mode auto — it can edit files (#4254).
raw there is nothing. Under orbstack and docker only the project directory is mounted, so a write outside it is refused by the kernel; raw is your real machine with an autonomous agent on it. jus-dispatch init prints that difference and takes a typed agree before it will select raw.
dontAsk, then plan after #3970 found that a project's own .claude/settings.json outranked the narrower mode in a trusted checkout. That approach is retired: the boundary is the container now, not the model's own restraint.
One rule still binds under auto, and it is the project's own. permissions.deny in .claude/settings.json is honoured and recorded. Measured on claude 2.1.273: asked for a deny-listed file, the CLI reached for it through cat — not the Read tool — and the rule stopped it anyway. --setting-sources is deliberately never passed, because it would discard exactly that.
--dangerously-skip-permissions is never passed and must not be. An autonomous mode answers the permission system; that flag switches it off, and takes the deny rules with it.
Setup
jus-dispatch initPress Enter to accept a default (shown in brackets):
| Prompt | Default | What it means |
|---|---|---|
| API token | (none — required) | Your Juscribe API token, from Settings → API Tokens. It authenticates the agent with the server. |
| Server URL | wss://app.juscribe.ai/cable |
The WebSocket endpoint for your Juscribe instance. Accept the default unless you have a designated subdomain. |
| Project path | Current directory | Absolute path to the git repository the agent runs in. |
| Sandbox | (none — you are asked) | Where the CLI runs: raw, orbstack or docker. raw is your real machine and requires a typed agree. |
| CLI provider | claude |
Only shown when multi-LLM is enabled for your workspace. |
| Thinking effort | medium |
low, medium, high or max. Claude only. |
| Log level | info |
debug, info, warn or error. Use debug when troubleshooting a connection. |
| Log file | ~/.local/share/jus-dispatch/logs/jus-dispatch.log |
Where the structured log is written, in addition to stderr. |
Config is saved to ~/.config/jus-dispatch/config.toml, or to <project>/.jus/dispatch.toml when the directory has been through jus init.
~/.config/jus-station/ is not read, at any precedence. A frozen station and a new agent can sit on one machine, and sharing a config would have each writing over the other's scope. The station cannot connect either way — the server's protocol floor is past it — but the file is left alone rather than migrated. See Upgrading from jus-station.
Every value can be overridden at runtime by a flag (--token, --server, --project, --log-level, --log-file) or an environment variable (JUSCRIBE_API_TOKEN, JUS_SERVER_URL, JUS_PROJECT_PATH, JUS_LOG_LEVEL, JUS_LOG_FILE, JUS_EFFORT_LEVEL).
Your project's toolchain is yours to install
jus-dispatch initoffers to file this as a chore on your board, with the commands below already filled in for your sandbox — you can decline, and nothing is written to your tracker unless you say yes.
A sandbox gets git, the AI CLI and the jus toolset, and nothing else. It does not get your language runtime, your package manager or your database client — jus-dispatch has no way to know what those are.
Put an executable .jus/hooks/sandbox-setup in your repository. Both setup-orb and setup-docker run it, with your project as the working directory:
#!/usr/bin/env bash
set -euo pipefail
sudo apt-get update
sudo apt-get install -y nodejs npm postgresql-client- No hook is not an error. Most projects need no provisioning and none is invented for them.
- A hook that fails, or exists without an executable bit, fails setup — a sandbox missing the tools it was meant to install is one every dispatch dies in, somewhere that names neither the hook nor its permissions.
- It is not bounded by a timeout. A toolchain install can legitimately run for half an hour; the output streams to your terminal and
Ctrl-Cworks. .jus/hooks/orb-setupstill works. That was the name before the hook reached docker. Both are found, on both placements, andsandbox-setupwins if you have written both.
.jus/hooks/worktree-setup, and the two are not interchangeable. That one runs per dispatch, in a fresh worktree, and restores what you gitignore — typically starting with a dependency install. This one runs once per sandbox and installs the thing that dependency install invokes.
| Placement | What the hook becomes |
|---|---|
orbstack |
A provisioning step inside the orb, run once by setup-orb after git, the CLI and the jus toolset are installed. |
docker |
A build layer. setup-docker builds an image from ghcr.io/juscribe/jus-dispatch with your hook in it, tags it jus-dispatch-<project>-<hash>:latest and points [sandbox] target at that. Every container is `docker run -... |
jus-dispatch v0.8.22
Installing jus-dispatch
jus-dispatch is the remote dispatch agent for Juscribe. It connects to the Juscribe server over a WebSocket, runs a coding-agent CLI against your project when a dispatch arrives, and reports the result back to the board.
Platform support: macOS and Linux, amd64 and arm64. Requires the CLI you dispatch to — Claude Code by default.
Install
brew install juscribe/tap/jusThat installs the jus CLI and jus-dispatch together, and brew upgrade jus moves both. Binaries for macOS and Linux, amd64 and arm64, are attached to every release at github.com/juscribe/jus-dispatch/releases and download without authentication.
A container image ships on the same cut, for the docker placement:
docker pull ghcr.io/juscribe/jus-dispatch:latestlinux/amd64 and linux/arm64. --sandbox docker mode that left with it; p188 restored the placement layer and the image came back with it.
To build from a checkout instead:
cd dispatch && make buildThat writes dispatch/bin/jus-dispatch. make build-all cross-compiles all four platforms into the same directory, and make install copies the host build into $GOPATH/bin.
What it does NOT do
The station created a git worktree per dispatch, ran the CLI inside it, and then merged, pushed or left the branch. jus-dispatch leaves the branch and stops there (#4223).
- It creates a worktree, runs the CLI in it, removes the worktree and keeps the branch. The board is told the branch name and how many commits are on it.
- No merge, no push, no pull request, on any path. A person reviews and lands it. A run that committed nothing gets its branch deleted and the board says so rather than naming an empty one.
⚠️ .jus/hooks/worktree-setupruns inside the new worktree first, if your project has one — a git checkout is missing everything you gitignore. A hook that fails or is not executable fails the dispatch rather than handing an agent a broken tree.branch_strategyno longer arrives on the wire at all (#3902), and nothing here reads it. There is one behaviour, so there is nothing to select.
raw / orbstack / docker and the setup-sandbox, setup-orb, setup-docker and auth commands were restored across #4222, #4221, #4220, #4243 and #4245. jus-dispatch init is what chooses between them — the Setup section below records the choice; it does not make it, and this sentence said otherwise until #4292.
What a dispatch is allowed to do
It runs under --permission-mode auto — it can edit files (#4254).
raw there is nothing. Under orbstack and docker only the project directory is mounted, so a write outside it is refused by the kernel; raw is your real machine with an autonomous agent on it. jus-dispatch init prints that difference and takes a typed agree before it will select raw.
dontAsk, then plan after #3970 found that a project's own .claude/settings.json outranked the narrower mode in a trusted checkout. That approach is retired: the boundary is the container now, not the model's own restraint.
One rule still binds under auto, and it is the project's own. permissions.deny in .claude/settings.json is honoured and recorded. Measured on claude 2.1.273: asked for a deny-listed file, the CLI reached for it through cat — not the Read tool — and the rule stopped it anyway. --setting-sources is deliberately never passed, because it would discard exactly that.
--dangerously-skip-permissions is never passed and must not be. An autonomous mode answers the permission system; that flag switches it off, and takes the deny rules with it.
Setup
jus-dispatch initPress Enter to accept a default (shown in brackets):
| Prompt | Default | What it means |
|---|---|---|
| API token | (none — required) | Your Juscribe API token, from Settings → API Tokens. It authenticates the agent with the server. |
| Server URL | wss://app.juscribe.ai/cable |
The WebSocket endpoint for your Juscribe instance. Accept the default unless you have a designated subdomain. |
| Project path | Current directory | Absolute path to the git repository the agent runs in. |
| Sandbox | (none — you are asked) | Where the CLI runs: raw, orbstack or docker. raw is your real machine and requires a typed agree. |
| CLI provider | claude |
Only shown when multi-LLM is enabled for your workspace. |
| Thinking effort | medium |
low, medium, high or max. Claude only. |
| Log level | info |
debug, info, warn or error. Use debug when troubleshooting a connection. |
| Log file | ~/.local/share/jus-dispatch/logs/jus-dispatch.log |
Where the structured log is written, in addition to stderr. |
Config is saved to ~/.config/jus-dispatch/config.toml, or to <project>/.jus/dispatch.toml when the directory has been through jus init.
~/.config/jus-station/ is not read, at any precedence. A frozen station and a new agent can sit on one machine, and sharing a config would have each writing over the other's scope. The station cannot connect either way — the server's protocol floor is past it — but the file is left alone rather than migrated. See Upgrading from jus-station.
Every value can be overridden at runtime by a flag (--token, --server, --project, --log-level, --log-file) or an environment variable (JUSCRIBE_API_TOKEN, JUS_SERVER_URL, JUS_PROJECT_PATH, JUS_LOG_LEVEL, JUS_LOG_FILE, JUS_EFFORT_LEVEL).
Your project's toolchain is yours to install
jus-dispatch initoffers to file this as a chore on your board, with the commands below already filled in for your sandbox — you can decline, and nothing is written to your tracker unless you say yes.
A sandbox gets git, the AI CLI and the jus toolset, and nothing else. It does not get your language runtime, your package manager or your database client — jus-dispatch has no way to know what those are.
Put an executable .jus/hooks/sandbox-setup in your repository. Both setup-orb and setup-docker run it, with your project as the working directory:
#!/usr/bin/env bash
set -euo pipefail
sudo apt-get update
sudo apt-get install -y nodejs npm postgresql-client- No hook is not an error. Most projects need no provisioning and none is invented for them.
- A hook that fails, or exists without an executable bit, fails setup — a sandbox missing the tools it was meant to install is one every dispatch dies in, somewhere that names neither the hook nor its permissions.
- It is not bounded by a timeout. A toolchain install can legitimately run for half an hour; the output streams to your terminal and
Ctrl-Cworks. .jus/hooks/orb-setupstill works. That was the name before the hook reached docker. Both are found, on both placements, andsandbox-setupwins if you have written both.
.jus/hooks/worktree-setup, and the two are not interchangeable. That one runs per dispatch, in a fresh worktree, and restores what you gitignore — typically starting with a dependency install. This one runs once per sandbox and installs the thing that dependency install invokes.
| Placement | What the hook becomes |
|---|---|
orbstack |
A provisioning step inside the orb, run once by setup-orb after git, the CLI and the jus toolset are installed. |
docker |
A build layer. setup-docker builds an image from ghcr.io/juscribe/jus-dispatch with your hook in it, tags it jus-dispatch-<project>-<hash>:latest and points [sandbox] target at that. Every container is `docker run -... |
jus-dispatch v0.8.21
Installing jus-dispatch
jus-dispatch is the remote dispatch agent for Juscribe. It connects to the Juscribe server over a WebSocket, runs a coding-agent CLI against your project when a dispatch arrives, and reports the result back to the board.
Platform support: macOS and Linux, amd64 and arm64. Requires the CLI you dispatch to — Claude Code by default.
Install
brew install juscribe/tap/jusThat installs the jus CLI and jus-dispatch together, and brew upgrade jus moves both. Binaries for macOS and Linux, amd64 and arm64, are attached to every release at github.com/juscribe/jus-dispatch/releases and download without authentication.
A container image ships on the same cut, for the docker placement:
docker pull ghcr.io/juscribe/jus-dispatch:latestlinux/amd64 and linux/arm64. --sandbox docker mode that left with it; p188 restored the placement layer and the image came back with it.
To build from a checkout instead:
cd dispatch && make buildThat writes dispatch/bin/jus-dispatch. make build-all cross-compiles all four platforms into the same directory, and make install copies the host build into $GOPATH/bin.
What it does NOT do
The station created a git worktree per dispatch, ran the CLI inside it, and then merged, pushed or left the branch. jus-dispatch leaves the branch and stops there (#4223).
- It creates a worktree, runs the CLI in it, removes the worktree and keeps the branch. The board is told the branch name and how many commits are on it.
- No merge, no push, no pull request, on any path. A person reviews and lands it. A run that committed nothing gets its branch deleted and the board says so rather than naming an empty one.
⚠️ .jus/hooks/worktree-setupruns inside the new worktree first, if your project has one — a git checkout is missing everything you gitignore. A hook that fails or is not executable fails the dispatch rather than handing an agent a broken tree.branch_strategyno longer arrives on the wire at all (#3902), and nothing here reads it. There is one behaviour, so there is nothing to select.
raw / orbstack / docker and the setup-sandbox, setup-orb, setup-docker and auth commands were restored across #4222, #4221, #4220, #4243 and #4245. jus-dispatch init is what chooses between them — the Setup section below records the choice; it does not make it, and this sentence said otherwise until #4292.
What a dispatch is allowed to do
It runs under --permission-mode auto — it can edit files (#4254).
raw there is nothing. Under orbstack and docker only the project directory is mounted, so a write outside it is refused by the kernel; raw is your real machine with an autonomous agent on it. jus-dispatch init prints that difference and takes a typed agree before it will select raw.
dontAsk, then plan after #3970 found that a project's own .claude/settings.json outranked the narrower mode in a trusted checkout. That approach is retired: the boundary is the container now, not the model's own restraint.
One rule still binds under auto, and it is the project's own. permissions.deny in .claude/settings.json is honoured and recorded. Measured on claude 2.1.273: asked for a deny-listed file, the CLI reached for it through cat — not the Read tool — and the rule stopped it anyway. --setting-sources is deliberately never passed, because it would discard exactly that.
--dangerously-skip-permissions is never passed and must not be. An autonomous mode answers the permission system; that flag switches it off, and takes the deny rules with it.
Setup
jus-dispatch initPress Enter to accept a default (shown in brackets):
| Prompt | Default | What it means |
|---|---|---|
| API token | (none — required) | Your Juscribe API token, from Settings → API Tokens. It authenticates the agent with the server. |
| Server URL | wss://app.juscribe.ai/cable |
The WebSocket endpoint for your Juscribe instance. Accept the default unless you have a designated subdomain. |
| Project path | Current directory | Absolute path to the git repository the agent runs in. |
| Sandbox | (none — you are asked) | Where the CLI runs: raw, orbstack or docker. raw is your real machine and requires a typed agree. |
| CLI provider | claude |
Only shown when multi-LLM is enabled for your workspace. |
| Thinking effort | medium |
low, medium, high or max. Claude only. |
| Log level | info |
debug, info, warn or error. Use debug when troubleshooting a connection. |
| Log file | ~/.local/share/jus-dispatch/logs/jus-dispatch.log |
Where the structured log is written, in addition to stderr. |
Config is saved to ~/.config/jus-dispatch/config.toml, or to <project>/.jus/dispatch.toml when the directory has been through jus init.
~/.config/jus-station/ is not read, at any precedence. A frozen station and a new agent can sit on one machine, and sharing a config would have each writing over the other's scope. The station cannot connect either way — the server's protocol floor is past it — but the file is left alone rather than migrated. See Upgrading from jus-station.
Every value can be overridden at runtime by a flag (--token, --server, --project, --log-level, --log-file) or an environment variable (JUSCRIBE_API_TOKEN, JUS_SERVER_URL, JUS_PROJECT_PATH, JUS_LOG_LEVEL, JUS_LOG_FILE, JUS_EFFORT_LEVEL).
Your project's toolchain is yours to install
jus-dispatch initoffers to file this as a chore on your board, with the commands below already filled in for your sandbox — you can decline, and nothing is written to your tracker unless you say yes.
A sandbox gets git, the AI CLI and the jus toolset, and nothing else. It does not get your language runtime, your package manager or your database client — jus-dispatch has no way to know what those are.
Put an executable .jus/hooks/sandbox-setup in your repository. Both setup-orb and setup-docker run it, with your project as the working directory:
#!/usr/bin/env bash
set -euo pipefail
sudo apt-get update
sudo apt-get install -y nodejs npm postgresql-client- No hook is not an error. Most projects need no provisioning and none is invented for them.
- A hook that fails, or exists without an executable bit, fails setup — a sandbox missing the tools it was meant to install is one every dispatch dies in, somewhere that names neither the hook nor its permissions.
- It is not bounded by a timeout. A toolchain install can legitimately run for half an hour; the output streams to your terminal and
Ctrl-Cworks. .jus/hooks/orb-setupstill works. That was the name before the hook reached docker. Both are found, on both placements, andsandbox-setupwins if you have written both.
.jus/hooks/worktree-setup, and the two are not interchangeable. That one runs per dispatch, in a fresh worktree, and restores what you gitignore — typically starting with a dependency install. This one runs once per sandbox and installs the thing that dependency install invokes.
| Placement | What the hook becomes |
|---|---|
orbstack |
A provisioning step inside the orb, run once by setup-orb after git, the CLI and the jus toolset are installed. |
docker |
A build layer. setup-docker builds an image from ghcr.io/juscribe/jus-dispatch with your hook in it, tags it jus-dispatch-<project>-<hash>:latest and points [sandbox] target at that. Every container is `docker run -... |
jus-dispatch v0.8.20
Installing jus-dispatch
jus-dispatch is the remote dispatch agent for Juscribe. It connects to the Juscribe server over a WebSocket, runs a coding-agent CLI against your project when a dispatch arrives, and reports the result back to the board.
Platform support: macOS and Linux, amd64 and arm64. Requires the CLI you dispatch to — Claude Code by default.
Install
brew install juscribe/tap/jusThat installs the jus CLI and jus-dispatch together, and brew upgrade jus moves both. Binaries for macOS and Linux, amd64 and arm64, are attached to every release at github.com/juscribe/jus-dispatch/releases and download without authentication.
A container image ships on the same cut, for the docker placement:
docker pull ghcr.io/juscribe/jus-dispatch:latestlinux/amd64 and linux/arm64. --sandbox docker mode that left with it; p188 restored the placement layer and the image came back with it.
To build from a checkout instead:
cd dispatch && make buildThat writes dispatch/bin/jus-dispatch. make build-all cross-compiles all four platforms into the same directory, and make install copies the host build into $GOPATH/bin.
What it does NOT do
The station created a git worktree per dispatch, ran the CLI inside it, and then merged, pushed or left the branch. jus-dispatch leaves the branch and stops there (#4223).
- It creates a worktree, runs the CLI in it, removes the worktree and keeps the branch. The board is told the branch name and how many commits are on it.
- No merge, no push, no pull request, on any path. A person reviews and lands it. A run that committed nothing gets its branch deleted and the board says so rather than naming an empty one.
⚠️ .jus/hooks/worktree-setupruns inside the new worktree first, if your project has one — a git checkout is missing everything you gitignore. A hook that fails or is not executable fails the dispatch rather than handing an agent a broken tree.branch_strategyno longer arrives on the wire at all (#3902), and nothing here reads it. There is one behaviour, so there is nothing to select.
raw / orbstack / docker and the setup-sandbox, setup-orb, setup-docker and auth commands were restored across #4222, #4221, #4220, #4243 and #4245. jus-dispatch init is what chooses between them — the Setup section below records the choice; it does not make it, and this sentence said otherwise until #4292.
What a dispatch is allowed to do
It runs under --permission-mode auto — it can edit files (#4254).
raw there is nothing. Under orbstack and docker only the project directory is mounted, so a write outside it is refused by the kernel; raw is your real machine with an autonomous agent on it. jus-dispatch init prints that difference and takes a typed agree before it will select raw.
dontAsk, then plan after #3970 found that a project's own .claude/settings.json outranked the narrower mode in a trusted checkout. That approach is retired: the boundary is the container now, not the model's own restraint.
One rule still binds under auto, and it is the project's own. permissions.deny in .claude/settings.json is honoured and recorded. Measured on claude 2.1.273: asked for a deny-listed file, the CLI reached for it through cat — not the Read tool — and the rule stopped it anyway. --setting-sources is deliberately never passed, because it would discard exactly that.
--dangerously-skip-permissions is never passed and must not be. An autonomous mode answers the permission system; that flag switches it off, and takes the deny rules with it.
Setup
jus-dispatch initPress Enter to accept a default (shown in brackets):
| Prompt | Default | What it means |
|---|---|---|
| API token | (none — required) | Your Juscribe API token, from Settings → API Tokens. It authenticates the agent with the server. |
| Server URL | wss://app.juscribe.ai/cable |
The WebSocket endpoint for your Juscribe instance. Accept the default unless you have a designated subdomain. |
| Project path | Current directory | Absolute path to the git repository the agent runs in. |
| Sandbox | (none — you are asked) | Where the CLI runs: raw, orbstack or docker. raw is your real machine and requires a typed agree. |
| CLI provider | claude |
Only shown when multi-LLM is enabled for your workspace. |
| Thinking effort | medium |
low, medium, high or max. Claude only. |
| Log level | info |
debug, info, warn or error. Use debug when troubleshooting a connection. |
| Log file | ~/.local/share/jus-dispatch/logs/jus-dispatch.log |
Where the structured log is written, in addition to stderr. |
Config is saved to ~/.config/jus-dispatch/config.toml, or to <project>/.jus/dispatch.toml when the directory has been through jus init.
~/.config/jus-station/ is not read, at any precedence. A frozen station and a new agent can sit on one machine, and sharing a config would have each writing over the other's scope. The station cannot connect either way — the server's protocol floor is past it — but the file is left alone rather than migrated. See Upgrading from jus-station.
Every value can be overridden at runtime by a flag (--token, --server, --project, --log-level, --log-file) or an environment variable (JUSCRIBE_API_TOKEN, JUS_SERVER_URL, JUS_PROJECT_PATH, JUS_LOG_LEVEL, JUS_LOG_FILE, JUS_EFFORT_LEVEL).
Your project's toolchain is yours to install
jus-dispatch initoffers to file this as a chore on your board, with the commands below already filled in for your sandbox — you can decline, and nothing is written to your tracker unless you say yes.
A sandbox gets git, the AI CLI and the jus toolset, and nothing else. It does not get your language runtime, your package manager or your database client — jus-dispatch has no way to know what those are.
Put an executable .jus/hooks/sandbox-setup in your repository. Both setup-orb and setup-docker run it, with your project as the working directory:
#!/usr/bin/env bash
set -euo pipefail
sudo apt-get update
sudo apt-get install -y nodejs npm postgresql-client- No hook is not an error. Most projects need no provisioning and none is invented for them.
- A hook that fails, or exists without an executable bit, fails setup — a sandbox missing the tools it was meant to install is one every dispatch dies in, somewhere that names neither the hook nor its permissions.
- It is not bounded by a timeout. A toolchain install can legitimately run for half an hour; the output streams to your terminal and
Ctrl-Cworks. .jus/hooks/orb-setupstill works. That was the name before the hook reached docker. Both are found, on both placements, andsandbox-setupwins if you have written both.
.jus/hooks/worktree-setup, and the two are not interchangeable. That one runs per dispatch, in a fresh worktree, and restores what you gitignore — typically starting with a dependency install. This one runs once per sandbox and installs the thing that dependency install invokes.
| Placement | What the hook becomes |
|---|---|
orbstack |
A provisioning step inside the orb, run once by setup-orb after git, the CLI and the jus toolset are installed. |
docker |
A build layer. setup-docker builds an image from ghcr.io/juscribe/jus-dispatch with your hook in it, tags it jus-dispatch-<project>-<hash>:latest and points [sandbox] target at that. Every container is `docker run -... |
jus-dispatch v0.8.19
Installing jus-dispatch
jus-dispatch is the remote dispatch agent for Juscribe. It connects to the Juscribe server over a WebSocket, runs a coding-agent CLI against your project when a dispatch arrives, and reports the result back to the board.
Platform support: macOS and Linux, amd64 and arm64. Requires the CLI you dispatch to — Claude Code by default.
Install
brew install juscribe/tap/jusThat installs the jus CLI and jus-dispatch together, and brew upgrade jus moves both. Binaries for macOS and Linux, amd64 and arm64, are attached to every release at github.com/juscribe/jus-dispatch/releases and download without authentication.
A container image ships on the same cut, for the docker placement:
docker pull ghcr.io/juscribe/jus-dispatch:latestlinux/amd64 and linux/arm64. --sandbox docker mode that left with it; p188 restored the placement layer and the image came back with it.
To build from a checkout instead:
cd dispatch && make buildThat writes dispatch/bin/jus-dispatch. make build-all cross-compiles all four platforms into the same directory, and make install copies the host build into $GOPATH/bin.
What it does NOT do
The station created a git worktree per dispatch, ran the CLI inside it, and then merged, pushed or left the branch. jus-dispatch leaves the branch and stops there (#4223).
- It creates a worktree, runs the CLI in it, removes the worktree and keeps the branch. The board is told the branch name and how many commits are on it.
- No merge, no push, no pull request, on any path. A person reviews and lands it. A run that committed nothing gets its branch deleted and the board says so rather than naming an empty one.
⚠️ .jus/hooks/worktree-setupruns inside the new worktree first, if your project has one — a git checkout is missing everything you gitignore. A hook that fails or is not executable fails the dispatch rather than handing an agent a broken tree.branch_strategyno longer arrives on the wire at all (#3902), and nothing here reads it. There is one behaviour, so there is nothing to select.
raw / orbstack / docker and the setup-sandbox, setup-orb, setup-docker and auth commands were restored across #4222, #4221, #4220, #4243 and #4245. jus-dispatch init is what chooses between them — the Setup section below records the choice; it does not make it, and this sentence said otherwise until #4292.
What a dispatch is allowed to do
It runs under --permission-mode auto — it can edit files (#4254).
raw there is nothing. Under orbstack and docker only the project directory is mounted, so a write outside it is refused by the kernel; raw is your real machine with an autonomous agent on it. jus-dispatch init prints that difference and takes a typed agree before it will select raw.
dontAsk, then plan after #3970 found that a project's own .claude/settings.json outranked the narrower mode in a trusted checkout. That approach is retired: the boundary is the container now, not the model's own restraint.
One rule still binds under auto, and it is the project's own. permissions.deny in .claude/settings.json is honoured and recorded. Measured on claude 2.1.273: asked for a deny-listed file, the CLI reached for it through cat — not the Read tool — and the rule stopped it anyway. --setting-sources is deliberately never passed, because it would discard exactly that.
--dangerously-skip-permissions is never passed and must not be. An autonomous mode answers the permission system; that flag switches it off, and takes the deny rules with it.
Setup
jus-dispatch initPress Enter to accept a default (shown in brackets):
| Prompt | Default | What it means |
|---|---|---|
| API token | (none — required) | Your Juscribe API token, from Settings → API Tokens. It authenticates the agent with the server. |
| Server URL | wss://app.juscribe.ai/cable |
The WebSocket endpoint for your Juscribe instance. Accept the default unless you have a designated subdomain. |
| Project path | Current directory | Absolute path to the git repository the agent runs in. |
| Sandbox | (none — you are asked) | Where the CLI runs: raw, orbstack or docker. raw is your real machine and requires a typed agree. |
| CLI provider | claude |
Only shown when multi-LLM is enabled for your workspace. |
| Thinking effort | medium |
low, medium, high or max. Claude only. |
| Log level | info |
debug, info, warn or error. Use debug when troubleshooting a connection. |
| Log file | ~/.local/share/jus-dispatch/logs/jus-dispatch.log |
Where the structured log is written, in addition to stderr. |
Config is saved to ~/.config/jus-dispatch/config.toml, or to <project>/.jus/dispatch.toml when the directory has been through jus init.
~/.config/jus-station/ is not read, at any precedence. A frozen station and a new agent can sit on one machine, and sharing a config would have each writing over the other's scope. The station cannot connect either way — the server's protocol floor is past it — but the file is left alone rather than migrated. See Upgrading from jus-station.
Every value can be overridden at runtime by a flag (--token, --server, --project, --log-level, --log-file) or an environment variable (JUSCRIBE_API_TOKEN, JUS_SERVER_URL, JUS_PROJECT_PATH, JUS_LOG_LEVEL, JUS_LOG_FILE, JUS_EFFORT_LEVEL).
Your project's toolchain is yours to install
jus-dispatch initoffers to file this as a chore on your board, with the commands below already filled in for your sandbox — you can decline, and nothing is written to your tracker unless you say yes.
A sandbox gets git, the AI CLI and the jus toolset, and nothing else. It does not get your language runtime, your package manager or your database client — jus-dispatch has no way to know what those are.
Put an executable .jus/hooks/sandbox-setup in your repository. Both setup-orb and setup-docker run it, with your project as the working directory:
#!/usr/bin/env bash
set -euo pipefail
sudo apt-get update
sudo apt-get install -y nodejs npm postgresql-client- No hook is not an error. Most projects need no provisioning and none is invented for them.
- A hook that fails, or exists without an executable bit, fails setup — a sandbox missing the tools it was meant to install is one every dispatch dies in, somewhere that names neither the hook nor its permissions.
- It is not bounded by a timeout. A toolchain install can legitimately run for half an hour; the output streams to your terminal and
Ctrl-Cworks. .jus/hooks/orb-setupstill works. That was the name before the hook reached docker. Both are found, on both placements, andsandbox-setupwins if you have written both.
.jus/hooks/worktree-setup, and the two are not interchangeable. That one runs per dispatch, in a fresh worktree, and restores what you gitignore — typically starting with a dependency install. This one runs once per sandbox and installs the thing that dependency install invokes.
| Placement | What the hook becomes |
|---|---|
orbstack |
A provisioning step inside the orb, run once by setup-orb after git, the CLI and the jus toolset are installed. |
docker |
A build layer. setup-docker builds an image from ghcr.io/juscribe/jus-dispatch with your hook in it, tags it jus-dispatch-<project>-<hash>:latest and points [sandbox] target at that. Every container is `docker run -... |