meshy-node 0.3.8 → 0.3.9
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-0TdEZxup.js +119 -0
- package/dashboard/assets/{DashboardShared-C3sx-Aj3.js → DashboardShared-BfSOAHkB.js} +1 -1
- package/dashboard/assets/{DiffTab-DF380dMh.js → DiffTab-Dkqx4lg8.js} +1 -1
- package/dashboard/assets/{FilesTab-DZ2CIfBe.js → FilesTab-BWK1YZk0.js} +1 -1
- package/dashboard/assets/{PreviewTab-DGzp5vs_.js → PreviewTab-CgGqqXSW.js} +5 -10
- package/dashboard/assets/{SharedConversationPage-6Y6HiGBv.js → SharedConversationPage-COhUZENs.js} +3 -3
- package/dashboard/assets/{file-CkjhxpTi.js → file-BdIshbRs.js} +1 -1
- package/dashboard/assets/{folder-DcAuKKJN.js → folder-Cl9WN_cx.js} +1 -1
- package/dashboard/assets/{index-U21aiFFx.js → index-DHC5U3_j.js} +2 -2
- package/dashboard/assets/input-CdkmqjGJ.js +6 -0
- package/dashboard/index.html +1 -1
- package/main.cjs +167 -242
- package/package.json +1 -1
- package/runtime-metadata.json +4 -4
- package/dashboard/assets/DashboardPage-BGDwH7LG.js +0 -119
- package/dashboard/assets/input-BA2z1FFh.js +0 -1
package/main.cjs
CHANGED
|
@@ -33297,6 +33297,7 @@ function createNodeMessage(kind, payload, options = {}) {
|
|
|
33297
33297
|
}
|
|
33298
33298
|
|
|
33299
33299
|
// ../../packages/core/src/messaging/node-message-client.ts
|
|
33300
|
+
var RETRYABLE_NODE_MESSAGE_STATUSES = /* @__PURE__ */ new Set([502, 503, 504]);
|
|
33300
33301
|
var NodeMessageClient = class {
|
|
33301
33302
|
constructor(options = {}) {
|
|
33302
33303
|
this.options = options;
|
|
@@ -33335,6 +33336,16 @@ var NodeMessageClient = class {
|
|
|
33335
33336
|
throw error;
|
|
33336
33337
|
}
|
|
33337
33338
|
if (!response.ok) {
|
|
33339
|
+
if (RETRYABLE_NODE_MESSAGE_STATUSES.has(response.status) && this.options.heartbeat?.enqueueNodeMessage) {
|
|
33340
|
+
this.log?.warn("direct node message delivery returned retryable status; queued for keepalive", {
|
|
33341
|
+
nodeId: node.id,
|
|
33342
|
+
messageId: message.id,
|
|
33343
|
+
kind: message.kind,
|
|
33344
|
+
statusCode: response.status
|
|
33345
|
+
});
|
|
33346
|
+
this.options.heartbeat.enqueueNodeMessage(node.id, message);
|
|
33347
|
+
return { queued: true };
|
|
33348
|
+
}
|
|
33338
33349
|
throw new Error(await formatHttpError(response));
|
|
33339
33350
|
}
|
|
33340
33351
|
return { queued: false };
|
|
@@ -43063,6 +43074,7 @@ var NativeSessionSummarySchema = external_exports.object({
|
|
|
43063
43074
|
summary: external_exports.string(),
|
|
43064
43075
|
updatedAt: external_exports.string().nullable()
|
|
43065
43076
|
});
|
|
43077
|
+
var NodeOperationStatusSchema = external_exports.enum(["queued", "running", "succeeded", "failed"]);
|
|
43066
43078
|
var NodeListQuery = external_exports.object({
|
|
43067
43079
|
status: external_exports.enum(["online", "busy", "offline"]).optional(),
|
|
43068
43080
|
capability: external_exports.string().optional()
|
|
@@ -43141,7 +43153,7 @@ var NodeNativeSessionsResponse = external_exports.object({
|
|
|
43141
43153
|
agent: external_exports.enum(["codex", "claudecode"]),
|
|
43142
43154
|
sessions: external_exports.array(NativeSessionSummarySchema)
|
|
43143
43155
|
});
|
|
43144
|
-
var
|
|
43156
|
+
var NodeTerminalExecuteResult = external_exports.object({
|
|
43145
43157
|
nodeId: external_exports.string(),
|
|
43146
43158
|
cwd: external_exports.string(),
|
|
43147
43159
|
command: external_exports.string(),
|
|
@@ -43153,6 +43165,20 @@ var NodeTerminalExecuteResponse = external_exports.object({
|
|
|
43153
43165
|
stdoutTruncated: external_exports.boolean(),
|
|
43154
43166
|
stderrTruncated: external_exports.boolean()
|
|
43155
43167
|
});
|
|
43168
|
+
var NodeTerminalExecuteResponse = external_exports.object({
|
|
43169
|
+
id: external_exports.string(),
|
|
43170
|
+
kind: external_exports.literal("terminal.execute"),
|
|
43171
|
+
nodeId: external_exports.string(),
|
|
43172
|
+
requestedByNodeId: external_exports.string().optional(),
|
|
43173
|
+
status: NodeOperationStatusSchema,
|
|
43174
|
+
payload: NodeTerminalExecuteBody,
|
|
43175
|
+
result: NodeTerminalExecuteResult.optional(),
|
|
43176
|
+
error: external_exports.string().optional(),
|
|
43177
|
+
createdAt: external_exports.number(),
|
|
43178
|
+
updatedAt: external_exports.number(),
|
|
43179
|
+
startedAt: external_exports.number().optional(),
|
|
43180
|
+
completedAt: external_exports.number().optional()
|
|
43181
|
+
});
|
|
43156
43182
|
var UpdateNodeBody = external_exports.object({
|
|
43157
43183
|
name: external_exports.string().min(1).optional(),
|
|
43158
43184
|
capabilities: external_exports.array(external_exports.string()).optional()
|
|
@@ -44477,8 +44503,8 @@ function computeParentPath(rootPath, currentPath, useAbsolute) {
|
|
|
44477
44503
|
}
|
|
44478
44504
|
|
|
44479
44505
|
// ../../packages/api/src/node/node-operation-service.ts
|
|
44480
|
-
var
|
|
44481
|
-
var
|
|
44506
|
+
var fs16 = __toESM(require("fs"), 1);
|
|
44507
|
+
var path18 = __toESM(require("path"), 1);
|
|
44482
44508
|
var import_node_crypto7 = require("crypto");
|
|
44483
44509
|
|
|
44484
44510
|
// ../../packages/api/src/node/agent-upgrade-service.ts
|
|
@@ -44764,6 +44790,95 @@ function upgradeRuntimeAgentForDeps(deps, agent) {
|
|
|
44764
44790
|
return result;
|
|
44765
44791
|
}
|
|
44766
44792
|
|
|
44793
|
+
// ../../packages/api/src/node/node-terminal-service.ts
|
|
44794
|
+
var import_node_child_process10 = require("child_process");
|
|
44795
|
+
var fs15 = __toESM(require("fs"), 1);
|
|
44796
|
+
var path17 = __toESM(require("path"), 1);
|
|
44797
|
+
var DEFAULT_TIMEOUT_MS = 3e4;
|
|
44798
|
+
var DEFAULT_OUTPUT_LIMIT_BYTES = 64 * 1024;
|
|
44799
|
+
function isAbsolutePath2(value) {
|
|
44800
|
+
return path17.isAbsolute(value) || /^[A-Za-z]:[\/]/.test(value);
|
|
44801
|
+
}
|
|
44802
|
+
function resolveCommandCwd(nodeId, rootPath, cwd) {
|
|
44803
|
+
if (!rootPath) {
|
|
44804
|
+
throw new MeshyError("VALIDATION_ERROR", `Node ${nodeId} does not expose a working directory`, 400);
|
|
44805
|
+
}
|
|
44806
|
+
const requestedCwd = cwd?.trim() || ".";
|
|
44807
|
+
const resolved = isAbsolutePath2(requestedCwd) ? path17.resolve(requestedCwd) : path17.resolve(rootPath, requestedCwd);
|
|
44808
|
+
if (!fs15.existsSync(resolved) || !fs15.statSync(resolved).isDirectory()) {
|
|
44809
|
+
throw new MeshyError("VALIDATION_ERROR", `Working directory does not exist: ${resolved}`, 400);
|
|
44810
|
+
}
|
|
44811
|
+
return resolved;
|
|
44812
|
+
}
|
|
44813
|
+
function captureLimited(chunks, chunk, currentBytes, limitBytes) {
|
|
44814
|
+
if (currentBytes >= limitBytes) {
|
|
44815
|
+
return currentBytes + chunk.length;
|
|
44816
|
+
}
|
|
44817
|
+
const remaining = limitBytes - currentBytes;
|
|
44818
|
+
chunks.push(chunk.length <= remaining ? chunk : chunk.subarray(0, remaining));
|
|
44819
|
+
return currentBytes + chunk.length;
|
|
44820
|
+
}
|
|
44821
|
+
function toCapturedOutput(chunks, observedBytes, limitBytes) {
|
|
44822
|
+
return {
|
|
44823
|
+
text: Buffer.concat(chunks).toString("utf8"),
|
|
44824
|
+
truncated: observedBytes > limitBytes
|
|
44825
|
+
};
|
|
44826
|
+
}
|
|
44827
|
+
function executeLocalNodeTerminalCommand(nodeId, rootPath, command, options = {}) {
|
|
44828
|
+
const normalizedCommand = command.trim();
|
|
44829
|
+
if (!normalizedCommand) {
|
|
44830
|
+
throw new MeshyError("VALIDATION_ERROR", "Command must not be empty", 400);
|
|
44831
|
+
}
|
|
44832
|
+
const cwd = resolveCommandCwd(nodeId, rootPath, options.cwd);
|
|
44833
|
+
const timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;
|
|
44834
|
+
const outputLimitBytes = options.outputLimitBytes ?? DEFAULT_OUTPUT_LIMIT_BYTES;
|
|
44835
|
+
const startedAt = Date.now();
|
|
44836
|
+
const stdoutChunks = [];
|
|
44837
|
+
const stderrChunks = [];
|
|
44838
|
+
let stdoutBytes = 0;
|
|
44839
|
+
let stderrBytes = 0;
|
|
44840
|
+
let timedOut = false;
|
|
44841
|
+
return new Promise((resolve15, reject) => {
|
|
44842
|
+
const child = (0, import_node_child_process10.spawn)(normalizedCommand, {
|
|
44843
|
+
cwd,
|
|
44844
|
+
shell: true,
|
|
44845
|
+
windowsHide: true,
|
|
44846
|
+
stdio: ["ignore", "pipe", "pipe"]
|
|
44847
|
+
});
|
|
44848
|
+
const timeout = setTimeout(() => {
|
|
44849
|
+
timedOut = true;
|
|
44850
|
+
child.kill("SIGTERM");
|
|
44851
|
+
}, timeoutMs);
|
|
44852
|
+
child.stdout?.on("data", (chunk) => {
|
|
44853
|
+
stdoutBytes = captureLimited(stdoutChunks, chunk, stdoutBytes, outputLimitBytes);
|
|
44854
|
+
});
|
|
44855
|
+
child.stderr?.on("data", (chunk) => {
|
|
44856
|
+
stderrBytes = captureLimited(stderrChunks, chunk, stderrBytes, outputLimitBytes);
|
|
44857
|
+
});
|
|
44858
|
+
child.on("error", (err) => {
|
|
44859
|
+
clearTimeout(timeout);
|
|
44860
|
+
reject(new MeshyError("VALIDATION_ERROR", err.message, 400));
|
|
44861
|
+
});
|
|
44862
|
+
child.on("close", (code) => {
|
|
44863
|
+
clearTimeout(timeout);
|
|
44864
|
+
const stdout = toCapturedOutput(stdoutChunks, stdoutBytes, outputLimitBytes);
|
|
44865
|
+
const stderr = toCapturedOutput(stderrChunks, stderrBytes, outputLimitBytes);
|
|
44866
|
+
resolve15({
|
|
44867
|
+
nodeId,
|
|
44868
|
+
cwd,
|
|
44869
|
+
command: normalizedCommand,
|
|
44870
|
+
exitCode: code,
|
|
44871
|
+
stdout: stdout.text,
|
|
44872
|
+
stderr: stderr.text,
|
|
44873
|
+
durationMs: Date.now() - startedAt,
|
|
44874
|
+
timedOut,
|
|
44875
|
+
stdoutTruncated: stdout.truncated,
|
|
44876
|
+
stderrTruncated: stderr.truncated
|
|
44877
|
+
});
|
|
44878
|
+
});
|
|
44879
|
+
});
|
|
44880
|
+
}
|
|
44881
|
+
|
|
44767
44882
|
// ../../packages/api/src/node/node-operation-service.ts
|
|
44768
44883
|
var NodeOperationFailure = class extends Error {
|
|
44769
44884
|
constructor(message, result) {
|
|
@@ -44827,8 +44942,8 @@ var FileNodeOperationStore = class {
|
|
|
44827
44942
|
load() {
|
|
44828
44943
|
if (this.loaded) return;
|
|
44829
44944
|
this.loaded = true;
|
|
44830
|
-
if (!
|
|
44831
|
-
const raw = JSON.parse(
|
|
44945
|
+
if (!fs16.existsSync(this.filePath)) return;
|
|
44946
|
+
const raw = JSON.parse(fs16.readFileSync(this.filePath, "utf-8"));
|
|
44832
44947
|
const entries = Array.isArray(raw) ? raw : Object.values(raw);
|
|
44833
44948
|
for (const entry of entries) {
|
|
44834
44949
|
if (isNodeOperation(entry)) {
|
|
@@ -44837,14 +44952,14 @@ var FileNodeOperationStore = class {
|
|
|
44837
44952
|
}
|
|
44838
44953
|
}
|
|
44839
44954
|
persist() {
|
|
44840
|
-
|
|
44955
|
+
fs16.mkdirSync(this.storagePath, { recursive: true });
|
|
44841
44956
|
const body = JSON.stringify(Object.fromEntries(this.operations), null, 2);
|
|
44842
44957
|
const tmpPath = `${this.filePath}.tmp`;
|
|
44843
|
-
|
|
44844
|
-
|
|
44958
|
+
fs16.writeFileSync(tmpPath, body, "utf-8");
|
|
44959
|
+
fs16.renameSync(tmpPath, this.filePath);
|
|
44845
44960
|
}
|
|
44846
44961
|
get filePath() {
|
|
44847
|
-
return
|
|
44962
|
+
return path18.join(this.storagePath, "node-operations.json");
|
|
44848
44963
|
}
|
|
44849
44964
|
};
|
|
44850
44965
|
var NodeOperationService = class {
|
|
@@ -44852,6 +44967,7 @@ var NodeOperationService = class {
|
|
|
44852
44967
|
this.deps = deps;
|
|
44853
44968
|
this.store = store;
|
|
44854
44969
|
this.registerHandler("agent.upgrade", runAgentUpgradeOperation);
|
|
44970
|
+
this.registerHandler("terminal.execute", runTerminalExecuteOperation);
|
|
44855
44971
|
this.registerHandler("workdir.branch-create", runWorkDirBranchCreateOperation);
|
|
44856
44972
|
}
|
|
44857
44973
|
handlers = /* @__PURE__ */ new Map();
|
|
@@ -44997,6 +45113,15 @@ function runAgentUpgradeOperation(operation, deps) {
|
|
|
44997
45113
|
}
|
|
44998
45114
|
return result;
|
|
44999
45115
|
}
|
|
45116
|
+
async function runTerminalExecuteOperation(operation, deps) {
|
|
45117
|
+
const self2 = deps.nodeRegistry.getSelf();
|
|
45118
|
+
return executeLocalNodeTerminalCommand(
|
|
45119
|
+
self2.id,
|
|
45120
|
+
self2.workDir ?? deps.workDir,
|
|
45121
|
+
readPayloadString(operation, "command"),
|
|
45122
|
+
{ cwd: readPayloadString(operation, "cwd") || void 0 }
|
|
45123
|
+
);
|
|
45124
|
+
}
|
|
45000
45125
|
function runWorkDirBranchCreateOperation(operation, deps) {
|
|
45001
45126
|
const self2 = deps.nodeRegistry.getSelf();
|
|
45002
45127
|
return createLocalNodeWorkDirBranch(
|
|
@@ -45154,7 +45279,7 @@ async function sendNodeWorkDirBranchCreateOperation(req, res, nodeId) {
|
|
|
45154
45279
|
}
|
|
45155
45280
|
|
|
45156
45281
|
// ../../packages/api/src/tasks/task-route-utils.ts
|
|
45157
|
-
var
|
|
45282
|
+
var fs17 = __toESM(require("fs"), 1);
|
|
45158
45283
|
var import_node_stream2 = require("stream");
|
|
45159
45284
|
var import_promises5 = require("stream/promises");
|
|
45160
45285
|
|
|
@@ -45209,10 +45334,10 @@ function readLocalTaskLogs(engineRegistry, taskId, after, agent) {
|
|
|
45209
45334
|
throw new MeshyError("VALIDATION_ERROR", `Engine not registered for agent: ${agent}`, 400);
|
|
45210
45335
|
}
|
|
45211
45336
|
const logPath = engine.getLogPath(taskId);
|
|
45212
|
-
if (!
|
|
45337
|
+
if (!fs17.existsSync(logPath)) {
|
|
45213
45338
|
return { logs: [], total: 0 };
|
|
45214
45339
|
}
|
|
45215
|
-
const content =
|
|
45340
|
+
const content = fs17.readFileSync(logPath, "utf-8");
|
|
45216
45341
|
const allLines = content.trim().split("\n").filter(Boolean);
|
|
45217
45342
|
const logs = [];
|
|
45218
45343
|
for (let i = after; i < allLines.length; i++) {
|
|
@@ -45442,95 +45567,6 @@ async function maybeProxyReadToLeader(req, res, options = {}) {
|
|
|
45442
45567
|
}
|
|
45443
45568
|
}
|
|
45444
45569
|
|
|
45445
|
-
// ../../packages/api/src/node/node-terminal-service.ts
|
|
45446
|
-
var import_node_child_process10 = require("child_process");
|
|
45447
|
-
var fs17 = __toESM(require("fs"), 1);
|
|
45448
|
-
var path18 = __toESM(require("path"), 1);
|
|
45449
|
-
var DEFAULT_TIMEOUT_MS = 3e4;
|
|
45450
|
-
var DEFAULT_OUTPUT_LIMIT_BYTES = 64 * 1024;
|
|
45451
|
-
function isAbsolutePath2(value) {
|
|
45452
|
-
return path18.isAbsolute(value) || /^[A-Za-z]:[\/]/.test(value);
|
|
45453
|
-
}
|
|
45454
|
-
function resolveCommandCwd(nodeId, rootPath, cwd) {
|
|
45455
|
-
if (!rootPath) {
|
|
45456
|
-
throw new MeshyError("VALIDATION_ERROR", `Node ${nodeId} does not expose a working directory`, 400);
|
|
45457
|
-
}
|
|
45458
|
-
const requestedCwd = cwd?.trim() || ".";
|
|
45459
|
-
const resolved = isAbsolutePath2(requestedCwd) ? path18.resolve(requestedCwd) : path18.resolve(rootPath, requestedCwd);
|
|
45460
|
-
if (!fs17.existsSync(resolved) || !fs17.statSync(resolved).isDirectory()) {
|
|
45461
|
-
throw new MeshyError("VALIDATION_ERROR", `Working directory does not exist: ${resolved}`, 400);
|
|
45462
|
-
}
|
|
45463
|
-
return resolved;
|
|
45464
|
-
}
|
|
45465
|
-
function captureLimited(chunks, chunk, currentBytes, limitBytes) {
|
|
45466
|
-
if (currentBytes >= limitBytes) {
|
|
45467
|
-
return currentBytes + chunk.length;
|
|
45468
|
-
}
|
|
45469
|
-
const remaining = limitBytes - currentBytes;
|
|
45470
|
-
chunks.push(chunk.length <= remaining ? chunk : chunk.subarray(0, remaining));
|
|
45471
|
-
return currentBytes + chunk.length;
|
|
45472
|
-
}
|
|
45473
|
-
function toCapturedOutput(chunks, observedBytes, limitBytes) {
|
|
45474
|
-
return {
|
|
45475
|
-
text: Buffer.concat(chunks).toString("utf8"),
|
|
45476
|
-
truncated: observedBytes > limitBytes
|
|
45477
|
-
};
|
|
45478
|
-
}
|
|
45479
|
-
function executeLocalNodeTerminalCommand(nodeId, rootPath, command, options = {}) {
|
|
45480
|
-
const normalizedCommand = command.trim();
|
|
45481
|
-
if (!normalizedCommand) {
|
|
45482
|
-
throw new MeshyError("VALIDATION_ERROR", "Command must not be empty", 400);
|
|
45483
|
-
}
|
|
45484
|
-
const cwd = resolveCommandCwd(nodeId, rootPath, options.cwd);
|
|
45485
|
-
const timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;
|
|
45486
|
-
const outputLimitBytes = options.outputLimitBytes ?? DEFAULT_OUTPUT_LIMIT_BYTES;
|
|
45487
|
-
const startedAt = Date.now();
|
|
45488
|
-
const stdoutChunks = [];
|
|
45489
|
-
const stderrChunks = [];
|
|
45490
|
-
let stdoutBytes = 0;
|
|
45491
|
-
let stderrBytes = 0;
|
|
45492
|
-
let timedOut = false;
|
|
45493
|
-
return new Promise((resolve15, reject) => {
|
|
45494
|
-
const child = (0, import_node_child_process10.spawn)(normalizedCommand, {
|
|
45495
|
-
cwd,
|
|
45496
|
-
shell: true,
|
|
45497
|
-
windowsHide: true,
|
|
45498
|
-
stdio: ["ignore", "pipe", "pipe"]
|
|
45499
|
-
});
|
|
45500
|
-
const timeout = setTimeout(() => {
|
|
45501
|
-
timedOut = true;
|
|
45502
|
-
child.kill("SIGTERM");
|
|
45503
|
-
}, timeoutMs);
|
|
45504
|
-
child.stdout?.on("data", (chunk) => {
|
|
45505
|
-
stdoutBytes = captureLimited(stdoutChunks, chunk, stdoutBytes, outputLimitBytes);
|
|
45506
|
-
});
|
|
45507
|
-
child.stderr?.on("data", (chunk) => {
|
|
45508
|
-
stderrBytes = captureLimited(stderrChunks, chunk, stderrBytes, outputLimitBytes);
|
|
45509
|
-
});
|
|
45510
|
-
child.on("error", (err) => {
|
|
45511
|
-
clearTimeout(timeout);
|
|
45512
|
-
reject(new MeshyError("VALIDATION_ERROR", err.message, 400));
|
|
45513
|
-
});
|
|
45514
|
-
child.on("close", (code) => {
|
|
45515
|
-
clearTimeout(timeout);
|
|
45516
|
-
const stdout = toCapturedOutput(stdoutChunks, stdoutBytes, outputLimitBytes);
|
|
45517
|
-
const stderr = toCapturedOutput(stderrChunks, stderrBytes, outputLimitBytes);
|
|
45518
|
-
resolve15({
|
|
45519
|
-
nodeId,
|
|
45520
|
-
cwd,
|
|
45521
|
-
command: normalizedCommand,
|
|
45522
|
-
exitCode: code,
|
|
45523
|
-
stdout: stdout.text,
|
|
45524
|
-
stderr: stderr.text,
|
|
45525
|
-
durationMs: Date.now() - startedAt,
|
|
45526
|
-
timedOut,
|
|
45527
|
-
stdoutTruncated: stdout.truncated,
|
|
45528
|
-
stderrTruncated: stderr.truncated
|
|
45529
|
-
});
|
|
45530
|
-
});
|
|
45531
|
-
});
|
|
45532
|
-
}
|
|
45533
|
-
|
|
45534
45570
|
// ../../packages/api/src/node/node-native-session-service.ts
|
|
45535
45571
|
function getLocalNodeNativeSessions(nodeId, agent, limit) {
|
|
45536
45572
|
return {
|
|
@@ -46954,142 +46990,35 @@ async function sendNodeAgentUpgrade(req, res, nodeId, agentParam) {
|
|
|
46954
46990
|
}
|
|
46955
46991
|
|
|
46956
46992
|
// ../../packages/api/src/routes/node-terminal.ts
|
|
46957
|
-
|
|
46958
|
-
function describeProxyError2(error) {
|
|
46959
|
-
if (error instanceof Error) {
|
|
46960
|
-
const errorCategory = error.name === "AbortError" || /aborted/i.test(error.message) ? "abort" : /timeout/i.test(error.message) ? "timeout" : "network";
|
|
46961
|
-
return {
|
|
46962
|
-
errorName: error.name,
|
|
46963
|
-
errorMessage: error.message,
|
|
46964
|
-
errorCategory
|
|
46965
|
-
};
|
|
46966
|
-
}
|
|
46967
|
-
return {
|
|
46968
|
-
errorName: "UnknownError",
|
|
46969
|
-
errorMessage: String(error),
|
|
46970
|
-
errorCategory: "unknown"
|
|
46971
|
-
};
|
|
46972
|
-
}
|
|
46973
|
-
function createNodeTerminalProxyTrace(log2, nodeId, proxyPath) {
|
|
46974
|
-
return {
|
|
46975
|
-
onAttempt: ({ attempt, endpoint, timeoutMs, totalEndpoints }) => {
|
|
46976
|
-
log2.debug("node terminal proxy attempt", {
|
|
46977
|
-
nodeId,
|
|
46978
|
-
proxyPath,
|
|
46979
|
-
endpoint,
|
|
46980
|
-
attempt,
|
|
46981
|
-
totalEndpoints,
|
|
46982
|
-
timeoutMs
|
|
46983
|
-
});
|
|
46984
|
-
},
|
|
46985
|
-
onResponse: ({ attempt, endpoint, response, timeoutMs, totalEndpoints }) => {
|
|
46986
|
-
log2.info("node terminal proxy response", {
|
|
46987
|
-
nodeId,
|
|
46988
|
-
proxyPath,
|
|
46989
|
-
endpoint,
|
|
46990
|
-
attempt,
|
|
46991
|
-
totalEndpoints,
|
|
46992
|
-
timeoutMs,
|
|
46993
|
-
ok: response.ok,
|
|
46994
|
-
statusCode: response.status
|
|
46995
|
-
});
|
|
46996
|
-
},
|
|
46997
|
-
onError: ({ attempt, endpoint, error, timeoutMs, totalEndpoints }) => {
|
|
46998
|
-
log2.warn("node terminal proxy attempt failed", {
|
|
46999
|
-
nodeId,
|
|
47000
|
-
proxyPath,
|
|
47001
|
-
endpoint,
|
|
47002
|
-
attempt,
|
|
47003
|
-
totalEndpoints,
|
|
47004
|
-
timeoutMs,
|
|
47005
|
-
...describeProxyError2(error)
|
|
47006
|
-
});
|
|
47007
|
-
}
|
|
47008
|
-
};
|
|
47009
|
-
}
|
|
47010
|
-
async function maybeHandleRemoteNodeTerminalExecuteRequest(req, res, nodeId) {
|
|
46993
|
+
async function sendNodeTerminalExecuteOperation(req, res, nodeId) {
|
|
47011
46994
|
const body = NodeTerminalExecuteBody.parse(req.body);
|
|
47012
|
-
const
|
|
46995
|
+
const deps = req.app.locals.deps;
|
|
46996
|
+
const { nodeRegistry } = deps;
|
|
47013
46997
|
const selfId = nodeRegistry.getSelf().id;
|
|
47014
|
-
|
|
47015
|
-
|
|
47016
|
-
|
|
47017
|
-
const
|
|
47018
|
-
if (!node) {
|
|
47019
|
-
throw new MeshyError("NODE_NOT_FOUND", `Node ${nodeId} not found`, 404);
|
|
47020
|
-
}
|
|
47021
|
-
const log2 = rootLogger.child("nodes/terminal");
|
|
47022
|
-
const proxyPath = req.originalUrl ?? `/api/nodes/${nodeId}/terminal/execute`;
|
|
47023
|
-
const fallbackRequest = createNodeMessage("node.terminal.execute", {
|
|
46998
|
+
const node = nodeId === selfId ? nodeRegistry.getSelf() : nodeRegistry.getNode(nodeId);
|
|
46999
|
+
if (!node) throw new MeshyError("NODE_NOT_FOUND", `Node ${nodeId} not found`, 404);
|
|
47000
|
+
const operations = getNodeOperationService(deps);
|
|
47001
|
+
const operation = operations.create("terminal.execute", nodeId, {
|
|
47024
47002
|
command: body.command,
|
|
47025
47003
|
cwd: body.cwd
|
|
47026
|
-
}
|
|
47027
|
-
|
|
47028
|
-
|
|
47029
|
-
|
|
47030
|
-
|
|
47031
|
-
|
|
47032
|
-
|
|
47033
|
-
|
|
47034
|
-
try {
|
|
47035
|
-
const { endpoint, response } = await fetchNodeWithFallback(
|
|
47036
|
-
node,
|
|
47037
|
-
proxyPath,
|
|
47038
|
-
{
|
|
47039
|
-
method: "POST",
|
|
47040
|
-
headers: { "Content-Type": "application/json" },
|
|
47041
|
-
body: JSON.stringify(body)
|
|
47042
|
-
},
|
|
47043
|
-
NODE_TERMINAL_PROXY_TIMEOUT_MS,
|
|
47044
|
-
createNodeTerminalProxyTrace(log2, nodeId, proxyPath),
|
|
47045
|
-
{ preferPublicEndpoint: true }
|
|
47046
|
-
);
|
|
47047
|
-
log2.debug("proxying node terminal request", { nodeId, endpoint, proxyPath });
|
|
47048
|
-
await sendProxyResponse(res, response);
|
|
47049
|
-
return true;
|
|
47050
|
-
} catch (err) {
|
|
47051
|
-
const errorDetails = describeProxyError2(err);
|
|
47052
|
-
log2.warn("node terminal proxy error", {
|
|
47053
|
-
nodeId,
|
|
47054
|
-
proxyPath,
|
|
47055
|
-
timeoutMs: NODE_TERMINAL_PROXY_TIMEOUT_MS,
|
|
47056
|
-
...errorDetails
|
|
47057
|
-
});
|
|
47058
|
-
if (canRequestNodeMessage(heartbeat)) {
|
|
47059
|
-
log2.warn("node terminal proxy failed, falling back to keepalive control", {
|
|
47060
|
-
nodeId,
|
|
47061
|
-
proxyPath,
|
|
47062
|
-
timeoutMs: NODE_TERMINAL_PROXY_TIMEOUT_MS,
|
|
47063
|
-
...errorDetails
|
|
47064
|
-
});
|
|
47065
|
-
const controlResponse = await requestFallbackNodeMessage(heartbeat, nodeId, fallbackRequest);
|
|
47066
|
-
sendWorkerControlResponse(res, controlResponse);
|
|
47067
|
-
return true;
|
|
47004
|
+
});
|
|
47005
|
+
if (nodeId === selfId) {
|
|
47006
|
+
operations.runLocal(operation.id);
|
|
47007
|
+
} else {
|
|
47008
|
+
try {
|
|
47009
|
+
await dispatchNodeOperation(deps, operation, node);
|
|
47010
|
+
} catch (err) {
|
|
47011
|
+
operations.markFailed(operation.id, err instanceof Error ? err.message : String(err));
|
|
47068
47012
|
}
|
|
47069
|
-
throw new MeshyError("NODE_OFFLINE", `Cannot reach node ${nodeId} to execute a terminal command`, 502);
|
|
47070
|
-
}
|
|
47071
|
-
}
|
|
47072
|
-
async function sendLocalNodeTerminalExecute(req, res, nodeId) {
|
|
47073
|
-
const body = NodeTerminalExecuteBody.parse(req.body);
|
|
47074
|
-
const { nodeRegistry, workDir } = req.app.locals.deps;
|
|
47075
|
-
const self2 = nodeRegistry.getSelf();
|
|
47076
|
-
if (nodeId !== self2.id) {
|
|
47077
|
-
throw new MeshyError("NODE_NOT_FOUND", `Node ${nodeId} not found`, 404);
|
|
47078
47013
|
}
|
|
47079
|
-
|
|
47080
|
-
self2.id,
|
|
47081
|
-
self2.workDir ?? workDir,
|
|
47082
|
-
body.command,
|
|
47083
|
-
{ cwd: body.cwd }
|
|
47084
|
-
);
|
|
47085
|
-
res.json(result);
|
|
47014
|
+
res.status(202).json(operation);
|
|
47086
47015
|
}
|
|
47087
47016
|
|
|
47088
47017
|
// ../../packages/api/src/routes/nodes.ts
|
|
47089
47018
|
var NODE_WORKDIR_PROXY_TIMEOUT_MS = 1e4;
|
|
47090
47019
|
var NODE_WORKDIR_BRANCH_PROXY_TIMEOUT_MS = 25e3;
|
|
47091
47020
|
var NODE_NATIVE_SESSIONS_PROXY_TIMEOUT_MS = 1e4;
|
|
47092
|
-
function
|
|
47021
|
+
function describeProxyError2(error) {
|
|
47093
47022
|
if (error instanceof Error) {
|
|
47094
47023
|
const errorCategory = error.name === "AbortError" || /aborted/i.test(error.message) ? "abort" : /timeout/i.test(error.message) ? "timeout" : "network";
|
|
47095
47024
|
return {
|
|
@@ -47136,7 +47065,7 @@ function createNodeWorkdirProxyTrace(log2, nodeId, proxyPath) {
|
|
|
47136
47065
|
attempt,
|
|
47137
47066
|
totalEndpoints,
|
|
47138
47067
|
timeoutMs,
|
|
47139
|
-
...
|
|
47068
|
+
...describeProxyError2(error)
|
|
47140
47069
|
});
|
|
47141
47070
|
}
|
|
47142
47071
|
};
|
|
@@ -47191,7 +47120,7 @@ async function maybeHandleRemoteNodeWorkDirRequest(req, res, nodeId) {
|
|
|
47191
47120
|
await sendProxyResponse(res, response);
|
|
47192
47121
|
return true;
|
|
47193
47122
|
} catch (err) {
|
|
47194
|
-
const errorDetails =
|
|
47123
|
+
const errorDetails = describeProxyError2(err);
|
|
47195
47124
|
log2.warn("node workdir proxy error", {
|
|
47196
47125
|
nodeId,
|
|
47197
47126
|
proxyPath,
|
|
@@ -47258,7 +47187,7 @@ async function maybeHandleRemoteNodeWorkDirBranchInfoRequest(req, res, nodeId) {
|
|
|
47258
47187
|
await sendProxyResponse(res, response);
|
|
47259
47188
|
return true;
|
|
47260
47189
|
} catch (err) {
|
|
47261
|
-
const errorDetails =
|
|
47190
|
+
const errorDetails = describeProxyError2(err);
|
|
47262
47191
|
log2.warn("node workdir branch proxy error", {
|
|
47263
47192
|
nodeId,
|
|
47264
47193
|
proxyPath,
|
|
@@ -47323,7 +47252,7 @@ async function maybeHandleRemoteNodeNativeSessionsRequest(req, res, nodeId) {
|
|
|
47323
47252
|
await sendProxyResponse(res, response);
|
|
47324
47253
|
return true;
|
|
47325
47254
|
} catch (err) {
|
|
47326
|
-
const errorDetails =
|
|
47255
|
+
const errorDetails = describeProxyError2(err);
|
|
47327
47256
|
log2.warn("node native sessions proxy error", {
|
|
47328
47257
|
nodeId,
|
|
47329
47258
|
proxyPath,
|
|
@@ -47412,11 +47341,7 @@ function createNodeRoutes() {
|
|
|
47412
47341
|
}));
|
|
47413
47342
|
router.post("/:id/terminal/execute", asyncHandler3(async (req, res) => {
|
|
47414
47343
|
const nodeId = req.params.id;
|
|
47415
|
-
|
|
47416
|
-
if (handled) {
|
|
47417
|
-
return;
|
|
47418
|
-
}
|
|
47419
|
-
await sendLocalNodeTerminalExecute(req, res, nodeId);
|
|
47344
|
+
await sendNodeTerminalExecuteOperation(req, res, nodeId);
|
|
47420
47345
|
}));
|
|
47421
47346
|
router.post("/:id/workdir/branch", asyncHandler3(async (req, res) => {
|
|
47422
47347
|
const nodeId = req.params.id;
|
|
@@ -47837,7 +47762,7 @@ function getTaskLogsProxyRequestMetadata(req) {
|
|
|
47837
47762
|
const sourceNodeId = req.get(TASK_LOG_PROXY_SOURCE_HEADER) ?? void 0;
|
|
47838
47763
|
return { isProxy: purpose === TASK_LOG_PROXY_PURPOSE, sourceNodeId, task: decodeTaskSnapshot(req.get(TASK_LOG_PROXY_TASK_HEADER)) };
|
|
47839
47764
|
}
|
|
47840
|
-
function
|
|
47765
|
+
function describeProxyError3(error) {
|
|
47841
47766
|
if (error instanceof Error) {
|
|
47842
47767
|
const errorCategory = error.name === "AbortError" || /aborted/i.test(error.message) ? "abort" : /timeout/i.test(error.message) ? "timeout" : "network";
|
|
47843
47768
|
return {
|
|
@@ -47879,7 +47804,7 @@ function createTaskLogsProxyTrace(log2, taskId, nodeId, proxyPath) {
|
|
|
47879
47804
|
attempt,
|
|
47880
47805
|
totalEndpoints,
|
|
47881
47806
|
timeoutMs,
|
|
47882
|
-
...
|
|
47807
|
+
...describeProxyError3(error)
|
|
47883
47808
|
});
|
|
47884
47809
|
}
|
|
47885
47810
|
};
|
|
@@ -47957,7 +47882,7 @@ async function sendTaskLogsResponse(req, res, taskId) {
|
|
|
47957
47882
|
log2.warn("failed to seed task snapshot before task logs proxy", {
|
|
47958
47883
|
taskId,
|
|
47959
47884
|
assignedTo,
|
|
47960
|
-
...
|
|
47885
|
+
...describeProxyError3(err)
|
|
47961
47886
|
});
|
|
47962
47887
|
return [];
|
|
47963
47888
|
});
|
|
@@ -47990,7 +47915,7 @@ async function sendTaskLogsResponse(req, res, taskId) {
|
|
|
47990
47915
|
taskId,
|
|
47991
47916
|
assignedTo,
|
|
47992
47917
|
timeoutMs: TASK_LOG_PROXY_TIMEOUT_MS,
|
|
47993
|
-
...
|
|
47918
|
+
...describeProxyError3(err)
|
|
47994
47919
|
});
|
|
47995
47920
|
const fallback = await requestTaskLogsOverKeepalive(heartbeat, assignedTo, task, after);
|
|
47996
47921
|
if (fallback) {
|
|
@@ -48067,7 +47992,7 @@ function resolveRequestOrigin(req) {
|
|
|
48067
47992
|
|
|
48068
47993
|
// ../../packages/api/src/routes/task-output.ts
|
|
48069
47994
|
var TASK_OUTPUT_PROXY_TIMEOUT_MS = 1e4;
|
|
48070
|
-
function
|
|
47995
|
+
function describeProxyError4(error) {
|
|
48071
47996
|
if (error instanceof Error) {
|
|
48072
47997
|
const errorCategory = error.name === "AbortError" || /aborted/i.test(error.message) ? "abort" : /timeout/i.test(error.message) ? "timeout" : "network";
|
|
48073
47998
|
return {
|
|
@@ -48120,7 +48045,7 @@ function createTaskOutputProxyTrace(log2, taskId, assignedTo, kind, proxyPath) {
|
|
|
48120
48045
|
attempt,
|
|
48121
48046
|
totalEndpoints,
|
|
48122
48047
|
timeoutMs,
|
|
48123
|
-
...
|
|
48048
|
+
...describeProxyError4(error)
|
|
48124
48049
|
});
|
|
48125
48050
|
}
|
|
48126
48051
|
};
|
|
@@ -48238,7 +48163,7 @@ async function maybeHandleRemoteTaskOutputRequest(req, res, taskId, subPath, ini
|
|
|
48238
48163
|
assignedTo: assignedNodeId,
|
|
48239
48164
|
kind: hydratedFallbackRequest.kind,
|
|
48240
48165
|
timeoutMs: TASK_OUTPUT_PROXY_TIMEOUT_MS,
|
|
48241
|
-
...
|
|
48166
|
+
...describeProxyError4(err)
|
|
48242
48167
|
});
|
|
48243
48168
|
const controlResponse = await requestFallbackNodeMessage(heartbeat, assignedNodeId, hydratedFallbackRequest);
|
|
48244
48169
|
if (hydratedFallbackRequest.kind === "task.preview.create" && controlResponse.bodyEncoding === "json" && isPreviewSessionPayload(controlResponse.body)) {
|
|
@@ -48255,7 +48180,7 @@ async function maybeHandleRemoteTaskOutputRequest(req, res, taskId, subPath, ini
|
|
|
48255
48180
|
assignedTo: assignedNodeId,
|
|
48256
48181
|
kind: messageKind,
|
|
48257
48182
|
timeoutMs: TASK_OUTPUT_PROXY_TIMEOUT_MS,
|
|
48258
|
-
...
|
|
48183
|
+
...describeProxyError4(err)
|
|
48259
48184
|
});
|
|
48260
48185
|
throw new MeshyError("NODE_OFFLINE", "Cannot reach worker for task output", 502);
|
|
48261
48186
|
}
|
package/package.json
CHANGED
package/runtime-metadata.json
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"packageName": "meshy-node",
|
|
3
|
-
"packageVersion": "0.3.
|
|
3
|
+
"packageVersion": "0.3.9",
|
|
4
4
|
"packages": {
|
|
5
5
|
"workspace": {
|
|
6
6
|
"name": "meshy",
|
|
7
|
-
"version": "0.3.
|
|
7
|
+
"version": "0.3.9"
|
|
8
8
|
},
|
|
9
9
|
"node": {
|
|
10
10
|
"name": "meshy-node",
|
|
11
|
-
"version": "0.3.
|
|
11
|
+
"version": "0.3.9"
|
|
12
12
|
},
|
|
13
13
|
"core": {
|
|
14
14
|
"name": "@meshy/core",
|
|
@@ -26,6 +26,6 @@
|
|
|
26
26
|
"repository": {
|
|
27
27
|
"url": "https://github.com/ai-microsoft/meshy",
|
|
28
28
|
"branch": "supportTerminal",
|
|
29
|
-
"commit": "
|
|
29
|
+
"commit": "0c23d39"
|
|
30
30
|
}
|
|
31
31
|
}
|