worktree-bay 2.3.4 → 2.3.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/dist/engine.js +4 -4
- package/dist/ports.js +13 -0
- package/package.json +1 -1
package/dist/engine.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import fs from 'node:fs';
|
|
2
2
|
import path from 'node:path';
|
|
3
3
|
import { renderTemplate } from './config.js';
|
|
4
|
-
import { portOf,
|
|
4
|
+
import { portOf, portInUse } from './ports.js';
|
|
5
5
|
import { scanOccupancy } from './slots.js';
|
|
6
6
|
import { addWorktree } from './git.js';
|
|
7
7
|
import { runShellLive, run, spliceArgv, isTTY } from './util/exec.js';
|
|
@@ -41,7 +41,7 @@ export function buildVars(cfg, ctx) {
|
|
|
41
41
|
}
|
|
42
42
|
export async function bringUp(ctx, base, branch) {
|
|
43
43
|
const { sp, dir, repo, vars } = ctx;
|
|
44
|
-
if (
|
|
44
|
+
if (await portInUse(Number(vars.port)))
|
|
45
45
|
throw new Error(t(`端口 ${vars.port} 已被占用。先停掉占用它的进程,或用 \`worktree-bay gc\`/\`worktree-bay down <功能>\` 释放其它槽后重试。`, `port ${vars.port} is already in use. Stop whatever is using it, or free a slot with \`worktree-bay gc\`/\`worktree-bay down <feature>\`, then retry.`));
|
|
46
46
|
log(t(` → 创建 worktree(分支 ${branch})…`, ` → creating worktree (branch ${branch})…`));
|
|
47
47
|
addWorktree(repo, dir, branch, base);
|
|
@@ -82,7 +82,7 @@ export async function ensureStarted(ctx) {
|
|
|
82
82
|
log(t(` • ${service} dev server 已在跑(pid ${rec.pid},端口 ${port})`, ` • ${service} dev server already running (pid ${rec.pid}, port ${port})`));
|
|
83
83
|
return;
|
|
84
84
|
}
|
|
85
|
-
if (
|
|
85
|
+
if (await portInUse(port)) {
|
|
86
86
|
log(t(` • 端口 ${port} 已在监听,视为 ${service} dev server 在跑,跳过启动`, ` • port ${port} already listening; treating ${service} dev server as up, skip`));
|
|
87
87
|
return;
|
|
88
88
|
}
|
|
@@ -107,7 +107,7 @@ export async function ensureStarted(ctx) {
|
|
|
107
107
|
async function waitForListen(port, ms) {
|
|
108
108
|
const end = Date.now() + ms;
|
|
109
109
|
for (;;) {
|
|
110
|
-
if (
|
|
110
|
+
if (await portInUse(port))
|
|
111
111
|
return true;
|
|
112
112
|
if (Date.now() >= end)
|
|
113
113
|
return false;
|
package/dist/ports.js
CHANGED
|
@@ -9,3 +9,16 @@ export function isPortFree(port) {
|
|
|
9
9
|
srv.listen(port, '127.0.0.1');
|
|
10
10
|
});
|
|
11
11
|
}
|
|
12
|
+
// 端口是否已被监听(连接探测,同时试 IPv4 与 IPv6 回环)。
|
|
13
|
+
// 比 bind 探测可靠:Windows 上 vite 等常监听 IPv6(::),单纯在 127.0.0.1 上 bind 测试会漏判。
|
|
14
|
+
export function portInUse(port) {
|
|
15
|
+
const probe = (host) => new Promise((resolve) => {
|
|
16
|
+
const sock = net.connect({ port, host });
|
|
17
|
+
const finish = (v) => { sock.destroy(); resolve(v); };
|
|
18
|
+
sock.setTimeout(1500);
|
|
19
|
+
sock.once('connect', () => finish(true));
|
|
20
|
+
sock.once('timeout', () => finish(false));
|
|
21
|
+
sock.once('error', () => resolve(false));
|
|
22
|
+
});
|
|
23
|
+
return Promise.all([probe('127.0.0.1'), probe('::1')]).then((r) => r.some(Boolean));
|
|
24
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "worktree-bay",
|
|
3
|
-
"version": "2.3.
|
|
3
|
+
"version": "2.3.5",
|
|
4
4
|
"description": "Per-feature git worktree + port slots for parallel multi-service development: auto deps, env wiring, frontend-to-backend, merge-aware reclaim, plus an MCP server for AI agents.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"git",
|