@serviceme/devtools-cli 0.1.2 → 0.1.4
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/bridgeServer.js +285 -69
- package/dist/cli.js +659 -290
- package/package.json +3 -3
package/dist/bridgeServer.js
CHANGED
|
@@ -4,8 +4,9 @@
|
|
|
4
4
|
var readline = require('readline');
|
|
5
5
|
var child_process = require('child_process');
|
|
6
6
|
require('fs/promises');
|
|
7
|
-
require('path');
|
|
8
|
-
require('fs');
|
|
7
|
+
var path5 = require('path');
|
|
8
|
+
var fs6 = require('fs');
|
|
9
|
+
require('os');
|
|
9
10
|
require('crypto');
|
|
10
11
|
|
|
11
12
|
function _interopNamespace(e) {
|
|
@@ -27,6 +28,8 @@ function _interopNamespace(e) {
|
|
|
27
28
|
}
|
|
28
29
|
|
|
29
30
|
var readline__namespace = /*#__PURE__*/_interopNamespace(readline);
|
|
31
|
+
var path5__namespace = /*#__PURE__*/_interopNamespace(path5);
|
|
32
|
+
var fs6__namespace = /*#__PURE__*/_interopNamespace(fs6);
|
|
30
33
|
|
|
31
34
|
var __create = Object.create;
|
|
32
35
|
var __defProp = Object.defineProperty;
|
|
@@ -297,9 +300,9 @@ var require_esprima = __commonJS({
|
|
|
297
300
|
});
|
|
298
301
|
};
|
|
299
302
|
CommentHandler2.prototype.visitComment = function(node, metadata) {
|
|
300
|
-
var
|
|
303
|
+
var type2 = node.type[0] === "L" ? "Line" : "Block";
|
|
301
304
|
var comment = {
|
|
302
|
-
type,
|
|
305
|
+
type: type2,
|
|
303
306
|
value: node.value
|
|
304
307
|
};
|
|
305
308
|
if (node.range) {
|
|
@@ -312,7 +315,7 @@ var require_esprima = __commonJS({
|
|
|
312
315
|
if (this.attach) {
|
|
313
316
|
var entry = {
|
|
314
317
|
comment: {
|
|
315
|
-
type,
|
|
318
|
+
type: type2,
|
|
316
319
|
value: node.value,
|
|
317
320
|
range: [metadata.start.offset, metadata.end.offset]
|
|
318
321
|
},
|
|
@@ -321,7 +324,7 @@ var require_esprima = __commonJS({
|
|
|
321
324
|
if (node.loc) {
|
|
322
325
|
entry.comment.loc = node.loc;
|
|
323
326
|
}
|
|
324
|
-
node.type =
|
|
327
|
+
node.type = type2;
|
|
325
328
|
this.leading.push(entry);
|
|
326
329
|
this.trailing.push(entry);
|
|
327
330
|
}
|
|
@@ -5136,28 +5139,28 @@ var require_esprima = __commonJS({
|
|
|
5136
5139
|
};
|
|
5137
5140
|
};
|
|
5138
5141
|
Scanner2.prototype.scanIdentifier = function() {
|
|
5139
|
-
var
|
|
5142
|
+
var type2;
|
|
5140
5143
|
var start = this.index;
|
|
5141
5144
|
var id = this.source.charCodeAt(start) === 92 ? this.getComplexIdentifier() : this.getIdentifier();
|
|
5142
5145
|
if (id.length === 1) {
|
|
5143
|
-
|
|
5146
|
+
type2 = 3;
|
|
5144
5147
|
} else if (this.isKeyword(id)) {
|
|
5145
|
-
|
|
5148
|
+
type2 = 4;
|
|
5146
5149
|
} else if (id === "null") {
|
|
5147
|
-
|
|
5150
|
+
type2 = 5;
|
|
5148
5151
|
} else if (id === "true" || id === "false") {
|
|
5149
|
-
|
|
5152
|
+
type2 = 1;
|
|
5150
5153
|
} else {
|
|
5151
|
-
|
|
5154
|
+
type2 = 3;
|
|
5152
5155
|
}
|
|
5153
|
-
if (
|
|
5156
|
+
if (type2 !== 3 && start + id.length !== this.index) {
|
|
5154
5157
|
var restore = this.index;
|
|
5155
5158
|
this.index = start;
|
|
5156
5159
|
this.tolerateUnexpectedToken(messages_1.Messages.InvalidEscapedReservedWord);
|
|
5157
5160
|
this.index = restore;
|
|
5158
5161
|
}
|
|
5159
5162
|
return {
|
|
5160
|
-
type,
|
|
5163
|
+
type: type2,
|
|
5161
5164
|
value: id,
|
|
5162
5165
|
lineNumber: this.lineNumber,
|
|
5163
5166
|
lineStart: this.lineStart,
|
|
@@ -7608,13 +7611,13 @@ var require_parse = __commonJS({
|
|
|
7608
7611
|
last = current;
|
|
7609
7612
|
current = new_token;
|
|
7610
7613
|
};
|
|
7611
|
-
var
|
|
7614
|
+
var type2 = () => {
|
|
7612
7615
|
if (!current) {
|
|
7613
7616
|
unexpected_end();
|
|
7614
7617
|
}
|
|
7615
7618
|
return current.type === "Punctuator" ? current.value : current.type;
|
|
7616
7619
|
};
|
|
7617
|
-
var is = (t) =>
|
|
7620
|
+
var is = (t) => type2() === t;
|
|
7618
7621
|
var expect = (a) => {
|
|
7619
7622
|
if (!is(a)) {
|
|
7620
7623
|
unexpected();
|
|
@@ -7769,7 +7772,7 @@ var require_parse = __commonJS({
|
|
|
7769
7772
|
return array;
|
|
7770
7773
|
};
|
|
7771
7774
|
function walk() {
|
|
7772
|
-
let tt =
|
|
7775
|
+
let tt = type2();
|
|
7773
7776
|
if (tt === CURLY_BRACKET_OPEN) {
|
|
7774
7777
|
next();
|
|
7775
7778
|
return {
|
|
@@ -7785,7 +7788,7 @@ var require_parse = __commonJS({
|
|
|
7785
7788
|
let negative = EMPTY;
|
|
7786
7789
|
if (tt === MINUS) {
|
|
7787
7790
|
next();
|
|
7788
|
-
tt =
|
|
7791
|
+
tt = type2();
|
|
7789
7792
|
negative = MINUS;
|
|
7790
7793
|
}
|
|
7791
7794
|
let v;
|
|
@@ -7911,11 +7914,11 @@ var require_stringify = __commonJS({
|
|
|
7911
7914
|
let is_line_comment = false;
|
|
7912
7915
|
const str = comments.reduce((prev, {
|
|
7913
7916
|
inline,
|
|
7914
|
-
type,
|
|
7917
|
+
type: type2,
|
|
7915
7918
|
value
|
|
7916
7919
|
}) => {
|
|
7917
7920
|
const delimiter = inline ? SPACE : LF + deeper_gap;
|
|
7918
|
-
is_line_comment =
|
|
7921
|
+
is_line_comment = type2 === "LineComment";
|
|
7919
7922
|
return prev + delimiter + comment_stringify(value, is_line_comment);
|
|
7920
7923
|
}, EMPTY);
|
|
7921
7924
|
return display_block || is_line_comment ? str + LF + deeper_gap : str;
|
|
@@ -8143,7 +8146,7 @@ var require_pend = __commonJS({
|
|
|
8143
8146
|
// ../../node_modules/.pnpm/yauzl@3.2.0/node_modules/yauzl/fd-slicer.js
|
|
8144
8147
|
var require_fd_slicer = __commonJS({
|
|
8145
8148
|
"../../node_modules/.pnpm/yauzl@3.2.0/node_modules/yauzl/fd-slicer.js"(exports$1) {
|
|
8146
|
-
var
|
|
8149
|
+
var fs10 = __require("fs");
|
|
8147
8150
|
var util = __require("util");
|
|
8148
8151
|
var stream = __require("stream");
|
|
8149
8152
|
var Readable = stream.Readable;
|
|
@@ -8168,7 +8171,7 @@ var require_fd_slicer = __commonJS({
|
|
|
8168
8171
|
FdSlicer.prototype.read = function(buffer, offset, length, position, callback) {
|
|
8169
8172
|
var self = this;
|
|
8170
8173
|
self.pend.go(function(cb) {
|
|
8171
|
-
|
|
8174
|
+
fs10.read(self.fd, buffer, offset, length, position, function(err, bytesRead, buffer2) {
|
|
8172
8175
|
cb();
|
|
8173
8176
|
callback(err, bytesRead, buffer2);
|
|
8174
8177
|
});
|
|
@@ -8177,7 +8180,7 @@ var require_fd_slicer = __commonJS({
|
|
|
8177
8180
|
FdSlicer.prototype.write = function(buffer, offset, length, position, callback) {
|
|
8178
8181
|
var self = this;
|
|
8179
8182
|
self.pend.go(function(cb) {
|
|
8180
|
-
|
|
8183
|
+
fs10.write(self.fd, buffer, offset, length, position, function(err, written, buffer2) {
|
|
8181
8184
|
cb();
|
|
8182
8185
|
callback(err, written, buffer2);
|
|
8183
8186
|
});
|
|
@@ -8198,7 +8201,7 @@ var require_fd_slicer = __commonJS({
|
|
|
8198
8201
|
if (self.refCount > 0) return;
|
|
8199
8202
|
if (self.refCount < 0) throw new Error("invalid unref");
|
|
8200
8203
|
if (self.autoClose) {
|
|
8201
|
-
|
|
8204
|
+
fs10.close(self.fd, onCloseDone);
|
|
8202
8205
|
}
|
|
8203
8206
|
function onCloseDone(err) {
|
|
8204
8207
|
if (err) {
|
|
@@ -8235,7 +8238,7 @@ var require_fd_slicer = __commonJS({
|
|
|
8235
8238
|
self.context.pend.go(function(cb) {
|
|
8236
8239
|
if (self.destroyed) return cb();
|
|
8237
8240
|
var buffer = Buffer.allocUnsafe(toRead);
|
|
8238
|
-
|
|
8241
|
+
fs10.read(self.context.fd, buffer, 0, toRead, self.pos, function(err, bytesRead) {
|
|
8239
8242
|
if (err) {
|
|
8240
8243
|
self.destroy(err);
|
|
8241
8244
|
} else if (bytesRead === 0) {
|
|
@@ -8282,7 +8285,7 @@ var require_fd_slicer = __commonJS({
|
|
|
8282
8285
|
}
|
|
8283
8286
|
self.context.pend.go(function(cb) {
|
|
8284
8287
|
if (self.destroyed) return cb();
|
|
8285
|
-
|
|
8288
|
+
fs10.write(self.context.fd, buffer, 0, buffer.length, self.pos, function(err2, bytes) {
|
|
8286
8289
|
if (err2) {
|
|
8287
8290
|
self.destroy();
|
|
8288
8291
|
cb();
|
|
@@ -8720,7 +8723,7 @@ var require_buffer_crc32 = __commonJS({
|
|
|
8720
8723
|
// ../../node_modules/.pnpm/yauzl@3.2.0/node_modules/yauzl/index.js
|
|
8721
8724
|
var require_yauzl = __commonJS({
|
|
8722
8725
|
"../../node_modules/.pnpm/yauzl@3.2.0/node_modules/yauzl/index.js"(exports$1) {
|
|
8723
|
-
var
|
|
8726
|
+
var fs10 = __require("fs");
|
|
8724
8727
|
var zlib = __require("zlib");
|
|
8725
8728
|
var fd_slicer = require_fd_slicer();
|
|
8726
8729
|
var crc32 = require_buffer_crc32();
|
|
@@ -8741,7 +8744,7 @@ var require_yauzl = __commonJS({
|
|
|
8741
8744
|
exports$1.Entry = Entry;
|
|
8742
8745
|
exports$1.LocalFileHeader = LocalFileHeader;
|
|
8743
8746
|
exports$1.RandomAccessReader = RandomAccessReader;
|
|
8744
|
-
function open2(
|
|
8747
|
+
function open2(path8, options2, callback) {
|
|
8745
8748
|
if (typeof options2 === "function") {
|
|
8746
8749
|
callback = options2;
|
|
8747
8750
|
options2 = null;
|
|
@@ -8753,10 +8756,10 @@ var require_yauzl = __commonJS({
|
|
|
8753
8756
|
if (options2.validateEntrySizes == null) options2.validateEntrySizes = true;
|
|
8754
8757
|
if (options2.strictFileNames == null) options2.strictFileNames = false;
|
|
8755
8758
|
if (callback == null) callback = defaultCallback;
|
|
8756
|
-
|
|
8759
|
+
fs10.open(path8, "r", function(err, fd) {
|
|
8757
8760
|
if (err) return callback(err);
|
|
8758
8761
|
fromFd(fd, options2, function(err2, zipfile) {
|
|
8759
|
-
if (err2)
|
|
8762
|
+
if (err2) fs10.close(fd, defaultCallback);
|
|
8760
8763
|
callback(err2, zipfile);
|
|
8761
8764
|
});
|
|
8762
8765
|
});
|
|
@@ -8773,7 +8776,7 @@ var require_yauzl = __commonJS({
|
|
|
8773
8776
|
if (options2.validateEntrySizes == null) options2.validateEntrySizes = true;
|
|
8774
8777
|
if (options2.strictFileNames == null) options2.strictFileNames = false;
|
|
8775
8778
|
if (callback == null) callback = defaultCallback;
|
|
8776
|
-
|
|
8779
|
+
fs10.fstat(fd, function(err, stats) {
|
|
8777
8780
|
if (err) return callback(err);
|
|
8778
8781
|
var reader = fd_slicer.createFromFd(fd, { autoClose: true });
|
|
8779
8782
|
fromRandomAccessReader(reader, stats.size, options2, callback);
|
|
@@ -9597,7 +9600,7 @@ function normalizeServicemeError(error, fallbackCode = "internal_error") {
|
|
|
9597
9600
|
}
|
|
9598
9601
|
|
|
9599
9602
|
// src/version.ts
|
|
9600
|
-
var SERVICEME_CLI_VERSION = "0.1.
|
|
9603
|
+
var SERVICEME_CLI_VERSION = "0.1.4";
|
|
9601
9604
|
|
|
9602
9605
|
// src/bridge/ndjson.ts
|
|
9603
9606
|
function writeBridgeMessage(message) {
|
|
@@ -9630,7 +9633,8 @@ async function runCommand(command, options2 = {}) {
|
|
|
9630
9633
|
cwd: options2.cwd,
|
|
9631
9634
|
env: options2.env,
|
|
9632
9635
|
shell: options2.shell,
|
|
9633
|
-
stdio: "pipe"
|
|
9636
|
+
stdio: "pipe",
|
|
9637
|
+
windowsHide: true
|
|
9634
9638
|
});
|
|
9635
9639
|
let stdout = "";
|
|
9636
9640
|
let stderr = "";
|
|
@@ -9717,8 +9721,45 @@ __toESM(require_src2());
|
|
|
9717
9721
|
|
|
9718
9722
|
// ../../packages/serviceme-core/src/utils/fileUtils.ts
|
|
9719
9723
|
__toESM(require_yauzl());
|
|
9720
|
-
|
|
9724
|
+
|
|
9725
|
+
// ../../packages/serviceme-core/src/scheduled-tasks/executors/timeout.ts
|
|
9726
|
+
function resolveConfiguredTimeoutMs(timeoutSeconds, defaultTimeoutMs) {
|
|
9727
|
+
if (timeoutSeconds === 0) {
|
|
9728
|
+
return void 0;
|
|
9729
|
+
}
|
|
9730
|
+
if (typeof timeoutSeconds !== "number" || !Number.isFinite(timeoutSeconds) || timeoutSeconds < 0) {
|
|
9731
|
+
return defaultTimeoutMs;
|
|
9732
|
+
}
|
|
9733
|
+
return timeoutSeconds * 1e3;
|
|
9734
|
+
}
|
|
9735
|
+
|
|
9736
|
+
// ../../packages/serviceme-core/src/scheduled-tasks/executors/GithubCopilotCliExecutor.ts
|
|
9721
9737
|
var MAX_OUTPUT_BYTES = 2 * 1024 * 1024;
|
|
9738
|
+
var DEFAULT_TIMEOUT_MS = 3e5;
|
|
9739
|
+
function redactArgs(args) {
|
|
9740
|
+
const redacted = [];
|
|
9741
|
+
let redactNext = false;
|
|
9742
|
+
for (const arg of args) {
|
|
9743
|
+
if (redactNext) {
|
|
9744
|
+
redacted.push("<redacted>");
|
|
9745
|
+
redactNext = false;
|
|
9746
|
+
continue;
|
|
9747
|
+
}
|
|
9748
|
+
redacted.push(arg);
|
|
9749
|
+
if (arg === "--prompt") {
|
|
9750
|
+
redactNext = true;
|
|
9751
|
+
}
|
|
9752
|
+
}
|
|
9753
|
+
return redacted;
|
|
9754
|
+
}
|
|
9755
|
+
function writeDiagnostic(message) {
|
|
9756
|
+
const logPath = process.env.SERVICEME_SCHEDULER_LOG_PATH;
|
|
9757
|
+
if (logPath) {
|
|
9758
|
+
fs6__namespace.appendFileSync(logPath, message);
|
|
9759
|
+
return;
|
|
9760
|
+
}
|
|
9761
|
+
process.stderr.write(message);
|
|
9762
|
+
}
|
|
9722
9763
|
var GithubCopilotCliExecutor = class {
|
|
9723
9764
|
async execute(payload, abortSignal) {
|
|
9724
9765
|
const authenticated = await isCopilotAuthenticated();
|
|
@@ -9741,7 +9782,7 @@ var GithubCopilotCliExecutor = class {
|
|
|
9741
9782
|
}
|
|
9742
9783
|
executeStreaming(payload, onOutput, abortSignal) {
|
|
9743
9784
|
const p = payload;
|
|
9744
|
-
const
|
|
9785
|
+
const timeoutMs = resolveConfiguredTimeoutMs(p.timeout, DEFAULT_TIMEOUT_MS);
|
|
9745
9786
|
let resolve;
|
|
9746
9787
|
const resultPromise = new Promise((r) => {
|
|
9747
9788
|
resolve = r;
|
|
@@ -9750,7 +9791,7 @@ var GithubCopilotCliExecutor = class {
|
|
|
9750
9791
|
const settle = (result) => {
|
|
9751
9792
|
if (settled) return;
|
|
9752
9793
|
settled = true;
|
|
9753
|
-
clearTimeout(timer);
|
|
9794
|
+
if (timer) clearTimeout(timer);
|
|
9754
9795
|
resolve?.(result);
|
|
9755
9796
|
};
|
|
9756
9797
|
if (abortSignal?.aborted) {
|
|
@@ -9776,23 +9817,32 @@ var GithubCopilotCliExecutor = class {
|
|
|
9776
9817
|
if (p.agent) {
|
|
9777
9818
|
args.push("--agent", p.agent);
|
|
9778
9819
|
}
|
|
9779
|
-
|
|
9780
|
-
|
|
9781
|
-
|
|
9820
|
+
args.push("--timeout", String(p.timeout ?? 0));
|
|
9821
|
+
writeDiagnostic(
|
|
9822
|
+
`[GithubCopilotCliExecutor] spawn: command=serviceme, args=${JSON.stringify(redactArgs(args))}, promptLen=${p.prompt.length}, cwd=${p.workspace ?? "(default)"}, platform=${process.platform}, windowsHide=true, pid=${process.pid}
|
|
9823
|
+
`
|
|
9824
|
+
);
|
|
9782
9825
|
const child = child_process.spawn("serviceme", args, {
|
|
9783
9826
|
cwd: p.workspace,
|
|
9784
|
-
stdio: ["ignore", "pipe", "pipe"]
|
|
9827
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
9828
|
+
windowsHide: true
|
|
9785
9829
|
});
|
|
9786
|
-
|
|
9830
|
+
if (child.pid) {
|
|
9831
|
+
writeDiagnostic(
|
|
9832
|
+
`[GithubCopilotCliExecutor] spawned child PID=${child.pid}
|
|
9833
|
+
`
|
|
9834
|
+
);
|
|
9835
|
+
}
|
|
9836
|
+
const timer = timeoutMs != null ? setTimeout(() => {
|
|
9787
9837
|
child.kill("SIGTERM");
|
|
9788
9838
|
setTimeout(() => {
|
|
9789
9839
|
if (!child.killed) child.kill("SIGKILL");
|
|
9790
9840
|
}, 5e3);
|
|
9791
9841
|
settle({
|
|
9792
9842
|
status: "timeout",
|
|
9793
|
-
error: `Copilot CLI execution timed out after ${
|
|
9843
|
+
error: `Copilot CLI execution timed out after ${timeoutMs / 1e3}s`
|
|
9794
9844
|
});
|
|
9795
|
-
},
|
|
9845
|
+
}, timeoutMs) : void 0;
|
|
9796
9846
|
let stdoutBuf = "";
|
|
9797
9847
|
let stderrBuf = "";
|
|
9798
9848
|
child.stdout.on("data", (chunk) => {
|
|
@@ -9836,17 +9886,19 @@ var GithubCopilotCliExecutor = class {
|
|
|
9836
9886
|
};
|
|
9837
9887
|
|
|
9838
9888
|
// ../../packages/serviceme-core/src/scheduled-tasks/executors/HttpRequestExecutor.ts
|
|
9839
|
-
var
|
|
9889
|
+
var DEFAULT_TIMEOUT_MS2 = 3e4;
|
|
9840
9890
|
var HttpRequestExecutor = class {
|
|
9841
9891
|
async execute(payload, abortSignal) {
|
|
9842
9892
|
const p = payload;
|
|
9843
|
-
const
|
|
9893
|
+
const timeoutMs = resolveConfiguredTimeoutMs(p.timeout, DEFAULT_TIMEOUT_MS2);
|
|
9844
9894
|
const ac = new AbortController();
|
|
9845
|
-
|
|
9895
|
+
let timedOut = false;
|
|
9896
|
+
const timer = timeoutMs != null ? setTimeout(() => {
|
|
9897
|
+
timedOut = true;
|
|
9846
9898
|
ac.abort();
|
|
9847
|
-
},
|
|
9899
|
+
}, timeoutMs) : void 0;
|
|
9848
9900
|
if (abortSignal?.aborted) {
|
|
9849
|
-
clearTimeout(timer);
|
|
9901
|
+
if (timer) clearTimeout(timer);
|
|
9850
9902
|
return { status: "cancelled", error: "Execution aborted" };
|
|
9851
9903
|
}
|
|
9852
9904
|
let externalAbort = false;
|
|
@@ -9854,7 +9906,7 @@ var HttpRequestExecutor = class {
|
|
|
9854
9906
|
"abort",
|
|
9855
9907
|
() => {
|
|
9856
9908
|
externalAbort = true;
|
|
9857
|
-
clearTimeout(timer);
|
|
9909
|
+
if (timer) clearTimeout(timer);
|
|
9858
9910
|
ac.abort();
|
|
9859
9911
|
},
|
|
9860
9912
|
{ once: true }
|
|
@@ -9866,7 +9918,7 @@ var HttpRequestExecutor = class {
|
|
|
9866
9918
|
body: p.body,
|
|
9867
9919
|
signal: ac.signal
|
|
9868
9920
|
});
|
|
9869
|
-
clearTimeout(timer);
|
|
9921
|
+
if (timer) clearTimeout(timer);
|
|
9870
9922
|
const body = await response.text();
|
|
9871
9923
|
if (response.ok) {
|
|
9872
9924
|
return {
|
|
@@ -9881,14 +9933,17 @@ ${body}`.trim()
|
|
|
9881
9933
|
${body}`.trim()
|
|
9882
9934
|
};
|
|
9883
9935
|
} catch (err) {
|
|
9884
|
-
clearTimeout(timer);
|
|
9936
|
+
if (timer) clearTimeout(timer);
|
|
9885
9937
|
if (err instanceof Error && err.name === "AbortError") {
|
|
9886
9938
|
if (externalAbort) {
|
|
9887
9939
|
return { status: "cancelled", error: "Execution cancelled" };
|
|
9888
9940
|
}
|
|
9941
|
+
if (!timedOut || timeoutMs == null) {
|
|
9942
|
+
return { status: "failure", error: err.message };
|
|
9943
|
+
}
|
|
9889
9944
|
return {
|
|
9890
9945
|
status: "timeout",
|
|
9891
|
-
error: `HTTP request timed out after ${
|
|
9946
|
+
error: `HTTP request timed out after ${timeoutMs / 1e3}s`
|
|
9892
9947
|
};
|
|
9893
9948
|
}
|
|
9894
9949
|
const message = err instanceof Error ? err.message : String(err);
|
|
@@ -9896,8 +9951,80 @@ ${body}`.trim()
|
|
|
9896
9951
|
}
|
|
9897
9952
|
}
|
|
9898
9953
|
};
|
|
9899
|
-
var DEFAULT_TIMEOUT3 = 6e4;
|
|
9900
9954
|
var MAX_OUTPUT_BYTES2 = 1024 * 1024;
|
|
9955
|
+
var DEFAULT_TIMEOUT_MS3 = 6e4;
|
|
9956
|
+
var POSIX_SHELL_CANDIDATES = ["bash.exe", "sh.exe"];
|
|
9957
|
+
function resolveShellExecution(script, options2 = {}) {
|
|
9958
|
+
const platform = options2.platform ?? process.platform;
|
|
9959
|
+
const env = options2.env ?? process.env;
|
|
9960
|
+
const fileExists = options2.fileExists ?? fs6__namespace.existsSync;
|
|
9961
|
+
if (platform === "win32") {
|
|
9962
|
+
const posixShell = usesPosixShellSyntax(script) ? findWindowsPosixShell(env, fileExists) : null;
|
|
9963
|
+
if (posixShell) {
|
|
9964
|
+
return {
|
|
9965
|
+
command: posixShell,
|
|
9966
|
+
args: ["-s"],
|
|
9967
|
+
stdinScript: script,
|
|
9968
|
+
outputEncoding: "utf8",
|
|
9969
|
+
shellKind: "posix"
|
|
9970
|
+
};
|
|
9971
|
+
}
|
|
9972
|
+
return {
|
|
9973
|
+
command: env.ComSpec ?? env.COMSPEC ?? "cmd.exe",
|
|
9974
|
+
args: ["/d", "/s", "/c", script],
|
|
9975
|
+
outputEncoding: "utf8",
|
|
9976
|
+
shellKind: "cmd"
|
|
9977
|
+
};
|
|
9978
|
+
}
|
|
9979
|
+
return {
|
|
9980
|
+
command: "sh",
|
|
9981
|
+
args: ["-s"],
|
|
9982
|
+
stdinScript: script,
|
|
9983
|
+
outputEncoding: "utf8",
|
|
9984
|
+
shellKind: "posix"
|
|
9985
|
+
};
|
|
9986
|
+
}
|
|
9987
|
+
function usesPosixShellSyntax(script) {
|
|
9988
|
+
return /\$\([^)]*\)|`[^`]*`/.test(script);
|
|
9989
|
+
}
|
|
9990
|
+
function findWindowsPosixShell(env, fileExists) {
|
|
9991
|
+
const explicitShell = env.SERVICEME_POSIX_SHELL;
|
|
9992
|
+
if (explicitShell && fileExists(explicitShell)) {
|
|
9993
|
+
return explicitShell;
|
|
9994
|
+
}
|
|
9995
|
+
const knownGitBashPaths = [
|
|
9996
|
+
"C:\\Program Files\\Git\\bin\\bash.exe",
|
|
9997
|
+
"C:\\Program Files\\Git\\usr\\bin\\bash.exe",
|
|
9998
|
+
"C:\\Program Files (x86)\\Git\\bin\\bash.exe",
|
|
9999
|
+
"C:\\Program Files (x86)\\Git\\usr\\bin\\bash.exe"
|
|
10000
|
+
];
|
|
10001
|
+
for (const candidate of knownGitBashPaths) {
|
|
10002
|
+
if (fileExists(candidate)) return candidate;
|
|
10003
|
+
}
|
|
10004
|
+
const pathValue = env.Path ?? env.PATH ?? "";
|
|
10005
|
+
for (const dir of pathValue.split(path5__namespace.win32.delimiter)) {
|
|
10006
|
+
if (!dir) continue;
|
|
10007
|
+
for (const executable of POSIX_SHELL_CANDIDATES) {
|
|
10008
|
+
const candidate = path5__namespace.win32.join(dir, executable);
|
|
10009
|
+
if (fileExists(candidate) && !isWindowsWslLauncher(candidate)) {
|
|
10010
|
+
return candidate;
|
|
10011
|
+
}
|
|
10012
|
+
}
|
|
10013
|
+
}
|
|
10014
|
+
return null;
|
|
10015
|
+
}
|
|
10016
|
+
function isWindowsWslLauncher(candidate) {
|
|
10017
|
+
const normalized = path5__namespace.win32.normalize(candidate).toLowerCase();
|
|
10018
|
+
return normalized.endsWith("\\windows\\system32\\bash.exe") || normalized.endsWith("\\windows\\syswow64\\bash.exe");
|
|
10019
|
+
}
|
|
10020
|
+
function writeDiagnostic2(message) {
|
|
10021
|
+
const logPath = process.env.SERVICEME_SCHEDULER_LOG_PATH;
|
|
10022
|
+
if (logPath) {
|
|
10023
|
+
fs6__namespace.appendFileSync(logPath, message);
|
|
10024
|
+
return;
|
|
10025
|
+
}
|
|
10026
|
+
process.stderr.write(message);
|
|
10027
|
+
}
|
|
9901
10028
|
var ShellExecutor = class {
|
|
9902
10029
|
async execute(payload, abortSignal) {
|
|
9903
10030
|
let output = "";
|
|
@@ -9913,7 +10040,7 @@ var ShellExecutor = class {
|
|
|
9913
10040
|
}
|
|
9914
10041
|
executeStreaming(payload, onOutput, abortSignal) {
|
|
9915
10042
|
const p = payload;
|
|
9916
|
-
const
|
|
10043
|
+
const timeoutMs = resolveConfiguredTimeoutMs(p.timeout, DEFAULT_TIMEOUT_MS3);
|
|
9917
10044
|
let resolve;
|
|
9918
10045
|
const resultPromise = new Promise((r) => {
|
|
9919
10046
|
resolve = r;
|
|
@@ -9922,7 +10049,7 @@ var ShellExecutor = class {
|
|
|
9922
10049
|
const settle = (result) => {
|
|
9923
10050
|
if (settled) return;
|
|
9924
10051
|
settled = true;
|
|
9925
|
-
clearTimeout(timer);
|
|
10052
|
+
if (timer) clearTimeout(timer);
|
|
9926
10053
|
resolve?.(result);
|
|
9927
10054
|
};
|
|
9928
10055
|
if (abortSignal?.aborted) {
|
|
@@ -9935,37 +10062,65 @@ var ShellExecutor = class {
|
|
|
9935
10062
|
}
|
|
9936
10063
|
};
|
|
9937
10064
|
}
|
|
9938
|
-
const
|
|
10065
|
+
const shellExecution = resolveShellExecution(p.script);
|
|
10066
|
+
const spawnOpts = {
|
|
9939
10067
|
cwd: p.cwd,
|
|
9940
|
-
stdio: ["ignore", "pipe", "pipe"]
|
|
9941
|
-
|
|
9942
|
-
|
|
10068
|
+
stdio: [shellExecution.stdinScript ? "pipe" : "ignore", "pipe", "pipe"],
|
|
10069
|
+
windowsHide: true
|
|
10070
|
+
};
|
|
10071
|
+
writeDiagnostic2(
|
|
10072
|
+
`[ShellExecutor] spawn:
|
|
10073
|
+
platform=${process.platform}
|
|
10074
|
+
shell=${shellExecution.shellKind}
|
|
10075
|
+
command=${shellExecution.command}
|
|
10076
|
+
args=${JSON.stringify(shellExecution.args.filter((a) => a !== p.script))}
|
|
10077
|
+
stdin=${shellExecution.stdinScript ? "true" : "false"}
|
|
10078
|
+
cwd=${p.cwd ?? "(default)"}
|
|
10079
|
+
timeout=${timeoutMs != null ? `${timeoutMs}ms` : "unlimited"}
|
|
10080
|
+
scriptLen=${p.script.length}
|
|
10081
|
+
windowsHide=true
|
|
10082
|
+
daemonPid=${process.pid}
|
|
10083
|
+
`
|
|
10084
|
+
);
|
|
10085
|
+
const child = child_process.spawn(shellExecution.command, shellExecution.args, spawnOpts);
|
|
10086
|
+
if (shellExecution.stdinScript && child.stdin) {
|
|
10087
|
+
child.stdin.end(shellExecution.stdinScript);
|
|
10088
|
+
}
|
|
10089
|
+
if (child.pid) {
|
|
10090
|
+
writeDiagnostic2(`[ShellExecutor] spawned child PID=${child.pid}
|
|
10091
|
+
`);
|
|
10092
|
+
}
|
|
10093
|
+
const timer = timeoutMs != null ? setTimeout(() => {
|
|
9943
10094
|
child.kill("SIGTERM");
|
|
9944
10095
|
setTimeout(() => {
|
|
9945
10096
|
if (!child.killed) child.kill("SIGKILL");
|
|
9946
10097
|
}, 5e3);
|
|
9947
10098
|
settle({
|
|
9948
10099
|
status: "timeout",
|
|
9949
|
-
error: `Shell execution timed out after ${
|
|
10100
|
+
error: `Shell execution timed out after ${timeoutMs / 1e3}s`
|
|
9950
10101
|
});
|
|
9951
|
-
},
|
|
10102
|
+
}, timeoutMs) : void 0;
|
|
9952
10103
|
let stdoutBuf = "";
|
|
9953
10104
|
let stderrBuf = "";
|
|
9954
|
-
child.stdout
|
|
9955
|
-
const data = chunk.toString();
|
|
10105
|
+
child.stdout?.on("data", (chunk) => {
|
|
10106
|
+
const data = chunk.toString(shellExecution.outputEncoding);
|
|
9956
10107
|
stdoutBuf += data;
|
|
9957
10108
|
if (stdoutBuf.length > MAX_OUTPUT_BYTES2)
|
|
9958
10109
|
stdoutBuf = stdoutBuf.slice(-MAX_OUTPUT_BYTES2);
|
|
9959
10110
|
onOutput("stdout", data);
|
|
9960
10111
|
});
|
|
9961
|
-
child.stderr
|
|
9962
|
-
const data = chunk.toString();
|
|
10112
|
+
child.stderr?.on("data", (chunk) => {
|
|
10113
|
+
const data = chunk.toString(shellExecution.outputEncoding);
|
|
9963
10114
|
stderrBuf += data;
|
|
9964
10115
|
if (stderrBuf.length > MAX_OUTPUT_BYTES2)
|
|
9965
10116
|
stderrBuf = stderrBuf.slice(-MAX_OUTPUT_BYTES2);
|
|
9966
10117
|
onOutput("stderr", data);
|
|
9967
10118
|
});
|
|
9968
10119
|
child.on("close", (code) => {
|
|
10120
|
+
writeDiagnostic2(
|
|
10121
|
+
`[ShellExecutor] child PID=${child.pid} exited: code=${code}
|
|
10122
|
+
`
|
|
10123
|
+
);
|
|
9969
10124
|
if (code === 0) {
|
|
9970
10125
|
settle({ status: "success", output: stdoutBuf || void 0 });
|
|
9971
10126
|
} else {
|
|
@@ -10003,10 +10158,65 @@ var executors = {
|
|
|
10003
10158
|
github_copilot_cli: new GithubCopilotCliExecutor()
|
|
10004
10159
|
};
|
|
10005
10160
|
function getExecutor(taskType) {
|
|
10006
|
-
|
|
10161
|
+
const executor = executors[taskType];
|
|
10162
|
+
if (!executor) {
|
|
10163
|
+
throw new Error(`Unsupported bridge task type: ${taskType}`);
|
|
10164
|
+
}
|
|
10165
|
+
return executor;
|
|
10166
|
+
}
|
|
10167
|
+
function isRecord3(value) {
|
|
10168
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
10169
|
+
}
|
|
10170
|
+
function requireNonEmptyString(payload, field, taskType) {
|
|
10171
|
+
if (!isRecord3(payload) || typeof payload[field] !== "string" || !payload[field].trim()) {
|
|
10172
|
+
throw createServicemeError(
|
|
10173
|
+
"invalid_payload",
|
|
10174
|
+
`${taskType} payload ${field} is required`
|
|
10175
|
+
);
|
|
10176
|
+
}
|
|
10177
|
+
}
|
|
10178
|
+
function validateTaskPayload(taskType, payload) {
|
|
10179
|
+
switch (taskType) {
|
|
10180
|
+
case "command":
|
|
10181
|
+
requireNonEmptyString(payload, "command", taskType);
|
|
10182
|
+
return;
|
|
10183
|
+
case "shell":
|
|
10184
|
+
requireNonEmptyString(payload, "script", taskType);
|
|
10185
|
+
return;
|
|
10186
|
+
case "http_request":
|
|
10187
|
+
requireNonEmptyString(payload, "url", taskType);
|
|
10188
|
+
requireNonEmptyString(payload, "method", taskType);
|
|
10189
|
+
return;
|
|
10190
|
+
case "github_copilot_cli":
|
|
10191
|
+
requireNonEmptyString(payload, "prompt", taskType);
|
|
10192
|
+
return;
|
|
10193
|
+
}
|
|
10007
10194
|
}
|
|
10008
10195
|
|
|
10009
10196
|
// ../../packages/serviceme-core/src/scheduled-tasks/TaskExecutionEngine.ts
|
|
10197
|
+
function hasNonEmptyString(value) {
|
|
10198
|
+
return typeof value === "string" && value.trim().length > 0;
|
|
10199
|
+
}
|
|
10200
|
+
function resolveTaskExecutionPayload(taskType, payload, workspacePath) {
|
|
10201
|
+
if (!hasNonEmptyString(workspacePath)) {
|
|
10202
|
+
return payload;
|
|
10203
|
+
}
|
|
10204
|
+
if (taskType === "shell") {
|
|
10205
|
+
const shellPayload = payload;
|
|
10206
|
+
if (hasNonEmptyString(shellPayload.cwd)) {
|
|
10207
|
+
return shellPayload;
|
|
10208
|
+
}
|
|
10209
|
+
return { ...shellPayload, cwd: workspacePath };
|
|
10210
|
+
}
|
|
10211
|
+
if (taskType === "github_copilot_cli") {
|
|
10212
|
+
const copilotPayload = payload;
|
|
10213
|
+
if (hasNonEmptyString(copilotPayload.workspace)) {
|
|
10214
|
+
return copilotPayload;
|
|
10215
|
+
}
|
|
10216
|
+
return { ...copilotPayload, workspace: workspacePath };
|
|
10217
|
+
}
|
|
10218
|
+
return payload;
|
|
10219
|
+
}
|
|
10010
10220
|
var TaskExecutionEngine = class {
|
|
10011
10221
|
constructor(getExecutor2) {
|
|
10012
10222
|
this.getExecutor = getExecutor2;
|
|
@@ -10027,7 +10237,6 @@ var TaskExecutionEngine = class {
|
|
|
10027
10237
|
);
|
|
10028
10238
|
}
|
|
10029
10239
|
}
|
|
10030
|
-
const executor = this.getExecutor(snapshot.type);
|
|
10031
10240
|
const startedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
10032
10241
|
if (!this.taskExecutions.has(snapshot.taskId)) {
|
|
10033
10242
|
this.taskExecutions.set(snapshot.taskId, /* @__PURE__ */ new Set());
|
|
@@ -10047,10 +10256,17 @@ var TaskExecutionEngine = class {
|
|
|
10047
10256
|
startedAt
|
|
10048
10257
|
});
|
|
10049
10258
|
try {
|
|
10259
|
+
const executionPayload = resolveTaskExecutionPayload(
|
|
10260
|
+
snapshot.type,
|
|
10261
|
+
snapshot.payload,
|
|
10262
|
+
snapshot.workspacePath
|
|
10263
|
+
);
|
|
10264
|
+
validateTaskPayload(snapshot.type, executionPayload);
|
|
10265
|
+
const executor = this.getExecutor(snapshot.type);
|
|
10050
10266
|
let result;
|
|
10051
10267
|
if (isStreamingTaskExecutor(executor)) {
|
|
10052
10268
|
const handle = executor.executeStreaming(
|
|
10053
|
-
|
|
10269
|
+
executionPayload,
|
|
10054
10270
|
(stream, data) => {
|
|
10055
10271
|
this.listener?.onOutput({
|
|
10056
10272
|
executionId: snapshot.executionId,
|
|
@@ -10066,7 +10282,7 @@ var TaskExecutionEngine = class {
|
|
|
10066
10282
|
};
|
|
10067
10283
|
result = await handle.result;
|
|
10068
10284
|
} else {
|
|
10069
|
-
result = await executor.execute(
|
|
10285
|
+
result = await executor.execute(executionPayload, ac.signal);
|
|
10070
10286
|
}
|
|
10071
10287
|
const log = {
|
|
10072
10288
|
id: snapshot.executionId,
|