@paleo/worktree-env 0.7.3 → 0.7.5
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/README.md +2 -1
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +8 -0
- package/dist/dev-server.js +29 -2
- package/dist/setup-worktree.d.ts +2 -0
- package/dist/setup-worktree.js +2 -3
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -27,7 +27,8 @@ The agent reads the skill, adapts the reference scripts to your stack, installs
|
|
|
27
27
|
|
|
28
28
|
```sh
|
|
29
29
|
npm run setup-worktree -- --create feat/42 # new branch + worktree + isolated env
|
|
30
|
-
npm run dev:up # start dev server in the background
|
|
30
|
+
npm run dev:up # start dev server in the background (no-op if already running here)
|
|
31
|
+
npm run dev:up -- --restart # stop the dev-server in this worktree if running, then start fresh
|
|
31
32
|
npm run dev:up -- --evict # if devLimit is reached, evict the oldest dev-server and start
|
|
32
33
|
npm run dev:list # active dev-servers across all worktrees
|
|
33
34
|
npm run dev:down # stop dev server (infrastructure stays up)
|
package/dist/cli.d.ts
CHANGED
|
@@ -22,6 +22,7 @@ export interface DevServerArgs {
|
|
|
22
22
|
list?: boolean;
|
|
23
23
|
all?: boolean;
|
|
24
24
|
evict?: boolean;
|
|
25
|
+
restart?: boolean;
|
|
25
26
|
}
|
|
26
27
|
export declare function parseSetupArgs(argv?: string[]): SetupArgs;
|
|
27
28
|
export declare function parseDevServerArgs(argv?: string[]): DevServerArgs;
|
package/dist/cli.js
CHANGED
|
@@ -66,6 +66,10 @@ const DEV_SERVER_OPTIONS = {
|
|
|
66
66
|
list: { type: "boolean", description: "List active dev-servers across all worktrees" },
|
|
67
67
|
all: { type: "boolean", description: "Apply --stop to every active dev-server" },
|
|
68
68
|
evict: { type: "boolean", description: "Evict the oldest dev-server when the cap is reached" },
|
|
69
|
+
restart: {
|
|
70
|
+
type: "boolean",
|
|
71
|
+
description: "If a dev-server is already running in this worktree, stop it first, then start",
|
|
72
|
+
},
|
|
69
73
|
};
|
|
70
74
|
export function parseSetupArgs(argv) {
|
|
71
75
|
return parseOptions(argv, SETUP_OPTIONS);
|
|
@@ -123,6 +127,10 @@ export function validateDevServerFlags(args) {
|
|
|
123
127
|
const conflict = args.stop ? "--stop" : args.list ? "--list" : "--all";
|
|
124
128
|
throw new ConfigError(`Error: --evict cannot be combined with ${conflict}.`);
|
|
125
129
|
}
|
|
130
|
+
if (args.restart && (args.stop || args.list || args.all)) {
|
|
131
|
+
const conflict = args.stop ? "--stop" : args.list ? "--list" : "--all";
|
|
132
|
+
throw new ConfigError(`Error: --restart cannot be combined with ${conflict}.`);
|
|
133
|
+
}
|
|
126
134
|
}
|
|
127
135
|
export function isSetupMode(args) {
|
|
128
136
|
return args.use !== undefined || args.create !== undefined || Boolean(args.here);
|
package/dist/dev-server.js
CHANGED
|
@@ -53,13 +53,18 @@ export async function runDevServer(config) {
|
|
|
53
53
|
await stopLocal(config, mainWorktree);
|
|
54
54
|
return;
|
|
55
55
|
}
|
|
56
|
-
await start(config, mainWorktree, {
|
|
56
|
+
await start(config, mainWorktree, {
|
|
57
|
+
evict: Boolean(args.evict),
|
|
58
|
+
restart: Boolean(args.restart),
|
|
59
|
+
});
|
|
57
60
|
}
|
|
58
61
|
function callbackServersOf(config) {
|
|
59
62
|
return config.servers.filter((s) => s.kind === "callback");
|
|
60
63
|
}
|
|
61
|
-
async function start(config, mainWorktree, { evict }) {
|
|
64
|
+
async function start(config, mainWorktree, { evict, restart }) {
|
|
62
65
|
const ctx = { cwd: process.cwd() };
|
|
66
|
+
if (await handleAlreadyRunning(config, mainWorktree, ctx, restart))
|
|
67
|
+
return;
|
|
63
68
|
await enforceCap(config, mainWorktree, evict);
|
|
64
69
|
checkNoLocalRegistryConflict(config, mainWorktree, ctx.cwd);
|
|
65
70
|
await checkPortsFree(config.servers);
|
|
@@ -136,6 +141,28 @@ async function rollbackStart(spawnPids, startedCallbacks, ctx) {
|
|
|
136
141
|
}
|
|
137
142
|
}
|
|
138
143
|
}
|
|
144
|
+
/**
|
|
145
|
+
* If a dev-server is already running in this worktree, either stop it (when `restart`) so the
|
|
146
|
+
* normal start path can proceed, or print a friendly notice and return `true` to short-circuit.
|
|
147
|
+
* Returns `true` when the caller should exit cleanly without starting.
|
|
148
|
+
*/
|
|
149
|
+
async function handleAlreadyRunning(config, mainWorktree, ctx, restart) {
|
|
150
|
+
const entry = findOwnEntry(mainWorktree, config.registryDir, ctx.cwd);
|
|
151
|
+
if (!entry)
|
|
152
|
+
return false;
|
|
153
|
+
const livePids = Object.entries(entry.pids).filter(([, pid]) => isProcessAlive(pid));
|
|
154
|
+
if (livePids.length === 0)
|
|
155
|
+
return false;
|
|
156
|
+
if (restart) {
|
|
157
|
+
console.log("Restarting dev-server in this worktree...");
|
|
158
|
+
await stopLocal(config, mainWorktree);
|
|
159
|
+
return false;
|
|
160
|
+
}
|
|
161
|
+
const pidList = livePids.map(([name, pid]) => `${name}=${pid}`).join(", ");
|
|
162
|
+
console.log(`dev-server already running for this worktree (slot ${entry.slot}, pids: ${pidList}).`);
|
|
163
|
+
console.log("Run `dev:down` to stop it, or re-run with --restart to restart.");
|
|
164
|
+
return true;
|
|
165
|
+
}
|
|
139
166
|
// TOCTOU: the cap check and the subsequent register are not atomic. Two concurrent `dev:up --evict`
|
|
140
167
|
// from different worktrees can both pass the cap check and both register, exceeding the limit by
|
|
141
168
|
// one. Accepted: the race window is narrow and the consequence is bounded (one extra dev-server).
|
package/dist/setup-worktree.d.ts
CHANGED
|
@@ -86,6 +86,8 @@ export interface PreSetupContext {
|
|
|
86
86
|
export interface SetupContext {
|
|
87
87
|
currentWorktree: string;
|
|
88
88
|
mainWorktree: string;
|
|
89
|
+
/** `true` when finalizing the main worktree. Gate "copy from main" steps with `!isMainWorktree`. */
|
|
90
|
+
isMainWorktree: boolean;
|
|
89
91
|
slot: number;
|
|
90
92
|
branch: string;
|
|
91
93
|
owner?: string;
|
package/dist/setup-worktree.js
CHANGED
|
@@ -181,6 +181,7 @@ async function runFinalize(args, config) {
|
|
|
181
181
|
const setupContext = {
|
|
182
182
|
currentWorktree: ctx.currentWorktree,
|
|
183
183
|
mainWorktree: ctx.mainWorktree,
|
|
184
|
+
isMainWorktree: ctx.isMainWorktree,
|
|
184
185
|
slot,
|
|
185
186
|
branch: entry.branch,
|
|
186
187
|
owner: entry.owner,
|
|
@@ -279,15 +280,13 @@ async function waitForSlot(slot, config, options = {}) {
|
|
|
279
280
|
process.exit(1);
|
|
280
281
|
}
|
|
281
282
|
if (entry.status === "ready") {
|
|
283
|
+
console.log("\n… ready");
|
|
282
284
|
if (printSummary) {
|
|
283
285
|
printWorktreeInfo(config, slot, entry.worktree, {
|
|
284
286
|
branch: entry.branch,
|
|
285
287
|
owner: entry.owner,
|
|
286
288
|
});
|
|
287
289
|
}
|
|
288
|
-
else {
|
|
289
|
-
console.log("Status: ready");
|
|
290
|
-
}
|
|
291
290
|
return;
|
|
292
291
|
}
|
|
293
292
|
if (entry.status === "failed") {
|