@paleo/worktree-env 0.7.0 → 0.7.2

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.
@@ -51,6 +51,9 @@ export interface SetupWorktreeConfig {
51
51
  * the worktree — this callback will be invoked again with the same context. Re-runs must not
52
52
  * error on pre-existing state (created directories, started containers, ran migrations,
53
53
  * installed deps, etc.).
54
+ *
55
+ * Runs in a detached child whose stdout/stderr are already redirected to
56
+ * `<runtimeDir>/wt-setup.log`. `console.log` and child-process `stdio: "inherit"` land there.
54
57
  */
55
58
  finalizeWorktree: (ctx: SetupContext) => Promise<void> | void;
56
59
  /**
@@ -79,6 +79,7 @@ async function runSetup(args, ctx, run, config) {
79
79
  scheme,
80
80
  });
81
81
  const setupCtx = ensureWorktree(args, ctx, run, config.worktreeDirName);
82
+ refuseIfFinalizePending(setupCtx, config.registryDir, args.force ?? false);
82
83
  const branch = getCurrentBranch(setupCtx.currentWorktree);
83
84
  const { port: slot, owner } = resolveAndRegisterSlot({
84
85
  slot: args.slot,
@@ -88,6 +89,7 @@ async function runSetup(args, ctx, run, config) {
88
89
  scheme,
89
90
  branch,
90
91
  requestedOwner: args.owner,
92
+ isMainWorktree: setupCtx.isMainWorktree,
91
93
  });
92
94
  const ports = portsFn(slot);
93
95
  const runtimeDir = join(setupCtx.currentWorktree, config.runtimeDir);
@@ -142,6 +144,20 @@ async function runSetup(args, ctx, run, config) {
142
144
  closeSync(logFd);
143
145
  return { slot };
144
146
  }
147
+ function refuseIfFinalizePending(ctx, registryDir, force) {
148
+ if (force)
149
+ return;
150
+ const registry = readSlots(ctx.mainWorktree, registryDir);
151
+ const resolvedCurrent = resolve(ctx.currentWorktree);
152
+ const found = Object.entries(registry.slots).find(([, e]) => resolve(e.worktree) === resolvedCurrent && e.status === "pending");
153
+ if (!found)
154
+ return;
155
+ const [slotPort] = found;
156
+ console.error(`Error: Setup is already in progress for slot ${slotPort}. ` +
157
+ `Run 'setup-worktree --wait --slot ${slotPort}' to wait for it to finish (or fail), ` +
158
+ "then retry. Use --force to bypass.");
159
+ process.exit(1);
160
+ }
145
161
  async function runFinalize(args, config) {
146
162
  const slot = Number(args.__finalize);
147
163
  const ctx = detectWorktree();
@@ -208,8 +224,7 @@ function printWorktreeInfo(config, slot, worktreeForLog, fallback) {
208
224
  const ports = resolvePortsFn(config)(slot);
209
225
  const branch = entry?.branch ?? fallback.branch;
210
226
  const owner = entry?.owner ?? fallback.owner;
211
- // Main worktree has no slot entry by design — treat it as ready when the registry has no row.
212
- const slotStatus = entry?.status ?? (ctx.isMainWorktree ? "ready" : "pending");
227
+ const slotStatus = entry?.status ?? "pending";
213
228
  const logHint = ` (tail ${join(worktreeForLog, config.runtimeDir, "wt-setup.log")})`;
214
229
  const display = slotStatus === "ready"
215
230
  ? "ready"
package/dist/slots.d.ts CHANGED
@@ -30,6 +30,8 @@ export interface RegisterSlotInput {
30
30
  scheme: PortScheme;
31
31
  branch: string;
32
32
  requestedOwner?: string;
33
+ /** When `true`, the slot is forced to `scheme.basePort` regardless of `slot` arg. */
34
+ isMainWorktree: boolean;
33
35
  }
34
36
  export declare function resolveAndRegisterSlot(input: RegisterSlotInput): {
35
37
  port: number;
package/dist/slots.js CHANGED
@@ -104,6 +104,8 @@ export function handleSetOwner(input) {
104
104
  }
105
105
  function pickSlotPort(args, registry) {
106
106
  const resolvedCurrent = resolve(args.currentWorktree);
107
+ if (args.isMainWorktree)
108
+ return args.scheme.basePort;
107
109
  if (args.slot !== undefined) {
108
110
  const port = Number(args.slot);
109
111
  if (!isValidPort(port, args.scheme)) {
package/dist/worktree.js CHANGED
@@ -17,12 +17,7 @@ export function enforceWorktreeMode(args, ctx) {
17
17
  process.exit(1);
18
18
  }
19
19
  }
20
- else if (args.here) {
21
- if (ctx.isMainWorktree) {
22
- console.error("Error: --here must be run from a linked worktree, not from the main worktree.");
23
- process.exit(1);
24
- }
25
- }
20
+ // --here runs in any worktree: linked worktree (retry path) or main (initial bootstrap).
26
21
  }
27
22
  export function useExistingBranch(branch, ctx, run, dirNameFn = defaultWorktreeDirName) {
28
23
  if (!branchExists(branch)) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@paleo/worktree-env",
3
- "version": "0.7.0",
3
+ "version": "0.7.2",
4
4
  "description": "Worktree-based concurrent local environment kernel.",
5
5
  "keywords": [
6
6
  "worktree",