Right now it seems to me the best way to work is with a bunch of Claude Code instances via Conductor. I’m getting out north of 30 PRs a day this way, some of them very significant in scope. What this means, though, is a lot of context switching. I am not going to remember that “fix-card-image-bg-loading” is running on port 3002 and “test-dropbox-cache-bust” is running on port 3010. So Claude and I wrote a shell script to keep us sane.
The basic idea is that you should be able to refer to any branch you are working on, by its branch name, and the script translates that into a running devserver and a browser pointing at it and local Inngest, too, isolated to just one devserver, if you need that. I also generate zsh completions so I can tab complete the branch name in all these commands.
#!/bin/bash
#
# mydev - Manage devservers across workspaces
#
# Usage:
# mydev [workspace] Start devserver and open browser (default)
# mydev open [workspace] Same as above (explicit)
# mydev start [workspace] Start devserver if not running (no browser, idempotent)
# mydev cd [workspace] cd to workspace/repo root
# mydev edit [workspace] Open workspace in editor ($VISUAL or $EDITOR)
# mydev list List all running devservers and Inngest status
# mydev inngest [workspace] Start Inngest dev server for a specific workspace
# mydev inngest-open Open Inngest dashboard in browser
# mydev stop [workspace] Stop devserver for workspace
# mydev stop-all Stop all devservers
# mydev help Show this help
#
# Workspace can be specified as:
# - Workspace name (e.g., "feature-1", "bugfix-2")
# - Branch name (e.g., "add-user-auth") - finds matching workspace
# - "main" - the main repo checkout at ~/my-project
# - Omitted - detects from current directory or git branch
#
# Inngest:
# The Inngest dev server connects to ONE app instance at a time.
# This prevents confusion when multiple instances are running - only the
# connected one will handle Inngest jobs.
#
# To use Inngest:
# 1. Start your devserver: mydev my-branch
# 2. In another terminal, connect Inngest: mydev inngest my-branch
# 3. To switch to a different instance: mydev inngest other-branch
#
# Dashboard: http://localhost:8288
#
# Setup:
# Add to your ~/.zshrc:
#
# export PATH="$HOME/my-project/scripts:$PATH"
# source "$HOME/my-project/scripts/mydev-completion.zsh"
#
# This gives you:
# - mydev command available everywhere
# - Tab completion for workspace names, branch names, and commands
set -e
REGISTRY_FILE="$HOME/.mydev-devservers.json"
INNGEST_LOCK_FILE="$HOME/.mydev-inngest-lock"
WORKSPACES_DIR="$HOME/workspaces"
MAIN_REPO="$HOME/my-project"
MAIN_WORKSPACE_NAME="main"
APP_SUBDIR="apps/frontend" # Path to your app within the repo
MIN_PORT=3000
MAX_PORT=3020
INNGEST_PORT=8288
# Initialize registry file if it doesn't exist
init_registry() {
if [[ ! -f "$REGISTRY_FILE" ]]; then
echo '{}' > "$REGISTRY_FILE"
fi
}
# Find workspace by branch name (scans all workspaces including main repo)
find_workspace_by_branch() {
local target_branch="$1"
# Check main repo first
if [[ -d "$MAIN_REPO/.git" ]]; then
local branch=$(git -C "$MAIN_REPO" rev-parse --abbrev-ref HEAD 2>/dev/null)
if [[ "$branch" == "$target_branch" ]]; then
echo "$MAIN_WORKSPACE_NAME"
return
fi
fi
# Check workspaces
for workspace_dir in "$WORKSPACES_DIR"/*/; do
if [[ -d "$workspace_dir/.git" ]] || [[ -f "$workspace_dir/.git" ]]; then
local branch=$(git -C "$workspace_dir" rev-parse --abbrev-ref HEAD 2>/dev/null)
if [[ "$branch" == "$target_branch" ]]; then
basename "$workspace_dir"
return
fi
fi
done
echo ""
}
# Get workspace name from current directory or argument
get_workspace() {
local input="$1"
if [[ -n "$input" ]]; then
if [[ "$input" == "$MAIN_WORKSPACE_NAME" ]]; then
echo "$MAIN_WORKSPACE_NAME"
return
fi
if [[ -d "$WORKSPACES_DIR/$input" ]]; then
echo "$input"
return
fi
local ws=$(find_workspace_by_branch "$input")
if [[ -n "$ws" ]]; then
echo "$ws"
return
fi
echo ""
return
fi
# Try to detect from current directory
local cwd="$(pwd)"
if [[ "$cwd" == "$MAIN_REPO"* ]]; then
echo "$MAIN_WORKSPACE_NAME"
return
fi
if [[ "$cwd" == "$WORKSPACES_DIR/"* ]]; then
local rel_path="${cwd#$WORKSPACES_DIR/}"
local workspace="${rel_path%%/*}"
echo "$workspace"
return
fi
# Fallback: try to match current git branch to a workspace's branch
if command -v git &>/dev/null && git rev-parse --git-dir &>/dev/null; then
local current_branch=$(git rev-parse --abbrev-ref HEAD 2>/dev/null)
if [[ -n "$current_branch" ]]; then
local ws=$(find_workspace_by_branch "$current_branch")
if [[ -n "$ws" ]]; then
echo "$ws"
return
fi
fi
fi
echo ""
}
# Get app directory for a workspace
get_app_dir() {
local workspace="$1"
if [[ "$workspace" == "$MAIN_WORKSPACE_NAME" ]]; then
echo "$MAIN_REPO/$APP_SUBDIR"
else
echo "$WORKSPACES_DIR/$workspace/$APP_SUBDIR"
fi
}
# Get workspace root directory
get_workspace_root() {
local workspace="$1"
if [[ "$workspace" == "$MAIN_WORKSPACE_NAME" ]]; then
echo "$MAIN_REPO"
else
echo "$WORKSPACES_DIR/$workspace"
fi
}
# Validate workspace exists and has the app
validate_workspace() {
local workspace="$1"
local app_path=$(get_app_dir "$workspace")
if [[ ! -d "$app_path" ]]; then
echo "Error: App not found at $app_path" >&2
echo "" >&2
echo "Available workspaces:" >&2
if [[ -d "$MAIN_REPO/$APP_SUBDIR" ]]; then
local main_branch=$(git -C "$MAIN_REPO" rev-parse --abbrev-ref HEAD 2>/dev/null || echo "unknown")
echo " $main_branch ($MAIN_WORKSPACE_NAME) [main repo]" >&2
fi
for ws_dir in "$WORKSPACES_DIR"/*/; do
local ws_name=$(basename "$ws_dir")
local ws_branch=$(git -C "$ws_dir" rev-parse --abbrev-ref HEAD 2>/dev/null || echo "unknown")
echo " $ws_branch ($ws_name)" >&2
done
return 1
fi
return 0
}
# Check if a port is in use
is_port_in_use() {
local port="$1"
lsof -i ":$port" >/dev/null 2>&1
}
# Find the first available port
find_available_port() {
for port in $(seq $MIN_PORT $MAX_PORT); do
if ! is_port_in_use "$port"; then
echo "$port"
return
fi
done
echo ""
}
# Get PID of process using a port
get_pid_on_port() {
local port="$1"
lsof -ti ":$port" 2>/dev/null | head -1
}
# Find existing devserver for a workspace by scanning processes
find_existing_devserver() {
local workspace="$1"
local workspace_root=$(get_workspace_root "$workspace")
local search_pattern
if [[ "$workspace" == "$MAIN_WORKSPACE_NAME" ]]; then
search_pattern="$MAIN_REPO/$APP_SUBDIR"
else
search_pattern="$workspace/$APP_SUBDIR"
fi
local process_line=$(ps aux | grep -E "$search_pattern.*/next.*dev|next.*dev.*$search_pattern" | grep -v grep | head -1)
if [[ -z "$process_line" ]]; then
process_line=$(ps aux | grep -E "$search_pattern.*next-server|next-server.*$search_pattern" | grep -v grep | head -1)
fi
if [[ -n "$process_line" ]]; then
local pid=$(echo "$process_line" | awk '{print $2}')
local port=$(echo "$process_line" | grep -oE '\-p [0-9]+' | tail -1 | awk '{print $2}')
if [[ -z "$port" ]]; then
port=3000
fi
if [[ -n "$pid" ]] && [[ -n "$port" ]]; then
echo "$port:$pid"
return
fi
fi
echo ""
}
# Registry operations
get_workspace_port() {
local workspace="$1"
if [[ -f "$REGISTRY_FILE" ]]; then
jq -r ".[\"$workspace\"].port // empty" "$REGISTRY_FILE"
fi
}
get_workspace_pid() {
local workspace="$1"
if [[ -f "$REGISTRY_FILE" ]]; then
jq -r ".[\"$workspace\"].pid // empty" "$REGISTRY_FILE"
fi
}
is_workspace_running() {
local workspace="$1"
local port=$(get_workspace_port "$workspace")
if [[ -z "$port" ]]; then
return 1
fi
if is_port_in_use "$port"; then
return 0
fi
return 1
}
save_registry_entry() {
local workspace="$1"
local port="$2"
local pid="$3"
local tmp_file=$(mktemp)
jq --arg ws "$workspace" --arg port "$port" --arg pid "$pid" \
'.[$ws] = {port: ($port | tonumber), pid: ($pid | tonumber)}' \
"$REGISTRY_FILE" > "$tmp_file" && mv "$tmp_file" "$REGISTRY_FILE"
}
remove_registry_entry() {
local workspace="$1"
local tmp_file=$(mktemp)
jq --arg ws "$workspace" 'del(.[$ws])' "$REGISTRY_FILE" > "$tmp_file" && mv "$tmp_file" "$REGISTRY_FILE"
}
cleanup_registry() {
if [[ ! -f "$REGISTRY_FILE" ]]; then
return
fi
local workspaces=$(jq -r 'keys[]' "$REGISTRY_FILE")
for ws in $workspaces; do
if ! is_workspace_running "$ws"; then
remove_registry_entry "$ws"
fi
done
}
# Inngest operations
is_inngest_running() {
is_port_in_use "$INNGEST_PORT"
}
get_inngest_lock_workspace() {
if [[ -f "$INNGEST_LOCK_FILE" ]]; then
cat "$INNGEST_LOCK_FILE"
else
echo ""
fi
}
set_inngest_lock() {
local workspace="$1"
echo "$workspace" > "$INNGEST_LOCK_FILE"
}
clear_inngest_lock() {
rm -f "$INNGEST_LOCK_FILE"
}
is_inngest_lock_valid() {
if is_inngest_running && [[ -f "$INNGEST_LOCK_FILE" ]]; then
return 0
fi
if [[ -f "$INNGEST_LOCK_FILE" ]] && ! is_inngest_running; then
clear_inngest_lock
fi
return 1
}
stop_inngest_and_wait() {
local inngest_pid=$(get_pid_on_port "$INNGEST_PORT")
if [[ -n "$inngest_pid" ]]; then
kill "$inngest_pid" 2>/dev/null || true
fi
local attempts=0
local max_attempts=50
while is_port_in_use "$INNGEST_PORT"; do
sleep 0.1
((attempts++))
if [[ $attempts -ge $max_attempts ]]; then
echo "Warning: Inngest port $INNGEST_PORT still in use after 5s, forcing..." >&2
lsof -ti ":$INNGEST_PORT" | xargs kill -9 2>/dev/null || true
sleep 0.5
break
fi
done
clear_inngest_lock
}
# Start devserver for a workspace
start_devserver() {
local workspace="$1"
local no_browser="${2:-}"
local app_path=$(get_app_dir "$workspace")
local ws_root=$(get_workspace_root "$workspace")
validate_workspace "$workspace" || exit 1
local port=$(find_available_port)
if [[ -z "$port" ]]; then
echo "Error: No available ports between $MIN_PORT and $MAX_PORT" >&2
exit 1
fi
local branch=$(git -C "$ws_root" rev-parse --abbrev-ref HEAD 2>/dev/null || echo "$workspace")
echo -ne "\033]0;▶ [$branch $port]\007"
if is_inngest_running; then
echo "🚀 App: $branch (port $port, inngest: $INNGEST_PORT)"
else
echo "🚀 App: $branch (port $port)"
echo " Note: Inngest not running. Start with: mydev inngest"
fi
cd "$app_path"
NEXT_PUBLIC_APP_URL="http://localhost:$port" INNGEST_BASE_URL="http://localhost:$INNGEST_PORT" pnpm dev -p "$port" &
local dev_pid=$!
trap 'kill $dev_pid 2>/dev/null; exit' INT TERM
trap 'kill $dev_pid 2>/dev/null' EXIT
local attempts=0
local max_attempts=150
while ! lsof -i ":$port" >/dev/null 2>&1; do
if ! kill -0 "$dev_pid" 2>/dev/null; then
echo "Error: devserver failed to start" >&2
wait "$dev_pid"
exit 1
fi
sleep 0.2
((attempts++))
if [[ $attempts -ge $max_attempts ]]; then
echo "Warning: Server not detected on port $port yet" >&2
break
fi
done
if [[ "$no_browser" != "--no-browser" ]]; then
open "http://localhost:$port"
fi
wait "$dev_pid"
}
# Stop devserver for a workspace
stop_devserver() {
local workspace="$1"
local port=$(get_workspace_port "$workspace")
local pid=$(get_workspace_pid "$workspace")
if [[ -z "$pid" ]]; then
local existing=$(find_existing_devserver "$workspace")
if [[ -n "$existing" ]]; then
port="${existing%%:*}"
pid="${existing##*:}"
fi
fi
if [[ -z "$pid" ]]; then
echo "No devserver found for workspace '$workspace'"
return
fi
echo "Stopping devserver for '$workspace' (PID: $pid)..."
pkill -P "$pid" 2>/dev/null || true
kill "$pid" 2>/dev/null || true
pkill -f "$workspace/$APP_SUBDIR.*next" 2>/dev/null || true
remove_registry_entry "$workspace"
echo "Stopped."
}
# Stop all devservers
stop_all_devservers() {
cleanup_registry
local stopped_any=false
if [[ -f "$REGISTRY_FILE" ]] && [[ "$(jq 'length' "$REGISTRY_FILE")" != "0" ]]; then
local workspaces=$(jq -r 'keys[]' "$REGISTRY_FILE")
for ws in $workspaces; do
stop_devserver "$ws"
stopped_any=true
done
fi
if [[ -d "$MAIN_REPO/$APP_SUBDIR" ]]; then
local existing=$(find_existing_devserver "$MAIN_WORKSPACE_NAME")
if [[ -n "$existing" ]]; then
stop_devserver "$MAIN_WORKSPACE_NAME"
stopped_any=true
fi
fi
for workspace_dir in "$WORKSPACES_DIR"/*/; do
local ws=$(basename "$workspace_dir")
local existing=$(find_existing_devserver "$ws")
if [[ -n "$existing" ]]; then
stop_devserver "$ws"
stopped_any=true
fi
done
if [[ "$stopped_any" != "true" ]]; then
echo "No devservers running."
fi
}
# List all running devservers
list_devservers() {
cleanup_registry
local inngest_lock_ws=""
if is_inngest_lock_valid; then
inngest_lock_ws=$(get_inngest_lock_workspace)
fi
echo "Inngest:"
if is_inngest_running; then
if [[ -n "$inngest_lock_ws" ]]; then
local lock_ws_root=$(get_workspace_root "$inngest_lock_ws")
local lock_branch=$(git -C "$lock_ws_root" rev-parse --abbrev-ref HEAD 2>/dev/null || echo "$inngest_lock_ws")
echo " ✅ Running on port $INNGEST_PORT → $lock_branch ($inngest_lock_ws)"
else
echo " ⚠️ Running on port $INNGEST_PORT (no lock - may route unpredictably)"
fi
else
echo " ❌ Not running. Start with: mydev inngest [workspace]"
fi
echo ""
echo "Devservers:"
echo ""
printf "%-30s %-20s %-6s %-10s\n" "BRANCH" "(WORKSPACE)" "PORT" "INNGEST"
printf "%-30s %-20s %-6s %-10s\n" "------" "-----------" "----" "-------"
local found_any=false
if [[ -f "$REGISTRY_FILE" ]] && [[ "$(jq 'length' "$REGISTRY_FILE")" != "0" ]]; then
jq -r 'to_entries[] | "\(.key)\t\(.value.port)\t\(.value.pid)"' "$REGISTRY_FILE" | \
while IFS=$'\t' read -r ws port pid; do
local ws_root=$(get_workspace_root "$ws")
local branch=$(git -C "$ws_root" rev-parse --abbrev-ref HEAD 2>/dev/null || echo "?")
branch="${branch:0:30}"
local inngest_marker=""
if [[ "$ws" == "$inngest_lock_ws" ]]; then
inngest_marker="← connected"
fi
printf "%-30s %-20s %-6s %-10s\n" "$branch" "($ws)" "$port" "$inngest_marker"
done
found_any=true
fi
if [[ -d "$MAIN_REPO/$APP_SUBDIR" ]]; then
if [[ ! -f "$REGISTRY_FILE" ]] || ! jq -e ".[\"$MAIN_WORKSPACE_NAME\"]" "$REGISTRY_FILE" >/dev/null 2>&1; then
local existing=$(find_existing_devserver "$MAIN_WORKSPACE_NAME")
if [[ -n "$existing" ]]; then
local port="${existing%%:*}"
local branch=$(git -C "$MAIN_REPO" rev-parse --abbrev-ref HEAD 2>/dev/null || echo "?")
branch="${branch:0:30}"
local inngest_marker=""
if [[ "$MAIN_WORKSPACE_NAME" == "$inngest_lock_ws" ]]; then
inngest_marker="← connected"
fi
printf "%-30s %-20s %-6s %-10s\n" "$branch" "($MAIN_WORKSPACE_NAME)" "$port" "$inngest_marker"
found_any=true
fi
fi
fi
for workspace_dir in "$WORKSPACES_DIR"/*/; do
local ws=$(basename "$workspace_dir")
if [[ -f "$REGISTRY_FILE" ]] && jq -e ".[\"$ws\"]" "$REGISTRY_FILE" >/dev/null 2>&1; then
continue
fi
local existing=$(find_existing_devserver "$ws")
if [[ -n "$existing" ]]; then
local port="${existing%%:*}"
local branch=$(git -C "$workspace_dir" rev-parse --abbrev-ref HEAD 2>/dev/null || echo "?")
branch="${branch:0:30}"
local inngest_marker=""
if [[ "$ws" == "$inngest_lock_ws" ]]; then
inngest_marker="← connected"
fi
printf "%-30s %-20s %-6s %-10s\n" "$branch" "($ws)" "$port" "$inngest_marker"
found_any=true
fi
done
if [[ "$found_any" != "true" ]]; then
echo "(none)"
fi
}
# Commands
cmd_start() {
local input="${1:-}"
local workspace=$(get_workspace "$input")
if [[ -z "$workspace" ]]; then
if [[ -n "$input" ]]; then
echo "Error: No workspace or branch found matching '$input'" >&2
else
echo "Error: No workspace specified and could not detect from current directory" >&2
fi
exit 1
fi
if is_workspace_running "$workspace"; then
local port=$(get_workspace_port "$workspace")
echo "Devserver for '$workspace' is already running on port $port" >&2
echo "$port"
exit 0
fi
local existing=$(find_existing_devserver "$workspace")
if [[ -n "$existing" ]]; then
local port="${existing%%:*}"
local pid="${existing##*:}"
echo "Found existing devserver for '$workspace' on port $port (PID: $pid)" >&2
save_registry_entry "$workspace" "$port" "$pid"
echo "$port"
exit 0
fi
start_devserver "$workspace" --no-browser
}
cmd_open() {
local input="${1:-}"
local workspace=$(get_workspace "$input")
if [[ -z "$workspace" ]]; then
cmd_start "$input"
return
fi
if is_workspace_running "$workspace"; then
local port=$(get_workspace_port "$workspace")
echo "Devserver for '$workspace' is already running on port $port"
open "http://localhost:$port"
exit 0
fi
local existing=$(find_existing_devserver "$workspace")
if [[ -n "$existing" ]]; then
local port="${existing%%:*}"
local pid="${existing##*:}"
echo "Found existing devserver for '$workspace' on port $port (PID: $pid)"
save_registry_entry "$workspace" "$port" "$pid"
open "http://localhost:$port"
exit 0
fi
start_devserver "$workspace"
}
cmd_dir() {
local workspace=$(get_workspace "${1:-}")
if [[ -z "$workspace" ]]; then
echo "Error: No workspace specified and could not detect from current directory" >&2
exit 1
fi
local ws_root=$(get_workspace_root "$workspace")
if [[ ! -d "$ws_root" ]]; then
echo "Error: Workspace root not found at $ws_root" >&2
exit 1
fi
echo "$ws_root"
}
cmd_edit() {
local workspace=$(get_workspace "${1:-}")
if [[ -z "$workspace" ]]; then
echo "Error: No workspace specified and could not detect from current directory" >&2
exit 1
fi
local ws_root=$(get_workspace_root "$workspace")
if [[ ! -d "$ws_root" ]]; then
echo "Error: Workspace root not found at $ws_root" >&2
exit 1
fi
local editor="${VISUAL:-$EDITOR}"
if [[ -z "$editor" ]]; then
echo "Error: No editor configured. Set \$VISUAL or \$EDITOR." >&2
exit 1
fi
exec "$editor" "$ws_root"
}
cmd_inngest_open() {
if ! is_inngest_running; then
echo "Error: Inngest is not running" >&2
echo "Start it with: mydev inngest" >&2
exit 1
fi
local url="http://localhost:$INNGEST_PORT"
echo "Opening Inngest dashboard: $url"
open "$url"
}
cmd_inngest() {
local input="${1:-}"
local workspace=$(get_workspace "$input")
if [[ -z "$workspace" ]]; then
if [[ -n "$input" ]]; then
echo "Error: No workspace or branch found matching '$input'" >&2
else
echo "Error: No workspace specified and could not detect from current directory" >&2
fi
echo "" >&2
echo "Usage: mydev inngest [workspace]" >&2
exit 1
fi
validate_workspace "$workspace" || exit 1
local ws_root=$(get_workspace_root "$workspace")
local branch=$(git -C "$ws_root" rev-parse --abbrev-ref HEAD 2>/dev/null || echo "$workspace")
if is_inngest_lock_valid; then
local current_lock=$(get_inngest_lock_workspace)
if [[ "$current_lock" == "$workspace" ]]; then
echo "Inngest is already running for '$workspace'" >&2
echo "Dashboard: http://localhost:$INNGEST_PORT" >&2
exit 0
else
local current_ws_root=$(get_workspace_root "$current_lock")
local current_branch=$(git -C "$current_ws_root" rev-parse --abbrev-ref HEAD 2>/dev/null || echo "$current_lock")
echo "Switching Inngest from '$current_branch' to '$branch'..."
stop_inngest_and_wait
fi
elif is_inngest_running; then
echo "Taking over orphaned Inngest server..."
stop_inngest_and_wait
fi
local app_port=""
if is_workspace_running "$workspace"; then
app_port=$(get_workspace_port "$workspace")
else
local existing=$(find_existing_devserver "$workspace")
if [[ -n "$existing" ]]; then
app_port="${existing%%:*}"
fi
fi
if [[ -z "$app_port" ]]; then
echo "Error: Devserver for '$workspace' is not running" >&2
echo "" >&2
echo "Start it first with: mydev $workspace" >&2
exit 1
fi
set_inngest_lock "$workspace"
trap 'clear_inngest_lock' EXIT INT TERM
local app_url="http://localhost:$app_port/api/inngest"
echo "🚀 Inngest dev server on port $INNGEST_PORT"
echo " Dashboard: http://localhost:$INNGEST_PORT"
echo " Connected to: $branch (port $app_port)"
echo ""
npx inngest-cli@latest dev --port "$INNGEST_PORT" --no-discovery -u "$app_url"
}
show_help() {
cat << 'EOF'
mydev - Manage devservers across workspaces
USAGE:
mydev [command] [workspace|branch]
COMMANDS:
open [workspace] Start devserver and open browser (default if no command given)
start [workspace] Start devserver if not running (no browser, idempotent)
cd [workspace] cd to workspace/repo root
edit [workspace] Open workspace in editor ($VISUAL or $EDITOR)
list List all running devservers and Inngest status
inngest [workspace] Start Inngest dev server for a specific workspace
inngest-open Open Inngest dashboard in browser
stop [workspace] Stop devserver for workspace
stop-all Stop all devservers
help Show this help
WORKSPACE ARGUMENT:
Can be specified as:
- Workspace name: "feature-1", "bugfix-2", etc.
- Branch name: "add-user-auth" - finds matching workspace
- Omitted: detects from current directory or git branch
INNGEST:
The Inngest dev server connects to ONE app instance at a time.
This prevents confusion when multiple instances are running.
Workflow:
1. Start your app: mydev my-branch
2. Connect Inngest: mydev inngest my-branch
3. Switch Inngest: mydev inngest other-branch
Dashboard: http://localhost:8288
EXAMPLES:
mydev feature-1 # Start/open devserver for feature-1 workspace
mydev start feature-1 # Start devserver (no browser)
mydev my-feature-branch # Start/open by branch name
mydev # Auto-detect from current dir/branch
mydev list # Show all running servers and Inngest status
mydev inngest feature-1 # Connect Inngest to feature-1's app
mydev inngest-open # Open Inngest dashboard
mydev stop feature-1 # Stop feature-1's server
mydev cd feature-1 # cd to feature-1 workspace root
mydev edit feature-1 # Open feature-1 in $VISUAL or $EDITOR
EOF
}
main() {
init_registry
cleanup_registry
local cmd="${1:-}"
case "$cmd" in
list|ls|-l|--list)
list_devservers
;;
stop)
shift
local workspace=$(get_workspace "${1:-}")
if [[ -z "$workspace" ]]; then
echo "Error: No workspace specified and could not detect from current directory"
exit 1
fi
stop_devserver "$workspace"
;;
stop-all|--stop-all)
stop_all_devservers
;;
cd|dir|path)
shift
cmd_dir "$@"
;;
edit)
shift
cmd_edit "$@"
;;
inngest)
shift
cmd_inngest "$@"
;;
inngest-open)
shift
cmd_inngest_open "$@"
;;
open)
shift
cmd_open "$@"
;;
start)
shift
cmd_start "$@"
;;
help|--help|-h)
show_help
;;
*)
cmd_open "$cmd"
;;
esac
}
main "$@"
