bosun 0.40.6 → 0.40.7
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/package.json +1 -1
- package/workflow/workflow-nodes.mjs +115 -8
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "bosun",
|
|
3
|
-
"version": "0.40.
|
|
3
|
+
"version": "0.40.7",
|
|
4
4
|
"description": "Bosun Autonomous Engineering — manages AI agent executors with failover, extremely powerful workflow builder, and a massive amount of included default workflow templates for autonomous engineering, creates PRs via Vibe-Kanban API, and sends Telegram notifications. Supports N executors with weighted distribution, multi-repo projects, and auto-setup.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -59,11 +59,118 @@ function makeIsolatedGitEnv(extra = {}) {
|
|
|
59
59
|
return env;
|
|
60
60
|
}
|
|
61
61
|
|
|
62
|
-
function
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
62
|
+
function resolveGitCandidates(env = process.env) {
|
|
63
|
+
const candidates = [];
|
|
64
|
+
const envGitExe = env?.GIT_EXE || process.env.GIT_EXE;
|
|
65
|
+
if (envGitExe) candidates.push(envGitExe);
|
|
66
|
+
if (process.platform === "win32") {
|
|
67
|
+
candidates.push(
|
|
68
|
+
"C:\\Program Files\\Git\\cmd\\git.exe",
|
|
69
|
+
"C:\\Program Files\\Git\\bin\\git.exe",
|
|
70
|
+
"C:\\Program Files (x86)\\Git\\cmd\\git.exe",
|
|
71
|
+
"C:\\Program Files (x86)\\Git\\bin\\git.exe",
|
|
72
|
+
);
|
|
73
|
+
} else {
|
|
74
|
+
candidates.push(
|
|
75
|
+
"/usr/bin/git",
|
|
76
|
+
"/usr/local/bin/git",
|
|
77
|
+
"/bin/git",
|
|
78
|
+
"/opt/homebrew/bin/git",
|
|
79
|
+
);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
if (process.platform === "win32") {
|
|
83
|
+
try {
|
|
84
|
+
const whereOutput = execFileSync("where.exe", ["git"], {
|
|
85
|
+
encoding: "utf8",
|
|
86
|
+
env,
|
|
87
|
+
stdio: ["ignore", "pipe", "ignore"],
|
|
88
|
+
windowsHide: true,
|
|
89
|
+
});
|
|
90
|
+
for (const line of String(whereOutput || "").split(/\r?\n/)) {
|
|
91
|
+
const candidate = line.trim();
|
|
92
|
+
if (!candidate) continue;
|
|
93
|
+
candidates.push(candidate);
|
|
94
|
+
}
|
|
95
|
+
} catch {
|
|
96
|
+
/* best-effort */
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
candidates.push("git");
|
|
101
|
+
const deduped = [];
|
|
102
|
+
const seen = new Set();
|
|
103
|
+
for (const candidate of candidates) {
|
|
104
|
+
const key = process.platform === "win32"
|
|
105
|
+
? String(candidate || "").toLowerCase()
|
|
106
|
+
: String(candidate || "");
|
|
107
|
+
if (!candidate || seen.has(key)) continue;
|
|
108
|
+
seen.add(key);
|
|
109
|
+
deduped.push(candidate);
|
|
110
|
+
}
|
|
111
|
+
return deduped;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
function buildGitExecutionEnv(baseEnv, gitBinary) {
|
|
115
|
+
if (process.platform !== "win32") return baseEnv;
|
|
116
|
+
const normalizedBinary = String(gitBinary || "").replace(/\//g, "\\");
|
|
117
|
+
if (!normalizedBinary.includes("\\") || !normalizedBinary.toLowerCase().endsWith("\\git.exe")) {
|
|
118
|
+
return baseEnv;
|
|
119
|
+
}
|
|
120
|
+
const env = { ...baseEnv };
|
|
121
|
+
const pathKey = Object.prototype.hasOwnProperty.call(env, "Path")
|
|
122
|
+
? "Path"
|
|
123
|
+
: "PATH";
|
|
124
|
+
const existing = String(env[pathKey] ?? env.PATH ?? env.Path ?? "");
|
|
125
|
+
const parts = existing
|
|
126
|
+
.split(";")
|
|
127
|
+
.map((part) => part.trim())
|
|
128
|
+
.filter(Boolean);
|
|
129
|
+
const seen = new Set(parts.map((part) => part.toLowerCase()));
|
|
130
|
+
const binaryDir = dirname(normalizedBinary);
|
|
131
|
+
const gitRoot = dirname(binaryDir);
|
|
132
|
+
for (const dir of [
|
|
133
|
+
binaryDir,
|
|
134
|
+
`${gitRoot}\\cmd`,
|
|
135
|
+
`${gitRoot}\\bin`,
|
|
136
|
+
`${gitRoot}\\mingw64\\bin`,
|
|
137
|
+
`${gitRoot}\\usr\\bin`,
|
|
138
|
+
]) {
|
|
139
|
+
const normalizedDir = String(dir || "").replace(/\//g, "\\");
|
|
140
|
+
if (!normalizedDir || seen.has(normalizedDir.toLowerCase())) continue;
|
|
141
|
+
seen.add(normalizedDir.toLowerCase());
|
|
142
|
+
parts.unshift(normalizedDir);
|
|
143
|
+
}
|
|
144
|
+
env[pathKey] = parts.join(";");
|
|
145
|
+
if (pathKey === "PATH") env.Path = env[pathKey];
|
|
146
|
+
else env.PATH = env[pathKey];
|
|
147
|
+
return env;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
function execGitArgsSync(args, options = {}) {
|
|
151
|
+
if (!Array.isArray(args) || !args.length) {
|
|
152
|
+
throw new Error("execGitArgsSync requires a non-empty args array");
|
|
153
|
+
}
|
|
154
|
+
const env = makeIsolatedGitEnv(options.env);
|
|
155
|
+
const gitArgs = args.map((arg) => String(arg));
|
|
156
|
+
let lastEnoent = null;
|
|
157
|
+
for (const gitBinary of resolveGitCandidates(env)) {
|
|
158
|
+
if (gitBinary !== "git" && !existsSync(gitBinary)) continue;
|
|
159
|
+
try {
|
|
160
|
+
return execFileSync(gitBinary, gitArgs, {
|
|
161
|
+
...options,
|
|
162
|
+
env: buildGitExecutionEnv(env, gitBinary),
|
|
163
|
+
});
|
|
164
|
+
} catch (error) {
|
|
165
|
+
if (error?.code === "ENOENT") {
|
|
166
|
+
lastEnoent = error;
|
|
167
|
+
continue;
|
|
168
|
+
}
|
|
169
|
+
throw error;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
if (lastEnoent) throw lastEnoent;
|
|
173
|
+
throw new Error("Git executable not found");
|
|
67
174
|
}
|
|
68
175
|
|
|
69
176
|
function trimLogText(value, max = 180) {
|
|
@@ -8537,7 +8644,7 @@ registerNodeType("action.detect_new_commits", {
|
|
|
8537
8644
|
// Get current HEAD
|
|
8538
8645
|
let postExecHead = "";
|
|
8539
8646
|
try {
|
|
8540
|
-
postExecHead =
|
|
8647
|
+
postExecHead = execGitArgsSync(["rev-parse", "HEAD"], {
|
|
8541
8648
|
cwd: worktreePath, encoding: "utf8", timeout: 5000,
|
|
8542
8649
|
}).trim();
|
|
8543
8650
|
} catch (err) {
|
|
@@ -8551,7 +8658,7 @@ registerNodeType("action.detect_new_commits", {
|
|
|
8551
8658
|
let hasUnpushed = false;
|
|
8552
8659
|
let commitCount = 0;
|
|
8553
8660
|
try {
|
|
8554
|
-
const log =
|
|
8661
|
+
const log = execGitArgsSync(["log", "--oneline", `${baseBranch}..HEAD`], {
|
|
8555
8662
|
cwd: worktreePath, encoding: "utf8", timeout: 10000,
|
|
8556
8663
|
stdio: ["ignore", "pipe", "pipe"],
|
|
8557
8664
|
}).trim();
|
|
@@ -8565,7 +8672,7 @@ registerNodeType("action.detect_new_commits", {
|
|
|
8565
8672
|
let diffStats = null;
|
|
8566
8673
|
if (hasNewCommits || hasUnpushed) {
|
|
8567
8674
|
try {
|
|
8568
|
-
const statOutput =
|
|
8675
|
+
const statOutput = execGitArgsSync(["diff", "--stat", `${baseBranch}..HEAD`], {
|
|
8569
8676
|
cwd: worktreePath, encoding: "utf8", timeout: 10000,
|
|
8570
8677
|
stdio: ["ignore", "pipe", "pipe"],
|
|
8571
8678
|
}).trim();
|