@aippt/worktree-man (0.4.0)
Installation
@aippt:registry=npm install @aippt/worktree-man@0.4.0"@aippt/worktree-man": "0.4.0"About this package
worktree-man
Creates, lists, and removes isolated Git worktrees with their own ports and database schema.
Each worktree gets a port offset, from which its env schema derives its ports, and a PostgreSQL
schema. Varlock resolves both from the worktree's own env files, so the
port and schema rules live only in the env schema: its ports are the variables it tags with
@tag(port), next to PORT_OFFSET and DB_SCHEMA.
Installation
Route the @aippt scope to its registry in pnpm-workspace.yaml and install the package next to
Vite+ and Varlock, its peer dependencies:
registries:
https://git.productteams.ai/api/packages/aippt/npm/:
scopes: ['@aippt']
pnpm add --save-dev @aippt/worktree-man
Tasks in vite.config.ts keep the commands at hand, as vp run wt:add <name>,
vp run wt:list, and vp run wt:rm <name>:
run: {
tasks: {
'wt:add': { command: 'worktree-man add', cache: false },
'wt:list': { command: 'worktree-man list', cache: false },
'wt:rm': { command: 'worktree-man rm', cache: false },
},
},
Command line
worktree-man add <name> [--quiet] # create a worktree with its own port offset and schema
worktree-man list # list every worktree with its status and resources
worktree-man rm <name> [--force] # run the teardown commands, then remove the worktree
Names start with a lowercase letter and contain lowercase letters or digits, with single hyphens
between segments, for example feature, prototype-answer-colors, or step-2.
add:
- creates a Git worktree and branch named
<name>, in kebab-case, next to the main worktree; - copies the main worktree's
.env.localfiles from every workspace package and the directories above them; - assigns the lowest unused
PORT_OFFSETstarting at the main worktree's offset (or0if it cannot be resolved), and warns about worktrees whose offset it cannot resolve; - creates a PostgreSQL schema named after the worktree, with hyphens replaced by underscores, and
sets
DB_SCHEMAto it; - runs the setup commands inside the new worktree;
- removes the schema, worktree, and branch if setup fails or is interrupted.
PORT_OFFSET and DB_SCHEMA go into the .env.local next to the .env.schema that declares them.
A variable no .env.schema declares is not set. The env schema bounds the offset, as with
@type=number(min=0, max=99): an offset beyond it fails the setup.
Set PORT_OFFSET in the main worktree's .env.local to give each project a different starting
offset. Leave enough space between projects for their worktrees, and ensure the env schema's
bounds allow those offsets. Existing worktrees keep their assigned offsets.
Only a project whose env schema declares DB_SCHEMA needs a database. worktree-man then connects
to it at DB_URL, taken from the environment or as the main worktree's env files resolve it, and
concurrent setups take turns through a PostgreSQL advisory lock. Without DB_SCHEMA, nothing keeps
concurrent setups from taking the same offset.
rm runs the teardown commands from the current checkout, then removes the worktree, its branch,
and, with DB_SCHEMA, its PostgreSQL schema. It refuses worktrees with uncommitted changes and
branches not merged into the main worktree's current branch, and keeps the worktree when a teardown
command fails. --force discards both kinds of work and removes the worktree regardless.
In the Git status list shows, a number counts uncommitted entries, and ↑N and ↓N count
commits ahead of and behind the main worktree's HEAD. ? marks resources that cannot be
resolved, — what a worktree lacks, such as a port its branch does not declare, and missing a
worktree whose directory was deleted without git worktree remove.
worktree-man expects a pnpm workspace and lists its packages with vp exec pnpm ls. It runs Varlock
from PATH, so run it through vp run or vp exec, which put the project's node_modules/.bin
there.
Configuration
The project configures worktree-man under the worktree-man key of its root package.json, read
from the checkout running the command:
"worktree-man": {
"setup": ["vp install", "vp run db:migrate"],
"teardown": ["vp run ps:stop \"$WORKTREE_NAME\""],
"portLabels": { "PLAYWRIGHT_UI_PORT": "PWUI_PORT", "STORYBOOK_PORT": "SB_PORT" }
}
setupcommands run in order inside a new worktree. They may change only the worktree's directory and its database schema, which a failed setup removes. They seeWORKTREE_NAMEandWORKTREE_DIR.teardowncommands run in order before a worktree is removed, from the checkout that removes it, so they work even for a worktree whose branch predates them. They see the same variables.portLabelsgives port variables whose names are too long for a table shorter column labels.
Development
Open the repository in its dev container; it provides the PostgreSQL test server. Then run:
vp install
vp check
vp test
vp run package
vp exec node src/cli.ts list
The dev container and CI provide PostgreSQL through the standard PG* environment variables. The
tests create and drop schemas named wt_test_*. See publishing for
package and version commands.
Dependencies
Dependencies
| ID | Version |
|---|---|
| postgres | 3.4.9 |
Development dependencies
| ID | Version |
|---|---|
| @types/node | 26.6.2 |
| @vitest/coverage-v8 | 4.1.11 |
| publint | 0.3.23 |
| typescript | 7.0.2 |
| varlock | 1.20.0 |
| vite | npm:@voidzero-dev/vite-plus-core@0.3.3 |
| vite-plus | 0.3.3 |
Peer dependencies
| ID | Version |
|---|---|
| varlock | ^1.20.0 |
| vite-plus | ^0.3.3 |