meshy-node 0.9.10 → 0.10.1
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/README.md +1 -1
- package/dashboard/assets/DashboardPage-BJhmjsGE.js +154 -0
- package/dashboard/assets/{DashboardShared-DfyXgvZj.js → DashboardShared-BvbuoP9b.js} +1 -1
- package/dashboard/assets/{DiffTab-3q3jwsm4.js → DiffTab-Bd3CsYCX.js} +4 -4
- package/dashboard/assets/{FilesTab-jB5PuAMB.js → FilesTab-Dr_X6U7n.js} +2 -2
- package/dashboard/assets/{MarkdownPreviewFrame-B1baNbJd.js → MarkdownPreviewFrame-xP27WQ5V.js} +1 -1
- package/dashboard/assets/{PreviewTab-5-N4l7V3.js → PreviewTab-DtBT527u.js} +2 -2
- package/dashboard/assets/{SharedConversationPage-D8TaynWN.js → SharedConversationPage-Cp-wV5Db.js} +2 -2
- package/dashboard/assets/{file-BO3_w-is.js → file-BoEYGA7g.js} +1 -1
- package/dashboard/assets/index-BZlZVBzf.js +346 -0
- package/dashboard/assets/index-z8uCUOPA.css +1 -0
- package/dashboard/index.html +2 -2
- package/main.cjs +588 -188
- package/package.json +1 -1
- package/runtime-metadata.json +4 -4
- package/dashboard/assets/DashboardPage-DL4PakzK.js +0 -154
- package/dashboard/assets/index-C8zHV8VY.js +0 -341
- package/dashboard/assets/index-Dsqqe-oH.css +0 -1
package/main.cjs
CHANGED
|
@@ -7021,7 +7021,7 @@ var require_dist = __commonJS({
|
|
|
7021
7021
|
};
|
|
7022
7022
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
7023
7023
|
exports2.Agent = void 0;
|
|
7024
|
-
var
|
|
7024
|
+
var net2 = __importStar(require("net"));
|
|
7025
7025
|
var http6 = __importStar(require("http"));
|
|
7026
7026
|
var https_1 = require("https");
|
|
7027
7027
|
__exportStar(require_helpers(), exports2);
|
|
@@ -7061,7 +7061,7 @@ var require_dist = __commonJS({
|
|
|
7061
7061
|
if (!this.sockets[name2]) {
|
|
7062
7062
|
this.sockets[name2] = [];
|
|
7063
7063
|
}
|
|
7064
|
-
const fakeSocket = new
|
|
7064
|
+
const fakeSocket = new net2.Socket({ writable: false });
|
|
7065
7065
|
this.sockets[name2].push(fakeSocket);
|
|
7066
7066
|
this.totalSocketCount++;
|
|
7067
7067
|
return fakeSocket;
|
|
@@ -7275,7 +7275,7 @@ var require_dist2 = __commonJS({
|
|
|
7275
7275
|
};
|
|
7276
7276
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
7277
7277
|
exports2.HttpsProxyAgent = void 0;
|
|
7278
|
-
var
|
|
7278
|
+
var net2 = __importStar(require("net"));
|
|
7279
7279
|
var tls = __importStar(require("tls"));
|
|
7280
7280
|
var assert_1 = __importDefault(require("assert"));
|
|
7281
7281
|
var debug_1 = __importDefault(require_src());
|
|
@@ -7284,7 +7284,7 @@ var require_dist2 = __commonJS({
|
|
|
7284
7284
|
var parse_proxy_response_1 = require_parse_proxy_response();
|
|
7285
7285
|
var debug = (0, debug_1.default)("https-proxy-agent");
|
|
7286
7286
|
var setServernameFromNonIpHost = (options) => {
|
|
7287
|
-
if (options.servername === void 0 && options.host && !
|
|
7287
|
+
if (options.servername === void 0 && options.host && !net2.isIP(options.host)) {
|
|
7288
7288
|
return {
|
|
7289
7289
|
...options,
|
|
7290
7290
|
servername: options.host
|
|
@@ -7324,10 +7324,10 @@ var require_dist2 = __commonJS({
|
|
|
7324
7324
|
socket = tls.connect(setServernameFromNonIpHost(this.connectOpts));
|
|
7325
7325
|
} else {
|
|
7326
7326
|
debug("Creating `net.Socket`: %o", this.connectOpts);
|
|
7327
|
-
socket =
|
|
7327
|
+
socket = net2.connect(this.connectOpts);
|
|
7328
7328
|
}
|
|
7329
7329
|
const headers = typeof this.proxyHeaders === "function" ? this.proxyHeaders() : { ...this.proxyHeaders };
|
|
7330
|
-
const host =
|
|
7330
|
+
const host = net2.isIPv6(opts.host) ? `[${opts.host}]` : opts.host;
|
|
7331
7331
|
let payload = `CONNECT ${host}:${opts.port} HTTP/1.1\r
|
|
7332
7332
|
`;
|
|
7333
7333
|
if (proxy.username || proxy.password) {
|
|
@@ -7360,7 +7360,7 @@ var require_dist2 = __commonJS({
|
|
|
7360
7360
|
return socket;
|
|
7361
7361
|
}
|
|
7362
7362
|
socket.destroy();
|
|
7363
|
-
const fakeSocket = new
|
|
7363
|
+
const fakeSocket = new net2.Socket({ writable: false });
|
|
7364
7364
|
fakeSocket.readable = true;
|
|
7365
7365
|
req.once("socket", (s) => {
|
|
7366
7366
|
debug("Replaying proxy buffer for failed request");
|
|
@@ -7426,7 +7426,7 @@ var require_dist3 = __commonJS({
|
|
|
7426
7426
|
};
|
|
7427
7427
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
7428
7428
|
exports2.HttpProxyAgent = void 0;
|
|
7429
|
-
var
|
|
7429
|
+
var net2 = __importStar(require("net"));
|
|
7430
7430
|
var tls = __importStar(require("tls"));
|
|
7431
7431
|
var debug_1 = __importDefault(require_src());
|
|
7432
7432
|
var events_1 = require("events");
|
|
@@ -7499,7 +7499,7 @@ var require_dist3 = __commonJS({
|
|
|
7499
7499
|
socket = tls.connect(this.connectOpts);
|
|
7500
7500
|
} else {
|
|
7501
7501
|
debug("Creating `net.Socket`: %o", this.connectOpts);
|
|
7502
|
-
socket =
|
|
7502
|
+
socket = net2.connect(this.connectOpts);
|
|
7503
7503
|
}
|
|
7504
7504
|
await (0, events_1.once)(socket, "connect");
|
|
7505
7505
|
return socket;
|
|
@@ -15362,8 +15362,8 @@ var require_node2 = __commonJS({
|
|
|
15362
15362
|
break;
|
|
15363
15363
|
case "PIPE":
|
|
15364
15364
|
case "TCP":
|
|
15365
|
-
var
|
|
15366
|
-
stream2 = new
|
|
15365
|
+
var net2 = require("net");
|
|
15366
|
+
stream2 = new net2.Socket({
|
|
15367
15367
|
fd: fd2,
|
|
15368
15368
|
readable: false,
|
|
15369
15369
|
writable: true
|
|
@@ -51922,7 +51922,7 @@ var require_cross_spawn = __commonJS({
|
|
|
51922
51922
|
var cp = require("child_process");
|
|
51923
51923
|
var parse6 = require_parse3();
|
|
51924
51924
|
var enoent = require_enoent();
|
|
51925
|
-
function
|
|
51925
|
+
function spawn11(command, args, options) {
|
|
51926
51926
|
const parsed = parse6(command, args, options);
|
|
51927
51927
|
const spawned = cp.spawn(parsed.command, parsed.args, parsed.options);
|
|
51928
51928
|
enoent.hookChildProcess(spawned, parsed);
|
|
@@ -51934,8 +51934,8 @@ var require_cross_spawn = __commonJS({
|
|
|
51934
51934
|
result.error = result.error || enoent.verifyENOENTSync(result.status, parsed);
|
|
51935
51935
|
return result;
|
|
51936
51936
|
}
|
|
51937
|
-
module2.exports =
|
|
51938
|
-
module2.exports.spawn =
|
|
51937
|
+
module2.exports = spawn11;
|
|
51938
|
+
module2.exports.spawn = spawn11;
|
|
51939
51939
|
module2.exports.sync = spawnSync7;
|
|
51940
51940
|
module2.exports._parse = parse6;
|
|
51941
51941
|
module2.exports._enoent = enoent;
|
|
@@ -71610,12 +71610,12 @@ var require_subchannel_address = __commonJS({
|
|
|
71610
71610
|
return address.path;
|
|
71611
71611
|
}
|
|
71612
71612
|
}
|
|
71613
|
-
var
|
|
71613
|
+
var DEFAULT_PORT2 = 443;
|
|
71614
71614
|
function stringToSubchannelAddress(addressString, port) {
|
|
71615
71615
|
if ((0, net_1.isIP)(addressString)) {
|
|
71616
71616
|
return {
|
|
71617
71617
|
host: addressString,
|
|
71618
|
-
port: port !== null && port !== void 0 ? port :
|
|
71618
|
+
port: port !== null && port !== void 0 ? port : DEFAULT_PORT2
|
|
71619
71619
|
};
|
|
71620
71620
|
} else {
|
|
71621
71621
|
return {
|
|
@@ -86019,7 +86019,7 @@ var require_transport = __commonJS({
|
|
|
86019
86019
|
var resolver_1 = require_resolver();
|
|
86020
86020
|
var subchannel_address_1 = require_subchannel_address();
|
|
86021
86021
|
var uri_parser_1 = require_uri_parser();
|
|
86022
|
-
var
|
|
86022
|
+
var net2 = require("net");
|
|
86023
86023
|
var subchannel_call_1 = require_subchannel_call();
|
|
86024
86024
|
var call_number_1 = require_call_number();
|
|
86025
86025
|
var TRACER_NAME = "transport";
|
|
@@ -86486,7 +86486,7 @@ var require_transport = __commonJS({
|
|
|
86486
86486
|
const errorCallback = (error2) => {
|
|
86487
86487
|
reject(error2);
|
|
86488
86488
|
};
|
|
86489
|
-
const socket =
|
|
86489
|
+
const socket = net2.connect(address, () => {
|
|
86490
86490
|
socket.removeListener("close", closeCallback);
|
|
86491
86491
|
socket.removeListener("error", errorCallback);
|
|
86492
86492
|
resolve24(socket);
|
|
@@ -92318,7 +92318,7 @@ var require_resolver_ip = __commonJS({
|
|
|
92318
92318
|
}
|
|
92319
92319
|
var IPV4_SCHEME = "ipv4";
|
|
92320
92320
|
var IPV6_SCHEME = "ipv6";
|
|
92321
|
-
var
|
|
92321
|
+
var DEFAULT_PORT2 = 443;
|
|
92322
92322
|
var IpResolver = class {
|
|
92323
92323
|
constructor(target, listener, channelOptions) {
|
|
92324
92324
|
var _a;
|
|
@@ -92357,7 +92357,7 @@ var require_resolver_ip = __commonJS({
|
|
|
92357
92357
|
}
|
|
92358
92358
|
addresses.push({
|
|
92359
92359
|
host: hostPort.host,
|
|
92360
|
-
port: (_a = hostPort.port) !== null && _a !== void 0 ? _a :
|
|
92360
|
+
port: (_a = hostPort.port) !== null && _a !== void 0 ? _a : DEFAULT_PORT2
|
|
92361
92361
|
});
|
|
92362
92362
|
}
|
|
92363
92363
|
this.endpoints = addresses.map((address) => ({ addresses: [address] }));
|
|
@@ -115987,14 +115987,14 @@ var init_constants6 = __esm({
|
|
|
115987
115987
|
});
|
|
115988
115988
|
|
|
115989
115989
|
// ../../node_modules/.pnpm/@azure+monitor-opentelemetry-exporter@1.0.0-beta.42/node_modules/@azure/monitor-opentelemetry-exporter/dist/esm/platform/nodejs/persist/fileAccessControl.js
|
|
115990
|
-
var import_node_fs4, import_node_os6,
|
|
115990
|
+
var import_node_fs4, import_node_os6, import_node_child_process16, import_node_process5, FileAccessControl;
|
|
115991
115991
|
var init_fileAccessControl = __esm({
|
|
115992
115992
|
"../../node_modules/.pnpm/@azure+monitor-opentelemetry-exporter@1.0.0-beta.42/node_modules/@azure/monitor-opentelemetry-exporter/dist/esm/platform/nodejs/persist/fileAccessControl.js"() {
|
|
115993
115993
|
"use strict";
|
|
115994
115994
|
init_cjs_shims();
|
|
115995
115995
|
import_node_fs4 = require("fs");
|
|
115996
115996
|
import_node_os6 = require("os");
|
|
115997
|
-
|
|
115997
|
+
import_node_child_process16 = require("child_process");
|
|
115998
115998
|
init_esm8();
|
|
115999
115999
|
import_node_process5 = __toESM(require("process"), 1);
|
|
116000
116000
|
FileAccessControl = class _FileAccessControl {
|
|
@@ -116054,7 +116054,7 @@ var init_fileAccessControl = __esm({
|
|
|
116054
116054
|
}
|
|
116055
116055
|
static _runICACLS(args) {
|
|
116056
116056
|
return new Promise((resolve24, reject) => {
|
|
116057
|
-
const aclProc = (0,
|
|
116057
|
+
const aclProc = (0, import_node_child_process16.spawn)(_FileAccessControl.ICACLS_PATH, args, {
|
|
116058
116058
|
windowsHide: true
|
|
116059
116059
|
});
|
|
116060
116060
|
aclProc.on("error", (e) => reject(e));
|
|
@@ -116068,8 +116068,8 @@ var init_fileAccessControl = __esm({
|
|
|
116068
116068
|
});
|
|
116069
116069
|
}
|
|
116070
116070
|
static _runICACLSSync(args) {
|
|
116071
|
-
if (
|
|
116072
|
-
const aclProc = (0,
|
|
116071
|
+
if (import_node_child_process16.spawnSync) {
|
|
116072
|
+
const aclProc = (0, import_node_child_process16.spawnSync)(_FileAccessControl.ICACLS_PATH, args, {
|
|
116073
116073
|
windowsHide: true
|
|
116074
116074
|
});
|
|
116075
116075
|
if (aclProc.error) {
|
|
@@ -116086,7 +116086,7 @@ var init_fileAccessControl = __esm({
|
|
|
116086
116086
|
if (_FileAccessControl.ACL_IDENTITY) {
|
|
116087
116087
|
resolve24(_FileAccessControl.ACL_IDENTITY);
|
|
116088
116088
|
}
|
|
116089
|
-
const psProc = (0,
|
|
116089
|
+
const psProc = (0, import_node_child_process16.spawn)(_FileAccessControl.POWERSHELL_PATH, ["-Command", "[System.Security.Principal.WindowsIdentity]::GetCurrent().Name"], {
|
|
116090
116090
|
windowsHide: true,
|
|
116091
116091
|
stdio: ["ignore", "pipe", "pipe"]
|
|
116092
116092
|
// Needed to prevent hanging on Win 7
|
|
@@ -116108,8 +116108,8 @@ var init_fileAccessControl = __esm({
|
|
|
116108
116108
|
if (_FileAccessControl.ACL_IDENTITY) {
|
|
116109
116109
|
return _FileAccessControl.ACL_IDENTITY;
|
|
116110
116110
|
}
|
|
116111
|
-
if (
|
|
116112
|
-
const psProc = (0,
|
|
116111
|
+
if (import_node_child_process16.spawnSync) {
|
|
116112
|
+
const psProc = (0, import_node_child_process16.spawnSync)(_FileAccessControl.POWERSHELL_PATH, ["-Command", "[System.Security.Principal.WindowsIdentity]::GetCurrent().Name"], {
|
|
116113
116113
|
windowsHide: true,
|
|
116114
116114
|
stdio: ["ignore", "pipe", "pipe"]
|
|
116115
116115
|
// Needed to prevent hanging on Win 7
|
|
@@ -139368,8 +139368,6 @@ var TaskEngine = class {
|
|
|
139368
139368
|
this.eventBus = eventBus;
|
|
139369
139369
|
this.logDir = logDir;
|
|
139370
139370
|
}
|
|
139371
|
-
/** Tracks which node a task was previously assigned to, for retry preference. */
|
|
139372
|
-
previousAssignments = /* @__PURE__ */ new Map();
|
|
139373
139371
|
deletedTaskIds = /* @__PURE__ */ new Set();
|
|
139374
139372
|
// ── Task CRUD ────────────────────────────────────────────────────────
|
|
139375
139373
|
createTask(input) {
|
|
@@ -139499,7 +139497,6 @@ var TaskEngine = class {
|
|
|
139499
139497
|
if (!task) return false;
|
|
139500
139498
|
const deleted = this.store.deleteTask(id);
|
|
139501
139499
|
if (!deleted) return false;
|
|
139502
|
-
this.previousAssignments.delete(id);
|
|
139503
139500
|
this.deletedTaskIds.add(id);
|
|
139504
139501
|
if (this.logDir) {
|
|
139505
139502
|
const logFile = path5.join(this.logDir, `${id}.jsonl`);
|
|
@@ -139521,7 +139518,6 @@ var TaskEngine = class {
|
|
|
139521
139518
|
}
|
|
139522
139519
|
const now = Date.now();
|
|
139523
139520
|
this.store.updateTask(id, { status: "cancelled", updatedAt: now });
|
|
139524
|
-
this.previousAssignments.delete(id);
|
|
139525
139521
|
this.eventBus.emit("task.status", {
|
|
139526
139522
|
taskId: id,
|
|
139527
139523
|
status: "cancelled"
|
|
@@ -139586,7 +139582,7 @@ var TaskEngine = class {
|
|
|
139586
139582
|
// ── Dispatch failure ─────────────────────────────────────────────────
|
|
139587
139583
|
/**
|
|
139588
139584
|
* Handle a dispatch failure for a task that is still in `assigned` status.
|
|
139589
|
-
*
|
|
139585
|
+
* Dispatch failures are terminal; explicit user retry is handled by retryTask().
|
|
139590
139586
|
*/
|
|
139591
139587
|
failDispatch(taskId, error2) {
|
|
139592
139588
|
const task = this.store.getTask(taskId);
|
|
@@ -139600,30 +139596,10 @@ var TaskEngine = class {
|
|
|
139600
139596
|
400
|
|
139601
139597
|
);
|
|
139602
139598
|
}
|
|
139603
|
-
const now = Date.now();
|
|
139604
|
-
const newRetryCount = task.retryCount + 1;
|
|
139605
|
-
if (newRetryCount <= task.maxRetries) {
|
|
139606
|
-
if (task.assignedTo) {
|
|
139607
|
-
this.previousAssignments.set(taskId, task.assignedTo);
|
|
139608
|
-
}
|
|
139609
|
-
const updated2 = this.store.updateTask(taskId, {
|
|
139610
|
-
status: "pending",
|
|
139611
|
-
retryCount: newRetryCount,
|
|
139612
|
-
assignedTo: null,
|
|
139613
|
-
assignedNodeName: null,
|
|
139614
|
-
error: error2,
|
|
139615
|
-
updatedAt: now
|
|
139616
|
-
});
|
|
139617
|
-
this.eventBus.emit("task.status", {
|
|
139618
|
-
taskId,
|
|
139619
|
-
status: "pending"
|
|
139620
|
-
});
|
|
139621
|
-
return updated2;
|
|
139622
|
-
}
|
|
139623
139599
|
const updated = this.store.updateTask(taskId, {
|
|
139624
139600
|
status: "failed",
|
|
139625
139601
|
error: error2,
|
|
139626
|
-
updatedAt: now
|
|
139602
|
+
updatedAt: Date.now()
|
|
139627
139603
|
});
|
|
139628
139604
|
this.eventBus.emit("task.status", {
|
|
139629
139605
|
taskId,
|
|
@@ -139687,12 +139663,12 @@ var TaskEngine = class {
|
|
|
139687
139663
|
const backoff = this.getRetryBackoff(task.retryCount - 1);
|
|
139688
139664
|
if (now - task.updatedAt < backoff) continue;
|
|
139689
139665
|
}
|
|
139690
|
-
const previousNodeId = this.previousAssignments.get(task.id);
|
|
139691
139666
|
const snapshotOwnerId = getJoinTaskSnapshotOwnerId(task);
|
|
139692
|
-
const
|
|
139667
|
+
const requiredNodeId = snapshotOwnerId ?? task.assignedTo;
|
|
139668
|
+
const candidateNodes = requiredNodeId ? availableNodes.filter((node) => node.id === requiredNodeId) : availableNodes;
|
|
139693
139669
|
const capableNodes = candidateNodes.filter((node) => nodeSupportsAgent(node, task.agent));
|
|
139694
139670
|
if (capableNodes.length === 0) continue;
|
|
139695
|
-
const targetNode = this.pickLeastBusyNode(capableNodes, nodeLoad
|
|
139671
|
+
const targetNode = this.pickLeastBusyNode(capableNodes, nodeLoad);
|
|
139696
139672
|
if (!targetNode) continue;
|
|
139697
139673
|
const assignedAt = Date.now();
|
|
139698
139674
|
this.store.updateTask(task.id, {
|
|
@@ -139754,7 +139730,6 @@ var TaskEngine = class {
|
|
|
139754
139730
|
status: "completed",
|
|
139755
139731
|
result
|
|
139756
139732
|
});
|
|
139757
|
-
this.previousAssignments.delete(taskId);
|
|
139758
139733
|
return updated;
|
|
139759
139734
|
}
|
|
139760
139735
|
reportFailure(taskId, error2) {
|
|
@@ -139769,30 +139744,10 @@ var TaskEngine = class {
|
|
|
139769
139744
|
400
|
|
139770
139745
|
);
|
|
139771
139746
|
}
|
|
139772
|
-
const now = Date.now();
|
|
139773
|
-
const newRetryCount = task.retryCount + 1;
|
|
139774
|
-
if (newRetryCount <= task.maxRetries) {
|
|
139775
|
-
if (task.assignedTo) {
|
|
139776
|
-
this.previousAssignments.set(taskId, task.assignedTo);
|
|
139777
|
-
}
|
|
139778
|
-
const updated2 = this.store.updateTask(taskId, {
|
|
139779
|
-
status: "pending",
|
|
139780
|
-
retryCount: newRetryCount,
|
|
139781
|
-
assignedTo: null,
|
|
139782
|
-
assignedNodeName: null,
|
|
139783
|
-
error: error2,
|
|
139784
|
-
updatedAt: now
|
|
139785
|
-
});
|
|
139786
|
-
this.eventBus.emit("task.status", {
|
|
139787
|
-
taskId,
|
|
139788
|
-
status: "pending"
|
|
139789
|
-
});
|
|
139790
|
-
return updated2;
|
|
139791
|
-
}
|
|
139792
139747
|
const updated = this.store.updateTask(taskId, {
|
|
139793
139748
|
status: "failed",
|
|
139794
139749
|
error: error2,
|
|
139795
|
-
updatedAt: now
|
|
139750
|
+
updatedAt: Date.now()
|
|
139796
139751
|
});
|
|
139797
139752
|
this.eventBus.emit("task.status", {
|
|
139798
139753
|
taskId,
|
|
@@ -139814,15 +139769,10 @@ var TaskEngine = class {
|
|
|
139814
139769
|
400
|
|
139815
139770
|
);
|
|
139816
139771
|
}
|
|
139817
|
-
if (task.assignedTo) {
|
|
139818
|
-
this.previousAssignments.set(taskId, task.assignedTo);
|
|
139819
|
-
}
|
|
139820
139772
|
const now = Date.now();
|
|
139821
139773
|
const updated = this.store.updateTask(taskId, {
|
|
139822
139774
|
status: "pending",
|
|
139823
139775
|
retryCount: 0,
|
|
139824
|
-
assignedTo: null,
|
|
139825
|
-
assignedNodeName: null,
|
|
139826
139776
|
error: null,
|
|
139827
139777
|
result: null,
|
|
139828
139778
|
updatedAt: now
|
|
@@ -139855,15 +139805,14 @@ var TaskEngine = class {
|
|
|
139855
139805
|
getRetryBackoff(retryCount) {
|
|
139856
139806
|
return Math.min(Math.pow(2, retryCount) * 1e3, 3e4);
|
|
139857
139807
|
}
|
|
139858
|
-
pickLeastBusyNode(nodes, loadMap
|
|
139808
|
+
pickLeastBusyNode(nodes, loadMap) {
|
|
139859
139809
|
if (nodes.length === 0) return null;
|
|
139860
139810
|
let bestNode = null;
|
|
139861
139811
|
let bestLoad = Infinity;
|
|
139862
139812
|
for (const node of nodes) {
|
|
139863
139813
|
const load = loadMap.get(node.id) ?? 0;
|
|
139864
|
-
|
|
139865
|
-
|
|
139866
|
-
bestLoad = adjustedLoad;
|
|
139814
|
+
if (load < bestLoad) {
|
|
139815
|
+
bestLoad = load;
|
|
139867
139816
|
bestNode = node;
|
|
139868
139817
|
}
|
|
139869
139818
|
}
|
|
@@ -146951,6 +146900,8 @@ var sharedMcpControl;
|
|
|
146951
146900
|
var DEFAULT_START_POLL_INTERVAL_MS = 1e4;
|
|
146952
146901
|
var DEFAULT_START_TIMEOUT_MS = 15 * 6e4;
|
|
146953
146902
|
var ALWAYS_ONLINE_STARTABLE_DEVBOX_STATUSES = /* @__PURE__ */ new Set(["hibernated", "stopped"]);
|
|
146903
|
+
var DEVBOX_MCP_COMMAND = "npx";
|
|
146904
|
+
var DEVBOX_MCP_ARGS = ["-y", "-p", "node@22", "-p", "@microsoft/devbox-mcp@latest", "devbox-mcp-server"];
|
|
146954
146905
|
function getDevBoxControl(deps) {
|
|
146955
146906
|
if (deps.devBoxControl) return deps.devBoxControl;
|
|
146956
146907
|
sharedMcpControl ??= new McpDevBoxControl(deps.logger);
|
|
@@ -147108,7 +147059,7 @@ var McpDevBoxControl = class {
|
|
|
147108
147059
|
Promise.resolve().then(() => (init_stdio2(), stdio_exports))
|
|
147109
147060
|
]);
|
|
147110
147061
|
const client = new Client2({ name: "meshy-devbox", version: "0.1.0" }, { capabilities: {} });
|
|
147111
|
-
const transport = new StdioClientTransport2({ command:
|
|
147062
|
+
const transport = new StdioClientTransport2({ command: DEVBOX_MCP_COMMAND, args: DEVBOX_MCP_ARGS });
|
|
147112
147063
|
transport.onclose = () => {
|
|
147113
147064
|
this.clientPromise = null;
|
|
147114
147065
|
};
|
|
@@ -148669,9 +148620,365 @@ function isRecord9(value) {
|
|
|
148669
148620
|
return Boolean(value && typeof value === "object" && !Array.isArray(value));
|
|
148670
148621
|
}
|
|
148671
148622
|
|
|
148623
|
+
// ../../packages/api/src/node/copilot-tunnel-service.ts
|
|
148624
|
+
init_cjs_shims();
|
|
148625
|
+
var import_node_child_process10 = require("child_process");
|
|
148626
|
+
var import_node_net = __toESM(require("net"), 1);
|
|
148627
|
+
var DEFAULT_HOST = "127.0.0.1";
|
|
148628
|
+
var DEFAULT_PORT = 8314;
|
|
148629
|
+
var DEFAULT_OUTPUT_LIMIT_BYTES = 8e3;
|
|
148630
|
+
var DEFAULT_PORT_CHECK_TIMEOUT_MS = 750;
|
|
148631
|
+
var DEFAULT_POLL_INTERVAL_MS = 1e3;
|
|
148632
|
+
var DEFAULT_STARTUP_TIMEOUT_MS = 15 * 60 * 1e3;
|
|
148633
|
+
var DEFAULT_STOP_TIMEOUT_MS = 3e3;
|
|
148634
|
+
var GHC_TUNNEL_ARGS = ["-y", "ghc-tunnel@latest", "-d"];
|
|
148635
|
+
var trackedTunnels = /* @__PURE__ */ new Map();
|
|
148636
|
+
function createTail() {
|
|
148637
|
+
return { text: "", observedBytes: 0, truncated: false };
|
|
148638
|
+
}
|
|
148639
|
+
function appendTail(tail, chunk, limitBytes) {
|
|
148640
|
+
tail.observedBytes += chunk.length;
|
|
148641
|
+
const current = Buffer.from(tail.text, "utf8");
|
|
148642
|
+
const combined = Buffer.concat([current, chunk]);
|
|
148643
|
+
const next = combined.length > limitBytes ? combined.subarray(combined.length - limitBytes) : combined;
|
|
148644
|
+
tail.text = next.toString("utf8");
|
|
148645
|
+
tail.truncated = tail.observedBytes > limitBytes;
|
|
148646
|
+
}
|
|
148647
|
+
function sleep2(ms) {
|
|
148648
|
+
return new Promise((resolve24) => setTimeout(resolve24, ms));
|
|
148649
|
+
}
|
|
148650
|
+
function defaultSpawnTunnel(command, args, options) {
|
|
148651
|
+
return (0, import_node_child_process10.spawn)(command, args, options);
|
|
148652
|
+
}
|
|
148653
|
+
function execFileText(command, args) {
|
|
148654
|
+
return new Promise((resolve24) => {
|
|
148655
|
+
(0, import_node_child_process10.execFile)(command, args, { windowsHide: true }, (error2, stdout) => {
|
|
148656
|
+
resolve24(error2 ? "" : stdout);
|
|
148657
|
+
});
|
|
148658
|
+
});
|
|
148659
|
+
}
|
|
148660
|
+
function parseProcessIds(output) {
|
|
148661
|
+
const seen = /* @__PURE__ */ new Set();
|
|
148662
|
+
for (const token of output.split(/\s+/)) {
|
|
148663
|
+
const pid = Number(token.trim());
|
|
148664
|
+
if (Number.isInteger(pid) && pid > 0 && pid !== process.pid) seen.add(pid);
|
|
148665
|
+
}
|
|
148666
|
+
return [...seen];
|
|
148667
|
+
}
|
|
148668
|
+
async function defaultFindPortProcessIds(port) {
|
|
148669
|
+
if (process.platform === "win32") {
|
|
148670
|
+
const output2 = await execFileText("powershell.exe", [
|
|
148671
|
+
"-NoProfile",
|
|
148672
|
+
"-NonInteractive",
|
|
148673
|
+
"-Command",
|
|
148674
|
+
`Get-NetTCPConnection -LocalPort ${port} -State Listen -ErrorAction SilentlyContinue | Select-Object -ExpandProperty OwningProcess -Unique`
|
|
148675
|
+
]);
|
|
148676
|
+
return parseProcessIds(output2);
|
|
148677
|
+
}
|
|
148678
|
+
const output = await execFileText("lsof", ["-nP", `-iTCP:${port}`, "-sTCP:LISTEN", "-t"]);
|
|
148679
|
+
return parseProcessIds(output);
|
|
148680
|
+
}
|
|
148681
|
+
async function defaultKillProcessId(pid, signal) {
|
|
148682
|
+
if (pid === process.pid) return;
|
|
148683
|
+
if (process.platform === "win32") {
|
|
148684
|
+
const args = ["/PID", String(pid), "/T"];
|
|
148685
|
+
if (signal === "SIGKILL") args.push("/F");
|
|
148686
|
+
await execFileText("taskkill.exe", args);
|
|
148687
|
+
return;
|
|
148688
|
+
}
|
|
148689
|
+
try {
|
|
148690
|
+
process.kill(pid, signal);
|
|
148691
|
+
} catch (err) {
|
|
148692
|
+
if (err.code !== "ESRCH") throw err;
|
|
148693
|
+
}
|
|
148694
|
+
}
|
|
148695
|
+
function tunnelKey(host, port) {
|
|
148696
|
+
return `${host}:${port}`;
|
|
148697
|
+
}
|
|
148698
|
+
function tunnelCommand(platform6) {
|
|
148699
|
+
return platform6 === "win32" ? "npx.cmd" : "npx";
|
|
148700
|
+
}
|
|
148701
|
+
function tunnelArgs() {
|
|
148702
|
+
return [...GHC_TUNNEL_ARGS];
|
|
148703
|
+
}
|
|
148704
|
+
function windowsShellQuote(value) {
|
|
148705
|
+
return /[\s&()^|<>"]/.test(value) ? `"${value.replace(/"/g, '\\"')}"` : value;
|
|
148706
|
+
}
|
|
148707
|
+
function createCopilotTunnelSpawnInvocation(host, port, platform6 = process.platform) {
|
|
148708
|
+
void host;
|
|
148709
|
+
void port;
|
|
148710
|
+
const displayCommand = tunnelCommand(platform6);
|
|
148711
|
+
const displayArgs = tunnelArgs();
|
|
148712
|
+
if (platform6 !== "win32") return { command: displayCommand, args: displayArgs, displayCommand, displayArgs };
|
|
148713
|
+
return {
|
|
148714
|
+
command: "cmd.exe",
|
|
148715
|
+
args: ["/d", "/s", "/c", [displayCommand, ...displayArgs].map(windowsShellQuote).join(" ")],
|
|
148716
|
+
displayCommand,
|
|
148717
|
+
displayArgs
|
|
148718
|
+
};
|
|
148719
|
+
}
|
|
148720
|
+
function checkTcpPort(host, port, timeoutMs) {
|
|
148721
|
+
return new Promise((resolve24) => {
|
|
148722
|
+
const socket = import_node_net.default.createConnection({ host, port });
|
|
148723
|
+
let settled = false;
|
|
148724
|
+
const finish = (available) => {
|
|
148725
|
+
if (settled) return;
|
|
148726
|
+
settled = true;
|
|
148727
|
+
socket.destroy();
|
|
148728
|
+
resolve24(available);
|
|
148729
|
+
};
|
|
148730
|
+
socket.setTimeout(timeoutMs);
|
|
148731
|
+
socket.once("connect", () => finish(true));
|
|
148732
|
+
socket.once("timeout", () => finish(false));
|
|
148733
|
+
socket.once("error", () => finish(false));
|
|
148734
|
+
});
|
|
148735
|
+
}
|
|
148736
|
+
function normalizeLoopbackHost(host) {
|
|
148737
|
+
return host.toLowerCase().replace(/^\[|\]$/g, "");
|
|
148738
|
+
}
|
|
148739
|
+
function loopbackProbeHosts(host) {
|
|
148740
|
+
const normalized = normalizeLoopbackHost(host);
|
|
148741
|
+
if (normalized !== DEFAULT_HOST && normalized !== "localhost" && normalized !== "::1") return [host];
|
|
148742
|
+
return Array.from(/* @__PURE__ */ new Set([normalized, DEFAULT_HOST, "localhost", "::1"]));
|
|
148743
|
+
}
|
|
148744
|
+
async function checkCopilotLoopbackPort(host, port, timeoutMs, checker = checkTcpPort) {
|
|
148745
|
+
const hosts = loopbackProbeHosts(host);
|
|
148746
|
+
const results = await Promise.all(hosts.map((candidate) => checker(candidate, port, timeoutMs)));
|
|
148747
|
+
return results.some(Boolean);
|
|
148748
|
+
}
|
|
148749
|
+
function parseGithubDeviceFlow(output) {
|
|
148750
|
+
const url3 = output.match(/Please visit:\s*(https?:\/\/\S+)/i)?.[1];
|
|
148751
|
+
const code = output.match(/enter the code:\s*([A-Z0-9]{4}-[A-Z0-9]{4})/i)?.[1];
|
|
148752
|
+
if (!url3 || !code) return null;
|
|
148753
|
+
const expires = output.match(/expires in\s+(\d+)\s+seconds/i)?.[1];
|
|
148754
|
+
return {
|
|
148755
|
+
url: url3,
|
|
148756
|
+
code,
|
|
148757
|
+
...expires ? { expiresInSeconds: Number(expires) } : {}
|
|
148758
|
+
};
|
|
148759
|
+
}
|
|
148760
|
+
function buildResult(options) {
|
|
148761
|
+
const available = options.available ?? (options.status === "already-running" || options.status === "available");
|
|
148762
|
+
return {
|
|
148763
|
+
ok: options.status !== "failed",
|
|
148764
|
+
available,
|
|
148765
|
+
port: options.port,
|
|
148766
|
+
host: options.host,
|
|
148767
|
+
command: options.command,
|
|
148768
|
+
args: options.args,
|
|
148769
|
+
pid: options.pid,
|
|
148770
|
+
status: options.status,
|
|
148771
|
+
stdout: options.stdout.text,
|
|
148772
|
+
stderr: options.stderr.text,
|
|
148773
|
+
stdoutTruncated: options.stdout.truncated,
|
|
148774
|
+
stderrTruncated: options.stderr.truncated,
|
|
148775
|
+
auth: options.auth ?? null,
|
|
148776
|
+
detail: options.detail ?? null
|
|
148777
|
+
};
|
|
148778
|
+
}
|
|
148779
|
+
async function checkGithubCopilotTunnel(options = {}) {
|
|
148780
|
+
const host = options.host ?? DEFAULT_HOST;
|
|
148781
|
+
const port = options.port ?? DEFAULT_PORT;
|
|
148782
|
+
const invocation = createCopilotTunnelSpawnInvocation(host, port);
|
|
148783
|
+
const command = invocation.displayCommand;
|
|
148784
|
+
const args = invocation.displayArgs;
|
|
148785
|
+
const stdout = createTail();
|
|
148786
|
+
const stderr = createTail();
|
|
148787
|
+
const portCheckTimeoutMs = options.portCheckTimeoutMs ?? DEFAULT_PORT_CHECK_TIMEOUT_MS;
|
|
148788
|
+
const portChecker = options.portChecker ?? checkCopilotLoopbackPort;
|
|
148789
|
+
const status = await portChecker(host, port, portCheckTimeoutMs) ? "already-running" : "unavailable";
|
|
148790
|
+
const pid = trackedTunnels.get(tunnelKey(host, port))?.pid ?? null;
|
|
148791
|
+
return buildResult({ host, port, command, args, pid, status, stdout, stderr });
|
|
148792
|
+
}
|
|
148793
|
+
function waitForProcessClose(child, timeoutMs) {
|
|
148794
|
+
return new Promise((resolve24) => {
|
|
148795
|
+
let settled = false;
|
|
148796
|
+
const finish = (closed) => {
|
|
148797
|
+
if (settled) return;
|
|
148798
|
+
settled = true;
|
|
148799
|
+
clearTimeout(timer);
|
|
148800
|
+
resolve24(closed);
|
|
148801
|
+
};
|
|
148802
|
+
const timer = setTimeout(() => finish(false), timeoutMs);
|
|
148803
|
+
child.once("close", () => finish(true));
|
|
148804
|
+
});
|
|
148805
|
+
}
|
|
148806
|
+
async function terminateChildProcess(child, timeoutMs) {
|
|
148807
|
+
const closedAfterTerm = waitForProcessClose(child, timeoutMs);
|
|
148808
|
+
child.kill?.("SIGTERM");
|
|
148809
|
+
if (await closedAfterTerm) return;
|
|
148810
|
+
const closedAfterKill = waitForProcessClose(child, Math.min(timeoutMs, 1e3));
|
|
148811
|
+
child.kill?.("SIGKILL");
|
|
148812
|
+
await closedAfterKill;
|
|
148813
|
+
}
|
|
148814
|
+
async function waitForPortToClose(options) {
|
|
148815
|
+
const deadline = Date.now() + options.timeoutMs;
|
|
148816
|
+
do {
|
|
148817
|
+
if (!await options.portChecker(options.host, options.port, options.portCheckTimeoutMs)) return true;
|
|
148818
|
+
await sleep2(Math.min(200, Math.max(0, deadline - Date.now())));
|
|
148819
|
+
} while (Date.now() < deadline);
|
|
148820
|
+
return !await options.portChecker(options.host, options.port, options.portCheckTimeoutMs);
|
|
148821
|
+
}
|
|
148822
|
+
async function stopPortOwners(options) {
|
|
148823
|
+
const pids = await options.findPortProcessIds(options.port);
|
|
148824
|
+
if (pids.length === 0) {
|
|
148825
|
+
return {
|
|
148826
|
+
pids,
|
|
148827
|
+
available: await options.portChecker(options.host, options.port, options.portCheckTimeoutMs)
|
|
148828
|
+
};
|
|
148829
|
+
}
|
|
148830
|
+
await Promise.all(pids.map((pid) => options.killProcessId(pid, "SIGTERM")));
|
|
148831
|
+
let closed = await waitForPortToClose({ ...options, timeoutMs: options.stopTimeoutMs });
|
|
148832
|
+
if (!closed) {
|
|
148833
|
+
await Promise.all(pids.map((pid) => options.killProcessId(pid, "SIGKILL")));
|
|
148834
|
+
closed = await waitForPortToClose({ ...options, timeoutMs: Math.min(options.stopTimeoutMs, 1e3) });
|
|
148835
|
+
}
|
|
148836
|
+
return { pids, available: !closed };
|
|
148837
|
+
}
|
|
148838
|
+
function formatProcessList(pids) {
|
|
148839
|
+
return pids.length === 1 ? `process ${pids[0]}` : `processes ${pids.join(", ")}`;
|
|
148840
|
+
}
|
|
148841
|
+
async function disableGithubCopilotTunnel(options = {}) {
|
|
148842
|
+
const host = options.host ?? DEFAULT_HOST;
|
|
148843
|
+
const port = options.port ?? DEFAULT_PORT;
|
|
148844
|
+
const invocation = createCopilotTunnelSpawnInvocation(host, port);
|
|
148845
|
+
const command = invocation.displayCommand;
|
|
148846
|
+
const args = invocation.displayArgs;
|
|
148847
|
+
const stdout = createTail();
|
|
148848
|
+
const stderr = createTail();
|
|
148849
|
+
const portCheckTimeoutMs = options.portCheckTimeoutMs ?? DEFAULT_PORT_CHECK_TIMEOUT_MS;
|
|
148850
|
+
const stopTimeoutMs = options.stopTimeoutMs ?? DEFAULT_STOP_TIMEOUT_MS;
|
|
148851
|
+
const portChecker = options.portChecker ?? checkCopilotLoopbackPort;
|
|
148852
|
+
const findPortProcessIds = options.findPortProcessIds ?? defaultFindPortProcessIds;
|
|
148853
|
+
const killProcessId = options.killProcessId ?? defaultKillProcessId;
|
|
148854
|
+
const key = tunnelKey(host, port);
|
|
148855
|
+
const child = trackedTunnels.get(key);
|
|
148856
|
+
if (!child) {
|
|
148857
|
+
const available2 = await portChecker(host, port, portCheckTimeoutMs);
|
|
148858
|
+
if (available2) {
|
|
148859
|
+
const stopped = await stopPortOwners({ host, port, stopTimeoutMs, portCheckTimeoutMs, portChecker, findPortProcessIds, killProcessId });
|
|
148860
|
+
return buildResult({
|
|
148861
|
+
host,
|
|
148862
|
+
port,
|
|
148863
|
+
command,
|
|
148864
|
+
args,
|
|
148865
|
+
pid: stopped.pids[0] ?? null,
|
|
148866
|
+
status: stopped.available ? "failed" : "stopped",
|
|
148867
|
+
available: stopped.available,
|
|
148868
|
+
stdout,
|
|
148869
|
+
stderr,
|
|
148870
|
+
detail: stopped.pids.length === 0 ? `No process owner was found for port ${port}` : stopped.available ? `Stopped ${formatProcessList(stopped.pids)} but port ${port} is still reachable` : `Stopped ${formatProcessList(stopped.pids)} on port ${port}`
|
|
148871
|
+
});
|
|
148872
|
+
}
|
|
148873
|
+
return buildResult({
|
|
148874
|
+
host,
|
|
148875
|
+
port,
|
|
148876
|
+
command,
|
|
148877
|
+
args,
|
|
148878
|
+
pid: null,
|
|
148879
|
+
status: "stopped",
|
|
148880
|
+
available: false,
|
|
148881
|
+
stdout,
|
|
148882
|
+
stderr,
|
|
148883
|
+
detail: null
|
|
148884
|
+
});
|
|
148885
|
+
}
|
|
148886
|
+
const pid = typeof child.pid === "number" ? child.pid : null;
|
|
148887
|
+
await terminateChildProcess(child, stopTimeoutMs);
|
|
148888
|
+
trackedTunnels.delete(key);
|
|
148889
|
+
let available = await portChecker(host, port, portCheckTimeoutMs);
|
|
148890
|
+
let stoppedOwners = [];
|
|
148891
|
+
if (available) {
|
|
148892
|
+
const stopped = await stopPortOwners({ host, port, stopTimeoutMs, portCheckTimeoutMs, portChecker, findPortProcessIds, killProcessId });
|
|
148893
|
+
available = stopped.available;
|
|
148894
|
+
stoppedOwners = stopped.pids;
|
|
148895
|
+
}
|
|
148896
|
+
return buildResult({
|
|
148897
|
+
host,
|
|
148898
|
+
port,
|
|
148899
|
+
command,
|
|
148900
|
+
args,
|
|
148901
|
+
pid,
|
|
148902
|
+
status: available ? "failed" : "stopped",
|
|
148903
|
+
available,
|
|
148904
|
+
stdout,
|
|
148905
|
+
stderr,
|
|
148906
|
+
detail: available ? `Copilot tunnel process ${pid ?? "unknown"} stopped but port ${port} is still reachable` : stoppedOwners.length > 0 ? `Stopped ${formatProcessList(stoppedOwners)} on port ${port}` : null
|
|
148907
|
+
});
|
|
148908
|
+
}
|
|
148909
|
+
async function enableGithubCopilotTunnel(options = {}) {
|
|
148910
|
+
const host = options.host ?? DEFAULT_HOST;
|
|
148911
|
+
const port = options.port ?? DEFAULT_PORT;
|
|
148912
|
+
const invocation = createCopilotTunnelSpawnInvocation(host, port);
|
|
148913
|
+
const command = invocation.displayCommand;
|
|
148914
|
+
const args = invocation.displayArgs;
|
|
148915
|
+
const stdout = createTail();
|
|
148916
|
+
const stderr = createTail();
|
|
148917
|
+
const outputLimitBytes = options.outputLimitBytes ?? DEFAULT_OUTPUT_LIMIT_BYTES;
|
|
148918
|
+
const portCheckTimeoutMs = options.portCheckTimeoutMs ?? DEFAULT_PORT_CHECK_TIMEOUT_MS;
|
|
148919
|
+
const pollIntervalMs = options.pollIntervalMs ?? DEFAULT_POLL_INTERVAL_MS;
|
|
148920
|
+
const stopTimeoutMs = options.stopTimeoutMs ?? DEFAULT_STOP_TIMEOUT_MS;
|
|
148921
|
+
const startupTimeoutMs = options.startupTimeoutMs ?? DEFAULT_STARTUP_TIMEOUT_MS;
|
|
148922
|
+
const portChecker = options.portChecker ?? checkCopilotLoopbackPort;
|
|
148923
|
+
const key = tunnelKey(host, port);
|
|
148924
|
+
if (await portChecker(host, port, portCheckTimeoutMs)) {
|
|
148925
|
+
return buildResult({ host, port, command, args, pid: null, status: "already-running", stdout, stderr });
|
|
148926
|
+
}
|
|
148927
|
+
let auth = null;
|
|
148928
|
+
const childState = { exit: null, spawnError: null };
|
|
148929
|
+
const child = (options.spawnTunnel ?? defaultSpawnTunnel)(invocation.command, invocation.args, {
|
|
148930
|
+
cwd: options.cwd ?? process.cwd(),
|
|
148931
|
+
shell: false,
|
|
148932
|
+
windowsHide: true,
|
|
148933
|
+
stdio: ["ignore", "pipe", "pipe"]
|
|
148934
|
+
});
|
|
148935
|
+
const pid = typeof child.pid === "number" ? child.pid : null;
|
|
148936
|
+
const publish2 = (status, detail) => {
|
|
148937
|
+
options.onProgress?.(buildResult({ host, port, command, args, pid, status, stdout, stderr, auth, detail }));
|
|
148938
|
+
};
|
|
148939
|
+
const handleOutput = (target, chunk) => {
|
|
148940
|
+
appendTail(target, chunk, outputLimitBytes);
|
|
148941
|
+
auth = parseGithubDeviceFlow(`${stdout.text}
|
|
148942
|
+
${stderr.text}`) ?? auth;
|
|
148943
|
+
publish2(auth ? "auth-required" : "starting");
|
|
148944
|
+
};
|
|
148945
|
+
child.stdout?.on("data", (chunk) => handleOutput(stdout, Buffer.isBuffer(chunk) ? chunk : Buffer.from(String(chunk))));
|
|
148946
|
+
child.stderr?.on("data", (chunk) => handleOutput(stderr, Buffer.isBuffer(chunk) ? chunk : Buffer.from(String(chunk))));
|
|
148947
|
+
child.once("error", (err) => {
|
|
148948
|
+
childState.spawnError = err instanceof Error ? err : new Error(String(err));
|
|
148949
|
+
});
|
|
148950
|
+
child.once("close", (code, signal) => {
|
|
148951
|
+
childState.exit = { code, signal };
|
|
148952
|
+
if (trackedTunnels.get(key) === child) trackedTunnels.delete(key);
|
|
148953
|
+
});
|
|
148954
|
+
publish2("starting");
|
|
148955
|
+
const deadline = Date.now() + startupTimeoutMs;
|
|
148956
|
+
while (Date.now() < deadline) {
|
|
148957
|
+
if (await portChecker(host, port, portCheckTimeoutMs)) {
|
|
148958
|
+
trackedTunnels.set(key, child);
|
|
148959
|
+
child.unref?.();
|
|
148960
|
+
return buildResult({ host, port, command, args, pid, status: "available", stdout, stderr, auth });
|
|
148961
|
+
}
|
|
148962
|
+
if (childState.spawnError) {
|
|
148963
|
+
return buildResult({ host, port, command, args, pid, status: "failed", stdout, stderr, auth, detail: childState.spawnError.message });
|
|
148964
|
+
}
|
|
148965
|
+
if (childState.exit) {
|
|
148966
|
+
const detail = childState.exit.code === 0 ? `ghc-tunnel exited before port ${port} became reachable` : `ghc-tunnel exited with code ${childState.exit.code ?? "null"}${childState.exit.signal ? ` (${childState.exit.signal})` : ""}`;
|
|
148967
|
+
return buildResult({ host, port, command, args, pid, status: "failed", stdout, stderr, auth, detail });
|
|
148968
|
+
}
|
|
148969
|
+
await sleep2(pollIntervalMs);
|
|
148970
|
+
}
|
|
148971
|
+
await terminateChildProcess(child, stopTimeoutMs);
|
|
148972
|
+
return buildResult({ host, port, command, args, pid, status: "failed", stdout, stderr, auth, detail: `Timed out waiting for port ${port}` });
|
|
148973
|
+
}
|
|
148974
|
+
|
|
148672
148975
|
// ../../packages/api/src/node/node-operation-service.ts
|
|
148673
148976
|
var LEADER_REPORT_RETRY_MS = 5e3;
|
|
148977
|
+
var REMOTE_OPERATION_REFRESH_TIMEOUT_MS = 2e3;
|
|
148674
148978
|
var OPERATION_COMMIT_EFFECT = /* @__PURE__ */ Symbol("operationCommitEffect");
|
|
148979
|
+
function sleep3(ms) {
|
|
148980
|
+
return new Promise((resolve24) => setTimeout(resolve24, ms));
|
|
148981
|
+
}
|
|
148675
148982
|
var NodeOperationFailure = class extends Error {
|
|
148676
148983
|
constructor(message, result) {
|
|
148677
148984
|
super(message);
|
|
@@ -148708,6 +149015,9 @@ var NodeOperationService = class {
|
|
|
148708
149015
|
this.registerHandler("devbox.start", runDevBoxStartOperation);
|
|
148709
149016
|
this.registerHandler("runtime.restart", runRuntimeRestartOperation);
|
|
148710
149017
|
this.registerHandler("workdir.branch-create", runWorkDirBranchCreateOperation);
|
|
149018
|
+
this.registerHandler("copilot.tunnel.status", runCopilotTunnelStatusOperation);
|
|
149019
|
+
this.registerHandler("copilot.tunnel", runCopilotTunnelOperation);
|
|
149020
|
+
this.registerHandler("copilot.tunnel.disable", runCopilotTunnelDisableOperation);
|
|
148711
149021
|
}
|
|
148712
149022
|
handlers = /* @__PURE__ */ new Map();
|
|
148713
149023
|
leaderReportRetryTimers = /* @__PURE__ */ new Map();
|
|
@@ -148737,6 +149047,15 @@ var NodeOperationService = class {
|
|
|
148737
149047
|
list(filter) {
|
|
148738
149048
|
return this.store.list(filter);
|
|
148739
149049
|
}
|
|
149050
|
+
async waitForTerminal(id, timeoutMs) {
|
|
149051
|
+
const deadline = Date.now() + timeoutMs;
|
|
149052
|
+
while (Date.now() < deadline) {
|
|
149053
|
+
const current = this.store.get(id);
|
|
149054
|
+
if (!current || isTerminalStatus(current.status)) return current;
|
|
149055
|
+
await sleep3(50);
|
|
149056
|
+
}
|
|
149057
|
+
return this.store.get(id);
|
|
149058
|
+
}
|
|
148740
149059
|
accept(operation) {
|
|
148741
149060
|
const current = this.store.get(operation.id);
|
|
148742
149061
|
if (current) {
|
|
@@ -148754,6 +149073,9 @@ var NodeOperationService = class {
|
|
|
148754
149073
|
}
|
|
148755
149074
|
applyRemoteUpdate(operation) {
|
|
148756
149075
|
const current = this.store.get(operation.id);
|
|
149076
|
+
if (current && isTerminalStatus(current.status) && !isTerminalStatus(operation.status)) {
|
|
149077
|
+
return current;
|
|
149078
|
+
}
|
|
148757
149079
|
const saved = this.store.upsert(current ? { ...current, ...operation } : operation);
|
|
148758
149080
|
this.applyOperationSideEffects(saved);
|
|
148759
149081
|
this.deps.eventBus.emit("node.operation.updated", { operation: saved });
|
|
@@ -148779,7 +149101,9 @@ var NodeOperationService = class {
|
|
|
148779
149101
|
try {
|
|
148780
149102
|
const handler = this.handlers.get(running.kind);
|
|
148781
149103
|
if (!handler) throw new Error(`No node operation handler registered for kind: ${running.kind}`);
|
|
148782
|
-
const handled = readOperationCommitEffect(await handler(running, this.deps
|
|
149104
|
+
const handled = readOperationCommitEffect(await handler(running, this.deps, {
|
|
149105
|
+
updateProgress: (result) => this.update(id, { result }, { reportToLeader: true })
|
|
149106
|
+
}));
|
|
148783
149107
|
const saved = this.update(id, { status: "succeeded", result: handled.result, completedAt: Date.now() }, {
|
|
148784
149108
|
reportToLeader: handled.afterCommit ? false : true
|
|
148785
149109
|
});
|
|
@@ -148892,19 +149216,69 @@ function getNodeOperationService(deps) {
|
|
|
148892
149216
|
deps.nodeOperationService = service;
|
|
148893
149217
|
return service;
|
|
148894
149218
|
}
|
|
148895
|
-
async function
|
|
148896
|
-
|
|
149219
|
+
async function refreshRemoteNodeOperation(deps, operation) {
|
|
149220
|
+
if (isTerminalStatus(operation.status)) return operation;
|
|
149221
|
+
const self2 = deps.nodeRegistry.getSelf();
|
|
149222
|
+
if (operation.nodeId === self2.id) return operation;
|
|
149223
|
+
const node = deps.nodeRegistry.getNode(operation.nodeId);
|
|
149224
|
+
if (!node) return operation;
|
|
149225
|
+
const message = createNodeMessage("node.operation.get", { operationId: operation.id });
|
|
149226
|
+
const heartbeat = deps.heartbeat;
|
|
149227
|
+
try {
|
|
149228
|
+
const response = heartbeat.canPushToNode?.(node.id) === false && heartbeat.requestNodeMessage ? await heartbeat.requestNodeMessage(node.id, { ...message, expectsResponse: true }, REMOTE_OPERATION_REFRESH_TIMEOUT_MS) : await new NodeMessageClient({
|
|
149229
|
+
heartbeat: heartbeat.requestNodeMessage ? { requestNodeMessage: heartbeat.requestNodeMessage.bind(heartbeat) } : void 0,
|
|
149230
|
+
timeoutMs: REMOTE_OPERATION_REFRESH_TIMEOUT_MS,
|
|
149231
|
+
logger: deps.logger
|
|
149232
|
+
}).request(node, message);
|
|
149233
|
+
const remote = readOperationFromResponse(response);
|
|
149234
|
+
return remote ? getNodeOperationService(deps).applyRemoteUpdate(remote) : operation;
|
|
149235
|
+
} catch (err) {
|
|
149236
|
+
deps.logger.child("node-operation").debug("failed to refresh remote node operation", {
|
|
149237
|
+
operationId: operation.id,
|
|
149238
|
+
kind: operation.kind,
|
|
149239
|
+
nodeId: operation.nodeId,
|
|
149240
|
+
error: err instanceof Error ? err.message : String(err)
|
|
149241
|
+
});
|
|
149242
|
+
return operation;
|
|
149243
|
+
}
|
|
149244
|
+
}
|
|
149245
|
+
async function dispatchNodeOperation(deps, operation, node, options = {}) {
|
|
149246
|
+
const message = createNodeMessage("node.operation.execute", {
|
|
149247
|
+
operation,
|
|
149248
|
+
...options.waitForCompletionMs !== void 0 ? { waitForCompletionMs: options.waitForCompletionMs } : {}
|
|
149249
|
+
});
|
|
148897
149250
|
const heartbeat = deps.heartbeat;
|
|
148898
149251
|
if (heartbeat.canPushToNode?.(node.id) === false) {
|
|
149252
|
+
if (options.waitForCompletionMs !== void 0 && heartbeat.requestNodeMessage) {
|
|
149253
|
+
const response = await heartbeat.requestNodeMessage(node.id, message, options.waitForCompletionMs + 1e4);
|
|
149254
|
+
return applyOperationResponse(deps, response);
|
|
149255
|
+
}
|
|
148899
149256
|
if (!heartbeat.enqueueNodeMessage) throw new Error(`Cannot queue node operation for ${node.id}`);
|
|
148900
149257
|
heartbeat.enqueueNodeMessage(node.id, message);
|
|
148901
|
-
return;
|
|
149258
|
+
return null;
|
|
148902
149259
|
}
|
|
148903
149260
|
const client = new NodeMessageClient({
|
|
148904
|
-
heartbeat:
|
|
149261
|
+
heartbeat: {
|
|
149262
|
+
...heartbeat.enqueueNodeMessage ? { enqueueNodeMessage: heartbeat.enqueueNodeMessage.bind(heartbeat) } : {},
|
|
149263
|
+
...heartbeat.requestNodeMessage ? { requestNodeMessage: heartbeat.requestNodeMessage.bind(heartbeat) } : {}
|
|
149264
|
+
},
|
|
148905
149265
|
logger: deps.logger
|
|
148906
149266
|
});
|
|
149267
|
+
if (options.waitForCompletionMs !== void 0) {
|
|
149268
|
+
return applyOperationResponse(deps, await client.request(node, message));
|
|
149269
|
+
}
|
|
148907
149270
|
await client.send(node, message);
|
|
149271
|
+
return null;
|
|
149272
|
+
}
|
|
149273
|
+
function applyOperationResponse(deps, response) {
|
|
149274
|
+
if (!response.ok) throw new Error(`Node operation delivery failed with HTTP ${response.statusCode}`);
|
|
149275
|
+
const operation = readOperationFromResponse(response);
|
|
149276
|
+
return operation ? getNodeOperationService(deps).applyRemoteUpdate(operation) : null;
|
|
149277
|
+
}
|
|
149278
|
+
function readOperationFromResponse(response) {
|
|
149279
|
+
if (!response.ok) return null;
|
|
149280
|
+
const operation = response.body && typeof response.body === "object" ? response.body.operation : void 0;
|
|
149281
|
+
return operation && typeof operation === "object" ? operation : null;
|
|
148908
149282
|
}
|
|
148909
149283
|
function runAgentUpgradeOperation(operation, deps) {
|
|
148910
149284
|
const agent = readPayloadString(operation, "agent");
|
|
@@ -148953,6 +149327,23 @@ function runWorkDirBranchCreateOperation(operation, deps) {
|
|
|
148953
149327
|
}
|
|
148954
149328
|
);
|
|
148955
149329
|
}
|
|
149330
|
+
async function runCopilotTunnelOperation(_operation, deps, context4) {
|
|
149331
|
+
const result = await (deps.enableCopilotTunnel?.({ onProgress: context4.updateProgress, cwd: deps.workDir }) ?? enableGithubCopilotTunnel({ onProgress: context4.updateProgress, cwd: deps.workDir }));
|
|
149332
|
+
if (!result.ok) {
|
|
149333
|
+
throw new NodeOperationFailure(result.detail ?? "Copilot tunnel failed", result);
|
|
149334
|
+
}
|
|
149335
|
+
return result;
|
|
149336
|
+
}
|
|
149337
|
+
async function runCopilotTunnelStatusOperation(_operation, deps) {
|
|
149338
|
+
return deps.checkCopilotTunnel?.({}) ?? checkGithubCopilotTunnel();
|
|
149339
|
+
}
|
|
149340
|
+
async function runCopilotTunnelDisableOperation(_operation, deps) {
|
|
149341
|
+
const result = await (deps.disableCopilotTunnel?.({}) ?? disableGithubCopilotTunnel());
|
|
149342
|
+
if (!result.ok) {
|
|
149343
|
+
throw new NodeOperationFailure(result.detail ?? "Copilot tunnel stop failed", result);
|
|
149344
|
+
}
|
|
149345
|
+
return result;
|
|
149346
|
+
}
|
|
148956
149347
|
function readPayloadString(operation, key) {
|
|
148957
149348
|
const payload = operation.payload;
|
|
148958
149349
|
if (!payload || typeof payload !== "object") return "";
|
|
@@ -149406,14 +149797,14 @@ init_cjs_shims();
|
|
|
149406
149797
|
|
|
149407
149798
|
// ../../packages/api/src/node/node-terminal-session-service.ts
|
|
149408
149799
|
init_cjs_shims();
|
|
149409
|
-
var
|
|
149800
|
+
var import_node_child_process11 = require("child_process");
|
|
149410
149801
|
var import_node_crypto8 = require("crypto");
|
|
149411
149802
|
|
|
149412
149803
|
// ../../packages/api/src/node/node-terminal-service.ts
|
|
149413
149804
|
init_cjs_shims();
|
|
149414
149805
|
var fs22 = __toESM(require("fs"), 1);
|
|
149415
149806
|
var path26 = __toESM(require("path"), 1);
|
|
149416
|
-
var
|
|
149807
|
+
var DEFAULT_OUTPUT_LIMIT_BYTES2 = 64 * 1024;
|
|
149417
149808
|
function isAbsolutePath2(value) {
|
|
149418
149809
|
return path26.isAbsolute(value) || /^[A-Za-z]:[\/]/.test(value);
|
|
149419
149810
|
}
|
|
@@ -149434,7 +149825,7 @@ var MAX_COMPLETED_SESSIONS = 10;
|
|
|
149434
149825
|
function createOutputBuffer() {
|
|
149435
149826
|
return { chunks: [], bytes: 0, observedBytes: 0 };
|
|
149436
149827
|
}
|
|
149437
|
-
function
|
|
149828
|
+
function appendTail2(buffer, chunk, limitBytes) {
|
|
149438
149829
|
buffer.observedBytes += chunk.length;
|
|
149439
149830
|
const nextChunk = chunk.length > limitBytes ? chunk.subarray(chunk.length - limitBytes) : chunk;
|
|
149440
149831
|
buffer.chunks.push(nextChunk);
|
|
@@ -149487,7 +149878,7 @@ var NodeTerminalSessionService = class {
|
|
|
149487
149878
|
}
|
|
149488
149879
|
const cwd = resolveNodeTerminalCwd(nodeId, rootPath, options.cwd);
|
|
149489
149880
|
const startedAt = Date.now();
|
|
149490
|
-
const child = (0,
|
|
149881
|
+
const child = (0, import_node_child_process11.spawn)(normalizedCommand, {
|
|
149491
149882
|
cwd,
|
|
149492
149883
|
shell: true,
|
|
149493
149884
|
windowsHide: true,
|
|
@@ -149518,15 +149909,15 @@ var NodeTerminalSessionService = class {
|
|
|
149518
149909
|
stderr: createOutputBuffer(),
|
|
149519
149910
|
sequence: this.nextSequence++
|
|
149520
149911
|
};
|
|
149521
|
-
const outputLimitBytes = options.outputLimitBytes ??
|
|
149912
|
+
const outputLimitBytes = options.outputLimitBytes ?? DEFAULT_OUTPUT_LIMIT_BYTES2;
|
|
149522
149913
|
this.sessions.set(session.id, state3);
|
|
149523
149914
|
child.stdout?.on("data", (chunk) => {
|
|
149524
|
-
|
|
149915
|
+
appendTail2(state3.stdout, chunk, outputLimitBytes);
|
|
149525
149916
|
this.refreshOutput(state3, outputLimitBytes);
|
|
149526
149917
|
});
|
|
149527
149918
|
child.stderr?.on("data", (chunk) => {
|
|
149528
149919
|
if (state3.session.status === "stopped") return;
|
|
149529
|
-
|
|
149920
|
+
appendTail2(state3.stderr, chunk, outputLimitBytes);
|
|
149530
149921
|
this.refreshOutput(state3, outputLimitBytes);
|
|
149531
149922
|
});
|
|
149532
149923
|
child.on("error", (err) => {
|
|
@@ -150976,8 +151367,28 @@ async function executeWorkerControlRequest(deps, request2) {
|
|
|
150976
151367
|
if (!operation || typeof operation !== "object") {
|
|
150977
151368
|
throw new MeshyError("VALIDATION_ERROR", "node.operation.execute requires an operation payload", 400);
|
|
150978
151369
|
}
|
|
150979
|
-
const
|
|
150980
|
-
|
|
151370
|
+
const service = getNodeOperationService(deps);
|
|
151371
|
+
const accepted = service.accept(operation);
|
|
151372
|
+
const waitForCompletionMs = payloadValue(request2, "waitForCompletionMs", 0);
|
|
151373
|
+
const observed = waitForCompletionMs > 0 ? await service.waitForTerminal(accepted.id, waitForCompletionMs) : accepted;
|
|
151374
|
+
const current = observed ?? accepted;
|
|
151375
|
+
response = jsonResponse(request2.id, current.status === "queued" || current.status === "running" ? 202 : 200, {
|
|
151376
|
+
operationId: accepted.id,
|
|
151377
|
+
accepted: true,
|
|
151378
|
+
operation: current
|
|
151379
|
+
});
|
|
151380
|
+
break;
|
|
151381
|
+
}
|
|
151382
|
+
case "node.operation.get": {
|
|
151383
|
+
const operationId = payloadValue(request2, "operationId", "");
|
|
151384
|
+
if (typeof operationId !== "string" || !operationId.trim()) {
|
|
151385
|
+
throw new MeshyError("VALIDATION_ERROR", "node.operation.get requires operationId", 400);
|
|
151386
|
+
}
|
|
151387
|
+
const operation = getNodeOperationService(deps).get(operationId);
|
|
151388
|
+
if (!operation) {
|
|
151389
|
+
throw new MeshyError("NODE_NOT_FOUND", `Node operation ${operationId} not found`, 404);
|
|
151390
|
+
}
|
|
151391
|
+
response = jsonResponse(request2.id, 200, { operation });
|
|
150981
151392
|
break;
|
|
150982
151393
|
}
|
|
150983
151394
|
case "node.capabilities.list": {
|
|
@@ -151217,6 +151628,49 @@ async function sendNodeAgentUpgrade(req, res, nodeId, agentParam) {
|
|
|
151217
151628
|
res.status(202).json(operation);
|
|
151218
151629
|
}
|
|
151219
151630
|
|
|
151631
|
+
// ../../packages/api/src/routes/node-copilot-tunnel.ts
|
|
151632
|
+
init_cjs_shims();
|
|
151633
|
+
var COPILOT_TUNNEL_PORT = 8314;
|
|
151634
|
+
var REMOTE_COPILOT_TUNNEL_WAIT_MS = 4e3;
|
|
151635
|
+
async function sendNodeCopilotTunnelOperation(req, res, nodeId, kind, actionLabel) {
|
|
151636
|
+
const deps = req.app.locals.deps;
|
|
151637
|
+
const self2 = deps.nodeRegistry.getSelf();
|
|
151638
|
+
const isSelf2 = nodeId === self2.id;
|
|
151639
|
+
if (!isSelf2 && !deps.election.isLeader()) {
|
|
151640
|
+
throw new MeshyError("NOT_LEADER", `Only the leader can ${actionLabel} Copilot tunnels on other nodes`, 403);
|
|
151641
|
+
}
|
|
151642
|
+
const node = isSelf2 ? self2 : deps.nodeRegistry.getNode(nodeId);
|
|
151643
|
+
if (!node) {
|
|
151644
|
+
throw new MeshyError("NODE_NOT_FOUND", `Node ${nodeId} not found`, 404);
|
|
151645
|
+
}
|
|
151646
|
+
const operations = getNodeOperationService(deps);
|
|
151647
|
+
const operation = operations.create(kind, nodeId, { port: COPILOT_TUNNEL_PORT });
|
|
151648
|
+
if (isSelf2) {
|
|
151649
|
+
operations.runLocal(operation.id);
|
|
151650
|
+
} else {
|
|
151651
|
+
try {
|
|
151652
|
+
const observed = await dispatchNodeOperation(deps, operation, node, { waitForCompletionMs: REMOTE_COPILOT_TUNNEL_WAIT_MS });
|
|
151653
|
+
if (observed) {
|
|
151654
|
+
res.status(202).json(observed);
|
|
151655
|
+
return;
|
|
151656
|
+
}
|
|
151657
|
+
} catch (err) {
|
|
151658
|
+
operations.markFailed(operation.id, err instanceof Error ? err.message : String(err));
|
|
151659
|
+
throw new MeshyError("NODE_OFFLINE", `Cannot reach node ${nodeId} to ${actionLabel} Copilot tunnel`, 502);
|
|
151660
|
+
}
|
|
151661
|
+
}
|
|
151662
|
+
res.status(202).json(operation);
|
|
151663
|
+
}
|
|
151664
|
+
async function sendNodeCopilotTunnelStatus(req, res, nodeId) {
|
|
151665
|
+
await sendNodeCopilotTunnelOperation(req, res, nodeId, "copilot.tunnel.status", "check");
|
|
151666
|
+
}
|
|
151667
|
+
async function sendNodeCopilotTunnelEnable(req, res, nodeId) {
|
|
151668
|
+
await sendNodeCopilotTunnelOperation(req, res, nodeId, "copilot.tunnel", "enable");
|
|
151669
|
+
}
|
|
151670
|
+
async function sendNodeCopilotTunnelDisable(req, res, nodeId) {
|
|
151671
|
+
await sendNodeCopilotTunnelOperation(req, res, nodeId, "copilot.tunnel.disable", "disable");
|
|
151672
|
+
}
|
|
151673
|
+
|
|
151220
151674
|
// ../../packages/api/src/routes/node-runtime.ts
|
|
151221
151675
|
init_cjs_shims();
|
|
151222
151676
|
async function sendNodeRuntimeRestart(req, res, nodeId) {
|
|
@@ -151845,6 +152299,15 @@ function createNodeRoutes() {
|
|
|
151845
152299
|
router.post("/:id/agents/:agent/upgrade", asyncHandler3(async (req, res) => {
|
|
151846
152300
|
await sendNodeAgentUpgrade(req, res, req.params.id, req.params.agent);
|
|
151847
152301
|
}));
|
|
152302
|
+
router.post("/:id/copilot-tunnel/enable", asyncHandler3(async (req, res) => {
|
|
152303
|
+
await sendNodeCopilotTunnelEnable(req, res, req.params.id);
|
|
152304
|
+
}));
|
|
152305
|
+
router.post("/:id/copilot-tunnel/status", asyncHandler3(async (req, res) => {
|
|
152306
|
+
await sendNodeCopilotTunnelStatus(req, res, req.params.id);
|
|
152307
|
+
}));
|
|
152308
|
+
router.post("/:id/copilot-tunnel/disable", asyncHandler3(async (req, res) => {
|
|
152309
|
+
await sendNodeCopilotTunnelDisable(req, res, req.params.id);
|
|
152310
|
+
}));
|
|
151848
152311
|
router.post("/:id/runtime/restart", asyncHandler3(async (req, res) => {
|
|
151849
152312
|
await sendNodeRuntimeRestart(req, res, req.params.id);
|
|
151850
152313
|
}));
|
|
@@ -152666,7 +153129,7 @@ function startLocalTaskFollowUp(deps, task, content, assignedTo, metadata) {
|
|
|
152666
153129
|
// ../../packages/api/src/tasks/task-message-queue.ts
|
|
152667
153130
|
var registeredDrainers = /* @__PURE__ */ new WeakSet();
|
|
152668
153131
|
var drainingTaskIds = /* @__PURE__ */ new Set();
|
|
152669
|
-
var QUEUE_DRAIN_STATUSES = /* @__PURE__ */ new Set(["completed", "cancelled"]);
|
|
153132
|
+
var QUEUE_DRAIN_STATUSES = /* @__PURE__ */ new Set(["completed", "failed", "cancelled"]);
|
|
152670
153133
|
function restoreQueuedMessage(taskEngine, taskId, message) {
|
|
152671
153134
|
const current = taskEngine.getTask(taskId);
|
|
152672
153135
|
if (!current) return;
|
|
@@ -153750,7 +154213,7 @@ function createTaskRoutes() {
|
|
|
153750
154213
|
if (!task) {
|
|
153751
154214
|
throw new MeshyError("TASK_NOT_FOUND", `Task ${taskId} not found`, 404);
|
|
153752
154215
|
}
|
|
153753
|
-
if (!["running", "completed", "cancelled"].includes(task.status)) {
|
|
154216
|
+
if (!["running", "completed", "cancelled", "failed"].includes(task.status)) {
|
|
153754
154217
|
throw new MeshyError("VALIDATION_ERROR", `Cannot send message to task in ${task.status} status`, 400);
|
|
153755
154218
|
}
|
|
153756
154219
|
if (task.status === "running") {
|
|
@@ -154494,7 +154957,8 @@ function createNodeOperationRoutes() {
|
|
|
154494
154957
|
router.get("/:id", asyncHandler12(async (req, res) => {
|
|
154495
154958
|
if (await maybeProxyReadToLeader(req, res)) return;
|
|
154496
154959
|
const deps = req.app.locals.deps;
|
|
154497
|
-
const
|
|
154960
|
+
const current = getNodeOperationService(deps).get(req.params.id);
|
|
154961
|
+
const operation = current ? await refreshRemoteNodeOperation(deps, current) : null;
|
|
154498
154962
|
if (!operation) {
|
|
154499
154963
|
throw new MeshyError("NODE_NOT_FOUND", `Node operation ${req.params.id} not found`, 404);
|
|
154500
154964
|
}
|
|
@@ -154711,31 +155175,6 @@ function resolveRuntimeBaseDir() {
|
|
|
154711
155175
|
}
|
|
154712
155176
|
return process.cwd();
|
|
154713
155177
|
}
|
|
154714
|
-
function escapeInlineJson(value) {
|
|
154715
|
-
return JSON.stringify(value).replace(/</g, "\\u003c").replace(/>/g, "\\u003e").replace(/&/g, "\\u0026").replace(/\u2028/g, "\\u2028").replace(/\u2029/g, "\\u2029");
|
|
154716
|
-
}
|
|
154717
|
-
function buildDashboardRuntimeConfigScript(req, deps) {
|
|
154718
|
-
const dashboardTunnelAuthorization = isShareHostRequest(req, deps.shareOrigin) ? null : deps.dashboardTunnelAuthorization ?? null;
|
|
154719
|
-
return `<script>window.__MESHY_RUNTIME_CONFIG__=${escapeInlineJson({ dashboardTunnelAuthorization })};</script>`;
|
|
154720
|
-
}
|
|
154721
|
-
function injectDashboardRuntimeConfig(html, req, deps) {
|
|
154722
|
-
const script = buildDashboardRuntimeConfigScript(req, deps);
|
|
154723
|
-
return html.includes("</head>") ? html.replace("</head>", `${script}</head>`) : `${script}${html}`;
|
|
154724
|
-
}
|
|
154725
|
-
function serveDashboardIndex(indexPath, deps) {
|
|
154726
|
-
return (req, res, next) => {
|
|
154727
|
-
fs27.readFile(indexPath, "utf8", (err, html) => {
|
|
154728
|
-
if (err) {
|
|
154729
|
-
next(err);
|
|
154730
|
-
return;
|
|
154731
|
-
}
|
|
154732
|
-
res.type("html").send(injectDashboardRuntimeConfig(html, req, deps));
|
|
154733
|
-
});
|
|
154734
|
-
};
|
|
154735
|
-
}
|
|
154736
|
-
function isDashboardIndexAssetRequest(req) {
|
|
154737
|
-
return req.method === "GET" && (req.path === "/" || req.path === "/index.html");
|
|
154738
|
-
}
|
|
154739
155178
|
function resolveStaticDir(baseDir) {
|
|
154740
155179
|
const envStaticDir = process.env.MESHY_STATIC_DIR;
|
|
154741
155180
|
const candidateDirs = [
|
|
@@ -154822,8 +155261,6 @@ function createServer2(deps) {
|
|
|
154822
155261
|
const staticDir = resolveStaticDir(runtimeBaseDir);
|
|
154823
155262
|
if (staticDir) {
|
|
154824
155263
|
const staticMiddleware = import_express17.default.static(staticDir);
|
|
154825
|
-
const indexPath = path31.join(staticDir, "index.html");
|
|
154826
|
-
const serveIndex = fs27.existsSync(indexPath) ? serveDashboardIndex(indexPath, deps) : null;
|
|
154827
155264
|
app.use((req, res, next) => {
|
|
154828
155265
|
if (isApiRequest(req) || isPreviewRequest(req)) {
|
|
154829
155266
|
next();
|
|
@@ -154833,10 +155270,6 @@ function createServer2(deps) {
|
|
|
154833
155270
|
res.status(404).type("text/plain").send("Not Found");
|
|
154834
155271
|
return;
|
|
154835
155272
|
}
|
|
154836
|
-
if (serveIndex && isDashboardIndexAssetRequest(req)) {
|
|
154837
|
-
serveIndex(req, res, next);
|
|
154838
|
-
return;
|
|
154839
|
-
}
|
|
154840
155273
|
staticMiddleware(req, res, next);
|
|
154841
155274
|
});
|
|
154842
155275
|
}
|
|
@@ -154888,7 +155321,6 @@ function createServer2(deps) {
|
|
|
154888
155321
|
if (staticDir) {
|
|
154889
155322
|
const indexPath = path31.join(staticDir, "index.html");
|
|
154890
155323
|
if (fs27.existsSync(indexPath)) {
|
|
154891
|
-
const serveIndex = serveDashboardIndex(indexPath, deps);
|
|
154892
155324
|
app.get("*", (req, res, next) => {
|
|
154893
155325
|
if (isApiRequest(req)) {
|
|
154894
155326
|
next();
|
|
@@ -154898,7 +155330,7 @@ function createServer2(deps) {
|
|
|
154898
155330
|
res.status(404).type("text/plain").send("Not Found");
|
|
154899
155331
|
return;
|
|
154900
155332
|
}
|
|
154901
|
-
|
|
155333
|
+
res.sendFile(indexPath);
|
|
154902
155334
|
});
|
|
154903
155335
|
}
|
|
154904
155336
|
}
|
|
@@ -155061,7 +155493,7 @@ var DirectTransport = class {
|
|
|
155061
155493
|
|
|
155062
155494
|
// ../../packages/transport/src/devtunnel.ts
|
|
155063
155495
|
init_cjs_shims();
|
|
155064
|
-
var
|
|
155496
|
+
var import_node_child_process12 = require("child_process");
|
|
155065
155497
|
var fs28 = __toESM(require("fs"), 1);
|
|
155066
155498
|
var path32 = __toESM(require("path"), 1);
|
|
155067
155499
|
function hiddenPipeOptions() {
|
|
@@ -155079,7 +155511,7 @@ function isInstalled(cmd) {
|
|
|
155079
155511
|
return fs28.existsSync(cmd);
|
|
155080
155512
|
}
|
|
155081
155513
|
try {
|
|
155082
|
-
(0,
|
|
155514
|
+
(0, import_node_child_process12.execFileSync)(process.platform === "win32" ? "where.exe" : "which", [cmd], hiddenPipeOptions());
|
|
155083
155515
|
return true;
|
|
155084
155516
|
} catch {
|
|
155085
155517
|
return false;
|
|
@@ -155133,10 +155565,10 @@ function resolveDevTunnelCommand() {
|
|
|
155133
155565
|
return "devtunnel";
|
|
155134
155566
|
}
|
|
155135
155567
|
function runDevTunnel(command, args) {
|
|
155136
|
-
return (0,
|
|
155568
|
+
return (0, import_node_child_process12.execFileSync)(command, args, hiddenPipeOptions());
|
|
155137
155569
|
}
|
|
155138
155570
|
function runDevTunnelText(command, args) {
|
|
155139
|
-
const result = (0,
|
|
155571
|
+
const result = (0, import_node_child_process12.spawnSync)(command, args, hiddenTextOptions());
|
|
155140
155572
|
if (result.error) {
|
|
155141
155573
|
throw result.error;
|
|
155142
155574
|
}
|
|
@@ -155178,7 +155610,7 @@ var DevTunnelTransport = class {
|
|
|
155178
155610
|
);
|
|
155179
155611
|
}
|
|
155180
155612
|
const hostArgs = this.buildHostArgs(localPort, devTunnelCommand);
|
|
155181
|
-
const child = (0,
|
|
155613
|
+
const child = (0, import_node_child_process12.spawn)(devTunnelCommand, hostArgs, hiddenSpawnOptions());
|
|
155182
155614
|
this.process = child;
|
|
155183
155615
|
this.publicUrl = await new Promise((resolve24, reject) => {
|
|
155184
155616
|
const timeout = setTimeout(() => {
|
|
@@ -155504,7 +155936,7 @@ init_cjs_shims();
|
|
|
155504
155936
|
var fs29 = __toESM(require("fs"), 1);
|
|
155505
155937
|
var path33 = __toESM(require("path"), 1);
|
|
155506
155938
|
var readline = __toESM(require("readline/promises"), 1);
|
|
155507
|
-
var
|
|
155939
|
+
var import_node_child_process13 = require("child_process");
|
|
155508
155940
|
var STARTUP_REQUIREMENTS = ["az", "devtunnel", "claude", "codex", "copilot"];
|
|
155509
155941
|
function writeLine(stream, message = "") {
|
|
155510
155942
|
stream.write(`${message}
|
|
@@ -155534,7 +155966,7 @@ function createPromptSession(prompt) {
|
|
|
155534
155966
|
}
|
|
155535
155967
|
function createDefaultCommandRunner(platform6) {
|
|
155536
155968
|
return (command, args, interactive = false) => {
|
|
155537
|
-
const result = (0,
|
|
155969
|
+
const result = (0, import_node_child_process13.spawnSync)(command, args, {
|
|
155538
155970
|
encoding: "utf-8",
|
|
155539
155971
|
shell: platform6 === "win32",
|
|
155540
155972
|
stdio: interactive ? "inherit" : "pipe",
|
|
@@ -155645,7 +156077,7 @@ function isRequirementSatisfied(requirement, status) {
|
|
|
155645
156077
|
}
|
|
155646
156078
|
return true;
|
|
155647
156079
|
}
|
|
155648
|
-
function
|
|
156080
|
+
function sleep4(ms) {
|
|
155649
156081
|
return new Promise((resolve24) => setTimeout(resolve24, ms));
|
|
155650
156082
|
}
|
|
155651
156083
|
function areCachedAuthRequirementsCurrent(commandRunner) {
|
|
@@ -155709,7 +156141,7 @@ async function ensureRequirementAuthenticated(requirement, getAsk, commandRunner
|
|
|
155709
156141
|
if (isAuthenticated(requirement, commandRunner)) {
|
|
155710
156142
|
return { authenticated: true, status: "ok" };
|
|
155711
156143
|
}
|
|
155712
|
-
await
|
|
156144
|
+
await sleep4(Math.max(0, authPollIntervalMs));
|
|
155713
156145
|
}
|
|
155714
156146
|
writeLine(stderr, `${requirement} login finished, but authentication was not available before timeout.`);
|
|
155715
156147
|
return { authenticated: false, status: "login-failed" };
|
|
@@ -156019,7 +156451,7 @@ function formatLoadedStartMetadata(info, authEnabled) {
|
|
|
156019
156451
|
init_cjs_shims();
|
|
156020
156452
|
var fs31 = __toESM(require("fs"), 1);
|
|
156021
156453
|
var path34 = __toESM(require("path"), 1);
|
|
156022
|
-
var
|
|
156454
|
+
var import_node_child_process14 = require("child_process");
|
|
156023
156455
|
var runtimeDir = resolveRuntimeDir();
|
|
156024
156456
|
var appRoot = resolveAppRoot(runtimeDir);
|
|
156025
156457
|
var repoRoot = path34.resolve(appRoot, "../..");
|
|
@@ -156115,7 +156547,7 @@ function readRepositoryUrlFromManifest(manifest) {
|
|
|
156115
156547
|
}
|
|
156116
156548
|
function readGitValue(args) {
|
|
156117
156549
|
try {
|
|
156118
|
-
const output = (0,
|
|
156550
|
+
const output = (0, import_node_child_process14.execFileSync)("git", args, {
|
|
156119
156551
|
cwd: repoRoot,
|
|
156120
156552
|
encoding: "utf-8",
|
|
156121
156553
|
stdio: ["ignore", "pipe", "ignore"],
|
|
@@ -156227,7 +156659,7 @@ function isDevTunnelOrigin(value) {
|
|
|
156227
156659
|
init_cjs_shims();
|
|
156228
156660
|
var fs32 = __toESM(require("fs"), 1);
|
|
156229
156661
|
var nodePath2 = __toESM(require("path"), 1);
|
|
156230
|
-
var
|
|
156662
|
+
var import_node_child_process15 = require("child_process");
|
|
156231
156663
|
var RUNTIME_UPDATE_CHECK_INTERVAL_MS = 6 * 60 * 60 * 1e3;
|
|
156232
156664
|
function resolveRuntimeRestartStartArgs(hydratedArgs, restartArgs) {
|
|
156233
156665
|
return restartArgs ? { ...restartArgs } : hydratedArgs;
|
|
@@ -156336,7 +156768,7 @@ function compareSemver2(left, right) {
|
|
|
156336
156768
|
return 0;
|
|
156337
156769
|
}
|
|
156338
156770
|
function runRuntimePackageCommand(command, args) {
|
|
156339
|
-
const result = (0,
|
|
156771
|
+
const result = (0, import_node_child_process15.spawnSync)(command, args, {
|
|
156340
156772
|
encoding: "utf-8",
|
|
156341
156773
|
windowsHide: true,
|
|
156342
156774
|
timeout: 2500
|
|
@@ -156361,7 +156793,7 @@ function resolveDevelopmentRepoRoot(cwd, env3, platform6) {
|
|
|
156361
156793
|
const packageParent = pathApi.basename(pathApi.dirname(cwd));
|
|
156362
156794
|
return packageDir === "node" && packageParent === "apps" ? pathApi.dirname(pathApi.dirname(cwd)) : cwd;
|
|
156363
156795
|
}
|
|
156364
|
-
function
|
|
156796
|
+
function windowsShellQuote2(value) {
|
|
156365
156797
|
return /[\s&()^|<>"]/.test(value) ? `"${value.replace(/"/g, '\\"')}"` : value;
|
|
156366
156798
|
}
|
|
156367
156799
|
function createSpawnableCommand(command, args, platform6) {
|
|
@@ -156369,13 +156801,13 @@ function createSpawnableCommand(command, args, platform6) {
|
|
|
156369
156801
|
if (platform6 !== "win32") return { command, args, displayCommand };
|
|
156370
156802
|
return {
|
|
156371
156803
|
command: "cmd.exe",
|
|
156372
|
-
args: ["/d", "/s", "/c", [command, ...args].map(
|
|
156804
|
+
args: ["/d", "/s", "/c", [command, ...args].map(windowsShellQuote2).join(" ")],
|
|
156373
156805
|
displayCommand
|
|
156374
156806
|
};
|
|
156375
156807
|
}
|
|
156376
156808
|
function readProcessCommand(pid, platform6) {
|
|
156377
156809
|
if (platform6 === "win32") return null;
|
|
156378
|
-
const result = (0,
|
|
156810
|
+
const result = (0, import_node_child_process15.spawnSync)("ps", ["-p", String(pid), "-o", "args="], {
|
|
156379
156811
|
encoding: "utf-8",
|
|
156380
156812
|
windowsHide: true,
|
|
156381
156813
|
timeout: 1e3
|
|
@@ -156469,7 +156901,7 @@ function createRuntimeRestartLaunchPlan(options) {
|
|
|
156469
156901
|
function scheduleRuntimeRestart(plan, options = {}) {
|
|
156470
156902
|
fs32.mkdirSync(nodePath2.dirname(plan.logPath), { recursive: true });
|
|
156471
156903
|
const logFd = fs32.openSync(plan.logPath, "a");
|
|
156472
|
-
const spawnImpl = options.spawnImpl ??
|
|
156904
|
+
const spawnImpl = options.spawnImpl ?? import_node_child_process15.spawn;
|
|
156473
156905
|
const env3 = {
|
|
156474
156906
|
...process.env,
|
|
156475
156907
|
MESHY_RESTART_PARENT_PID: String(options.parentPid ?? process.pid),
|
|
@@ -164919,7 +165351,6 @@ async function fetchWithTimeout2(fetchImpl, url3, timeoutMs) {
|
|
|
164919
165351
|
function createTunnelManager(options) {
|
|
164920
165352
|
const { authMetadata, config: config2, meshyNode } = options;
|
|
164921
165353
|
let dashboardOrigin;
|
|
164922
|
-
let dashboardTunnelAuthorization;
|
|
164923
165354
|
let shareOrigin;
|
|
164924
165355
|
let dashboardTransport = null;
|
|
164925
165356
|
let shareTransport = null;
|
|
@@ -164960,10 +165391,6 @@ function createTunnelManager(options) {
|
|
|
164960
165391
|
options.onDashboardOriginChange(origin);
|
|
164961
165392
|
meshyNode.getNodeRegistry().updateDashboardOrigin(meshyNode.getNodeRegistry().getSelf().id, origin);
|
|
164962
165393
|
}
|
|
164963
|
-
function setDashboardTunnelAuthorization(authorization) {
|
|
164964
|
-
dashboardTunnelAuthorization = authorization;
|
|
164965
|
-
options.onDashboardTunnelAuthorizationChange(authorization);
|
|
164966
|
-
}
|
|
164967
165394
|
function setShareOrigin(origin) {
|
|
164968
165395
|
shareOrigin = origin;
|
|
164969
165396
|
options.onShareOriginChange(origin);
|
|
@@ -165004,32 +165431,17 @@ function createTunnelManager(options) {
|
|
|
165004
165431
|
if (dashboardOrigin) {
|
|
165005
165432
|
setDashboardOrigin(void 0);
|
|
165006
165433
|
}
|
|
165007
|
-
setDashboardTunnelAuthorization(void 0);
|
|
165008
165434
|
return;
|
|
165009
165435
|
}
|
|
165010
165436
|
await dashboardTransport.stop().catch(() => void 0);
|
|
165011
165437
|
dashboardTransport = null;
|
|
165012
165438
|
setDashboardOrigin(void 0);
|
|
165013
|
-
setDashboardTunnelAuthorization(void 0);
|
|
165014
165439
|
meshyNode.getLogger().info("stopped dashboard tunnel", {
|
|
165015
165440
|
reason,
|
|
165016
165441
|
mainTransportType: meshyNode.getTransportType(),
|
|
165017
165442
|
sidecarEnabled: meshyNode.isDevTunnelEnabled()
|
|
165018
165443
|
});
|
|
165019
165444
|
}
|
|
165020
|
-
async function resolveDashboardTunnelAuthorization(transport) {
|
|
165021
|
-
if (typeof transport.getAuthorizationHeader !== "function") {
|
|
165022
|
-
return void 0;
|
|
165023
|
-
}
|
|
165024
|
-
try {
|
|
165025
|
-
return await transport.getAuthorizationHeader();
|
|
165026
|
-
} catch (err) {
|
|
165027
|
-
meshyNode.getLogger().warn("failed to create dashboard tunnel authorization header", {
|
|
165028
|
-
error: err instanceof Error ? err.message : String(err)
|
|
165029
|
-
});
|
|
165030
|
-
return void 0;
|
|
165031
|
-
}
|
|
165032
|
-
}
|
|
165033
165445
|
async function restartDashboardTransport(reason) {
|
|
165034
165446
|
const transportConfig = createDashboardTransportConfig();
|
|
165035
165447
|
const previousTransport = dashboardTransport;
|
|
@@ -165038,15 +165450,12 @@ function createTunnelManager(options) {
|
|
|
165038
165450
|
await previousTransport.stop().catch(() => void 0);
|
|
165039
165451
|
dashboardTransport = null;
|
|
165040
165452
|
setDashboardOrigin(void 0);
|
|
165041
|
-
setDashboardTunnelAuthorization(void 0);
|
|
165042
165453
|
}
|
|
165043
165454
|
try {
|
|
165044
165455
|
nextTransport = createTransport(transportConfig);
|
|
165045
165456
|
await nextTransport.start(config2.node.port);
|
|
165046
165457
|
const nextOrigin = await nextTransport.getEndpoint();
|
|
165047
|
-
const nextAuthorization = await resolveDashboardTunnelAuthorization(nextTransport);
|
|
165048
165458
|
dashboardTransport = nextTransport;
|
|
165049
|
-
setDashboardTunnelAuthorization(nextAuthorization);
|
|
165050
165459
|
setDashboardOrigin(nextOrigin);
|
|
165051
165460
|
meshyNode.getLogger().info("started dashboard tunnel", {
|
|
165052
165461
|
reason,
|
|
@@ -165061,7 +165470,6 @@ function createTunnelManager(options) {
|
|
|
165061
165470
|
}
|
|
165062
165471
|
dashboardTransport = null;
|
|
165063
165472
|
setDashboardOrigin(void 0);
|
|
165064
|
-
setDashboardTunnelAuthorization(void 0);
|
|
165065
165473
|
meshyNode.getLogger().warn("failed to start dashboard transport", {
|
|
165066
165474
|
reason,
|
|
165067
165475
|
error: err instanceof Error ? err.message : String(err),
|
|
@@ -165273,7 +165681,6 @@ function createTunnelManager(options) {
|
|
|
165273
165681
|
await dashboardTransport.stop();
|
|
165274
165682
|
dashboardTransport = null;
|
|
165275
165683
|
setDashboardOrigin(void 0);
|
|
165276
|
-
setDashboardTunnelAuthorization(void 0);
|
|
165277
165684
|
}
|
|
165278
165685
|
if (shareTransport) {
|
|
165279
165686
|
await shareTransport.stop();
|
|
@@ -165284,7 +165691,6 @@ function createTunnelManager(options) {
|
|
|
165284
165691
|
return {
|
|
165285
165692
|
ensureShareTunnel,
|
|
165286
165693
|
getDashboardOrigin: () => dashboardOrigin,
|
|
165287
|
-
getDashboardTunnelAuthorization: () => dashboardTunnelAuthorization,
|
|
165288
165694
|
getShareOrigin: () => shareOrigin,
|
|
165289
165695
|
startHealthChecks,
|
|
165290
165696
|
stop,
|
|
@@ -165532,11 +165938,6 @@ async function startNode(args) {
|
|
|
165532
165938
|
deps.dashboardOrigin = origin;
|
|
165533
165939
|
}
|
|
165534
165940
|
},
|
|
165535
|
-
onDashboardTunnelAuthorizationChange: (authorization) => {
|
|
165536
|
-
if (deps) {
|
|
165537
|
-
deps.dashboardTunnelAuthorization = authorization;
|
|
165538
|
-
}
|
|
165539
|
-
},
|
|
165540
165941
|
onShareOriginChange: (origin) => {
|
|
165541
165942
|
if (deps) {
|
|
165542
165943
|
deps.shareOrigin = origin;
|
|
@@ -165645,7 +166046,6 @@ async function startNode(args) {
|
|
|
165645
166046
|
runtimeMetadata
|
|
165646
166047
|
}),
|
|
165647
166048
|
dashboardOrigin: tunnelManager.getDashboardOrigin(),
|
|
165648
|
-
dashboardTunnelAuthorization: tunnelManager.getDashboardTunnelAuthorization(),
|
|
165649
166049
|
shareOrigin: tunnelManager.getShareOrigin(),
|
|
165650
166050
|
ensureShareTunnel: () => tunnelManager.ensureShareTunnel(),
|
|
165651
166051
|
runtimeMetadata,
|