@serviceme/devtools-cli 0.1.3 → 0.1.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/bridgeServer.js +306 -83
- package/dist/cli.js +715 -327
- 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.5";
|
|
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,69 @@ __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
|
+
}
|
|
9763
|
+
function resolveGithubCopilotCliExecution(payload) {
|
|
9764
|
+
const args = ["copilot", "prompt", "--prompt", payload.prompt];
|
|
9765
|
+
if (payload.autopilot) {
|
|
9766
|
+
args.push("--autopilot");
|
|
9767
|
+
}
|
|
9768
|
+
if (payload.allowTools && payload.allowTools.length > 0) {
|
|
9769
|
+
args.push("--allow-tools", payload.allowTools.join(","));
|
|
9770
|
+
}
|
|
9771
|
+
if (payload.model) {
|
|
9772
|
+
args.push("--model", payload.model);
|
|
9773
|
+
}
|
|
9774
|
+
if (payload.agent) {
|
|
9775
|
+
args.push("--agent", payload.agent);
|
|
9776
|
+
}
|
|
9777
|
+
args.push("--timeout", String(payload.timeout ?? 0));
|
|
9778
|
+
return {
|
|
9779
|
+
command: "serviceme",
|
|
9780
|
+
args,
|
|
9781
|
+
cwd: payload.workspace,
|
|
9782
|
+
timeoutMs: resolveConfiguredTimeoutMs(payload.timeout, DEFAULT_TIMEOUT_MS),
|
|
9783
|
+
diagnosticArgs: redactArgs(args),
|
|
9784
|
+
promptLen: payload.prompt.length
|
|
9785
|
+
};
|
|
9786
|
+
}
|
|
9722
9787
|
var GithubCopilotCliExecutor = class {
|
|
9723
9788
|
async execute(payload, abortSignal) {
|
|
9724
9789
|
const authenticated = await isCopilotAuthenticated();
|
|
@@ -9741,7 +9806,7 @@ var GithubCopilotCliExecutor = class {
|
|
|
9741
9806
|
}
|
|
9742
9807
|
executeStreaming(payload, onOutput, abortSignal) {
|
|
9743
9808
|
const p = payload;
|
|
9744
|
-
const
|
|
9809
|
+
const execution = resolveGithubCopilotCliExecution(p);
|
|
9745
9810
|
let resolve;
|
|
9746
9811
|
const resultPromise = new Promise((r) => {
|
|
9747
9812
|
resolve = r;
|
|
@@ -9750,7 +9815,7 @@ var GithubCopilotCliExecutor = class {
|
|
|
9750
9815
|
const settle = (result) => {
|
|
9751
9816
|
if (settled) return;
|
|
9752
9817
|
settled = true;
|
|
9753
|
-
clearTimeout(timer);
|
|
9818
|
+
if (timer) clearTimeout(timer);
|
|
9754
9819
|
resolve?.(result);
|
|
9755
9820
|
};
|
|
9756
9821
|
if (abortSignal?.aborted) {
|
|
@@ -9763,36 +9828,32 @@ var GithubCopilotCliExecutor = class {
|
|
|
9763
9828
|
}
|
|
9764
9829
|
};
|
|
9765
9830
|
}
|
|
9766
|
-
|
|
9767
|
-
|
|
9768
|
-
|
|
9769
|
-
|
|
9770
|
-
|
|
9771
|
-
|
|
9772
|
-
|
|
9773
|
-
|
|
9774
|
-
args.push("--model", p.model);
|
|
9775
|
-
}
|
|
9776
|
-
if (p.agent) {
|
|
9777
|
-
args.push("--agent", p.agent);
|
|
9778
|
-
}
|
|
9779
|
-
if (p.timeout != null) {
|
|
9780
|
-
args.push("--timeout", String(p.timeout));
|
|
9781
|
-
}
|
|
9782
|
-
const child = child_process.spawn("serviceme", args, {
|
|
9783
|
-
cwd: p.workspace,
|
|
9784
|
-
stdio: ["ignore", "pipe", "pipe"]
|
|
9831
|
+
writeDiagnostic(
|
|
9832
|
+
`[GithubCopilotCliExecutor] spawn: command=${execution.command}, args=${JSON.stringify(execution.diagnosticArgs)}, promptLen=${execution.promptLen}, cwd=${execution.cwd ?? "(default)"}, platform=${process.platform}, windowsHide=true, pid=${process.pid}
|
|
9833
|
+
`
|
|
9834
|
+
);
|
|
9835
|
+
const child = child_process.spawn(execution.command, execution.args, {
|
|
9836
|
+
cwd: execution.cwd,
|
|
9837
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
9838
|
+
windowsHide: true
|
|
9785
9839
|
});
|
|
9786
|
-
|
|
9840
|
+
if (child.pid) {
|
|
9841
|
+
writeDiagnostic(
|
|
9842
|
+
`[GithubCopilotCliExecutor] spawned child PID=${child.pid}
|
|
9843
|
+
`
|
|
9844
|
+
);
|
|
9845
|
+
}
|
|
9846
|
+
const timeoutMs = execution.timeoutMs;
|
|
9847
|
+
const timer = timeoutMs != null ? setTimeout(() => {
|
|
9787
9848
|
child.kill("SIGTERM");
|
|
9788
9849
|
setTimeout(() => {
|
|
9789
9850
|
if (!child.killed) child.kill("SIGKILL");
|
|
9790
9851
|
}, 5e3);
|
|
9791
9852
|
settle({
|
|
9792
9853
|
status: "timeout",
|
|
9793
|
-
error: `Copilot CLI execution timed out after ${
|
|
9854
|
+
error: `Copilot CLI execution timed out after ${timeoutMs / 1e3}s`
|
|
9794
9855
|
});
|
|
9795
|
-
},
|
|
9856
|
+
}, timeoutMs) : void 0;
|
|
9796
9857
|
let stdoutBuf = "";
|
|
9797
9858
|
let stderrBuf = "";
|
|
9798
9859
|
child.stdout.on("data", (chunk) => {
|
|
@@ -9836,17 +9897,19 @@ var GithubCopilotCliExecutor = class {
|
|
|
9836
9897
|
};
|
|
9837
9898
|
|
|
9838
9899
|
// ../../packages/serviceme-core/src/scheduled-tasks/executors/HttpRequestExecutor.ts
|
|
9839
|
-
var
|
|
9900
|
+
var DEFAULT_TIMEOUT_MS2 = 3e4;
|
|
9840
9901
|
var HttpRequestExecutor = class {
|
|
9841
9902
|
async execute(payload, abortSignal) {
|
|
9842
9903
|
const p = payload;
|
|
9843
|
-
const
|
|
9904
|
+
const timeoutMs = resolveConfiguredTimeoutMs(p.timeout, DEFAULT_TIMEOUT_MS2);
|
|
9844
9905
|
const ac = new AbortController();
|
|
9845
|
-
|
|
9906
|
+
let timedOut = false;
|
|
9907
|
+
const timer = timeoutMs != null ? setTimeout(() => {
|
|
9908
|
+
timedOut = true;
|
|
9846
9909
|
ac.abort();
|
|
9847
|
-
},
|
|
9910
|
+
}, timeoutMs) : void 0;
|
|
9848
9911
|
if (abortSignal?.aborted) {
|
|
9849
|
-
clearTimeout(timer);
|
|
9912
|
+
if (timer) clearTimeout(timer);
|
|
9850
9913
|
return { status: "cancelled", error: "Execution aborted" };
|
|
9851
9914
|
}
|
|
9852
9915
|
let externalAbort = false;
|
|
@@ -9854,7 +9917,7 @@ var HttpRequestExecutor = class {
|
|
|
9854
9917
|
"abort",
|
|
9855
9918
|
() => {
|
|
9856
9919
|
externalAbort = true;
|
|
9857
|
-
clearTimeout(timer);
|
|
9920
|
+
if (timer) clearTimeout(timer);
|
|
9858
9921
|
ac.abort();
|
|
9859
9922
|
},
|
|
9860
9923
|
{ once: true }
|
|
@@ -9866,7 +9929,7 @@ var HttpRequestExecutor = class {
|
|
|
9866
9929
|
body: p.body,
|
|
9867
9930
|
signal: ac.signal
|
|
9868
9931
|
});
|
|
9869
|
-
clearTimeout(timer);
|
|
9932
|
+
if (timer) clearTimeout(timer);
|
|
9870
9933
|
const body = await response.text();
|
|
9871
9934
|
if (response.ok) {
|
|
9872
9935
|
return {
|
|
@@ -9881,14 +9944,17 @@ ${body}`.trim()
|
|
|
9881
9944
|
${body}`.trim()
|
|
9882
9945
|
};
|
|
9883
9946
|
} catch (err) {
|
|
9884
|
-
clearTimeout(timer);
|
|
9947
|
+
if (timer) clearTimeout(timer);
|
|
9885
9948
|
if (err instanceof Error && err.name === "AbortError") {
|
|
9886
9949
|
if (externalAbort) {
|
|
9887
9950
|
return { status: "cancelled", error: "Execution cancelled" };
|
|
9888
9951
|
}
|
|
9952
|
+
if (!timedOut || timeoutMs == null) {
|
|
9953
|
+
return { status: "failure", error: err.message };
|
|
9954
|
+
}
|
|
9889
9955
|
return {
|
|
9890
9956
|
status: "timeout",
|
|
9891
|
-
error: `HTTP request timed out after ${
|
|
9957
|
+
error: `HTTP request timed out after ${timeoutMs / 1e3}s`
|
|
9892
9958
|
};
|
|
9893
9959
|
}
|
|
9894
9960
|
const message = err instanceof Error ? err.message : String(err);
|
|
@@ -9896,8 +9962,80 @@ ${body}`.trim()
|
|
|
9896
9962
|
}
|
|
9897
9963
|
}
|
|
9898
9964
|
};
|
|
9899
|
-
var DEFAULT_TIMEOUT3 = 6e4;
|
|
9900
9965
|
var MAX_OUTPUT_BYTES2 = 1024 * 1024;
|
|
9966
|
+
var DEFAULT_TIMEOUT_MS3 = 6e4;
|
|
9967
|
+
var POSIX_SHELL_CANDIDATES = ["bash.exe", "sh.exe"];
|
|
9968
|
+
function resolveShellExecution(script, options2 = {}) {
|
|
9969
|
+
const platform = options2.platform ?? process.platform;
|
|
9970
|
+
const env = options2.env ?? process.env;
|
|
9971
|
+
const fileExists = options2.fileExists ?? fs6__namespace.existsSync;
|
|
9972
|
+
if (platform === "win32") {
|
|
9973
|
+
const posixShell = usesPosixShellSyntax(script) ? findWindowsPosixShell(env, fileExists) : null;
|
|
9974
|
+
if (posixShell) {
|
|
9975
|
+
return {
|
|
9976
|
+
command: posixShell,
|
|
9977
|
+
args: ["-s"],
|
|
9978
|
+
stdinScript: script,
|
|
9979
|
+
outputEncoding: "utf8",
|
|
9980
|
+
shellKind: "posix"
|
|
9981
|
+
};
|
|
9982
|
+
}
|
|
9983
|
+
return {
|
|
9984
|
+
command: env.ComSpec ?? env.COMSPEC ?? "cmd.exe",
|
|
9985
|
+
args: ["/d", "/s", "/c", script],
|
|
9986
|
+
outputEncoding: "utf8",
|
|
9987
|
+
shellKind: "cmd"
|
|
9988
|
+
};
|
|
9989
|
+
}
|
|
9990
|
+
return {
|
|
9991
|
+
command: "sh",
|
|
9992
|
+
args: ["-s"],
|
|
9993
|
+
stdinScript: script,
|
|
9994
|
+
outputEncoding: "utf8",
|
|
9995
|
+
shellKind: "posix"
|
|
9996
|
+
};
|
|
9997
|
+
}
|
|
9998
|
+
function usesPosixShellSyntax(script) {
|
|
9999
|
+
return /\$\([^)]*\)|`[^`]*`/.test(script);
|
|
10000
|
+
}
|
|
10001
|
+
function findWindowsPosixShell(env, fileExists) {
|
|
10002
|
+
const explicitShell = env.SERVICEME_POSIX_SHELL;
|
|
10003
|
+
if (explicitShell && fileExists(explicitShell)) {
|
|
10004
|
+
return explicitShell;
|
|
10005
|
+
}
|
|
10006
|
+
const knownGitBashPaths = [
|
|
10007
|
+
"C:\\Program Files\\Git\\bin\\bash.exe",
|
|
10008
|
+
"C:\\Program Files\\Git\\usr\\bin\\bash.exe",
|
|
10009
|
+
"C:\\Program Files (x86)\\Git\\bin\\bash.exe",
|
|
10010
|
+
"C:\\Program Files (x86)\\Git\\usr\\bin\\bash.exe"
|
|
10011
|
+
];
|
|
10012
|
+
for (const candidate of knownGitBashPaths) {
|
|
10013
|
+
if (fileExists(candidate)) return candidate;
|
|
10014
|
+
}
|
|
10015
|
+
const pathValue = env.Path ?? env.PATH ?? "";
|
|
10016
|
+
for (const dir of pathValue.split(path5__namespace.win32.delimiter)) {
|
|
10017
|
+
if (!dir) continue;
|
|
10018
|
+
for (const executable of POSIX_SHELL_CANDIDATES) {
|
|
10019
|
+
const candidate = path5__namespace.win32.join(dir, executable);
|
|
10020
|
+
if (fileExists(candidate) && !isWindowsWslLauncher(candidate)) {
|
|
10021
|
+
return candidate;
|
|
10022
|
+
}
|
|
10023
|
+
}
|
|
10024
|
+
}
|
|
10025
|
+
return null;
|
|
10026
|
+
}
|
|
10027
|
+
function isWindowsWslLauncher(candidate) {
|
|
10028
|
+
const normalized = path5__namespace.win32.normalize(candidate).toLowerCase();
|
|
10029
|
+
return normalized.endsWith("\\windows\\system32\\bash.exe") || normalized.endsWith("\\windows\\syswow64\\bash.exe");
|
|
10030
|
+
}
|
|
10031
|
+
function writeDiagnostic2(message) {
|
|
10032
|
+
const logPath = process.env.SERVICEME_SCHEDULER_LOG_PATH;
|
|
10033
|
+
if (logPath) {
|
|
10034
|
+
fs6__namespace.appendFileSync(logPath, message);
|
|
10035
|
+
return;
|
|
10036
|
+
}
|
|
10037
|
+
process.stderr.write(message);
|
|
10038
|
+
}
|
|
9901
10039
|
var ShellExecutor = class {
|
|
9902
10040
|
async execute(payload, abortSignal) {
|
|
9903
10041
|
let output = "";
|
|
@@ -9913,7 +10051,7 @@ var ShellExecutor = class {
|
|
|
9913
10051
|
}
|
|
9914
10052
|
executeStreaming(payload, onOutput, abortSignal) {
|
|
9915
10053
|
const p = payload;
|
|
9916
|
-
const
|
|
10054
|
+
const timeoutMs = resolveConfiguredTimeoutMs(p.timeout, DEFAULT_TIMEOUT_MS3);
|
|
9917
10055
|
let resolve;
|
|
9918
10056
|
const resultPromise = new Promise((r) => {
|
|
9919
10057
|
resolve = r;
|
|
@@ -9922,7 +10060,7 @@ var ShellExecutor = class {
|
|
|
9922
10060
|
const settle = (result) => {
|
|
9923
10061
|
if (settled) return;
|
|
9924
10062
|
settled = true;
|
|
9925
|
-
clearTimeout(timer);
|
|
10063
|
+
if (timer) clearTimeout(timer);
|
|
9926
10064
|
resolve?.(result);
|
|
9927
10065
|
};
|
|
9928
10066
|
if (abortSignal?.aborted) {
|
|
@@ -9935,37 +10073,65 @@ var ShellExecutor = class {
|
|
|
9935
10073
|
}
|
|
9936
10074
|
};
|
|
9937
10075
|
}
|
|
9938
|
-
const
|
|
10076
|
+
const shellExecution = resolveShellExecution(p.script);
|
|
10077
|
+
const spawnOpts = {
|
|
9939
10078
|
cwd: p.cwd,
|
|
9940
|
-
stdio: ["ignore", "pipe", "pipe"]
|
|
9941
|
-
|
|
9942
|
-
|
|
10079
|
+
stdio: [shellExecution.stdinScript ? "pipe" : "ignore", "pipe", "pipe"],
|
|
10080
|
+
windowsHide: true
|
|
10081
|
+
};
|
|
10082
|
+
writeDiagnostic2(
|
|
10083
|
+
`[ShellExecutor] spawn:
|
|
10084
|
+
platform=${process.platform}
|
|
10085
|
+
shell=${shellExecution.shellKind}
|
|
10086
|
+
command=${shellExecution.command}
|
|
10087
|
+
args=${JSON.stringify(shellExecution.args.filter((a) => a !== p.script))}
|
|
10088
|
+
stdin=${shellExecution.stdinScript ? "true" : "false"}
|
|
10089
|
+
cwd=${p.cwd ?? "(default)"}
|
|
10090
|
+
timeout=${timeoutMs != null ? `${timeoutMs}ms` : "unlimited"}
|
|
10091
|
+
scriptLen=${p.script.length}
|
|
10092
|
+
windowsHide=true
|
|
10093
|
+
daemonPid=${process.pid}
|
|
10094
|
+
`
|
|
10095
|
+
);
|
|
10096
|
+
const child = child_process.spawn(shellExecution.command, shellExecution.args, spawnOpts);
|
|
10097
|
+
if (shellExecution.stdinScript && child.stdin) {
|
|
10098
|
+
child.stdin.end(shellExecution.stdinScript);
|
|
10099
|
+
}
|
|
10100
|
+
if (child.pid) {
|
|
10101
|
+
writeDiagnostic2(`[ShellExecutor] spawned child PID=${child.pid}
|
|
10102
|
+
`);
|
|
10103
|
+
}
|
|
10104
|
+
const timer = timeoutMs != null ? setTimeout(() => {
|
|
9943
10105
|
child.kill("SIGTERM");
|
|
9944
10106
|
setTimeout(() => {
|
|
9945
10107
|
if (!child.killed) child.kill("SIGKILL");
|
|
9946
10108
|
}, 5e3);
|
|
9947
10109
|
settle({
|
|
9948
10110
|
status: "timeout",
|
|
9949
|
-
error: `Shell execution timed out after ${
|
|
10111
|
+
error: `Shell execution timed out after ${timeoutMs / 1e3}s`
|
|
9950
10112
|
});
|
|
9951
|
-
},
|
|
10113
|
+
}, timeoutMs) : void 0;
|
|
9952
10114
|
let stdoutBuf = "";
|
|
9953
10115
|
let stderrBuf = "";
|
|
9954
|
-
child.stdout
|
|
9955
|
-
const data = chunk.toString();
|
|
10116
|
+
child.stdout?.on("data", (chunk) => {
|
|
10117
|
+
const data = chunk.toString(shellExecution.outputEncoding);
|
|
9956
10118
|
stdoutBuf += data;
|
|
9957
10119
|
if (stdoutBuf.length > MAX_OUTPUT_BYTES2)
|
|
9958
10120
|
stdoutBuf = stdoutBuf.slice(-MAX_OUTPUT_BYTES2);
|
|
9959
10121
|
onOutput("stdout", data);
|
|
9960
10122
|
});
|
|
9961
|
-
child.stderr
|
|
9962
|
-
const data = chunk.toString();
|
|
10123
|
+
child.stderr?.on("data", (chunk) => {
|
|
10124
|
+
const data = chunk.toString(shellExecution.outputEncoding);
|
|
9963
10125
|
stderrBuf += data;
|
|
9964
10126
|
if (stderrBuf.length > MAX_OUTPUT_BYTES2)
|
|
9965
10127
|
stderrBuf = stderrBuf.slice(-MAX_OUTPUT_BYTES2);
|
|
9966
10128
|
onOutput("stderr", data);
|
|
9967
10129
|
});
|
|
9968
10130
|
child.on("close", (code) => {
|
|
10131
|
+
writeDiagnostic2(
|
|
10132
|
+
`[ShellExecutor] child PID=${child.pid} exited: code=${code}
|
|
10133
|
+
`
|
|
10134
|
+
);
|
|
9969
10135
|
if (code === 0) {
|
|
9970
10136
|
settle({ status: "success", output: stdoutBuf || void 0 });
|
|
9971
10137
|
} else {
|
|
@@ -10009,8 +10175,59 @@ function getExecutor(taskType) {
|
|
|
10009
10175
|
}
|
|
10010
10176
|
return executor;
|
|
10011
10177
|
}
|
|
10178
|
+
function isRecord3(value) {
|
|
10179
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
10180
|
+
}
|
|
10181
|
+
function requireNonEmptyString(payload, field, taskType) {
|
|
10182
|
+
if (!isRecord3(payload) || typeof payload[field] !== "string" || !payload[field].trim()) {
|
|
10183
|
+
throw createServicemeError(
|
|
10184
|
+
"invalid_payload",
|
|
10185
|
+
`${taskType} payload ${field} is required`
|
|
10186
|
+
);
|
|
10187
|
+
}
|
|
10188
|
+
}
|
|
10189
|
+
function validateTaskPayload(taskType, payload) {
|
|
10190
|
+
switch (taskType) {
|
|
10191
|
+
case "command":
|
|
10192
|
+
requireNonEmptyString(payload, "command", taskType);
|
|
10193
|
+
return;
|
|
10194
|
+
case "shell":
|
|
10195
|
+
requireNonEmptyString(payload, "script", taskType);
|
|
10196
|
+
return;
|
|
10197
|
+
case "http_request":
|
|
10198
|
+
requireNonEmptyString(payload, "url", taskType);
|
|
10199
|
+
requireNonEmptyString(payload, "method", taskType);
|
|
10200
|
+
return;
|
|
10201
|
+
case "github_copilot_cli":
|
|
10202
|
+
requireNonEmptyString(payload, "prompt", taskType);
|
|
10203
|
+
return;
|
|
10204
|
+
}
|
|
10205
|
+
}
|
|
10012
10206
|
|
|
10013
10207
|
// ../../packages/serviceme-core/src/scheduled-tasks/TaskExecutionEngine.ts
|
|
10208
|
+
function hasNonEmptyString(value) {
|
|
10209
|
+
return typeof value === "string" && value.trim().length > 0;
|
|
10210
|
+
}
|
|
10211
|
+
function resolveTaskExecutionPayload(taskType, payload, workspacePath) {
|
|
10212
|
+
if (!hasNonEmptyString(workspacePath)) {
|
|
10213
|
+
return payload;
|
|
10214
|
+
}
|
|
10215
|
+
if (taskType === "shell") {
|
|
10216
|
+
const shellPayload = payload;
|
|
10217
|
+
if (hasNonEmptyString(shellPayload.cwd)) {
|
|
10218
|
+
return shellPayload;
|
|
10219
|
+
}
|
|
10220
|
+
return { ...shellPayload, cwd: workspacePath };
|
|
10221
|
+
}
|
|
10222
|
+
if (taskType === "github_copilot_cli") {
|
|
10223
|
+
const copilotPayload = payload;
|
|
10224
|
+
if (hasNonEmptyString(copilotPayload.workspace)) {
|
|
10225
|
+
return copilotPayload;
|
|
10226
|
+
}
|
|
10227
|
+
return { ...copilotPayload, workspace: workspacePath };
|
|
10228
|
+
}
|
|
10229
|
+
return payload;
|
|
10230
|
+
}
|
|
10014
10231
|
var TaskExecutionEngine = class {
|
|
10015
10232
|
constructor(getExecutor2) {
|
|
10016
10233
|
this.getExecutor = getExecutor2;
|
|
@@ -10031,7 +10248,6 @@ var TaskExecutionEngine = class {
|
|
|
10031
10248
|
);
|
|
10032
10249
|
}
|
|
10033
10250
|
}
|
|
10034
|
-
const executor = this.getExecutor(snapshot.type);
|
|
10035
10251
|
const startedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
10036
10252
|
if (!this.taskExecutions.has(snapshot.taskId)) {
|
|
10037
10253
|
this.taskExecutions.set(snapshot.taskId, /* @__PURE__ */ new Set());
|
|
@@ -10051,10 +10267,17 @@ var TaskExecutionEngine = class {
|
|
|
10051
10267
|
startedAt
|
|
10052
10268
|
});
|
|
10053
10269
|
try {
|
|
10270
|
+
const executionPayload = resolveTaskExecutionPayload(
|
|
10271
|
+
snapshot.type,
|
|
10272
|
+
snapshot.payload,
|
|
10273
|
+
snapshot.workspacePath
|
|
10274
|
+
);
|
|
10275
|
+
validateTaskPayload(snapshot.type, executionPayload);
|
|
10276
|
+
const executor = this.getExecutor(snapshot.type);
|
|
10054
10277
|
let result;
|
|
10055
10278
|
if (isStreamingTaskExecutor(executor)) {
|
|
10056
10279
|
const handle = executor.executeStreaming(
|
|
10057
|
-
|
|
10280
|
+
executionPayload,
|
|
10058
10281
|
(stream, data) => {
|
|
10059
10282
|
this.listener?.onOutput({
|
|
10060
10283
|
executionId: snapshot.executionId,
|
|
@@ -10070,7 +10293,7 @@ var TaskExecutionEngine = class {
|
|
|
10070
10293
|
};
|
|
10071
10294
|
result = await handle.result;
|
|
10072
10295
|
} else {
|
|
10073
|
-
result = await executor.execute(
|
|
10296
|
+
result = await executor.execute(executionPayload, ac.signal);
|
|
10074
10297
|
}
|
|
10075
10298
|
const log = {
|
|
10076
10299
|
id: snapshot.executionId,
|