Package Exports
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (zdev) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
🐂 zdev
Multi-agent worktree development environment for Vite/TanStack projects.
Built for Clawdbot users who want to run multiple AI coding agents on different features simultaneously.
Supports:
- Vite / TanStack Start frontends
- Convex backend (optional — auto-detected)
- Monorepos with
web/,apps/web/, etc.
Features
- Worktree Management — Isolated git worktrees per feature
- Port Allocation — Automatic port assignment, no conflicts
- Preview URLs — Public HTTPS URLs via Traefik (optional)
- Config Auto-Copy —
.env.localand other files copied automatically - Vite Support — Auto-patches
allowedHostsfor external access - Convex Integration — Auto-detected; runs
convex devif present - Monorepo Support — Auto-detects
web/,frontend/,apps/web/, etc.
Installation
# Run directly
bunx zdev
# Or install globally
bun add -g zdevUsing with AI Agents
Claude Code / Clawdbot
Add the zdev skill to teach your agent the workflow:
npx add-skill 5hanth/zdev-skillThen prompt your agent:
Use zdev to create a new project called my-app and start a feature branch for authentication.Manual Setup
If your agent doesn't support skills, copy the SKILL.md contents into your agent's context or system prompt.
Prerequisites
Required
- Bun —
curl -fsSL https://bun.sh/install | bash - Git repository with Vite-based frontend
Optional
- Convex — auto-detected if
convex/directory exists
Optional (for public preview URLs)
- Traefik reverse proxy with file provider
- DNS wildcard record (
*.dev.yourdomain.com)
See Traefik Setup below.
Quick Start
New Project
# Create a new TanStack Start project
zdev create my-app
# Or with Convex backend
zdev create my-app --convex
# Flat structure (no monorepo)
zdev create my-app --convex --flatExisting Project
# 1. Initialize your project
cd your-project
zdev init
# 2. (Convex only) Setup Convex once if not already done
cd web # or wherever package.json is
bunx convex dev # select project, then Ctrl+C
# 3. Start a feature
zdev start my-feature -p /path/to/project
# 4. Work on it
cd ~/.zdev/worktrees/project-my-feature
# 5. Stop when done
zdev stop my-feature -p /path/to/projectCommands
zdev create <name>
Create a new TanStack Start project from scratch.
zdev create my-app # Basic TanStack Start
zdev create my-app --convex # With Convex backend
zdev create my-app --flat # Flat structure (no monorepo)By default creates a monorepo with web/ subdirectory. Use --flat for single-package structure.
zdev init [path]
Initialize zdev for an existing project. Creates seed data from current Convex state.
zdev init # Current directory
zdev init ./my-project # Specific path
zdev init -s # Also create seed snapshotzdev start <feature>
Start working on a feature. Creates worktree, installs deps, starts servers.
zdev start auth -p ./my-project
zdev start auth -p ./my-project --local # Skip public URL
zdev start auth -p ./my-project --port 3000 # Specific port
zdev start auth -p ./my-project --seed # Import seed data
zdev start auth --base-branch origin/develop # Different basezdev stop <feature>
Stop servers for a feature.
zdev stop auth -p ./my-project
zdev stop auth --keep # Keep worktree, just stop serverszdev list
List all active features and their status.
zdev list
zdev list --jsonzdev clean <feature>
Remove a feature worktree completely (use after PR merged).
zdev clean auth -p ./my-project
zdev clean auth --force # Force even if git failszdev seed export/import
Manage database seed data.
zdev seed export # Export current Convex state
zdev seed import # Import into current worktreezdev config
View and manage configuration.
zdev config --list
zdev config --set devDomain=dev.example.com
zdev config --set traefikConfigDir=/etc/traefik/dynamic
zdev config --add .env.production
zdev config --remove .env.productionSetup Script
zdev uses .zdev/setup.sh in your project to run setup commands when creating worktrees.
Default (generated by zdev create):
#!/bin/bash
# .zdev/setup.sh - Runs after worktree creation
set -e
bun installCustomize it:
#!/bin/bash
set -e
# Use a different package manager
pnpm install
# Generate Prisma client
bunx prisma generate
# Copy secrets from parent
cp ../.env.local .This file is committed to git, so all team members use the same setup.
Configuration
Config stored at ~/.zdev/config.json:
| Key | Default | Description |
|---|---|---|
devDomain |
(empty) | Domain for preview URLs (e.g., dev.example.com) |
dockerHostIp |
172.17.0.1 |
How Traefik (in Docker) reaches host services |
traefikConfigDir |
/infra/traefik/dynamic |
Directory where Traefik watches for route configs (see below) |
copyPatterns |
.env.local, etc. |
Files to auto-copy to worktrees |
Traefik Setup for Preview URLs
What's a "dynamic config directory"?
Traefik can be configured to watch a folder for
.ymlfiles. Each file defines a route (e.g., "requests toauth.dev.example.comgo to port 5173"). When you add/remove files, Traefik automatically updates its routing — no restart needed.zdev uses this to create/remove routes on-the-fly as you start/stop features.
To get public HTTPS URLs for each feature:
1. DNS Wildcard
Add a wildcard A record pointing to your server:
*.dev.example.com → your-server-ip2. Traefik with File Provider
Configure Traefik to watch a dynamic config directory:
# traefik.yml
providers:
file:
directory: /etc/traefik/dynamic # zdev writes route files here
watch: true
entryPoints:
web:
address: ":80"
websecure:
address: ":443"
certificatesResolvers:
letsencrypt:
acme:
email: you@example.com
storage: /etc/traefik/acme.json
httpChallenge:
entryPoint: web3. Configure zdev
zdev config --set devDomain=dev.example.com
zdev config --set traefikConfigDir=/etc/traefik/dynamic
zdev config --set dockerHostIp=172.17.0.1 # or host.docker.internal on MacHow It Works
When you run zdev start my-feature, it creates a file like /etc/traefik/dynamic/project-my-feature.yml:
http:
routers:
project-my-feature:
rule: "Host(`project-my-feature.dev.example.com`)"
service: project-my-feature
entryPoints:
- websecure
tls:
certResolver: letsencrypt
services:
project-my-feature:
loadBalancer:
servers:
- url: "http://172.17.0.1:5173" # Host port from Docker's perspectiveTraefik watches the directory and automatically picks up the new route.
Multi-Agent Workflow
- Agent A works on auth:
zdev start auth -p ./project - Agent B works on billing:
zdev start billing -p ./project - Each gets isolated worktree + ports + preview URL
- No conflicts, parallel development
Directory Structure
~/.zdev/
├── config.json # Global config
├── worktrees/ # All worktrees live here
│ ├── project-auth/
│ └── project-billing/
└── seeds/ # Seed data snapshots
└── project.zip