fix: change cmux npm package to mux (#533)

This commit is contained in:
Michael Suchacz
2025-11-15 18:57:42 +01:00
committed by GitHub
parent f304201b6f
commit 0e3263fd6f
7 changed files with 262 additions and 191 deletions
View File

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 18 KiB

-135
View File
@@ -1,135 +0,0 @@
#!/usr/bin/env bash
BOLD='\033[0;1m'
RESET='\033[0m'
CMUX_BINARY="${INSTALL_PREFIX}/cmux"
function run_cmux() {
local port_value
port_value="${PORT}"
if [ -z "$port_value" ]; then
port_value="4000"
fi
echo "🚀 Starting cmux server on port $port_value..."
echo "Check logs at ${LOG_PATH}!"
PORT="$port_value" "$CMUX_BINARY" server --port "$port_value" > "${LOG_PATH}" 2>&1 &
}
# Check if cmux is already installed for offline mode
if [ "${OFFLINE}" = true ]; then
if [ -f "$CMUX_BINARY" ]; then
echo "🥳 Found a copy of cmux"
run_cmux
exit 0
fi
echo "❌ Failed to find a copy of cmux"
exit 1
fi
# If there is no cached install OR we don't want to use a cached install
if [ ! -f "$CMUX_BINARY" ] || [ "${USE_CACHED}" != true ]; then
printf "$${BOLD}Installing cmux from npm...\n"
# Clean up from other install (in case install prefix changed).
if [ -n "$CODER_SCRIPT_BIN_DIR" ] && [ -e "$CODER_SCRIPT_BIN_DIR/cmux" ]; then
rm "$CODER_SCRIPT_BIN_DIR/cmux"
fi
mkdir -p "$(dirname "$CMUX_BINARY")"
if command -v npm > /dev/null 2>&1; then
echo "📦 Installing @coder/cmux via npm into ${INSTALL_PREFIX}..."
NPM_WORKDIR="${INSTALL_PREFIX}/npm"
mkdir -p "$NPM_WORKDIR"
cd "$NPM_WORKDIR" || exit 1
if [ ! -f package.json ]; then
echo '{}' > package.json
fi
PKG="@coder/cmux"
if [ -z "${VERSION}" ] || [ "${VERSION}" = "latest" ]; then
PKG_SPEC="$PKG@latest"
else
PKG_SPEC="$PKG@${VERSION}"
fi
if ! npm install --no-audit --no-fund --omit=dev "$PKG_SPEC"; then
echo "❌ Failed to install @coder/cmux via npm"
exit 1
fi
# Determine the installed binary path
BIN_DIR="$NPM_WORKDIR/node_modules/.bin"
CANDIDATE="$BIN_DIR/cmux"
if [ ! -f "$CANDIDATE" ]; then
echo "❌ Could not locate cmux binary after npm install"
exit 1
fi
chmod +x "$CANDIDATE" || true
ln -sf "$CANDIDATE" "$CMUX_BINARY"
else
echo "📥 npm not found; downloading tarball from npm registry..."
VERSION_TO_USE="${VERSION}"
if [ -z "$VERSION_TO_USE" ] || [ "$VERSION_TO_USE" = "latest" ]; then
# Try to determine the latest version
META_URL="https://registry.npmjs.org/@coder/cmux/latest"
VERSION_TO_USE="$(curl -fsSL "$META_URL" | sed -n 's/.*"version":"\([^"]*\)".*/\1/p' | head -n1)"
if [ -z "$VERSION_TO_USE" ]; then
echo "❌ Could not determine latest version for @coder/cmux"
exit 1
fi
fi
TARBALL_URL="https://registry.npmjs.org/@coder/cmux/-/cmux-$VERSION_TO_USE.tgz"
TMP_DIR="$(mktemp -d)"
TAR_PATH="$TMP_DIR/cmux.tgz"
if ! curl -fsSL "$TARBALL_URL" -o "$TAR_PATH"; then
echo "❌ Failed to download tarball: $TARBALL_URL"
rm -rf "$TMP_DIR"
exit 1
fi
if ! tar -xzf "$TAR_PATH" -C "$TMP_DIR"; then
echo "❌ Failed to extract tarball"
rm -rf "$TMP_DIR"
exit 1
fi
CANDIDATE=""
# Common locations
if [ -f "$TMP_DIR/package/bin/cmux" ]; then
CANDIDATE="$TMP_DIR/package/bin/cmux"
elif [ -f "$TMP_DIR/package/bin/cmux.js" ]; then
CANDIDATE="$TMP_DIR/package/bin/cmux.js"
elif [ -f "$TMP_DIR/package/bin/cmux.mjs" ]; then
CANDIDATE="$TMP_DIR/package/bin/cmux.mjs"
else
# Try to read package.json bin field
if [ -f "$TMP_DIR/package/package.json" ]; then
BIN_PATH=$(sed -n 's/.*"bin"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p' "$TMP_DIR/package/package.json" | head -n1)
if [ -z "$BIN_PATH" ]; then
BIN_PATH=$(sed -n '/"bin"[[:space:]]*:[[:space:]]*{/,/}/p' "$TMP_DIR/package/package.json" | sed -n 's/.*"cmux"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p' | head -n1)
fi
if [ -n "$BIN_PATH" ] && [ -f "$TMP_DIR/package/$BIN_PATH" ]; then
CANDIDATE="$TMP_DIR/package/$BIN_PATH"
fi
fi
# Fallback: search for plausible filenames
if [ -z "$CANDIDATE" ] || [ ! -f "$CANDIDATE" ]; then
CANDIDATE=$(find "$TMP_DIR/package" -maxdepth 4 -type f \( -name "cmux" -o -name "cmux.js" -o -name "cmux.mjs" -o -name "cmux.cjs" \) | head -n1)
fi
fi
if [ -z "$CANDIDATE" ] || [ ! -f "$CANDIDATE" ]; then
echo "❌ Could not locate cmux binary in tarball"
rm -rf "$TMP_DIR"
exit 1
fi
cp "$CANDIDATE" "$CMUX_BINARY"
chmod +x "$CMUX_BINARY" || true
rm -rf "$TMP_DIR"
fi
printf "🥳 cmux has been installed in ${INSTALL_PREFIX}\n\n"
fi
# Make cmux available in PATH if CODER_SCRIPT_BIN_DIR is set
if [ -n "$CODER_SCRIPT_BIN_DIR" ] && [ ! -e "$CODER_SCRIPT_BIN_DIR/cmux" ]; then
ln -s "$CMUX_BINARY" "$CODER_SCRIPT_BIN_DIR/cmux"
fi
# Start cmux
run_cmux
@@ -1,20 +1,20 @@
---
display_name: cmux
display_name: mux
description: Coding Agent Multiplexer - Run multiple AI agents in parallel
icon: ../../../../.icons/cmux.svg
icon: ../../../../.icons/mux.svg
verified: false
tags: [ai, agents, development, multiplexer]
---
# cmux
# mux
Automatically install and run [cmux](https://github.com/coder/cmux) in a Coder workspace. By default, the module installs `@coder/cmux@latest` from npm (with a fallback to downloading the npm tarball if npm is unavailable). cmux is a desktop application for parallel agentic development that enables developers to run multiple AI agents simultaneously across isolated cmux workspaces.
Automatically install and run mux in a Coder workspace. By default, the module installs `mux@next` from npm (with a fallback to downloading the npm tarball if npm is unavailable). mux is a desktop application for parallel agentic development that enables developers to run multiple AI agents simultaneously across isolated workspaces.
```tf
module "cmux" {
module "mux" {
count = data.coder_workspace.me.start_count
source = "registry.coder.com/coder/cmux/coder"
version = "1.0.2"
source = "registry.coder.com/coder/mux/coder"
version = "1.0.0"
agent_id = coder_agent.example.id
}
```
@@ -22,8 +22,8 @@ module "cmux" {
## Features
- **Parallel Agent Execution**: Run multiple AI agents simultaneously on different tasks
- **Cmux Workspace Isolation**: Each agent works in its own isolated environment
- **Git Divergence Visualization**: Track changes across different cmux agent workspaces
- **Mux Workspace Isolation**: Each agent works in its own isolated environment
- **Git Divergence Visualization**: Track changes across different mux agent workspaces
- **Long-Running Processes**: Resume AI work after interruptions
- **Cost Tracking**: Monitor API usage across agents
@@ -32,10 +32,10 @@ module "cmux" {
### Basic Usage
```tf
module "cmux" {
module "mux" {
count = data.coder_workspace.me.start_count
source = "registry.coder.com/coder/cmux/coder"
version = "1.0.2"
source = "registry.coder.com/coder/mux/coder"
version = "1.0.0"
agent_id = coder_agent.example.id
}
```
@@ -43,10 +43,10 @@ module "cmux" {
### Pin Version
```tf
module "cmux" {
module "mux" {
count = data.coder_workspace.me.start_count
source = "registry.coder.com/coder/cmux/coder"
version = "1.0.2"
source = "registry.coder.com/coder/mux/coder"
version = "1.0.0"
agent_id = coder_agent.example.id
# Default is "latest"; set to a specific version to pin
install_version = "0.4.0"
@@ -56,10 +56,10 @@ module "cmux" {
### Custom Port
```tf
module "cmux" {
module "mux" {
count = data.coder_workspace.me.start_count
source = "registry.coder.com/coder/cmux/coder"
version = "1.0.2"
source = "registry.coder.com/coder/mux/coder"
version = "1.0.0"
agent_id = coder_agent.example.id
port = 8080
}
@@ -67,13 +67,13 @@ module "cmux" {
### Use Cached Installation
Run an existing copy of cmux if found, otherwise install from npm:
Run an existing copy of mux if found, otherwise install from npm:
```tf
module "cmux" {
module "mux" {
count = data.coder_workspace.me.start_count
source = "registry.coder.com/coder/cmux/coder"
version = "1.0.2"
source = "registry.coder.com/coder/mux/coder"
version = "1.0.0"
agent_id = coder_agent.example.id
use_cached = true
}
@@ -81,13 +81,13 @@ module "cmux" {
### Skip Install
Run without installing from the network (requires cmux to be pre-installed):
Run without installing from the network (requires mux to be pre-installed):
```tf
module "cmux" {
module "mux" {
count = data.coder_workspace.me.start_count
source = "registry.coder.com/coder/cmux/coder"
version = "1.0.2"
source = "registry.coder.com/coder/mux/coder"
version = "1.0.0"
agent_id = coder_agent.example.id
install = false
}
@@ -99,6 +99,6 @@ module "cmux" {
## Notes
- cmux is currently in preview and you may encounter bugs
- mux is currently in preview and you may encounter bugs
- Requires internet connectivity for agent operations (unless `install` is set to false)
- Installs `@coder/cmux` from npm by default (falls back to the npm tarball if npm is unavailable)
- Installs `mux@next` from npm by default (falls back to the npm tarball if npm is unavailable)
@@ -6,7 +6,7 @@ import {
testRequiredVariables,
} from "~test";
describe("cmux", async () => {
describe("mux", async () => {
await runTerraformInit(import.meta.dir);
testRequiredVariables(import.meta.dir, {
@@ -31,9 +31,9 @@ describe("cmux", async () => {
expect(output.exitCode).toBe(0);
const expectedLines = [
"📥 npm not found; downloading tarball from npm registry...",
"🥳 cmux has been installed in /tmp/cmux",
"🚀 Starting cmux server on port 4000...",
"Check logs at /tmp/cmux.log!",
"🥳 mux has been installed in /tmp/mux",
"🚀 Starting mux server on port 4000...",
"Check logs at /tmp/mux.log!",
];
for (const line of expectedLines) {
expect(output.stdout).toContain(line);
@@ -54,10 +54,10 @@ describe("cmux", async () => {
expect(output.exitCode).toBe(0);
const expectedLines = [
"📦 Installing @coder/cmux via npm into /tmp/cmux...",
"🥳 cmux has been installed in /tmp/cmux",
"🚀 Starting cmux server on port 4000...",
"Check logs at /tmp/cmux.log!",
"📦 Installing mux via npm into /tmp/mux...",
"🥳 mux has been installed in /tmp/mux",
"🚀 Starting mux server on port 4000...",
"Check logs at /tmp/mux.log!",
];
for (const line of expectedLines) {
expect(output.stdout).toContain(line);
@@ -17,38 +17,44 @@ variable "agent_id" {
variable "port" {
type = number
description = "The port to run cmux on."
description = "The port to run mux on."
default = 4000
}
variable "display_name" {
type = string
description = "The display name for the cmux application."
default = "cmux"
description = "The display name for the mux application."
default = "mux"
}
variable "slug" {
type = string
description = "The slug for the cmux application."
default = "cmux"
description = "The slug for the mux application."
default = "mux"
}
variable "install_prefix" {
type = string
description = "The prefix to install cmux to."
default = "/tmp/cmux"
description = "The prefix to install mux to."
default = "/tmp/mux"
}
variable "log_path" {
type = string
description = "The path for cmux logs."
default = "/tmp/cmux.log"
description = "The path for mux logs."
default = "/tmp/mux.log"
}
variable "add-project" {
type = string
description = "Path to add/open as a project in mux (idempotent)."
default = ""
}
variable "install_version" {
type = string
description = "The version of cmux to install."
default = "latest"
description = "The version or dist-tag of mux to install."
default = "next"
}
variable "share" {
@@ -74,13 +80,13 @@ variable "group" {
variable "install" {
type = bool
description = "Install cmux from the network (npm or tarball). If false, run without installing (requires a pre-installed cmux)."
description = "Install mux from the network (npm or tarball). If false, run without installing (requires a pre-installed mux)."
default = true
}
variable "use_cached" {
type = bool
description = "Use cached copy of cmux if present; otherwise install from npm"
description = "Use cached copy of mux if present; otherwise install from npm"
default = false
}
@@ -107,14 +113,15 @@ variable "open_in" {
}
}
resource "coder_script" "cmux" {
resource "coder_script" "mux" {
agent_id = var.agent_id
display_name = "cmux"
icon = "/icon/cmux.svg"
display_name = "mux"
icon = "/icon/mux.svg"
script = templatefile("${path.module}/run.sh", {
VERSION : var.install_version,
PORT : var.port,
LOG_PATH : var.log_path,
ADD_PROJECT : var.add-project,
INSTALL_PREFIX : var.install_prefix,
OFFLINE : !var.install,
USE_CACHED : var.use_cached,
@@ -129,12 +136,12 @@ resource "coder_script" "cmux" {
}
}
resource "coder_app" "cmux" {
resource "coder_app" "mux" {
agent_id = var.agent_id
slug = var.slug
display_name = var.display_name
url = "http://localhost:${var.port}"
icon = "/icon/cmux.svg"
icon = "/icon/mux.svg"
subdomain = var.subdomain
share = var.share
order = var.order
@@ -147,3 +154,5 @@ resource "coder_app" "cmux" {
threshold = 6
}
}
@@ -16,7 +16,7 @@ run "install_false_and_use_cached_conflict" {
}
expect_failures = [
resource.coder_script.cmux
resource.coder_script.mux
]
}
@@ -29,7 +29,7 @@ run "custom_port" {
}
assert {
condition = resource.coder_app.cmux.url == "http://localhost:8080"
condition = resource.coder_app.mux.url == "http://localhost:8080"
error_message = "coder_app URL must use the configured port"
}
}
@@ -62,3 +62,5 @@ run "use_cached_only_success" {
use_cached = true
}
}
+195
View File
@@ -0,0 +1,195 @@
#!/usr/bin/env bash
BOLD='\033[0;1m'
RESET='\033[0m'
MUX_BINARY="${INSTALL_PREFIX}/mux"
function run_mux() {
local port_value
port_value="${PORT}"
if [ -z "$port_value" ]; then
port_value="4000"
fi
# Build args for mux (POSIX-compatible, avoid bash arrays)
set -- server --port "$port_value"
if [ -n "${ADD_PROJECT}" ]; then
set -- "$@" --add-project "${ADD_PROJECT}"
fi
echo "🚀 Starting mux server on port $port_value..."
echo "Check logs at ${LOG_PATH}!"
PORT="$port_value" "$MUX_BINARY" "$@" > "${LOG_PATH}" 2>&1 &
}
# Check if mux is already installed for offline mode
if [ "${OFFLINE}" = true ]; then
if [ -f "$MUX_BINARY" ]; then
echo "🥳 Found a copy of mux"
run_mux
exit 0
fi
echo "❌ Failed to find a copy of mux"
exit 1
fi
# If there is no cached install OR we don't want to use a cached install
if [ ! -f "$MUX_BINARY" ] || [ "${USE_CACHED}" != true ]; then
printf "$${BOLD}Installing mux from npm...\n"
# Clean up from other install (in case install prefix changed).
if [ -n "$CODER_SCRIPT_BIN_DIR" ] && [ -e "$CODER_SCRIPT_BIN_DIR/mux" ]; then
rm "$CODER_SCRIPT_BIN_DIR/mux"
fi
mkdir -p "$(dirname "$MUX_BINARY")"
if command -v npm > /dev/null 2>&1; then
echo "📦 Installing mux via npm into ${INSTALL_PREFIX}..."
NPM_WORKDIR="${INSTALL_PREFIX}/npm"
mkdir -p "$NPM_WORKDIR"
cd "$NPM_WORKDIR" || exit 1
if [ ! -f package.json ]; then
echo '{}' > package.json
fi
PKG="mux"
if [ -z "${VERSION}" ] || [ "${VERSION}" = "latest" ]; then
PKG_SPEC="$PKG@latest"
else
PKG_SPEC="$PKG@${VERSION}"
fi
if ! npm install --no-audit --no-fund --omit=dev "$PKG_SPEC"; then
echo "❌ Failed to install mux via npm"
exit 1
fi
# Determine the installed binary path
BIN_DIR="$NPM_WORKDIR/node_modules/.bin"
CANDIDATE="$BIN_DIR/mux"
if [ ! -f "$CANDIDATE" ]; then
echo "❌ Could not locate mux binary after npm install"
exit 1
fi
chmod +x "$CANDIDATE" || true
ln -sf "$CANDIDATE" "$MUX_BINARY"
else
echo "📥 npm not found; downloading tarball from npm registry..."
VERSION_TO_USE="${VERSION}"
if [ -z "$VERSION_TO_USE" ]; then
VERSION_TO_USE="next"
fi
META_URL="https://registry.npmjs.org/mux/$VERSION_TO_USE"
META_JSON="$(curl -fsSL "$META_URL" || true)"
if [ -z "$META_JSON" ]; then
echo "❌ Failed to fetch npm metadata: $META_URL"
exit 1
fi
# Normalize JSON to a single line for robust pattern matching across environments
META_ONE_LINE="$(printf "%s" "$META_JSON" | tr -d '\n' || true)"
if [ -z "$META_ONE_LINE" ]; then
META_ONE_LINE="$META_JSON"
fi
# Try to extract tarball URL directly from metadata (prefer Node if available for robust JSON parsing)
TARBALL_URL=""
if command -v node > /dev/null 2>&1; then
TARBALL_URL="$(printf "%s" "$META_JSON" | node -e 'try{const fs=require("fs");const data=JSON.parse(fs.readFileSync(0,"utf8"));if(data&&data.dist&&data.dist.tarball){console.log(data.dist.tarball);}}catch(e){}')"
fi
# sed-based fallback
if [ -z "$TARBALL_URL" ]; then
TARBALL_URL="$(printf "%s" "$META_ONE_LINE" | sed -n 's/.*\"tarball\":\"\\([^\"]*\\)\".*/\\1/p' | head -n1)"
fi
# Fallback: resolve version then construct tarball URL
if [ -z "$TARBALL_URL" ]; then
RESOLVED_VERSION=""
if command -v node > /dev/null 2>&1; then
RESOLVED_VERSION="$(printf "%s" "$META_JSON" | node -e 'try{const fs=require("fs");const data=JSON.parse(fs.readFileSync(0,"utf8"));if(data&&data.version){console.log(data.version);}}catch(e){}')"
fi
if [ -z "$RESOLVED_VERSION" ]; then
RESOLVED_VERSION="$(printf "%s" "$META_ONE_LINE" | sed -n 's/.*\"version\":\"\\([^\"]*\\)\".*/\\1/p' | head -n1)"
fi
if [ -z "$RESOLVED_VERSION" ]; then
RESOLVED_VERSION="$(printf "%s" "$META_ONE_LINE" | grep -o '\"version\":\"[^\"]*\"' | head -n1 | cut -d '\"' -f4)"
fi
if [ -n "$RESOLVED_VERSION" ]; then
VERSION_TO_USE="$RESOLVED_VERSION"
fi
if [ -z "$VERSION_TO_USE" ]; then
echo "❌ Could not determine version for mux"
exit 1
fi
TARBALL_URL="https://registry.npmjs.org/mux/-/mux-$VERSION_TO_USE.tgz"
fi
TMP_DIR="$(mktemp -d)"
TAR_PATH="$TMP_DIR/mux.tgz"
if ! curl -fsSL "$TARBALL_URL" -o "$TAR_PATH"; then
echo "❌ Failed to download tarball: $TARBALL_URL"
rm -rf "$TMP_DIR"
exit 1
fi
if ! tar -xzf "$TAR_PATH" -C "$TMP_DIR"; then
echo "❌ Failed to extract tarball"
rm -rf "$TMP_DIR"
exit 1
fi
CANDIDATE=""
BIN_PATH=""
# Prefer reading bin path from package.json
if [ -f "$TMP_DIR/package/package.json" ]; then
if command -v node > /dev/null 2>&1; then
BIN_PATH="$(node -e 'try{const fs=require("fs");const p=JSON.parse(fs.readFileSync(process.argv[1],"utf8"));let bp=typeof p.bin==="string"?p.bin:(p.bin&&p.bin.mux);if(bp){console.log(bp)}}catch(e){}' "$TMP_DIR/package/package.json")"
fi
if [ -z "$BIN_PATH" ]; then
# sed fallbacks (handle both string and object forms)
BIN_PATH=$(sed -n 's/.*\"bin\"[[:space:]]*:[[:space:]]*\"\\([^\"]*\\)\".*/\\1/p' "$TMP_DIR/package/package.json" | head -n1)
if [ -z "$BIN_PATH" ]; then
BIN_PATH=$(sed -n '/\"bin\"[[:space:]]*:[[:space:]]*{/,/}/p' "$TMP_DIR/package/package.json" | sed -n 's/.*\"mux\"[[:space:]]*:[[:space:]]*\"\\([^\"]*\\)\".*/\\1/p' | head -n1)
fi
fi
if [ -n "$BIN_PATH" ] && [ -f "$TMP_DIR/package/$BIN_PATH" ]; then
CANDIDATE="$TMP_DIR/package/$BIN_PATH"
fi
fi
# Fallback: check common locations
if [ -z "$CANDIDATE" ]; then
if [ -f "$TMP_DIR/package/bin/mux" ]; then
CANDIDATE="$TMP_DIR/package/bin/mux"
elif [ -f "$TMP_DIR/package/bin/mux.js" ]; then
CANDIDATE="$TMP_DIR/package/bin/mux.js"
elif [ -f "$TMP_DIR/package/bin/mux.mjs" ]; then
CANDIDATE="$TMP_DIR/package/bin/mux.mjs"
fi
fi
# Fallback: search for plausible filenames
if [ -z "$CANDIDATE" ] || [ ! -f "$CANDIDATE" ]; then
CANDIDATE=$(find "$TMP_DIR/package" -maxdepth 4 -type f \( -name "mux" -o -name "mux.js" -o -name "mux.mjs" -o -name "mux.cjs" -o -name "main.js" \) | head -n1)
fi
if [ -z "$CANDIDATE" ] || [ ! -f "$CANDIDATE" ]; then
echo "❌ Could not locate mux binary in tarball"
rm -rf "$TMP_DIR"
exit 1
fi
# Copy entire package to installation directory to preserve relative imports
DEST_DIR="${INSTALL_PREFIX}/.mux-package"
rm -rf "$DEST_DIR"
mkdir -p "$DEST_DIR"
cp -R "$TMP_DIR/package/." "$DEST_DIR/"
# Create/refresh launcher symlink
if [ -n "$BIN_PATH" ] && [ -f "$DEST_DIR/$BIN_PATH" ]; then
ln -sf "$DEST_DIR/$BIN_PATH" "$MUX_BINARY"
chmod +x "$DEST_DIR/$BIN_PATH" || true
else
ln -sf "$DEST_DIR/$(basename "$CANDIDATE")" "$MUX_BINARY"
chmod +x "$DEST_DIR/$(basename "$CANDIDATE")" || true
fi
rm -rf "$TMP_DIR"
fi
printf "🥳 mux has been installed in ${INSTALL_PREFIX}\n\n"
fi
# Make mux available in PATH if CODER_SCRIPT_BIN_DIR is set
if [ -n "$CODER_SCRIPT_BIN_DIR" ]; then
if [ ! -e "$CODER_SCRIPT_BIN_DIR/mux" ]; then
ln -s "$MUX_BINARY" "$CODER_SCRIPT_BIN_DIR/mux"
fi
fi
# Start mux
run_mux