From db6440ca3e25e2d409a4da7b95e487b9f0848cff Mon Sep 17 00:00:00 2001 From: Ruben Fiszel Date: Thu, 19 Feb 2026 11:56:41 +0100 Subject: [PATCH] chore: add workmux config for worktree-based development (#8015) Co-authored-by: Claude Opus 4.6 --- .gitignore | 3 +++ .workmux.yaml | 47 ++++++++++++++++++++++++++++++++++++++++++ backend/.workmux.yaml | 8 +++++++ frontend/.workmux.yaml | 15 ++++++++++++++ scripts/worktree-env | 31 ++++++++++++++++++++++++++++ 5 files changed, 104 insertions(+) create mode 100644 .workmux.yaml create mode 100644 backend/.workmux.yaml create mode 100644 frontend/.workmux.yaml create mode 100755 scripts/worktree-env diff --git a/.gitignore b/.gitignore index 18588e149a..2c3dae5c35 100644 --- a/.gitignore +++ b/.gitignore @@ -14,6 +14,9 @@ backend/.minio-data !.aiderignore rust-client/Cargo.toml +# Worktree-generated port isolation +.env.local + # Symlinked cache directories (for git worktrees) backend/target frontend/node_modules diff --git a/.workmux.yaml b/.workmux.yaml new file mode 100644 index 0000000000..36a57ab13c --- /dev/null +++ b/.workmux.yaml @@ -0,0 +1,47 @@ +main_branch: main + +merge_strategy: rebase +# worktree_dir: .worktrees + +worktree_naming: basename + +worktree_prefix: "" + +# Default: "wm-" +window_prefix: "wm-" + +auto_name: + model: "claude-sonnet-4.6" + system_prompt: "Generate a kebab-case git branch name." + background: true # Always run in background when using --auto-name + + +# Commands to run in new worktree before tmux window opens. +# These block window creation - use for short tasks only. +# Use "" to inherit from global config. +# Set to empty list to disable: `post_create: []` +# post_create: +# - "" +# - mise use +post_create: + - ./scripts/worktree-env + +panes: + - command: + focus: true + - command: "[ -f .env.local ] && source .env.local; cd backend && PORT=${BACKEND_PORT:-8000} cargo run" + split: horizontal + - command: "[ -f .env.local ] && source .env.local; cd frontend && REMOTE=${REMOTE:-http://localhost:${BACKEND_PORT:-8000}} npm run dev -- --port ${FRONTEND_PORT:-3000}" + split: vertical + +files: + copy: + - backend/.env + - scripts/ + symlink: + - frontend/node_modules + - frontend/.svelte-kit + +sandbox: + enabled: false + toolchain: off diff --git a/backend/.workmux.yaml b/backend/.workmux.yaml new file mode 100644 index 0000000000..4091eccbb2 --- /dev/null +++ b/backend/.workmux.yaml @@ -0,0 +1,8 @@ +panes: + # Pane 1: Install dependencies, then start dev server + - command: cargo run + + # Pane 2: AI agent + - command: + split: horizontal + focus: true diff --git a/frontend/.workmux.yaml b/frontend/.workmux.yaml new file mode 100644 index 0000000000..5806617069 --- /dev/null +++ b/frontend/.workmux.yaml @@ -0,0 +1,15 @@ +panes: + # Pane 1: Install dependencies, then start dev server + - command: npm install && npm run generate-backend-client && npm run dev + + # Pane 2: AI agent + - command: + split: horizontal + focus: true + +files: + copy: + - .env + + symlink: + - node_modules diff --git a/scripts/worktree-env b/scripts/worktree-env new file mode 100755 index 0000000000..944a5cc8b3 --- /dev/null +++ b/scripts/worktree-env @@ -0,0 +1,31 @@ +#!/usr/bin/env bash +set -euo pipefail + +port_in_use() { + lsof -nP -iTCP:"$1" -sTCP:LISTEN &>/dev/null +} + +find_port() { + local port=$1 + while port_in_use "$port"; do + ((port++)) + done + echo "$port" +} + +# Hash the handle to get a deterministic port offset (0-99) +hash=$(echo -n "$WM_HANDLE" | md5sum | cut -c1-4) +offset=$((16#$hash % 100)) + +# Find available ports starting from the hash-based offset +backend_port=$(find_port $((8000 + offset * 10))) +frontend_port=$(find_port $((3000 + offset * 10))) + +# Generate .env.local with port overrides +cat > .env.local <