zdev 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +13 -0
- package/README.md +311 -0
- package/bun.lock +29 -0
- package/dist/index.js +3098 -0
- package/package.json +36 -0
- package/src/commands/clean.ts +122 -0
- package/src/commands/config.ts +105 -0
- package/src/commands/create.ts +381 -0
- package/src/commands/init.ts +80 -0
- package/src/commands/list.ts +78 -0
- package/src/commands/seed.ts +98 -0
- package/src/commands/start.ts +306 -0
- package/src/commands/stop.ts +101 -0
- package/src/config.ts +106 -0
- package/src/index.ts +129 -0
- package/src/utils.ts +230 -0
- package/tsconfig.json +17 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
|
|
2
|
+
Version 2, January 2026
|
|
3
|
+
|
|
4
|
+
Copyright (C) 2026 5hanth
|
|
5
|
+
|
|
6
|
+
Everyone is permitted to copy and distribute verbatim or modified
|
|
7
|
+
copies of this license document, and changing it is allowed as long
|
|
8
|
+
as the name is changed.
|
|
9
|
+
|
|
10
|
+
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
|
|
11
|
+
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
|
12
|
+
|
|
13
|
+
0. You just DO WHAT THE FUCK YOU WANT TO.
|
package/README.md
ADDED
|
@@ -0,0 +1,311 @@
|
|
|
1
|
+
# 🐂 zdev
|
|
2
|
+
|
|
3
|
+
Multi-agent worktree development environment for Vite/TanStack projects.
|
|
4
|
+
|
|
5
|
+
Built for [Clawdbot](https://docs.clawd.bot) users who want to run multiple AI coding agents on different features simultaneously.
|
|
6
|
+
|
|
7
|
+
Supports:
|
|
8
|
+
- **Vite** / **TanStack Start** frontends
|
|
9
|
+
- **Convex** backend (optional — auto-detected)
|
|
10
|
+
- **Monorepos** with `web/`, `apps/web/`, etc.
|
|
11
|
+
|
|
12
|
+
## Features
|
|
13
|
+
|
|
14
|
+
- **Worktree Management** — Isolated git worktrees per feature
|
|
15
|
+
- **Port Allocation** — Automatic port assignment, no conflicts
|
|
16
|
+
- **Preview URLs** — Public HTTPS URLs via Traefik (optional)
|
|
17
|
+
- **Config Auto-Copy** — `.env.local` and other files copied automatically
|
|
18
|
+
- **Vite Support** — Auto-patches `allowedHosts` for external access
|
|
19
|
+
- **Convex Integration** — Auto-detected; runs `convex dev` if present
|
|
20
|
+
- **Monorepo Support** — Auto-detects `web/`, `frontend/`, `apps/web/`, etc.
|
|
21
|
+
|
|
22
|
+
## Installation
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
# Run directly
|
|
26
|
+
bunx zdev
|
|
27
|
+
|
|
28
|
+
# Or install globally
|
|
29
|
+
bun add -g zdev
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Using with AI Agents
|
|
33
|
+
|
|
34
|
+
### Claude Code / Clawdbot
|
|
35
|
+
|
|
36
|
+
Add the zdev skill to teach your agent the workflow:
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
npx add-skill 5hanth/zdev-skill
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Then prompt your agent:
|
|
43
|
+
```
|
|
44
|
+
Use zdev to create a new project called my-app and start a feature branch for authentication.
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### Manual Setup
|
|
48
|
+
|
|
49
|
+
If your agent doesn't support skills, copy the [SKILL.md](https://github.com/5hanth/zdev-skill/blob/main/SKILL.md) contents into your agent's context or system prompt.
|
|
50
|
+
|
|
51
|
+
## Prerequisites
|
|
52
|
+
|
|
53
|
+
### Required
|
|
54
|
+
- [Bun](https://bun.sh) — `curl -fsSL https://bun.sh/install | bash`
|
|
55
|
+
- Git repository with Vite-based frontend
|
|
56
|
+
|
|
57
|
+
### Optional
|
|
58
|
+
- [Convex](https://convex.dev) — auto-detected if `convex/` directory exists
|
|
59
|
+
|
|
60
|
+
### Optional (for public preview URLs)
|
|
61
|
+
- [Traefik](https://traefik.io) reverse proxy with file provider
|
|
62
|
+
- DNS wildcard record (`*.dev.yourdomain.com`)
|
|
63
|
+
|
|
64
|
+
See [Traefik Setup](#traefik-setup-for-preview-urls) below.
|
|
65
|
+
|
|
66
|
+
## Quick Start
|
|
67
|
+
|
|
68
|
+
### New Project
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
# Create a new TanStack Start project
|
|
72
|
+
zdev create my-app
|
|
73
|
+
|
|
74
|
+
# Or with Convex backend
|
|
75
|
+
zdev create my-app --convex
|
|
76
|
+
|
|
77
|
+
# Flat structure (no monorepo)
|
|
78
|
+
zdev create my-app --convex --flat
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### Existing Project
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
# 1. Initialize your project
|
|
85
|
+
cd your-project
|
|
86
|
+
zdev init
|
|
87
|
+
|
|
88
|
+
# 2. (Convex only) Setup Convex once if not already done
|
|
89
|
+
cd web # or wherever package.json is
|
|
90
|
+
bunx convex dev # select project, then Ctrl+C
|
|
91
|
+
|
|
92
|
+
# 3. Start a feature
|
|
93
|
+
zdev start my-feature -p /path/to/project
|
|
94
|
+
|
|
95
|
+
# 4. Work on it
|
|
96
|
+
cd ~/.zdev/worktrees/project-my-feature
|
|
97
|
+
|
|
98
|
+
# 5. Stop when done
|
|
99
|
+
zdev stop my-feature -p /path/to/project
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
## Commands
|
|
103
|
+
|
|
104
|
+
### `zdev create <name>`
|
|
105
|
+
Create a new TanStack Start project from scratch.
|
|
106
|
+
|
|
107
|
+
```bash
|
|
108
|
+
zdev create my-app # Basic TanStack Start
|
|
109
|
+
zdev create my-app --convex # With Convex backend
|
|
110
|
+
zdev create my-app --flat # Flat structure (no monorepo)
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
By default creates a monorepo with `web/` subdirectory. Use `--flat` for single-package structure.
|
|
114
|
+
|
|
115
|
+
### `zdev init [path]`
|
|
116
|
+
Initialize zdev for an existing project. Creates seed data from current Convex state.
|
|
117
|
+
|
|
118
|
+
```bash
|
|
119
|
+
zdev init # Current directory
|
|
120
|
+
zdev init ./my-project # Specific path
|
|
121
|
+
zdev init -s # Also create seed snapshot
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
### `zdev start <feature>`
|
|
125
|
+
Start working on a feature. Creates worktree, installs deps, starts servers.
|
|
126
|
+
|
|
127
|
+
```bash
|
|
128
|
+
zdev start auth -p ./my-project
|
|
129
|
+
zdev start auth -p ./my-project --local # Skip public URL
|
|
130
|
+
zdev start auth -p ./my-project --port 3000 # Specific port
|
|
131
|
+
zdev start auth -p ./my-project --seed # Import seed data
|
|
132
|
+
zdev start auth --base-branch origin/develop # Different base
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
### `zdev stop <feature>`
|
|
136
|
+
Stop servers for a feature.
|
|
137
|
+
|
|
138
|
+
```bash
|
|
139
|
+
zdev stop auth -p ./my-project
|
|
140
|
+
zdev stop auth --keep # Keep worktree, just stop servers
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
### `zdev list`
|
|
144
|
+
List all active features and their status.
|
|
145
|
+
|
|
146
|
+
```bash
|
|
147
|
+
zdev list
|
|
148
|
+
zdev list --json
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
### `zdev clean <feature>`
|
|
152
|
+
Remove a feature worktree completely (use after PR merged).
|
|
153
|
+
|
|
154
|
+
```bash
|
|
155
|
+
zdev clean auth -p ./my-project
|
|
156
|
+
zdev clean auth --force # Force even if git fails
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
### `zdev seed export/import`
|
|
160
|
+
Manage database seed data.
|
|
161
|
+
|
|
162
|
+
```bash
|
|
163
|
+
zdev seed export # Export current Convex state
|
|
164
|
+
zdev seed import # Import into current worktree
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
### `zdev config`
|
|
168
|
+
View and manage configuration.
|
|
169
|
+
|
|
170
|
+
```bash
|
|
171
|
+
zdev config --list
|
|
172
|
+
zdev config --set devDomain=dev.example.com
|
|
173
|
+
zdev config --set traefikConfigDir=/etc/traefik/dynamic
|
|
174
|
+
zdev config --add .env.production
|
|
175
|
+
zdev config --remove .env.production
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
## Setup Script
|
|
179
|
+
|
|
180
|
+
zdev uses `.zdev/setup.sh` in your project to run setup commands when creating worktrees.
|
|
181
|
+
|
|
182
|
+
**Default (generated by `zdev create`):**
|
|
183
|
+
```bash
|
|
184
|
+
#!/bin/bash
|
|
185
|
+
# .zdev/setup.sh - Runs after worktree creation
|
|
186
|
+
|
|
187
|
+
set -e
|
|
188
|
+
bun install
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
**Customize it:**
|
|
192
|
+
```bash
|
|
193
|
+
#!/bin/bash
|
|
194
|
+
set -e
|
|
195
|
+
|
|
196
|
+
# Use a different package manager
|
|
197
|
+
pnpm install
|
|
198
|
+
|
|
199
|
+
# Generate Prisma client
|
|
200
|
+
bunx prisma generate
|
|
201
|
+
|
|
202
|
+
# Copy secrets from parent
|
|
203
|
+
cp ../.env.local .
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
This file is committed to git, so all team members use the same setup.
|
|
207
|
+
|
|
208
|
+
## Configuration
|
|
209
|
+
|
|
210
|
+
Config stored at `~/.zdev/config.json`:
|
|
211
|
+
|
|
212
|
+
| Key | Default | Description |
|
|
213
|
+
|-----|---------|-------------|
|
|
214
|
+
| `devDomain` | (empty) | Domain for preview URLs (e.g., `dev.example.com`) |
|
|
215
|
+
| `dockerHostIp` | `172.17.0.1` | How Traefik (in Docker) reaches host services |
|
|
216
|
+
| `traefikConfigDir` | `/infra/traefik/dynamic` | Directory where Traefik watches for route configs (see below) |
|
|
217
|
+
| `copyPatterns` | `.env.local`, etc. | Files to auto-copy to worktrees |
|
|
218
|
+
|
|
219
|
+
## Traefik Setup for Preview URLs
|
|
220
|
+
|
|
221
|
+
> **What's a "dynamic config directory"?**
|
|
222
|
+
>
|
|
223
|
+
> Traefik can be configured to watch a folder for `.yml` files. Each file defines a route (e.g., "requests to `auth.dev.example.com` go to port 5173"). When you add/remove files, Traefik automatically updates its routing — no restart needed.
|
|
224
|
+
>
|
|
225
|
+
> zdev uses this to create/remove routes on-the-fly as you start/stop features.
|
|
226
|
+
|
|
227
|
+
To get public HTTPS URLs for each feature:
|
|
228
|
+
|
|
229
|
+
### 1. DNS Wildcard
|
|
230
|
+
Add a wildcard A record pointing to your server:
|
|
231
|
+
```
|
|
232
|
+
*.dev.example.com → your-server-ip
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
### 2. Traefik with File Provider
|
|
236
|
+
Configure Traefik to watch a dynamic config directory:
|
|
237
|
+
|
|
238
|
+
```yaml
|
|
239
|
+
# traefik.yml
|
|
240
|
+
providers:
|
|
241
|
+
file:
|
|
242
|
+
directory: /etc/traefik/dynamic # zdev writes route files here
|
|
243
|
+
watch: true
|
|
244
|
+
|
|
245
|
+
entryPoints:
|
|
246
|
+
web:
|
|
247
|
+
address: ":80"
|
|
248
|
+
websecure:
|
|
249
|
+
address: ":443"
|
|
250
|
+
|
|
251
|
+
certificatesResolvers:
|
|
252
|
+
letsencrypt:
|
|
253
|
+
acme:
|
|
254
|
+
email: you@example.com
|
|
255
|
+
storage: /etc/traefik/acme.json
|
|
256
|
+
httpChallenge:
|
|
257
|
+
entryPoint: web
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
### 3. Configure zdev
|
|
261
|
+
```bash
|
|
262
|
+
zdev config --set devDomain=dev.example.com
|
|
263
|
+
zdev config --set traefikConfigDir=/etc/traefik/dynamic
|
|
264
|
+
zdev config --set dockerHostIp=172.17.0.1 # or host.docker.internal on Mac
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
### How It Works
|
|
268
|
+
When you run `zdev start my-feature`, it creates a file like `/etc/traefik/dynamic/project-my-feature.yml`:
|
|
269
|
+
|
|
270
|
+
```yaml
|
|
271
|
+
http:
|
|
272
|
+
routers:
|
|
273
|
+
project-my-feature:
|
|
274
|
+
rule: "Host(`project-my-feature.dev.example.com`)"
|
|
275
|
+
service: project-my-feature
|
|
276
|
+
entryPoints:
|
|
277
|
+
- websecure
|
|
278
|
+
tls:
|
|
279
|
+
certResolver: letsencrypt
|
|
280
|
+
|
|
281
|
+
services:
|
|
282
|
+
project-my-feature:
|
|
283
|
+
loadBalancer:
|
|
284
|
+
servers:
|
|
285
|
+
- url: "http://172.17.0.1:5173" # Host port from Docker's perspective
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
Traefik watches the directory and automatically picks up the new route.
|
|
289
|
+
|
|
290
|
+
## Multi-Agent Workflow
|
|
291
|
+
|
|
292
|
+
1. **Agent A** works on auth: `zdev start auth -p ./project`
|
|
293
|
+
2. **Agent B** works on billing: `zdev start billing -p ./project`
|
|
294
|
+
3. Each gets isolated worktree + ports + preview URL
|
|
295
|
+
4. No conflicts, parallel development
|
|
296
|
+
|
|
297
|
+
## Directory Structure
|
|
298
|
+
|
|
299
|
+
```
|
|
300
|
+
~/.zdev/
|
|
301
|
+
├── config.json # Global config
|
|
302
|
+
├── worktrees/ # All worktrees live here
|
|
303
|
+
│ ├── project-auth/
|
|
304
|
+
│ └── project-billing/
|
|
305
|
+
└── seeds/ # Seed data snapshots
|
|
306
|
+
└── project.zip
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
## License
|
|
310
|
+
|
|
311
|
+
[WTFPL](LICENSE)
|
package/bun.lock
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
{
|
|
2
|
+
"lockfileVersion": 1,
|
|
3
|
+
"configVersion": 1,
|
|
4
|
+
"workspaces": {
|
|
5
|
+
"": {
|
|
6
|
+
"name": "zebu",
|
|
7
|
+
"dependencies": {
|
|
8
|
+
"commander": "^12.0.0",
|
|
9
|
+
},
|
|
10
|
+
"devDependencies": {
|
|
11
|
+
"@types/bun": "latest",
|
|
12
|
+
"typescript": "^5.0.0",
|
|
13
|
+
},
|
|
14
|
+
},
|
|
15
|
+
},
|
|
16
|
+
"packages": {
|
|
17
|
+
"@types/bun": ["@types/bun@1.3.6", "", { "dependencies": { "bun-types": "1.3.6" } }, "sha512-uWCv6FO/8LcpREhenN1d1b6fcspAB+cefwD7uti8C8VffIv0Um08TKMn98FynpTiU38+y2dUO55T11NgDt8VAA=="],
|
|
18
|
+
|
|
19
|
+
"@types/node": ["@types/node@25.0.10", "", { "dependencies": { "undici-types": "~7.16.0" } }, "sha512-zWW5KPngR/yvakJgGOmZ5vTBemDoSqF3AcV/LrO5u5wTWyEAVVh+IT39G4gtyAkh3CtTZs8aX/yRM82OfzHJRg=="],
|
|
20
|
+
|
|
21
|
+
"bun-types": ["bun-types@1.3.6", "", { "dependencies": { "@types/node": "*" } }, "sha512-OlFwHcnNV99r//9v5IIOgQ9Uk37gZqrNMCcqEaExdkVq3Avwqok1bJFmvGMCkCE0FqzdY8VMOZpfpR3lwI+CsQ=="],
|
|
22
|
+
|
|
23
|
+
"commander": ["commander@12.1.0", "", {}, "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA=="],
|
|
24
|
+
|
|
25
|
+
"typescript": ["typescript@5.9.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="],
|
|
26
|
+
|
|
27
|
+
"undici-types": ["undici-types@7.16.0", "", {}, "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw=="],
|
|
28
|
+
}
|
|
29
|
+
}
|