{"id":"9236d2b0-e148-4268-987a-7ab9d3cd09fd","shortId":"dQEft4","kind":"skill","title":"multi-worktree-dev","tagline":"Design and implementation guide for parallel multi-worktree development environments. Use whenever the user mentions multi-worktree development, git worktree, port conflicts, concurrent dev environments, feature branch isolation, local environment setup, or multi-developer collab","description":"# multi-worktree-dev\n\nHandbook for designing and deploying parallel multi-worktree development environments — helps teams define a layered environment strategy that supports concurrent worktree development, parallel testing, and stable shared infrastructure.\n\n## Core Design Goals\n\n| Goal | Specific Design |\n|------|----------|\n| Zero complexity | Creating a new worktree requires no manual configuration — `make dev` handles all setup automatically |\n| Parallel safety | Tests across multiple worktrees run fully in parallel without blocking each other |\n| Shared channel exclusivity | Singleton channels like Feishu WS are held by only one worktree at a time |\n| Instant layer switching | Layer 1 stays running; switching worktrees only requires starting L2/L3 |\n| Zero port conflicts | Ports are assigned via **automatic hash offset**; developers never need to manually edit configuration |\n| Smooth development | Layer 3 is fully hot-reloaded; code changes require no process restart |\n\n## Description\n\nThis Skill covers designing a local environment system from scratch that supports parallel multi-branch development. The core idea is the following **three-layer separation** structure:\n\n| Layer                          | Description                                                           | Lifecycle               |\n| ----------------------------- | -------------------------------------------------------------- | ---------------------- |\n| Layer 1 — Global Shared Infra      | Database, cache, message queue (Kafka/RabbitMQ), LLM proxy, and other heavyweight services | Always running, shared across all branches     |\n| Layer 2 — Worktree-Exclusive Infra | Services that require isolation (e.g., Temporal, secret store)                    | Started/stopped with the worktree  |\n| Layer 3 — Host Processes           | Application services (API, Worker, frontend)                              | Hot-reloaded, run directly on the host machine |\n\n\n## Rules\n\n### Rule 0 — Scan the codebase first; auto-discover services\n\nWhen receiving a layered design request, **do not start by asking the user \"what services do you have\"**. First proactively scan the codebase, auto-discover dependencies, then provide an evidence-based layering recommendation.\n\n**Scanning order (by priority)**:\n\n1. **docker-compose files** (most direct)\n\n   ```bash\n   find . -name \"docker-compose*.yml\" -o -name \"docker-compose*.yaml\" | head -20\n   ```\n\n   Parse the `services:` blocks to extract all service names and images.\n\n2. **requirements / dependency manifests** (infer middleware)\n\n   ```bash\n   # Python\n   grep -rE \"(redis|postgres|psycopg|sqlalchemy|temporalio|kafka|rabbitmq|celery|vault|consul)\" \\\n     requirements*.txt pyproject.toml 2>/dev/null\n\n   # Node.js\n   grep -rE \"(redis|pg|sequelize|temporal|kafka|amqp|consul)\" \\\n     package.json 2>/dev/null\n\n   # Go\n   grep -rE \"(go-redis|lib/pq|temporal|kafka|vault)\" go.mod 2>/dev/null\n   ```\n\n3. **Environment variable files** (discover existing configurations)\n\n   ```bash\n   cat .env.example .env.local.example 2>/dev/null | grep -E \"_URL=|_HOST=|_PORT=\"\n   ```\n\n4. **Makefile / startup scripts** (discover existing dev workflows)\n\n   ```bash\n   grep -E \"^(dev|start|up|test)\" Makefile 2>/dev/null | head -20\n   cat scripts/dev.sh scripts/start.sh 2>/dev/null | head -50\n   ```\n\n5. **Dockerfile files** (discover application service build targets)\n   ```bash\n   find . -name \"Dockerfile*\" | head -20\n   ```\n   Parse each Dockerfile's directory and `EXPOSE` ports to infer which L3 service it is (vs. L1/L2 middleware from step 1's docker-compose).\n\nAfter scanning, compile the discovered service list and, combined with Rule 1's decision tree, present a **pre-filled layering recommendation table** for the user to confirm or correct, rather than having the user describe from scratch.\n\n> **Why scan first?** Users often cannot list all dependencies completely, and the service names they mention may differ from those in the codebase. Discovering directly from the codebase is more accurate and saves back-and-forth communication time.\n\n### Rule 1 — Service Layering Decision\n\nBased on Rule 0's scan results, classify each service using the following decision tree:\n\n```\nCan the service be shared across branches (data overwrites do not affect other branches)?\n  └─ Yes, and startup cost is high (> 30s) → Layer 1 (global shared)\n       └─ No, and branch data isolation is needed → Layer 2 (worktree-exclusive, dynamic port)\n            └─ No, it is the application code itself → Layer 3 (host process, hot-reload)\n```\n\n**Common classification examples**:\n\n| Service                  | Layer | Reasoning                                       |\n| --------------------- | ---- | ------------------------------------------ |\n| PostgreSQL / MySQL    | L1   | Shared schema across branches; isolate by different DB names |\n| Redis                 | L1   | Key prefix isolation is sufficient                           |\n| LiteLLM / model proxy    | L1   | Stateless, safe to share                           |\n| Kafka / RabbitMQ      | L1   | Shared message queue; isolate by topic/queue        |\n| Temporal              | L2   | Requires namespace isolation                        |\n| Vault / Consul        | L2   | Requires independent secret paths                       |\n| API Gateway / Backend | L3   | Hot-reloaded code, runs independently per branch                   |\n| Frontend Dev Server       | L3   | Vite HMR / Next.js dev                     |\n\n### Rule 2 — Port Management (Multi-Worktree Concurrency)\n\nWhen running multiple worktrees concurrently, L2 and L3 services need **dynamic port offsets** to avoid port conflicts.\n\n**Dual-file overlay strategy**:\n\n| File            | Contents                    | Maintained By                                 |\n| --------------- | ----------------------- | -------------------------------------- |\n| `.env.local`    | Default ports, API Keys      | Developer writes once; commit `.example` to Git |\n| `.worktree.env` | Offset ports, overrides above | Auto-generated by `make dev`; add to `.gitignore` |\n\nWith a single worktree, `.worktree.env` is not generated and `.env.local` defaults take effect directly; with concurrent worktrees, the offset kicks in automatically.\n\n**Port hash algorithm example (bash)**:\n\n```bash\n# Deterministic hash offset based on worktree path (range 0-49)\nWT_HASH=$(echo -n \"$(pwd)\" | md5sum | cut -c1-4)\nPORT_OFFSET=$(( 16#${WT_HASH} % 50 ))\n\n# Write to .worktree.env\necho \"GATEWAY_PORT=$(( 8000 + PORT_OFFSET ))\" > .worktree.env\necho \"DASHBOARD_PORT=$(( 3000 + PORT_OFFSET ))\" >> .worktree.env\necho \"TEMPORAL_PORT=$(( 7233 + PORT_OFFSET ))\" >> .worktree.env\n```\n\n**Overlay loading at startup**:\n\n```bash\n# L2 (docker compose)\ndocker compose --env-file .env.local --env-file .worktree.env up -d\n\n# L3 (host process)\nsource .env.local && source .worktree.env\nuvicorn app.main:app --port ${GATEWAY_PORT:-8000} --reload\n```\n\n### Rule 3 — Exclusive Switching for Shared Channels\n\nFeishu WS, WebSocket push endpoints, and other **global singleton channels** can only be held by one worktree at a time.\n\n**Switching mechanism design requirements**:\n\n1. When `make dev` is triggered, automatically execute `scripts/feishu-switch.sh $(PWD)`\n2. The script iterates over all worktrees and sends a \"close channel\" command to other worktrees (update `.worktree.env` + restart the corresponding L3 process)\n3. Only enable the channel in the current worktree\n4. `make test*` **does not trigger** this script — tests do not seize the shared channel\n\n**feishu-switch.sh logic skeleton**:\n\n```bash\n#!/usr/bin/env bash\nCURRENT_WT=\"$1\"\n\n# Iterate over all worktrees\ngit worktree list --porcelain | grep \"^worktree \" | awk '{print $2}' | while read wt; do\n  if [ \"$wt\" != \"$CURRENT_WT\" ]; then\n    # Close Feishu WS in other worktrees\n    echo \"FEISHU_WS_ENABLED=false\" >> \"$wt/.worktree.env\"\n    # Trigger hot-reload of the corresponding gateway (uvicorn --reload detects file changes)\n    touch \"$wt/services/gateway/main.py\"\n  fi\ndone\n\n# Enable in current worktree\necho \"FEISHU_WS_ENABLED=true\" >> \"$CURRENT_WT/.worktree.env\"\n```\n\n### Rule 4 — Idempotent ensure-up Pattern\n\nAll startup scripts must be **idempotent**: calling multiple times produces the same result without creating duplicate resources.\n\n```bash\n# Recommended pattern: check first, then start\nensure_service_up() {\n  local service=$1\n  if ! docker ps --filter \"name=${service}\" --filter \"status=running\" -q | grep -q .; then\n    docker compose up -d \"${service}\"\n  fi\n}\n```\n\n`make test*` internally calls `ensure_service_up` — no need to manually run `make dev` first.\n\n### Rule 4b — Cross-Platform Background Process Startup\n\nLayer 3 host processes need to detach from the parent shell (not killed by SIGHUP when `make` exits); different systems require different commands:\n\n| Platform | Recommended Approach | Notes |\n|------|---------|------|\n| **macOS** | `nohup cmd & disown $!` | `setsid` is not available on macOS |\n| **Linux** | `nohup cmd & disown $!` | Also works; `setsid nohup cmd &` is possible but unnecessary |\n| **Windows (Git Bash/WSL)** | `nohup cmd & disown $!` | Git Bash has built-in `nohup`; `disown` is a bash builtin |\n| **Windows (native cmd/PowerShell)** | `Start-Process -NoNewWindow` / `start /B` | Only for non-bash scenarios |\n\n**Cross-platform unified approach** (in `bash`/`zsh` scripts):\n\n```bash\n_start_bg() {\n  local logfile=\"$LOG_DIR/${1}.log\"\n  mkdir -p \"$LOG_DIR\"\n  nohup \"${@:2}\" > \"$logfile\" 2>&1 &   # nohup: ignore HUP signal\n  local pid=$!\n  disown \"$pid\"                          # disown: remove from shell job table; make exit does not propagate HUP\n  echo \"$pid\"\n}\n\n# Usage\npid=$(_start_bg \"gateway\" bash -c \"cd services/gateway && uvicorn src.main:app --reload\")\n\n```\n\n> **Common pitfall**: `setsid` is Linux-only (util-linux package); on macOS it reports `command not found`.\n> `nohup + disown` is the POSIX-compatible solution, unified across all three platforms.\n\n> **disown scope limitation**: `nohup cmd & disown $!` must be executed within the **same shell context** (same function body or same `{}` block); it cannot span `&&` chains. Inside a subshell within a `&&` chain, `disown` cannot find the job. Wrapping in a function (like `_start_bg` above) ensures correct scope.\n\n\n### Rule 4c — Post-Startup Health Verification (No Faking Ready)\n\nAfter Layer 3 processes start, `make dev` **must perform real port/HTTP health probing** rather than simply printing \"=== Dev environment ready ===\".\n\n**Correct verification logic**:\n\n```bash\n_check_health() {\n  local name=\"$1\" url=\"$2\" port=\"$3\"\n  if [ -n \"$url\" ]; then\n    curl -sf --max-time 3 \"$url\" >/dev/null 2>&1 \\\n      && echo \"  ✓ ${name}\" \\\n      || echo \"  ✗ ${name} (not ready — check .logs/${name}.log)\"\n  else\n    nc -z localhost \"$port\" 2>/dev/null \\\n      && echo \"  ✓ ${name}:${port}\" \\\n      || echo \"  ✗ ${name}:${port} (not ready — check .logs/${name}.log)\"\n  fi\n}\n\nsleep 2  # brief grace for port binding\n_check_health \"gateway\"   \"http://localhost:${GATEWAY_PORT}/health\" \"\"\n_check_health \"sandbox\"   \"http://localhost:${SANDBOX_PORT}/health\" \"\"\n_check_health \"temporal\"  \"\" \"${TEMPORAL_HOST_PORT}\"\n```\n\n**Mandatory requirements**:\n- Every Layer 3 service must have a port or HTTP health probe\n- On failure, output `✗ service (not ready — check .logs/service.log)` with log path guidance\n- A Layer 3 process PID does not mean the service is ready (uvicorn needs 1-2s to bind the port)\n- Checking only PID existence and declaring ready is prohibited\n- \"Dev environment ready\" must not appear while any service is actually down\n\n**Optional services like Vault**: If the service is not configured (Docker cannot pull the image, etc.), display `(not running)` instead of `✗`, and do not block the startup flow.\n\n### Rule 5 — Test Parallel Safety\n\nTest command design standards (naming follows the L1/L2/L3 layer convention from the `testing-strategy` Skill):\n\n| Layer | Command | Infra Dependency | Affects Shared Channel |\n|------|------|-----------|----------------|\n| L1 Unit | `make test-unit` | None (pure code) | No |\n| L2 Integration | `make test-l2` | L1 + L2 (auto ensure) | No |\n| L3 E2E | `make test-l3` | L1 + L2 + L3 services | No |\n| L4 UAT | `make test-l4-uat` | All (requires real Staging environment) | No |\n| Smoke | `make smoke` | All (requires make dev to run first) | No |\n| Full Regression | `make regression` | All (CI quality gate) | No |\n\n> **Core constraint: `make test*` commands do not open, close, or touch singleton channels like Feishu WS.**\n>\n> Specifically:\n> - Does not call `feishu-switch.sh` (does not seize or switch)\n> - Does not set `FEISHU_WS_ENABLED=true` (does not proactively enable)\n> - Does not set `FEISHU_WS_ENABLED=false` and restart gateway (does not proactively disable)\n> - Preserves the current worktree's WS state as-is; state is unchanged after tests complete\n>\n> **Purpose**: While worktree-A is running `make dev` and holding the WS, worktree-B can safely run `make test-l2` without interrupting A's connection.\n\nFor detailed layered testing strategy (coverage gates, mock isolation, TDD debugging, CI pipeline configuration), refer to the `testing-strategy` Skill.\n\n\n### Rule 6 — Hot-Reload and Watch Auto-Build\n\nLayer 3 services should all be configured with hot-reload — code changes **require no manual process restart**.\n\n**Select watch tool by service type**:\n\n| Service Type | Recommended Tool | Startup Command | Trigger Condition |\n|---------|---------|---------|--------|\n| Python API (FastAPI/Flask) | `uvicorn --reload` | `uvicorn app.main:app --reload --reload-dir src` | `.py` file changes |\n| Python Worker (Temporal/Celery) | `watchfiles` | `watchfiles 'python worker.py' src/` | `.py` file changes |\n| Node.js / TypeScript Worker | `tsx watch` / `nodemon` | `tsx watch src/worker.ts` | `.ts/.js` changes |\n| Frontend (React/Next.js/Vite) | Built-in HMR | `vite dev` / `next dev` | Instant partial browser refresh, no manual refresh |\n| Go service | `air` | `air -c .air.toml` | `.go` file changes trigger auto-recompile |\n| Static files / config | `watchexec` | `watchexec -e yaml,toml -- ./restart.sh` | Config file changes trigger restart script |\n| Flutter Web | `flutter build web` + Vite hosting | Build first, Vite hosts `/build/web/`; dev with `flutter run -d chrome` | Dart file changes trigger Hot Restart |\n\n**Multi-worktree note**: Each worktree's watch processes are independent; ports are already isolated via Rule 2's offset, so no extra handling is needed.\n\n#### Container Hot-Reload (Volume Mount Mode)\n\nFor L3 services running as **containers** (not host processes), hot-reload is achieved by **mounting the source directory** rather than rebuilding the image:\n\n```yaml\n# docker-compose.dev.yml — Dev mode: mount host source code\nservices:\n  sandbox:\n    image: your-org/your-image:latest   # Image only provides the runtime environment\n    volumes:\n      - ./services/sandbox:/app/src  # Host source → inside container\n    command: tsx watch /app/src/index.ts  # Container watcher monitors changes\n    environment:\n      - NODE_ENV=development\n```\n\n```yaml\n# docker-compose.prod.yml — Production mode: code baked into image\nservices:\n  sandbox:\n    image: your-org/your-image:${IMAGE_TAG}  # Code packaged at image build time\n    # No volumes, no watcher, code is immutable\n```\n\n**Key differences between dev and production**:\n\n| Dimension | Dev Mode (volume mount) | Production Mode (baked image) |\n|------|------------------------|----------------------|\n| Code source | Real-time mount from host directory | Frozen into image at build time |\n| Hot-reload | Container watcher monitors changes | Requires image rebuild for code changes |\n| Image build | Not needed (fast startup) | CI build → push to Harbor |\n| Isolation | Low (shares source with host) | High (completely independent) |\n| Use case | Local development iteration | staging / prod deployment |\n\n**In a multi-worktree environment**, dev mode volume mount paths already contain the worktree's absolute path, so different worktrees are naturally isolated — no extra handling is needed.\n\n**Scan for existing watch configuration** (check alongside Rule 0 scan):\n\n```bash\n# Check if existing docker-compose distinguishes dev/prod modes\nls docker-compose*.yml\ngrep -l \"volumes:\" docker-compose*.yml   # Files with volumes are dev-style\ngrep -l \"NODE_ENV=production\" docker-compose*.yml  # Production mode\n\n# Check if services already have watch configured\ngrep -rE \"(--reload|watchfiles|nodemon|tsx watch|air|HMR)\" \\\n  Makefile scripts/*.sh 2>/dev/null\n```\n\nIf the project has only a single `docker-compose.yml` without dev/prod distinction, recommend splitting into `docker-compose.yml` (base) + `docker-compose.dev.yml` (dev override).\n\n### Rule 7 — Dev Lifecycle Command Design\n\n`make dev` is not the only command — a complete lifecycle command set is needed:\n\n| Command | Behavior | Typical Implementation |\n|------|------|--------|\n| `make dev` | Start current worktree (L2 + L3), switch shared channels | ensure L1 → ensure L2 → start L3 with watch → feishu-switch |\n| `make dev-down` | Stop current worktree (L2 + L3 stop, **L1 keeps running**) | stop L3 pids → docker compose stop L2 services |\n| `make dev-check` | Check health status of all services | curl each service health endpoint, list UP/DOWN |\n| `make dev-restart` | Quick restart L3 processes (without restarting L2) | kill L3 pids → restart with watch |\n\n**Two modes for E2E testing** (applicable to L3 services with external API dependencies):\n\n| Mode | External Dependency Handling | Applicable Stage |\n|------|------------|---------|\n| **Mock mode** (daily) | Use mock server to simulate external APIs | Daily development iteration; fast startup, no extra dependencies |\n| **Real mode** (pre-acceptance) | Connect to real external services/environments | Pre-release acceptance; verify real integration behavior |\n\n\n\n**Prerequisite checks** (auto-verified before `make dev` starts):\n\n```bash\ncheck_prerequisites() {\n  command -v docker >/dev/null || { echo \"❌ docker not found\"; exit 1; }\n  command -v uv >/dev/null    || { echo \"❌ uv not found\"; exit 1; }\n  command -v node >/dev/null  || { echo \"❌ node not found\"; exit 1; }\n  docker info >/dev/null 2>&1 || { echo \"❌ Docker daemon not running\"; exit 1; }\n  echo \"✅ prerequisites OK\"\n}\n```\n\n### Rule 8 — Documentation Structure (Quad-File Pattern)\n\nFor each service with independent deployment complexity, documentation is organized into four files:\n\n```\ndocs/deployment/\n  overview.md    # Architecture overview, Mermaid flow diagrams (local → CI → CD)\n  local-dev.md   # Split into \"User Guide\" and \"Implementation Details\" sections\n  ci.md          # CI pipeline design, testing strategy\n  cd.md          # K8s / Terraform / ArgoCD configuration\n```\n\n`local-dev.md` must have two sections:\n\n- **User Guide**: Commands and results only, for developers\n- **Implementation Details**: Explains the design rationale, for maintainers\n\n### Rule 9 — Operational Red Lines\n\n- **Prohibited**: Modifying Layer 1 docker-compose configuration without notifying other running worktrees\n- **Prohibited**: Calling shared channel switching scripts in `make test*`\n- **Prohibited**: Committing `.worktree.env` to Git (must be gitignored)\n- **Prohibited**: Hard-coding port numbers in a multi-worktree environment (must use environment variables + offset)\n- When Layer 1 services go down, **investigate shared resources first** before restarting to avoid affecting other worktrees running tests\n- **Bare commands that change state must be synced back to make/scripts**: Running `docker compose up/down`, `uvicorn`, `pytest`, etc. directly changes system state (starts processes, occupies ports, writes pid files), but make and scripts are unaware — next time `make dev` runs, ports are already occupied, pid files are stale, and infra state is mismatched, causing make to fail.\n  - If bare commands were used for temporary debugging, after debugging either **kill the manually started processes** or **codify the changes into scripts/**, keeping make and actual state consistent.\n  - Correct: bare command debugging → kill processes after debugging → `make dev` takes over\n  - Wrong: Start sandbox with a bare command, don't kill it, run `make dev` directly → port already in use\n- **Bare commands are prohibited**: All development/test operations must use existing `make` targets. First check if existing targets cover the need; if not, check if parameter combinations can achieve it.\n- **Make targets are fixed; adding new ones arbitrarily is prohibited**: The allowed targets are a fixed set:\n  - Development lifecycle: `make dev`, `make dev-check`, `make dev-down`\n  - Testing: `make test-unit`, `make test-l2`, `make test-l3`, `make test-l4-uat`, `make smoke`, `make regression`, `make test-cov`, `make test-watch`\n  - Build/quality: `make lint`, `make format`, `make build-*`\n  - New targets that do not belong to any of the above categories must not be added.\n\n### Rule 10 — Flutter Web E2E Testing (Playwright + Semantics Tree)\n\nFlutter Web E2E testing uses Playwright to operate the Flutter Semantics tree (accessible DOM tree) without modifying Flutter production code.\n\n**Core approach** (based on iot-system-template):\n\n| Step | Description |\n|------|------|\n| Wait for ready | Poll for `<flutter-view>` or `<flt-glass-pane>` to appear |\n| Enable Semantics | Click Flutter's built-in \"Enable accessibility\" button |\n| Element location | Locate via ARIA role attributes (`role=\"button\"`, `role=\"switch\"`, etc.) |\n| Interaction | Standard Playwright click/fill/assert operations |\n\n**Playwright configuration notes**:\n\n```typescript\n// playwright.config.ts\nexport default defineConfig({\n  testDir: './tests/l3-browser',\n  timeout: 60_000,           // Flutter Web loads slowly\n  expect: { timeout: 15_000 },\n  workers: 1,                // Flutter Web does not support parallelism\n  projects: [{\n    name: 'chromium',\n    use: {\n      headless: true,\n      screenshot: 'only-on-failure',\n      video: 'retain-on-failure',\n    },\n  }],\n  webServer: {\n    command: 'npm run dev',  // or vite dev\n    port: 5173,\n    reuseExistingServer: true,\n    timeout: 120_000,\n  },\n});\n```\n\n**Test helper functions**:\n\n```typescript\nasync function waitForFlutterReady(page: Page) {\n  await page.waitForSelector('flutter-view, flt-glass-pane', { timeout: 30_000 });\n}\n\nasync function enableFlutterSemantics(page: Page) {\n  const btn = page.locator('flt-semantics-placeholder');\n  if (await btn.isVisible()) await btn.click();\n}\n```\n\n**Multi-worktree note**: The Playwright webServer port is automatically isolated via `.worktree.env` offset, so multiple worktrees can run E2E tests in parallel without conflicts.\n\n## Examples\n\n### Bad\n\n```\nNew project layering design:\n- Temporal in Layer 1 (all worktrees share the same Temporal namespace)\n  → Problem: worktree-A's Workflows will be picked up by worktree-B's Workers\n\n- make test calls feishu-switch.sh\n  → Problem: running a test seizes a colleague's Feishu connection\n\n- GATEWAY_PORT=8001 hard-coded in code\n  → Problem: the second worktree gets a port conflict on startup\n```\n\n### Good\n\n```\nNew project layering design:\n- Temporal → Layer 2 (each worktree has independent port + namespace: wt-{hash})\n- make test* → only ensures L1/L2; does not call feishu-switch.sh\n- Ports computed automatically via PORT_OFFSET=$(hash(pwd) % 50), written to .worktree.env\n\nStandard multi-worktree concurrent development flow:\n  worktree-A: make dev       → holds Feishu WS, receives messages normally\n  worktree-B: make test-l2   → runs integration tests in parallel without affecting A's connection\n  Switch development: worktree-A make dev-down → worktree-B make dev (instant)\n```\n\n## References\n\n- [testing-strategy Skill](../testing-strategy/SKILL.md) — Complete L1/L2/L3/L4 layered testing strategy with CI quality gates and TDD debugging workflow\n- [YourProject local dev environment docs](../../YourProject/.claude/worktrees/local-dev/docs/deployment/local-dev.md) — Reference implementation for L1/L2/L3 layering\n- [YourProject deployment architecture overview](../../YourProject/.claude/worktrees/local-dev/docs/deployment/overview.md) — Mermaid architecture diagrams + full CI/CD chain","tags":["multi","worktree","dev","enterprise","harness","engineering","addxai","agent-skills","ai-agent","ai-engineering","claude-code","code-review"],"capabilities":["skill","source-addxai","skill-multi-worktree-dev","topic-agent-skills","topic-ai-agent","topic-ai-engineering","topic-claude-code","topic-code-review","topic-cursor","topic-devops","topic-enterprise","topic-sre","topic-windsurf"],"categories":["enterprise-harness-engineering"],"synonyms":[],"warnings":[],"endpointUrl":"https://skills.sh/addxai/enterprise-harness-engineering/multi-worktree-dev","protocol":"skill","transport":"skills-sh","auth":{"type":"none","details":{"cli":"npx skills add addxai/enterprise-harness-engineering","source_repo":"https://github.com/addxai/enterprise-harness-engineering","install_from":"skills.sh"}},"qualityScore":"0.458","qualityRationale":"deterministic score 0.46 from registry signals: · indexed on github topic:agent-skills · 16 github stars · SKILL.md body (24,293 chars)","verified":false,"liveness":"unknown","lastLivenessCheck":null,"agentReviews":{"count":0,"score_avg":null,"cost_usd_avg":null,"success_rate":null,"latency_p50_ms":null,"narrative_summary":null,"summary_updated_at":null},"enrichmentModel":"deterministic:skill-github:v1","enrichmentVersion":1,"enrichedAt":"2026-04-22T01:02:12.353Z","embedding":null,"createdAt":"2026-04-21T19:04:01.848Z","updatedAt":"2026-04-22T01:02:12.353Z","lastSeenAt":"2026-04-22T01:02:12.353Z","tsv":"'-2':1493 '-20':335,435,456 '-4':812 '-49':803 '-50':442 '-8000':876 '/../yourproject/.claude/worktrees/local-dev/docs/deployment/local-dev.md':3180 '/../yourproject/.claude/worktrees/local-dev/docs/deployment/overview.md':3190 '/app/src':1987 '/app/src/index.ts':1995 '/b':1192 '/build/web':1893 '/dev/null':371,384,397,410,433,440,1392,1411,2204,2394,2404,2414,2423 '/health':1438,1445 '/restart.sh':1875 '/services/sandbox':1986 '/testing-strategy/skill.md':3161 '/tests/l3-browser':2890 '/usr/bin/env':970 '/your-image':1977,2018 '0':266,567,802,2142 '000':2893,2901,2940,2961 '1':133,207,314,477,493,560,601,909,974,1073,1215,1225,1376,1394,1492,2400,2410,2420,2425,2432,2516,2562,2903,3013 '10':2807 '120':2939 '15':2900 '16':815 '2':229,347,370,383,396,409,432,439,612,707,919,987,1222,1224,1378,1393,1410,1426,1923,2203,2424,3076 '3':162,247,398,626,879,942,1117,1350,1380,1390,1456,1480,1768 '30':2960 '3000':832 '30s':599 '4':416,951,1038 '4b':1109 '4c':1339 '5':443,1549 '50':818,3102 '5173':2935 '6':1758 '60':2892 '7':2225 '7233':839 '8':2437 '8000':825 '8001':3053 '9':2509 'absolut':2121 'accept':2365,2374 'access':2827,2862 'accur':550 'achiev':1952,2722 'across':101,225,584,643,1288 'actual':1518,2661 'ad':2728,2805 'add':763 'affect':590,1573,2574,3137 'air':1856,1857,2198 'air.toml':1859 'algorithm':790 'allow':2735 'alongsid':2140 'alreadi':1919,2116,2187,2621,2692 'also':1157 'alway':222 'amqp':380 'api':252,686,743,1800,2335,2352 'app':872,1259,1806 'app.main':871,1805 'appear':1513,2852 'applic':250,447,622,2329,2341 'approach':1141,1203,2836 'arbitrarili':2731 'architectur':2459,3188,3192 'argocd':2485 'aria':2868 'as-i':1699 'ask':285 'assign':147 'async':2945,2962 'attribut':2870 'auto':272,299,758,1594,1765,1865,2382 'auto-build':1764 'auto-discov':271,298 'auto-gener':757 'auto-recompil':1864 'auto-verifi':2381 'automat':97,149,787,915,2988,3096 'avail':1150 'avoid':728,2573 'await':2950,2975,2977 'awk':985 'b':1723,3034,3126,3152 'back':554,2587 'back-and-forth':553 'backend':688 'background':1113 'bad':3005 'bake':2009,2047 'bare':2579,2637,2665,2681,2695 'base':307,564,797,2220,2837 'bash':321,353,405,424,451,792,793,847,969,971,1061,1173,1182,1197,1205,1208,1253,1371,2144,2388 'bash/wsl':1168 'behavior':2245,2378 'belong':2795 'bg':1210,1251,1333 'bind':1431,1496 'block':109,339,1311,1544 'bodi':1308 'branch':33,190,227,585,592,606,644,697 'brief':1427 'browser':1849 'btn':2968 'btn.click':2978 'btn.isvisible':2976 'build':449,1766,1885,1889,2025,2062,2078,2084,2789 'build/quality':2783 'built':1176,1840,2859 'built-in':1175,1839,2858 'builtin':1183 'button':2863,2872 'c':1254,1858 'c1':811 'cach':212 'call':1050,1096,1660,2527,3039,3092 'cannot':525,1313,1323,1531 'case':2098 'cat':406,436 'categori':2801 'caus':2632 'cd':1255,2466 'cd.md':2482 'celeri':364 'chain':1315,1321,3196 'chang':169,1021,1779,1814,1825,1836,1862,1878,1902,1999,2070,2076,2582,2598,2655 'channel':113,116,884,894,930,946,965,1575,1653,2257,2529 'check':1064,1372,1401,1420,1432,1439,1446,1472,1499,2139,2145,2184,2293,2294,2380,2389,2708,2717,2748 'chrome':1899 'chromium':2912 'ci':1637,1747,2083,2465,2477,3168 'ci.md':2476 'ci/cd':3195 'classif':633 'classifi':571 'click':2855 'click/fill/assert':2879 'close':929,997,1649 'cmd':1145,1155,1161,1170,1296 'cmd/powershell':1186 'code':168,623,693,1584,1778,1970,2008,2021,2031,2049,2075,2546,2834,3056,3058 'codebas':269,297,542,547 'codifi':2653 'collab':42 'colleagu':3047 'combin':490,2720 'command':931,1138,1276,1554,1570,1645,1796,1992,2228,2236,2240,2244,2391,2401,2411,2494,2580,2638,2666,2682,2696,2927 'commit':748,2536 'common':632,1261 'communic':557 'compat':1285 'compil':484 'complet':529,1707,2095,2238,3162 'complex':83,2450 'compos':317,326,332,481,850,852,1088,2150,2157,2164,2180,2286,2519,2592 'comput':3095 'concurr':29,67,713,718,781,3110 'condit':1798 'config':1869,1876 'configur':91,158,404,1529,1749,1773,2138,2190,2486,2520,2882 'confirm':509 'conflict':28,144,730,3003,3066 'connect':1735,2366,3050,3140 'consist':2663 'const':2967 'constraint':1642 'consul':366,381,680 'contain':1932,1944,1991,1996,2067,2117 'content':737 'context':1305 'convent':1562 'core':76,193,1641,2835 'correct':511,1336,1368,2664 'correspond':939,1015 'cost':596 'cov':2778 'cover':177,2712 'coverag':1741 'creat':84,1058 'cross':1111,1200 'cross-platform':1110,1199 'curl':1385,2300 'current':949,972,994,1028,1035,1694,2251,2274 'cut':810 'd':862,1090,1898 'daemon':2428 'daili':2345,2353 'dart':1900 'dashboard':830 'data':586,607 'databas':211 'db':648 'debug':1746,2643,2645,2667,2671,3173 'decis':495,563,577 'declar':1504 'default':741,776,2887 'defin':60 'defineconfig':2888 'depend':301,349,528,1572,2336,2339,2360 'deploy':51,2104,2449,3187 'describ':517 'descript':174,204,2844 'design':5,49,77,81,178,279,907,1555,2229,2479,2504,3009,3073 'detach':1122 'detail':1737,2474,2501 'detect':1019 'determinist':794 'dev':4,30,46,93,422,427,699,705,762,912,1106,1354,1365,1508,1627,1716,1844,1846,1894,1965,2037,2041,2111,2171,2222,2226,2231,2249,2271,2292,2309,2386,2617,2673,2689,2744,2747,2751,2930,2933,3117,3148,3154,3177 'dev-check':2291,2746 'dev-down':2270,2750,3147 'dev-restart':2308 'dev-styl':2170 'dev/prod':2152,2214 'develop':14,24,41,56,69,152,160,191,745,2003,2100,2354,2499,2741,3111,3142 'development/test':2700 'diagram':2463,3193 'differ':537,647,1134,1137,2035,2124 'dimens':2040 'dir':1214,1220,1810 'direct':259,320,544,779,2597,2690 'directori':461,1957,2057 'disabl':1691 'discov':273,300,402,420,446,486,543 'disown':1146,1156,1171,1179,1232,1234,1280,1292,1297,1322 'display':1536 'distinct':2215 'distinguish':2151 'doc':3179 'docker':316,325,331,480,849,851,1075,1087,1530,2149,2156,2163,2179,2285,2393,2396,2421,2427,2518,2591 'docker-compos':315,324,330,479,2148,2155,2162,2178,2517 'docker-compose.dev.yml':1964,2221 'docker-compose.prod.yml':2005 'docker-compose.yml':2212,2219 'dockerfil':444,454,459 'docs/deployment':2457 'document':2438,2451 'dom':2828 'done':1025 'dual':732 'dual-fil':731 'duplic':1059 'dynam':616,724 'e':412,426,1872 'e.g':238 'e2e':1598,2327,2810,2817,2998 'echo':806,822,829,836,1003,1030,1246,1395,1397,1412,1415,2395,2405,2415,2426,2433 'edit':157 'effect':778 'either':2646 'element':2864 'els':1405 'enabl':944,1006,1026,1033,1672,1677,1683,2853,2861 'enablefluttersemant':2964 'endpoint':889,2304 'ensur':1041,1068,1097,1335,1595,2258,2260,3088 'ensure-up':1040 'env':854,858,2002,2176 'env-fil':853,857 'env.example':407 'env.local':740,775,856,867 'env.local.example':408 'environ':15,31,36,57,63,181,399,1366,1509,1619,1984,2000,2110,2554,2557,3178 'etc':1535,2596,2875 'everi':1454 'evid':306 'evidence-bas':305 'exampl':634,749,791,3004 'exclus':114,232,615,880 'execut':916,1300 'exist':403,421,1502,2136,2147,2704,2710 'exit':1133,1241,2399,2409,2419,2431 'expect':2898 'explain':2502 'export':2886 'expos':463 'extern':2334,2338,2351,2369 'extra':1928,2130,2359 'extract':341 'fail':2635 'failur':1467,2920,2925 'fake':1346 'fals':1007,1684 'fast':2081,2356 'fastapi/flask':1801 'featur':32 'feishu':118,885,998,1004,1031,1655,1670,1681,2267,3049,3119 'feishu-switch':2266 'feishu-switch.sh':966,1661,3040,3093 'fi':1024,1092,1424 'file':318,401,445,733,736,855,859,1020,1813,1824,1861,1868,1877,1901,2166,2442,2456,2607,2624 'fill':501 'filter':1077,1080 'find':322,452,1324 'first':270,293,522,1065,1107,1630,1890,2569,2707 'fix':2727,2739 'flow':1547,2462,3112 'flt':2956,2971 'flt-glass-pan':2955 'flt-semantics-placehold':2970 'flutter':1882,1884,1896,2808,2815,2824,2832,2856,2894,2904,2953 'flutter-view':2952 'follow':197,576,1558 'format':2787 'forth':556 'found':1278,2398,2408,2418 'four':2455 'frontend':254,698,1837 'frozen':2058 'full':1632,3194 'fulli':105,164 'function':1307,1330,2943,2946,2963 'gate':1639,1742,3170 'gateway':687,823,874,1016,1252,1434,1436,1687,3051 'generat':759,773 'get':3063 'git':25,751,979,1167,1172,2539 'gitignor':765,2542 'glass':2957 'global':208,602,892 'go':385,389,1854,1860,2564 'go-redi':388 'go.mod':395 'goal':78,79 'good':3069 'grace':1428 'grep':355,373,386,411,425,983,1084,2159,2173,2191 'guid':8,2471,2493 'guidanc':1477 'handbook':47 'handl':94,1929,2131,2340 'harbor':2087 'hard':2545,3055 'hard-cod':2544,3054 'hash':150,789,795,805,817,3084,3100 'head':334,434,441,455 'headless':2914 'health':1343,1359,1373,1433,1440,1447,1464,2295,2303 'heavyweight':220 'held':121,898 'help':58 'helper':2942 'high':598,2094 'hmr':703,1842,2199 'hold':1718,3118 'host':248,262,414,627,864,1118,1450,1888,1892,1946,1968,1988,2056,2093 'hot':166,256,630,691,1011,1760,1776,1904,1934,1949,2065 'hot-reload':165,255,629,690,1010,1759,1775,1933,1948,2064 'http':1463 'hup':1228,1245 'idea':194 'idempot':1039,1049 'ignor':1227 'imag':346,1534,1962,1973,1979,2011,2014,2019,2024,2048,2060,2072,2077 'immut':2033 'implement':7,2247,2473,2500,3182 'independ':683,695,1916,2096,2448,3080 'infer':351,466 'info':2422 'infra':210,233,1571,2628 'infrastructur':75 'insid':1316,1990 'instant':129,1847,3155 'instead':1539 'integr':1587,2377,3132 'interact':2876 'intern':1095 'interrupt':1732 'investig':2566 'iot':2840 'iot-system-templ':2839 'isol':34,237,608,645,654,671,678,1744,1920,2088,2128,2989 'iter':922,975,2101,2355 'job':1238,1326 'k8s':2483 'kafka':362,379,393,665 'kafka/rabbitmq':215 'keep':2280,2658 'key':652,744,2034 'kick':785 'kill':1128,2318,2647,2668,2685 'l':2160,2174 'l1':640,651,660,667,1576,1592,1603,2259,2279 'l1/l2':473,3089 'l1/l2/l3':1560,3184 'l1/l2/l3/l4':3163 'l2':675,681,719,848,1586,1591,1593,1604,1730,2253,2261,2276,2288,2317,2761,3130 'l2/l3':141 'l3':468,689,701,721,863,940,1597,1602,1605,1940,2254,2263,2277,2283,2313,2319,2331,2765 'l4':1608,1613,2769 'latest':1978 'layer':62,130,132,161,200,203,206,228,246,278,308,502,562,600,611,625,636,1116,1349,1455,1479,1561,1569,1738,1767,2515,2561,3008,3012,3072,3075,3164,3185 'lib/pq':391 'lifecycl':205,2227,2239,2742 'like':117,1331,1522,1654 'limit':1294 'line':2512 'lint':2785 'linux':1153,1266,1270 'linux-on':1265 'list':488,526,981,2305 'litellm':657 'llm':216 'load':844,2896 'local':35,180,1071,1211,1230,1374,2099,2464,3176 'local-dev.md':2467,2487 'localhost':1408,1435,1442 'locat':2865,2866 'log':1213,1216,1219,1402,1404,1421,1423,1475 'logfil':1212,1223 'logic':967,1370 'logs/service.log':1473 'low':2089 'ls':2154 'machin':263 'maco':1143,1152,1273 'maintain':738,2507 'make':92,761,911,952,1093,1105,1132,1240,1353,1578,1588,1599,1610,1622,1626,1634,1643,1715,1727,2230,2248,2269,2290,2307,2385,2533,2609,2616,2633,2659,2672,2688,2705,2724,2743,2745,2749,2754,2758,2762,2766,2771,2773,2775,2779,2784,2786,2788,3037,3085,3116,3127,3146,3153 'make/scripts':2589 'makefil':417,431,2200 'manag':709 'mandatori':1452 'manifest':350 'manual':90,156,1103,1782,1852,2649 'max':1388 'max-tim':1387 'may':536 'md5sum':809 'mean':1485 'mechan':906 'mention':20,535 'mermaid':2461,3191 'messag':213,669,3122 'middlewar':352,474 'mismatch':2631 'mkdir':1217 'mock':1743,2343,2347 'mode':1938,1966,2007,2042,2046,2112,2153,2183,2325,2337,2344,2362 'model':658 'modifi':2514,2831 'monitor':1998,2069 'mount':1937,1954,1967,2044,2054,2114 'multi':2,12,22,40,44,54,189,711,1907,2108,2552,2980,3108 'multi-branch':188 'multi-develop':39 'multi-worktre':11,21,53,710,1906,2107,2551,2979,3107 'multi-worktree-dev':1,43 'multipl':102,716,1051,2994 'must':1047,1298,1355,1458,1511,2488,2540,2555,2584,2702,2802 'mysql':639 'n':807,1382 'name':323,329,344,453,533,649,1078,1375,1396,1398,1403,1413,1416,1422,1557,2911 'namespac':677,3020,3082 'nativ':1185 'natur':2127 'nc':1406 'need':154,610,723,1101,1120,1491,1931,2080,2133,2243,2714 'never':153 'new':86,2729,2790,3006,3070 'next':1845,2614 'next.js':704 'node':2001,2175,2413,2416 'node.js':372,1826 'nodemon':1831,2195 'nohup':1144,1154,1160,1169,1178,1221,1226,1279,1295 'non':1196 'non-bash':1195 'none':1582 'nonewwindow':1190 'normal':3123 'note':1142,1909,2883,2982 'notifi':2522 'npm':2928 'number':2548 'o':328 'occupi':2603,2622 'offset':151,726,753,784,796,814,827,834,841,1925,2559,2992,3099 'often':524 'ok':2435 'one':124,900,2730 'only-on-failur':2917 'open':1648 'oper':2510,2701,2822,2880 'option':1520 'order':311 'org':1976,2017 'organ':2453 'output':1468 'overlay':734,843 'overrid':755,2223 'overview':2460,3189 'overview.md':2458 'overwrit':587 'p':1218 'packag':1271,2022 'package.json':382 'page':2948,2949,2965,2966 'page.locator':2969 'page.waitforselector':2951 'pane':2958 'parallel':10,52,70,98,107,187,1551,2909,3001,3135 'paramet':2719 'parent':1125 'pars':336,457 'partial':1848 'path':685,800,1476,2115,2122 'pattern':1043,1063,2443 'per':696 'perform':1356 'pg':376 'pick':3029 'pid':1231,1233,1247,1249,1482,1501,2284,2320,2606,2623 'pipelin':1748,2478 'pitfal':1262 'placehold':2973 'platform':1112,1139,1201,1291 'playwright':2812,2820,2878,2881,2984 'playwright.config.ts':2885 'poll':2848 'porcelain':982 'port':27,143,145,415,464,617,708,725,729,742,754,788,813,824,826,831,833,838,840,873,875,1379,1409,1414,1417,1430,1437,1444,1451,1461,1498,1917,2547,2604,2619,2691,2934,2986,3052,3065,3081,3094,3098 'port/http':1358 'posix':1284 'posix-compat':1283 'possibl':1163 'post':1341 'post-startup':1340 'postgr':358 'postgresql':638 'pre':500,2364,2372 'pre-accept':2363 'pre-fil':499 'pre-releas':2371 'prefix':653 'prerequisit':2379,2390,2434 'present':497 'preserv':1692 'print':986,1364 'prioriti':313 'proactiv':294,1676,1690 'probe':1360,1465 'problem':3021,3041,3059 'process':172,249,628,865,941,1114,1119,1189,1351,1481,1783,1914,1947,2314,2602,2651,2669 'prod':2103 'produc':1053 'product':2006,2039,2045,2177,2182,2833 'prohibit':1507,2513,2526,2535,2543,2698,2733 'project':2207,2910,3007,3071 'propag':1244 'provid':303,1981 'proxi':217,659 'ps':1076 'psycopg':359 'pull':1532 'pure':1583 'purpos':1708 'push':888,2085 'pwd':808,918,3101 'py':1812,1823 'pyproject.toml':369 'pytest':2595 'python':354,1799,1815,1820 'q':1083,1085 'quad':2441 'quad-fil':2440 'qualiti':1638,3169 'queue':214,670 'quick':2311 'rabbitmq':363,666 'rang':801 'rather':512,1361,1958 'rational':2505 're':356,374,387,2192 'react/next.js/vite':1838 'read':989 'readi':1347,1367,1400,1419,1471,1489,1505,1510,2847 'real':1357,1617,2052,2361,2368,2376 'real-tim':2051 'reason':637 'rebuild':1960,2073 'receiv':276,3121 'recommend':309,503,1062,1140,1793,2216 'recompil':1866 'red':2511 'redi':357,375,390,650 'refer':1750,3156,3181 'refresh':1850,1853 'regress':1633,1635,2774 'releas':2373 'reload':167,257,631,692,877,1012,1018,1260,1761,1777,1803,1807,1809,1935,1950,2066,2193 'reload-dir':1808 'remov':1235 'report':1275 'request':280 'requir':88,139,170,236,348,367,676,682,908,1136,1453,1616,1625,1780,2071 'resourc':1060,2568 'restart':173,937,1686,1784,1880,1905,2310,2312,2316,2321,2571 'result':570,1056,2496 'retain':2923 'retain-on-failur':2922 'reuseexistingserv':2936 'role':2869,2871,2873 'rule':264,265,492,559,566,706,878,1037,1108,1338,1548,1757,1922,2141,2224,2436,2508,2806 'run':104,135,223,258,694,715,1082,1104,1538,1629,1714,1726,1897,1942,2281,2430,2524,2577,2590,2618,2687,2929,2997,3042,3131 'runtim':1983 'safe':662,1725 'safeti':99,1552 'sandbox':1441,1443,1972,2013,2678 'save':552 'scan':267,295,310,483,521,569,2134,2143 'scenario':1198 'schema':642 'scope':1293,1337 'scratch':184,519 'screenshot':2916 'script':419,921,958,1046,1207,1881,2201,2531,2611,2657 'scripts/dev.sh':437 'scripts/feishu-switch.sh':917 'scripts/start.sh':438 'second':3061 'secret':240,684 'section':2475,2491 'seiz':962,1664,3045 'select':1785 'semant':2813,2825,2854,2972 'send':927 'separ':201 'sequel':377 'server':700,2348 'servic':221,234,251,274,289,338,343,448,469,487,532,561,573,581,635,722,1069,1072,1079,1091,1098,1457,1469,1487,1516,1521,1526,1606,1769,1789,1791,1855,1941,1971,2012,2186,2289,2299,2302,2332,2446,2563 'services/environments':2370 'services/gateway':1256 'set':1669,1680,2241,2740 'setsid':1147,1159,1263 'setup':37,96 'sf':1386 'sh':2202 'share':74,112,209,224,583,603,641,664,668,883,964,1574,2090,2256,2528,2567,3016 'shell':1126,1237,1304 'sighup':1130 'signal':1229 'simpli':1363 'simul':2350 'singl':768,2211 'singleton':115,893,1652 'skeleton':968 'skill':176,1568,1756,3160 'skill-multi-worktree-dev' 'sleep':1425 'slowli':2897 'smoke':1621,1623,2772 'smooth':159 'solut':1286 'sourc':866,868,1956,1969,1989,2050,2091 'source-addxai' 'span':1314 'specif':80,1657 'split':2217,2468 'sqlalchemi':360 'src':1811,1822 'src.main':1258 'src/worker.ts':1834 'stabl':73 'stage':1618,2102,2342 'stale':2626 'standard':1556,2877,3106 'start':140,283,428,1067,1188,1191,1209,1250,1332,1352,2250,2262,2387,2601,2650,2677 'start-process':1187 'started/stopped':242 'startup':418,595,846,1045,1115,1342,1546,1795,2082,2357,3068 'state':1698,1702,2583,2600,2629,2662 'stateless':661 'static':1867 'status':1081,2296 'stay':134 'step':476,2843 'stop':2273,2278,2282,2287 'store':241 'strategi':64,735,1567,1740,1755,2481,3159,3166 'structur':202,2439 'style':2172 'subshel':1318 'suffici':656 'support':66,186,2908 'switch':131,136,881,905,1666,2255,2268,2530,2874,3141 'sync':2586 'system':182,1135,2599,2841 'tabl':504,1239 'tag':2020 'take':777,2674 'target':450,2706,2711,2725,2736,2791 'tdd':1745,3172 'team':59 'templat':2842 'tempor':239,378,392,674,837,1448,1449,3010,3019,3074 'temporal/celery':1817 'temporalio':361 'temporari':2642 'terraform':2484 'test':71,100,430,953,959,1094,1550,1553,1566,1580,1590,1601,1612,1644,1706,1729,1739,1754,2328,2480,2534,2578,2753,2756,2760,2764,2768,2777,2781,2811,2818,2941,2999,3038,3044,3086,3129,3133,3158,3165 'test-cov':2776 'test-l2':1589,1728,2759,3128 'test-l3':1600,2763 'test-l4-uat':1611,2767 'test-unit':1579,2755 'test-watch':2780 'testdir':2889 'testing-strategi':1565,1753,3157 'three':199,1290 'three-lay':198 'time':128,558,904,1052,1389,2026,2053,2063,2615 'timeout':2891,2899,2938,2959 'toml':1874 'tool':1787,1794 'topic-agent-skills' 'topic-ai-agent' 'topic-ai-engineering' 'topic-claude-code' 'topic-code-review' 'topic-cursor' 'topic-devops' 'topic-enterprise' 'topic-sre' 'topic-windsurf' 'topic/queue':673 'touch':1022,1651 'tree':496,578,2814,2826,2829 'trigger':914,956,1009,1797,1863,1879,1903 'true':1034,1673,2915,2937 'ts/.js':1835 'tsx':1829,1832,1993,2196 'two':2324,2490 'txt':368 'type':1790,1792 'typescript':1827,2884,2944 'typic':2246 'uat':1609,1614,2770 'unawar':2613 'unchang':1704 'unifi':1202,1287 'unit':1577,1581,2757 'unnecessari':1165 'up/down':2306,2593 'updat':935 'url':413,1377,1383,1391 'usag':1248 'use':16,574,2097,2346,2556,2640,2694,2703,2819,2913 'user':19,287,507,516,523,2470,2492 'util':1269 'util-linux':1268 'uv':2403,2406 'uvicorn':870,1017,1257,1490,1802,1804,2594 'v':2392,2402,2412 'variabl':400,2558 'vault':365,394,679,1523 'verif':1344,1369 'verifi':2375,2383 'via':148,1921,2867,2990,3097 'video':2921 'view':2954 'vite':702,1843,1887,1891,2932 'volum':1936,1985,2028,2043,2113,2161,2168 'vs':472 'wait':2845 'waitforflutterreadi':2947 'watch':1763,1786,1830,1833,1913,1994,2137,2189,2197,2265,2323,2782 'watcher':1997,2030,2068 'watchexec':1870,1871 'watchfil':1818,1819,2194 'web':1883,1886,2809,2816,2895,2905 'webserv':2926,2985 'websocket':887 'whenev':17 'window':1166,1184 'within':1301,1319 'without':108,1057,1731,2213,2315,2521,2830,3002,3136 'work':1158 'worker':253,1816,1828,2902,3036 'worker.py':1821 'workflow':423,3026,3174 'worktre':3,13,23,26,45,55,68,87,103,125,137,231,245,614,712,717,769,782,799,901,925,934,950,978,980,984,1002,1029,1695,1711,1722,1908,1911,2109,2119,2125,2252,2275,2525,2553,2576,2981,2995,3015,3023,3033,3062,3078,3109,3114,3125,3144,3151 'worktree-a':1710,3022,3113,3143 'worktree-b':1721,3032,3124,3150 'worktree-exclus':230,613 'worktree.env':752,770,821,828,835,842,860,869,936,2537,2991,3105 'wrap':1327 'write':746,819,2605 'written':3103 'wrong':2676 'ws':119,886,999,1005,1032,1656,1671,1682,1697,1720,3120 'wt':804,816,973,990,993,995,3083 'wt/.worktree.env':1008,1036 'wt/services/gateway/main.py':1023 'yaml':333,1873,1963,2004 'yes':593 'yml':327,2158,2165,2181 'your-org':1974,2015 'yourproject':3175,3186 'z':1407 'zero':82,142 'zsh':1206","prices":[{"id":"c96f4574-6c9c-4653-a683-c0887b420080","listingId":"9236d2b0-e148-4268-987a-7ab9d3cd09fd","amountUsd":"0","unit":"free","nativeCurrency":null,"nativeAmount":null,"chain":null,"payTo":null,"paymentMethod":"skill-free","isPrimary":true,"details":{"org":"addxai","category":"enterprise-harness-engineering","install_from":"skills.sh"},"createdAt":"2026-04-21T19:04:01.848Z"}],"sources":[{"listingId":"9236d2b0-e148-4268-987a-7ab9d3cd09fd","source":"github","sourceId":"addxai/enterprise-harness-engineering/multi-worktree-dev","sourceUrl":"https://github.com/addxai/enterprise-harness-engineering/tree/main/skills/multi-worktree-dev","isPrimary":false,"firstSeenAt":"2026-04-21T19:04:01.848Z","lastSeenAt":"2026-04-22T01:02:12.353Z"}],"details":{"listingId":"9236d2b0-e148-4268-987a-7ab9d3cd09fd","quickStartSnippet":null,"exampleRequest":null,"exampleResponse":null,"schema":null,"openapiUrl":null,"agentsTxtUrl":null,"citations":[],"useCases":[],"bestFor":[],"notFor":[],"kindDetails":{"org":"addxai","slug":"multi-worktree-dev","github":{"repo":"addxai/enterprise-harness-engineering","stars":16,"topics":["agent-skills","ai-agent","ai-engineering","claude-code","code-review","cursor","devops","enterprise","sre","windsurf"],"license":"apache-2.0","html_url":"https://github.com/addxai/enterprise-harness-engineering","pushed_at":"2026-04-17T08:57:37Z","description":"Enterprise-grade AI Agent Skills for software development, DevOps, SRE, security, and product teams. Compatible with Claude Code, Cursor, Windsurf, Gemini CLI, GitHub Copilot, and 30+ AI coding agents.","skill_md_sha":"71b71f4f20affe2520886b5d4ac5ce396727aa4a","skill_md_path":"skills/multi-worktree-dev/SKILL.md","default_branch":"main","skill_tree_url":"https://github.com/addxai/enterprise-harness-engineering/tree/main/skills/multi-worktree-dev"},"layout":"multi","source":"github","category":"enterprise-harness-engineering","frontmatter":{"name":"multi-worktree-dev","description":"Design and implementation guide for parallel multi-worktree development environments. Use whenever the user mentions multi-worktree development, git worktree, port conflicts, concurrent dev environments, feature branch isolation, local environment setup, or multi-developer collaboration conflicts. Even if the user casually says \"we have several worktrees running simultaneously\", this Skill should be triggered to guide them toward a proper layered environment."},"skills_sh_url":"https://skills.sh/addxai/enterprise-harness-engineering/multi-worktree-dev"},"updatedAt":"2026-04-22T01:02:12.353Z"}}