Docs
DocsRemote DevelopmentRemote Tasks

Remote Tasks

Provision and tear down per-task remote workspaces with your own infrastructure scripts

Contact us to get started:

Remote Tasks let each agent run in its own isolated remote workspace. Your provision script creates the workspace, Emdash connects to it over SSH, and the task's terminals, agent processes, Git operations, and file browsing run inside that workspace.

When the workspace is terminated, Emdash runs your terminate command so your infrastructure can clean up the remote workspace.

This can work with cloud VMs, Kubernetes pods, Docker containers, internal dev environment platforms, or any backend that can expose an SSH-accessible workspace.

AWSHetznerAzureDocker

How It Works

  1. Configure a workspace provider for the project.
  2. Create a task with remote infrastructure enabled.
  3. Emdash runs your provision command from the project directory.
  4. Your command prints a JSON object to stdout with SSH connection details.
  5. Emdash connects to the workspace over SSH.
  6. Emdash starts task terminals and coding agents inside worktreePath.
  7. When the workspace is terminated, Emdash runs your terminate command.

After Emdash connects, remote task workspaces use the same remote workspace capabilities as remote projects.

Setup

1. Create Scripts

Create provision and terminate scripts in your project, for example:

scripts/provision-workspace.sh
scripts/terminate-workspace.sh

Make them executable:

chmod +x scripts/provision-workspace.sh scripts/terminate-workspace.sh

Provision Script

The provision script creates the workspace and prints SSH connection details as JSON to stdout.

Only the JSON object should be printed to stdout. Send logs to stderr.

#!/bin/bash
set -euo pipefail

echo "Provisioning workspace..." >&2

WORKSPACE_ID="ws-$(date +%s)"
HOST="localhost"
PORT="2222"
USERNAME="devuser"
PASSWORD="devpass"
WORKTREE_PATH="/home/devuser/workspace"
FORWARD_AGENT=false

# Create your VM, pod, container, or internal workspace here.
# Ensure SSH is reachable and the repository exists at WORKTREE_PATH.

cat <<EOF
{
  "id": "$WORKSPACE_ID",
  "host": "$HOST",
  "port": $PORT,
  "username": "$USERNAME",
  "password": "$PASSWORD",
  "worktreePath": "$WORKTREE_PATH",
  "forwardAgent": $FORWARD_AGENT
}
EOF

Provision output fields:

FieldRequiredDescription
idYesExternal workspace identifier. Passed to terminate as REMOTE_WORKSPACE_ID.
hostYesHostname or IP address Emdash should connect to.
portNoSSH port. Defaults to 22.
usernameNoSSH username. Defaults to the current Emdash process user.
passwordNoSSH password. If omitted, Emdash attempts SSH agent auth using SSH_AUTH_SOCK.
worktreePathNoRepository path on the provisioned workspace. Defaults to the project path.
forwardAgentNoJSON boolean. Set to true to forward the local SSH agent into the workspace. Defaults to false.

Terminate Script

The terminate command runs when Emdash terminates the workspace. Emdash sets REMOTE_WORKSPACE_ID to the id returned by the provision command.

#!/bin/bash
set -euo pipefail

echo "Terminating workspace $REMOTE_WORKSPACE_ID..." >&2

# Destroy your VM, pod, container, or internal workspace here.
# your-cli delete-workspace "$REMOTE_WORKSPACE_ID"

echo "Done." >&2

Configure the workspace provider

  1. Open the project.
  2. Open Project Settings.
  3. Find Workspace provider.
  4. Enter the provision and terminate commands.
  5. Save.

Create A Remote Task

When the workspace provider feature is enabled in your Emdash build:

  1. Click New Task.
  2. Enable remote infrastructure.
  3. Create the task.

Emdash will run the provision command, parse the JSON output, connect to the remote workspace over SSH, and start the task inside the returned worktreePath.

Workspace Requirements

Provisioned workspaces should include:

  • An SSH server reachable from the project host running the provision command.
  • Git.
  • Any CLI coding agents you want to use.
  • Any credentials or environment variables needed by those agents.

Recommended:

  • tmux, if you want persistent sessions.
  • gh, if you want GitHub workflows from inside the workspace.
  • Repository credentials for pushing and pulling.

SSH Authentication

Remote task SSH connections are ephemeral and are created from the JSON returned by your provision command.

If password is returned, Emdash uses password authentication.

If password is omitted, Emdash attempts SSH agent authentication using SSH_AUTH_SOCK.

SSH agent authentication and SSH agent forwarding are separate. Agent authentication lets Emdash use your local SSH agent to connect to the provisioned workspace. Agent forwarding exposes that local agent inside the provisioned workspace for nested SSH or Git commands.

To enable agent forwarding, return "forwardAgent": true from the provision command. Omitting forwardAgent or returning false keeps forwarding disabled. The value must be a JSON boolean, not the string "true" or "false".

When forwardAgent is true, Emdash requires a local SSH agent socket. If no socket is available, the SSH connection fails instead of silently starting without forwarding.

Only enable agent forwarding for provisioned workspaces you trust. It is useful when Git commit signing, private Git remotes, or nested SSH commands inside the workspace need access to your local SSH agent.

For the most predictable setup, return explicit host, port, username, and either password or ensure the SSH agent available to Emdash can authenticate to the workspace.

Script Contract Reference

Provision Command

AspectDetails
Execution/bin/sh -c <provisionCommand>
Working directoryProject directory on the project host. For local projects, this is the local project root. For SSH projects, this is the remote project path.
EnvironmentInherits the Emdash process environment for local projects, or the remote shell environment for SSH projects. Emdash does not currently inject remote task provision variables.
StdoutA single JSON object with at least id and host
StderrCaptured as process stderr
SuccessExit code 0 and valid JSON output
FailureNon-zero exit code, empty stdout, invalid JSON, or failed SSH connection
TimeoutThe task provisioning operation times out after 10 minutes

Terminate Command

AspectDetails
Execution/bin/sh -c <terminateCommand>
Working directoryProject directory on the project host
EnvironmentREMOTE_WORKSPACE_ID is set to the id returned by the provision command
SuccessExit code 0
FailureLogged during cleanup; Emdash continues task deletion cleanup
TimeoutThe task teardown operation times out after 10 minutes

Troubleshooting

Provision Fails

Run the provision command manually from the project directory:

./scripts/provision-workspace.sh

Validate stdout:

./scripts/provision-workspace.sh 2>/dev/null | jq .

Check that:

  • stdout contains only the JSON object.
  • id and host are present.
  • port, if present, is a number.
  • the command exits with code 0.

SSH Connection Fails

Use the values returned by the provision script and test SSH manually:

ssh -p <port> <username>@<host>

Check that:

  • the workspace is reachable from the machine running Emdash.
  • the SSH server is running.
  • password or SSH agent authentication works.
  • if forwardAgent is true, SSH_AUTH_SOCK is available to Emdash and ssh-add -l lists the expected key.
  • the repository exists at worktreePath.

Terminate Does Not Clean Up

Run the terminate command manually:

REMOTE_WORKSPACE_ID=<id-from-provision-output> ./scripts/terminate-workspace.sh

The terminate script should tolerate repeated calls and missing infrastructure, since cleanup may be retried or run after partial failures.

Last updated on June 30, 2026
Â