webmux 0.31.1 → 0.31.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.
- package/backend/dist/server.js +41 -14
- package/bin/webmux.js +40 -13
- package/package.json +1 -1
package/backend/dist/server.js
CHANGED
|
@@ -14975,12 +14975,26 @@ import { randomUUID } from "crypto";
|
|
|
14975
14975
|
// backend/src/adapters/git.ts
|
|
14976
14976
|
import { readdirSync, rmSync, statSync } from "fs";
|
|
14977
14977
|
import { resolve as resolve6, join as join5 } from "path";
|
|
14978
|
+
function spawnGit(args, cwd) {
|
|
14979
|
+
try {
|
|
14980
|
+
return {
|
|
14981
|
+
ok: true,
|
|
14982
|
+
result: Bun.spawnSync(["git", ...args], {
|
|
14983
|
+
cwd,
|
|
14984
|
+
stdout: "pipe",
|
|
14985
|
+
stderr: "pipe"
|
|
14986
|
+
})
|
|
14987
|
+
};
|
|
14988
|
+
} catch (error) {
|
|
14989
|
+
return { ok: false, stderr: `spawn error (cwd=${cwd}): ${errorMessage(error)}` };
|
|
14990
|
+
}
|
|
14991
|
+
}
|
|
14978
14992
|
function runGit(args, cwd) {
|
|
14979
|
-
const
|
|
14980
|
-
|
|
14981
|
-
|
|
14982
|
-
|
|
14983
|
-
}
|
|
14993
|
+
const spawned = spawnGit(args, cwd);
|
|
14994
|
+
if (!spawned.ok) {
|
|
14995
|
+
throw new Error(`git ${args.join(" ")} failed: ${spawned.stderr}`);
|
|
14996
|
+
}
|
|
14997
|
+
const { result } = spawned;
|
|
14984
14998
|
if (result.exitCode !== 0) {
|
|
14985
14999
|
const stderr = new TextDecoder().decode(result.stderr).trim();
|
|
14986
15000
|
throw new Error(`git ${args.join(" ")} failed: ${stderr || `exit ${result.exitCode}`}`);
|
|
@@ -14988,11 +15002,11 @@ function runGit(args, cwd) {
|
|
|
14988
15002
|
return new TextDecoder().decode(result.stdout).trim();
|
|
14989
15003
|
}
|
|
14990
15004
|
function tryRunGit(args, cwd) {
|
|
14991
|
-
const
|
|
14992
|
-
|
|
14993
|
-
|
|
14994
|
-
|
|
14995
|
-
}
|
|
15005
|
+
const spawned = spawnGit(args, cwd);
|
|
15006
|
+
if (!spawned.ok) {
|
|
15007
|
+
return { ok: false, stderr: spawned.stderr };
|
|
15008
|
+
}
|
|
15009
|
+
const { result } = spawned;
|
|
14996
15010
|
if (result.exitCode !== 0) {
|
|
14997
15011
|
return {
|
|
14998
15012
|
ok: false,
|
|
@@ -15113,6 +15127,16 @@ function listGitWorktrees(cwd) {
|
|
|
15113
15127
|
const output = runGit(["worktree", "list", "--porcelain"], cwd);
|
|
15114
15128
|
return parseGitWorktreePorcelain(output);
|
|
15115
15129
|
}
|
|
15130
|
+
function worktreeEntryPathExists(entry) {
|
|
15131
|
+
try {
|
|
15132
|
+
return statSync(entry.path).isDirectory();
|
|
15133
|
+
} catch {
|
|
15134
|
+
return false;
|
|
15135
|
+
}
|
|
15136
|
+
}
|
|
15137
|
+
function filterLiveWorktreeEntries(entries) {
|
|
15138
|
+
return entries.filter(worktreeEntryPathExists);
|
|
15139
|
+
}
|
|
15116
15140
|
function listLocalGitBranches(cwd) {
|
|
15117
15141
|
const output = runGit(["for-each-ref", "--format=%(refname:short)", "refs/heads"], cwd);
|
|
15118
15142
|
return output.split(`
|
|
@@ -15173,6 +15197,9 @@ class BunGitGateway {
|
|
|
15173
15197
|
listWorktrees(cwd) {
|
|
15174
15198
|
return listGitWorktrees(cwd);
|
|
15175
15199
|
}
|
|
15200
|
+
listLiveWorktrees(cwd) {
|
|
15201
|
+
return filterLiveWorktreeEntries(listGitWorktrees(cwd));
|
|
15202
|
+
}
|
|
15176
15203
|
listLocalBranches(cwd) {
|
|
15177
15204
|
return listLocalGitBranches(cwd);
|
|
15178
15205
|
}
|
|
@@ -15736,7 +15763,7 @@ class LifecycleService {
|
|
|
15736
15763
|
}
|
|
15737
15764
|
listProjectWorktrees() {
|
|
15738
15765
|
const projectRoot2 = resolve7(this.deps.projectRoot);
|
|
15739
|
-
return this.deps.git.
|
|
15766
|
+
return this.deps.git.listLiveWorktrees(projectRoot2).filter((entry) => !entry.bare && resolve7(entry.path) !== projectRoot2);
|
|
15740
15767
|
}
|
|
15741
15768
|
async readManagedMetas() {
|
|
15742
15769
|
const metas = await Promise.all(this.listProjectWorktrees().map(async (entry) => {
|
|
@@ -16623,7 +16650,7 @@ function resetProcessedIssues() {
|
|
|
16623
16650
|
|
|
16624
16651
|
// backend/src/services/auto-remove-service.ts
|
|
16625
16652
|
async function runAutoRemove(deps) {
|
|
16626
|
-
const worktrees = deps.git.
|
|
16653
|
+
const worktrees = deps.git.listLiveWorktrees(deps.projectRoot).filter((e) => !e.bare && e.branch !== null && e.path !== deps.projectRoot);
|
|
16627
16654
|
for (const entry of worktrees) {
|
|
16628
16655
|
const branch = entry.branch;
|
|
16629
16656
|
if (deps.isRemoving(branch))
|
|
@@ -18205,7 +18232,7 @@ class ReconciliationService {
|
|
|
18205
18232
|
return await this.inFlight;
|
|
18206
18233
|
}
|
|
18207
18234
|
async runReconcile(normalizedRepoRoot) {
|
|
18208
|
-
const worktrees = this.deps.git.
|
|
18235
|
+
const worktrees = this.deps.git.listLiveWorktrees(normalizedRepoRoot);
|
|
18209
18236
|
const sessionName = buildProjectSessionName(normalizedRepoRoot);
|
|
18210
18237
|
let windows = [];
|
|
18211
18238
|
try {
|
|
@@ -18610,7 +18637,7 @@ async function hasValidControlToken(req) {
|
|
|
18610
18637
|
async function getWorktreeGitDirs() {
|
|
18611
18638
|
const gitDirs = new Map;
|
|
18612
18639
|
const projectRoot2 = resolve9(PROJECT_DIR);
|
|
18613
|
-
for (const entry of git.
|
|
18640
|
+
for (const entry of git.listLiveWorktrees(projectRoot2)) {
|
|
18614
18641
|
if (entry.bare || resolve9(entry.path) === projectRoot2 || !entry.branch)
|
|
18615
18642
|
continue;
|
|
18616
18643
|
gitDirs.set(entry.branch, git.resolveWorktreeGitDir(entry.path));
|
package/bin/webmux.js
CHANGED
|
@@ -50,12 +50,26 @@ var __require = import.meta.require;
|
|
|
50
50
|
// backend/src/adapters/git.ts
|
|
51
51
|
import { readdirSync, rmSync, statSync } from "fs";
|
|
52
52
|
import { resolve, join } from "path";
|
|
53
|
+
function spawnGit(args, cwd) {
|
|
54
|
+
try {
|
|
55
|
+
return {
|
|
56
|
+
ok: true,
|
|
57
|
+
result: Bun.spawnSync(["git", ...args], {
|
|
58
|
+
cwd,
|
|
59
|
+
stdout: "pipe",
|
|
60
|
+
stderr: "pipe"
|
|
61
|
+
})
|
|
62
|
+
};
|
|
63
|
+
} catch (error) {
|
|
64
|
+
return { ok: false, stderr: `spawn error (cwd=${cwd}): ${errorMessage(error)}` };
|
|
65
|
+
}
|
|
66
|
+
}
|
|
53
67
|
function runGit(args, cwd) {
|
|
54
|
-
const
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
}
|
|
68
|
+
const spawned = spawnGit(args, cwd);
|
|
69
|
+
if (!spawned.ok) {
|
|
70
|
+
throw new Error(`git ${args.join(" ")} failed: ${spawned.stderr}`);
|
|
71
|
+
}
|
|
72
|
+
const { result } = spawned;
|
|
59
73
|
if (result.exitCode !== 0) {
|
|
60
74
|
const stderr = new TextDecoder().decode(result.stderr).trim();
|
|
61
75
|
throw new Error(`git ${args.join(" ")} failed: ${stderr || `exit ${result.exitCode}`}`);
|
|
@@ -63,11 +77,11 @@ function runGit(args, cwd) {
|
|
|
63
77
|
return new TextDecoder().decode(result.stdout).trim();
|
|
64
78
|
}
|
|
65
79
|
function tryRunGit(args, cwd) {
|
|
66
|
-
const
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
}
|
|
80
|
+
const spawned = spawnGit(args, cwd);
|
|
81
|
+
if (!spawned.ok) {
|
|
82
|
+
return { ok: false, stderr: spawned.stderr };
|
|
83
|
+
}
|
|
84
|
+
const { result } = spawned;
|
|
71
85
|
if (result.exitCode !== 0) {
|
|
72
86
|
return {
|
|
73
87
|
ok: false,
|
|
@@ -188,6 +202,16 @@ function listGitWorktrees(cwd) {
|
|
|
188
202
|
const output = runGit(["worktree", "list", "--porcelain"], cwd);
|
|
189
203
|
return parseGitWorktreePorcelain(output);
|
|
190
204
|
}
|
|
205
|
+
function worktreeEntryPathExists(entry) {
|
|
206
|
+
try {
|
|
207
|
+
return statSync(entry.path).isDirectory();
|
|
208
|
+
} catch {
|
|
209
|
+
return false;
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
function filterLiveWorktreeEntries(entries) {
|
|
213
|
+
return entries.filter(worktreeEntryPathExists);
|
|
214
|
+
}
|
|
191
215
|
function listLocalGitBranches(cwd) {
|
|
192
216
|
const output = runGit(["for-each-ref", "--format=%(refname:short)", "refs/heads"], cwd);
|
|
193
217
|
return output.split(`
|
|
@@ -248,6 +272,9 @@ class BunGitGateway {
|
|
|
248
272
|
listWorktrees(cwd) {
|
|
249
273
|
return listGitWorktrees(cwd);
|
|
250
274
|
}
|
|
275
|
+
listLiveWorktrees(cwd) {
|
|
276
|
+
return filterLiveWorktreeEntries(listGitWorktrees(cwd));
|
|
277
|
+
}
|
|
251
278
|
listLocalBranches(cwd) {
|
|
252
279
|
return listLocalGitBranches(cwd);
|
|
253
280
|
}
|
|
@@ -17754,7 +17781,7 @@ class LifecycleService {
|
|
|
17754
17781
|
}
|
|
17755
17782
|
listProjectWorktrees() {
|
|
17756
17783
|
const projectRoot2 = resolve8(this.deps.projectRoot);
|
|
17757
|
-
return this.deps.git.
|
|
17784
|
+
return this.deps.git.listLiveWorktrees(projectRoot2).filter((entry) => !entry.bare && resolve8(entry.path) !== projectRoot2);
|
|
17758
17785
|
}
|
|
17759
17786
|
async readManagedMetas() {
|
|
17760
17787
|
const metas = await Promise.all(this.listProjectWorktrees().map(async (entry) => {
|
|
@@ -18507,7 +18534,7 @@ class ReconciliationService {
|
|
|
18507
18534
|
return await this.inFlight;
|
|
18508
18535
|
}
|
|
18509
18536
|
async runReconcile(normalizedRepoRoot) {
|
|
18510
|
-
const worktrees = this.deps.git.
|
|
18537
|
+
const worktrees = this.deps.git.listLiveWorktrees(normalizedRepoRoot);
|
|
18511
18538
|
const sessionName = buildProjectSessionName(normalizedRepoRoot);
|
|
18512
18539
|
let windows = [];
|
|
18513
18540
|
try {
|
|
@@ -19351,7 +19378,7 @@ import { fileURLToPath } from "url";
|
|
|
19351
19378
|
// package.json
|
|
19352
19379
|
var package_default = {
|
|
19353
19380
|
name: "webmux",
|
|
19354
|
-
version: "0.31.
|
|
19381
|
+
version: "0.31.2",
|
|
19355
19382
|
description: "Web dashboard for workmux \u2014 browser UI with embedded terminals, PR monitoring, and CI integration",
|
|
19356
19383
|
type: "module",
|
|
19357
19384
|
repository: {
|