meshy-node 0.3.2 → 0.3.3
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-vg1FNZ-b.js +124 -0
- package/dashboard/assets/DashboardShared-C9XLT05J.js +54 -0
- package/dashboard/assets/DiffTab-BBoqxtBo.js +4 -0
- package/dashboard/assets/{FilesTab-CSpNGxJl.js → FilesTab-8j_HSIrt.js} +14 -13
- package/dashboard/assets/{PreviewTab-CEFgpX6R.js → PreviewTab-CcfSJBUg.js} +4 -4
- package/dashboard/assets/{SharedConversationPage-CgHzpTa0.js → SharedConversationPage-CNmEk_vb.js} +4 -4
- package/dashboard/assets/{file-DCzQQ4U3.js → file-DgdB9H7_.js} +1 -1
- package/dashboard/assets/{folder-D2R8g5cx.js → folder-5L-FBUD2.js} +1 -1
- package/dashboard/assets/index-D2dDklXI.js +266 -0
- package/dashboard/assets/index-XG2bTevi.css +1 -0
- package/dashboard/index.html +2 -2
- package/main.cjs +526 -214
- package/package.json +1 -1
- package/runtime-metadata.json +5 -5
- package/dashboard/assets/DashboardPage-BMIVTxil.js +0 -130
- package/dashboard/assets/DashboardShared-BSmoDCJG.js +0 -59
- package/dashboard/assets/DiffTab-BLGTdyp_.js +0 -4
- package/dashboard/assets/index-CSVyG8lh.js +0 -250
- package/dashboard/assets/index-CnhngBZ-.css +0 -1
package/main.cjs
CHANGED
|
@@ -34555,6 +34555,7 @@ var NODE_KIND_BY_LEGACY = {
|
|
|
34555
34555
|
"node-workdir-branch-create": "node.workdir.branch-create",
|
|
34556
34556
|
"node-sessions-list": "node.sessions.list",
|
|
34557
34557
|
devtunnel: "node.transport.set",
|
|
34558
|
+
"node-agent-upgrade": "node.agent.upgrade",
|
|
34558
34559
|
"task-cancel": "task.cancel",
|
|
34559
34560
|
"task-logs": "task.logs",
|
|
34560
34561
|
"task-output-summary": "task.output.summary",
|
|
@@ -35601,6 +35602,9 @@ function compareUpdatedSessions(left, right) {
|
|
|
35601
35602
|
const rightTime = right.updatedAt ? Date.parse(right.updatedAt) : 0;
|
|
35602
35603
|
return rightTime - leftTime || left.sessionId.localeCompare(right.sessionId);
|
|
35603
35604
|
}
|
|
35605
|
+
function getNativeHomeDir() {
|
|
35606
|
+
return process.env.HOME || process.env.USERPROFILE || os4.homedir();
|
|
35607
|
+
}
|
|
35604
35608
|
function findMatchingFiles(rootDir, predicate) {
|
|
35605
35609
|
if (!fs7.existsSync(rootDir)) {
|
|
35606
35610
|
return [];
|
|
@@ -35747,7 +35751,7 @@ function findClaudeSessionSummary(entries, sessionId) {
|
|
|
35747
35751
|
};
|
|
35748
35752
|
}
|
|
35749
35753
|
function loadCodexSessionIndex() {
|
|
35750
|
-
const indexPath = path7.join(
|
|
35754
|
+
const indexPath = path7.join(getNativeHomeDir(), ".codex", "session_index.jsonl");
|
|
35751
35755
|
const index = /* @__PURE__ */ new Map();
|
|
35752
35756
|
for (const entry of readJsonLines(indexPath)) {
|
|
35753
35757
|
if (typeof entry.id !== "string" || !entry.id.trim()) {
|
|
@@ -35797,7 +35801,7 @@ function findCodexSessionSummary(entries, filePath, sessionIndex) {
|
|
|
35797
35801
|
};
|
|
35798
35802
|
}
|
|
35799
35803
|
function loadClaudeSessionHistory(sessionId) {
|
|
35800
|
-
const projectsDir = path7.join(
|
|
35804
|
+
const projectsDir = path7.join(getNativeHomeDir(), ".claude", "projects");
|
|
35801
35805
|
const sessionFile = findFirstMatchingFile(projectsDir, (filePath) => {
|
|
35802
35806
|
if (filePath.includes(`${path7.sep}subagents${path7.sep}`)) {
|
|
35803
35807
|
return false;
|
|
@@ -35816,7 +35820,7 @@ function loadClaudeSessionHistory(sessionId) {
|
|
|
35816
35820
|
return { logs, sourcePath: sessionFile };
|
|
35817
35821
|
}
|
|
35818
35822
|
function loadCodexSessionHistory(sessionId) {
|
|
35819
|
-
const sessionsDir = path7.join(
|
|
35823
|
+
const sessionsDir = path7.join(getNativeHomeDir(), ".codex", "sessions");
|
|
35820
35824
|
const sessionFile = findFirstMatchingFile(sessionsDir, (filePath) => path7.basename(filePath).toLowerCase().includes(sessionId.toLowerCase()) && filePath.toLowerCase().endsWith(".jsonl"));
|
|
35821
35825
|
if (!sessionFile) {
|
|
35822
35826
|
return { logs: [], sourcePath: null };
|
|
@@ -35852,7 +35856,7 @@ function loadNativeSessionHistory(input) {
|
|
|
35852
35856
|
function listNativeSessions(input) {
|
|
35853
35857
|
const limit = Math.min(Math.max(1, input.limit ?? 50), 100);
|
|
35854
35858
|
if (input.agent === "claudecode") {
|
|
35855
|
-
const projectsDir = path7.join(
|
|
35859
|
+
const projectsDir = path7.join(getNativeHomeDir(), ".claude", "projects");
|
|
35856
35860
|
return findMatchingFiles(projectsDir, (filePath) => {
|
|
35857
35861
|
if (filePath.includes(`${path7.sep}subagents${path7.sep}`)) {
|
|
35858
35862
|
return false;
|
|
@@ -35871,7 +35875,7 @@ function listNativeSessions(input) {
|
|
|
35871
35875
|
}).filter((session) => session !== null).sort(compareUpdatedSessions).slice(0, limit);
|
|
35872
35876
|
}
|
|
35873
35877
|
const sessionIndex = loadCodexSessionIndex();
|
|
35874
|
-
const sessionsDir = path7.join(
|
|
35878
|
+
const sessionsDir = path7.join(getNativeHomeDir(), ".codex", "sessions");
|
|
35875
35879
|
return findMatchingFiles(sessionsDir, (filePath) => filePath.toLowerCase().endsWith(".jsonl")).map((filePath) => {
|
|
35876
35880
|
const summary = findCodexSessionSummary(readJsonLines(filePath), filePath, sessionIndex);
|
|
35877
35881
|
if (!summary) {
|
|
@@ -38287,7 +38291,7 @@ async function apiFetch(ctx, port, apiPath) {
|
|
|
38287
38291
|
const body = await res.json().catch(() => null);
|
|
38288
38292
|
throw new Error(body?.error?.message ?? `API error: ${res.status} ${res.statusText}`);
|
|
38289
38293
|
}
|
|
38290
|
-
return res.json();
|
|
38294
|
+
return await res.json();
|
|
38291
38295
|
}
|
|
38292
38296
|
async function apiWrite(ctx, method, port, apiPath, body) {
|
|
38293
38297
|
const res = await ctx.fetchImpl(`http://localhost:${port}${apiPath}`, {
|
|
@@ -38299,7 +38303,7 @@ async function apiWrite(ctx, method, port, apiPath, body) {
|
|
|
38299
38303
|
const data = await res.json().catch(() => null);
|
|
38300
38304
|
throw new Error(data?.error?.message ?? `HTTP ${res.status}`);
|
|
38301
38305
|
}
|
|
38302
|
-
return res.json();
|
|
38306
|
+
return await res.json();
|
|
38303
38307
|
}
|
|
38304
38308
|
function writeLines(stream, lines) {
|
|
38305
38309
|
stream.write(`${lines.join("\n")}
|
|
@@ -42827,7 +42831,15 @@ var SystemAgentInfoSchema = external_exports.object({
|
|
|
42827
42831
|
version: external_exports.string().nullable(),
|
|
42828
42832
|
checkedAt: external_exports.string(),
|
|
42829
42833
|
detail: external_exports.string().nullable().optional(),
|
|
42830
|
-
metadataStatus: external_exports.string().nullable().optional()
|
|
42834
|
+
metadataStatus: external_exports.string().nullable().optional(),
|
|
42835
|
+
update: external_exports.object({
|
|
42836
|
+
packageName: external_exports.string(),
|
|
42837
|
+
currentVersion: external_exports.string().nullable(),
|
|
42838
|
+
latestVersion: external_exports.string().nullable(),
|
|
42839
|
+
updateAvailable: external_exports.boolean(),
|
|
42840
|
+
checkedAt: external_exports.string(),
|
|
42841
|
+
detail: external_exports.string().nullable().optional()
|
|
42842
|
+
}).optional()
|
|
42831
42843
|
});
|
|
42832
42844
|
var NodeSettingsSnapshotSchema = external_exports.object({
|
|
42833
42845
|
collectedAt: external_exports.number(),
|
|
@@ -44152,7 +44164,7 @@ function getGitDiff(dirPath) {
|
|
|
44152
44164
|
const branch = git2(["rev-parse", "--abbrev-ref", "HEAD"], dirPath) || null;
|
|
44153
44165
|
const staged = git2(["diff", "--cached"], dirPath);
|
|
44154
44166
|
const unstaged = git2(["diff"], dirPath);
|
|
44155
|
-
const statusOutput = git2(["status", "--porcelain"], dirPath);
|
|
44167
|
+
const statusOutput = git2(["status", "--porcelain", "-uall"], dirPath);
|
|
44156
44168
|
const changedFiles = [];
|
|
44157
44169
|
const untrackedFiles = [];
|
|
44158
44170
|
for (const line of statusOutput.split("\n")) {
|
|
@@ -44385,6 +44397,7 @@ var LEGACY_KIND_BY_NODE_MESSAGE = {
|
|
|
44385
44397
|
"node.workdir.branch-create": "node-workdir-branch-create",
|
|
44386
44398
|
"node.sessions.list": "node-sessions-list",
|
|
44387
44399
|
"node.transport.set": "devtunnel",
|
|
44400
|
+
"node.agent.upgrade": "node-agent-upgrade",
|
|
44388
44401
|
"task.cancel": "task-cancel",
|
|
44389
44402
|
"task.logs": "task-logs",
|
|
44390
44403
|
"task.output.summary": "task-output-summary",
|
|
@@ -45144,6 +45157,289 @@ async function createPreviewSessionPayload(deps, taskId, entryPath, requestOrigi
|
|
|
45144
45157
|
};
|
|
45145
45158
|
}
|
|
45146
45159
|
|
|
45160
|
+
// ../../packages/api/src/node/agent-upgrade-service.ts
|
|
45161
|
+
var import_node_child_process9 = require("child_process");
|
|
45162
|
+
|
|
45163
|
+
// ../../packages/api/src/app/system-info.ts
|
|
45164
|
+
var os6 = __toESM(require("os"), 1);
|
|
45165
|
+
var import_node_child_process8 = require("child_process");
|
|
45166
|
+
var RUNTIME_TOOLS = [
|
|
45167
|
+
{ id: "claude", label: "Claude Code", command: "claude", packageName: "@anthropic-ai/claude-code" },
|
|
45168
|
+
{ id: "codex", label: "Codex", command: "codex", packageName: "@openai/codex" }
|
|
45169
|
+
];
|
|
45170
|
+
var runtimeToolUpdateCache = /* @__PURE__ */ new Map();
|
|
45171
|
+
function clearRuntimeToolUpdateCache(packageName) {
|
|
45172
|
+
if (packageName) {
|
|
45173
|
+
runtimeToolUpdateCache.delete(packageName);
|
|
45174
|
+
return;
|
|
45175
|
+
}
|
|
45176
|
+
runtimeToolUpdateCache.clear();
|
|
45177
|
+
}
|
|
45178
|
+
function runRuntimeToolCommand(command, args, platform2) {
|
|
45179
|
+
const result = (0, import_node_child_process8.spawnSync)(command, args, {
|
|
45180
|
+
encoding: "utf-8",
|
|
45181
|
+
shell: platform2 === "win32" && command !== "where",
|
|
45182
|
+
windowsHide: true,
|
|
45183
|
+
timeout: 2500
|
|
45184
|
+
});
|
|
45185
|
+
return {
|
|
45186
|
+
status: result.status,
|
|
45187
|
+
stdout: typeof result.stdout === "string" ? result.stdout : "",
|
|
45188
|
+
stderr: typeof result.stderr === "string" ? result.stderr : "",
|
|
45189
|
+
error: result.error?.message ?? null
|
|
45190
|
+
};
|
|
45191
|
+
}
|
|
45192
|
+
function normalizeOutput(output) {
|
|
45193
|
+
if (!output) {
|
|
45194
|
+
return null;
|
|
45195
|
+
}
|
|
45196
|
+
const firstLine = output.split(/\r?\n/).map((line) => line.trim()).find(Boolean);
|
|
45197
|
+
return firstLine ?? null;
|
|
45198
|
+
}
|
|
45199
|
+
function formatLocalDate(date) {
|
|
45200
|
+
const year = date.getFullYear();
|
|
45201
|
+
const month = String(date.getMonth() + 1).padStart(2, "0");
|
|
45202
|
+
const day = String(date.getDate()).padStart(2, "0");
|
|
45203
|
+
return `${year}-${month}-${day}`;
|
|
45204
|
+
}
|
|
45205
|
+
function resolveCommandPath(command, commandRunner, platform2) {
|
|
45206
|
+
const lookupCommand = platform2 === "win32" ? "where" : "which";
|
|
45207
|
+
const result = commandRunner(lookupCommand, [command]);
|
|
45208
|
+
if (result.status === 0) {
|
|
45209
|
+
return { path: normalizeOutput(result.stdout) };
|
|
45210
|
+
}
|
|
45211
|
+
return {
|
|
45212
|
+
path: null,
|
|
45213
|
+
detail: normalizeOutput(result.stderr) ?? result.error ?? null
|
|
45214
|
+
};
|
|
45215
|
+
}
|
|
45216
|
+
function extractSemver(value) {
|
|
45217
|
+
return value?.match(/\d+\.\d+\.\d+(?:[-+][0-9A-Za-z.-]+)?/)?.[0] ?? null;
|
|
45218
|
+
}
|
|
45219
|
+
function normalizePackageVersion(output) {
|
|
45220
|
+
if (!output) return null;
|
|
45221
|
+
const trimmed = output.trim();
|
|
45222
|
+
try {
|
|
45223
|
+
const parsed = JSON.parse(trimmed);
|
|
45224
|
+
if (typeof parsed === "string") {
|
|
45225
|
+
return parsed.trim() || null;
|
|
45226
|
+
}
|
|
45227
|
+
} catch {
|
|
45228
|
+
}
|
|
45229
|
+
return normalizeOutput(trimmed);
|
|
45230
|
+
}
|
|
45231
|
+
function normalizeInstalledPackageVersion(output, packageName) {
|
|
45232
|
+
if (!output) return null;
|
|
45233
|
+
const trimmed = output.trim();
|
|
45234
|
+
try {
|
|
45235
|
+
const parsed = JSON.parse(trimmed);
|
|
45236
|
+
const version2 = parsed.dependencies?.[packageName]?.version;
|
|
45237
|
+
if (typeof version2 === "string") {
|
|
45238
|
+
return version2.trim() || null;
|
|
45239
|
+
}
|
|
45240
|
+
} catch {
|
|
45241
|
+
}
|
|
45242
|
+
return extractSemver(normalizeOutput(trimmed));
|
|
45243
|
+
}
|
|
45244
|
+
function resolveInstalledPackageVersion(definition, commandRunner) {
|
|
45245
|
+
const result = commandRunner("npm", ["list", "-g", definition.packageName, "--depth=0", "--json"]);
|
|
45246
|
+
return normalizeInstalledPackageVersion(result.stdout ?? null, definition.packageName);
|
|
45247
|
+
}
|
|
45248
|
+
function compareSemver(left, right) {
|
|
45249
|
+
const leftParts = left.split(/[.-]/).map((part) => Number.parseInt(part, 10));
|
|
45250
|
+
const rightParts = right.split(/[.-]/).map((part) => Number.parseInt(part, 10));
|
|
45251
|
+
for (let index = 0; index < 3; index += 1) {
|
|
45252
|
+
const delta = (leftParts[index] || 0) - (rightParts[index] || 0);
|
|
45253
|
+
if (delta !== 0) return delta;
|
|
45254
|
+
}
|
|
45255
|
+
return 0;
|
|
45256
|
+
}
|
|
45257
|
+
function checkToolUpdate(definition, installedVersion, checkedAt, commandRunner, checkedOn, updateCache) {
|
|
45258
|
+
const currentVersion = extractSemver(installedVersion);
|
|
45259
|
+
const cached = updateCache.get(definition.packageName);
|
|
45260
|
+
let latestVersion = cached?.latestVersion ?? null;
|
|
45261
|
+
let detail = cached?.detail ?? null;
|
|
45262
|
+
let updateCheckedAt = cached?.checkedAt ?? checkedAt;
|
|
45263
|
+
if (cached?.checkedOn !== checkedOn) {
|
|
45264
|
+
const latestResult = commandRunner("npm", ["view", definition.packageName, "version", "--json"]);
|
|
45265
|
+
latestVersion = latestResult.status === 0 ? normalizePackageVersion(latestResult.stdout ?? null) : null;
|
|
45266
|
+
detail = latestResult.status === 0 ? null : normalizeOutput(latestResult.stderr) ?? latestResult.error ?? "Update check failed";
|
|
45267
|
+
updateCheckedAt = checkedAt;
|
|
45268
|
+
updateCache.set(definition.packageName, {
|
|
45269
|
+
checkedOn,
|
|
45270
|
+
checkedAt,
|
|
45271
|
+
latestVersion,
|
|
45272
|
+
detail
|
|
45273
|
+
});
|
|
45274
|
+
}
|
|
45275
|
+
return {
|
|
45276
|
+
packageName: definition.packageName,
|
|
45277
|
+
currentVersion,
|
|
45278
|
+
latestVersion,
|
|
45279
|
+
updateAvailable: Boolean(currentVersion && latestVersion && compareSemver(latestVersion, currentVersion) > 0),
|
|
45280
|
+
checkedAt: updateCheckedAt,
|
|
45281
|
+
detail
|
|
45282
|
+
};
|
|
45283
|
+
}
|
|
45284
|
+
function inspectTool(definition, commandRunner, checkedAt, checkedOn, updateCache, platform2) {
|
|
45285
|
+
const resolved = resolveCommandPath(definition.command, commandRunner, platform2);
|
|
45286
|
+
if (!resolved.path) {
|
|
45287
|
+
return {
|
|
45288
|
+
id: definition.id,
|
|
45289
|
+
label: definition.label,
|
|
45290
|
+
command: definition.command,
|
|
45291
|
+
available: false,
|
|
45292
|
+
path: null,
|
|
45293
|
+
version: null,
|
|
45294
|
+
checkedAt,
|
|
45295
|
+
detail: resolved.detail ?? "Command not found on PATH",
|
|
45296
|
+
update: checkToolUpdate(definition, null, checkedAt, commandRunner, checkedOn, updateCache)
|
|
45297
|
+
};
|
|
45298
|
+
}
|
|
45299
|
+
const versionResult = commandRunner(definition.command, ["--version"]);
|
|
45300
|
+
const commandVersion = normalizeOutput(versionResult.stdout) ?? normalizeOutput(versionResult.stderr);
|
|
45301
|
+
const version2 = extractSemver(commandVersion) ? commandVersion : resolveInstalledPackageVersion(definition, commandRunner);
|
|
45302
|
+
const detail = versionResult.status === 0 ? null : normalizeOutput(versionResult.stderr) ?? versionResult.error ?? "Version check failed";
|
|
45303
|
+
return {
|
|
45304
|
+
id: definition.id,
|
|
45305
|
+
label: definition.label,
|
|
45306
|
+
command: definition.command,
|
|
45307
|
+
available: true,
|
|
45308
|
+
path: resolved.path,
|
|
45309
|
+
version: version2,
|
|
45310
|
+
checkedAt,
|
|
45311
|
+
detail,
|
|
45312
|
+
update: checkToolUpdate(definition, version2, checkedAt, commandRunner, checkedOn, updateCache)
|
|
45313
|
+
};
|
|
45314
|
+
}
|
|
45315
|
+
function inspectRuntimeTools(options = {}) {
|
|
45316
|
+
const platform2 = options.platform ?? process.platform;
|
|
45317
|
+
const commandRunner = options.commandRunner ?? ((command, args) => runRuntimeToolCommand(command, args, platform2));
|
|
45318
|
+
const now = options.now ?? /* @__PURE__ */ new Date();
|
|
45319
|
+
const checkedAt = now.toISOString();
|
|
45320
|
+
const checkedOn = formatLocalDate(now);
|
|
45321
|
+
const updateCache = options.updateCache ?? runtimeToolUpdateCache;
|
|
45322
|
+
return RUNTIME_TOOLS.map((definition) => inspectTool(definition, commandRunner, checkedAt, checkedOn, updateCache, platform2));
|
|
45323
|
+
}
|
|
45324
|
+
function getOsSnapshot() {
|
|
45325
|
+
const cpus2 = os6.cpus();
|
|
45326
|
+
return {
|
|
45327
|
+
platform: os6.platform(),
|
|
45328
|
+
release: os6.release(),
|
|
45329
|
+
arch: os6.arch(),
|
|
45330
|
+
hostname: os6.hostname(),
|
|
45331
|
+
cpuModel: cpus2[0]?.model ?? null,
|
|
45332
|
+
cpuCount: cpus2.length,
|
|
45333
|
+
totalMemoryBytes: os6.totalmem(),
|
|
45334
|
+
freeMemoryBytes: os6.freemem()
|
|
45335
|
+
};
|
|
45336
|
+
}
|
|
45337
|
+
function buildNodeSettingsSnapshot(options) {
|
|
45338
|
+
const uptime = process.uptime();
|
|
45339
|
+
const runtimeMetadata = options.runtimeMetadata;
|
|
45340
|
+
const agents = (options.inspectRuntimeTools?.() ?? inspectRuntimeTools()).map((agent) => ({
|
|
45341
|
+
...agent,
|
|
45342
|
+
metadataStatus: runtimeMetadata?.components?.[agent.id]?.status ?? null
|
|
45343
|
+
}));
|
|
45344
|
+
return {
|
|
45345
|
+
collectedAt: Date.now(),
|
|
45346
|
+
version: runtimeMetadata?.packageVersion ?? "0.1.0",
|
|
45347
|
+
packageName: runtimeMetadata?.packageName ?? "meshy",
|
|
45348
|
+
uptime,
|
|
45349
|
+
auth: options.auth,
|
|
45350
|
+
os: getOsSnapshot(),
|
|
45351
|
+
runtime: {
|
|
45352
|
+
nodeVersion: process.version,
|
|
45353
|
+
pid: process.pid,
|
|
45354
|
+
startedAt: Date.now() - Math.floor(uptime * 1e3),
|
|
45355
|
+
cwd: process.cwd(),
|
|
45356
|
+
workDir: options.workDir ?? null,
|
|
45357
|
+
storagePath: options.storagePath ?? null,
|
|
45358
|
+
localDashboardOrigin: options.localDashboardOrigin ?? null
|
|
45359
|
+
},
|
|
45360
|
+
agents,
|
|
45361
|
+
startupRequirements: {
|
|
45362
|
+
lastCheckedAt: runtimeMetadata?.startupRequirementsLastCheckedAt,
|
|
45363
|
+
lastCheckedOn: runtimeMetadata?.startupRequirementsLastCheckedOn,
|
|
45364
|
+
components: runtimeMetadata?.components ?? {}
|
|
45365
|
+
},
|
|
45366
|
+
components: runtimeMetadata?.components ?? {},
|
|
45367
|
+
repository: runtimeMetadata?.repository ?? {},
|
|
45368
|
+
packages: runtimeMetadata?.packages ?? {}
|
|
45369
|
+
};
|
|
45370
|
+
}
|
|
45371
|
+
|
|
45372
|
+
// ../../packages/api/src/node/agent-upgrade-service.ts
|
|
45373
|
+
var AGENT_PACKAGES = {
|
|
45374
|
+
claude: "@anthropic-ai/claude-code",
|
|
45375
|
+
codex: "@openai/codex"
|
|
45376
|
+
};
|
|
45377
|
+
var OUTPUT_LIMIT = 4e3;
|
|
45378
|
+
function summarizeOutput(value) {
|
|
45379
|
+
const text = value ?? "";
|
|
45380
|
+
return text.length > OUTPUT_LIMIT ? `${text.slice(0, OUTPUT_LIMIT)}\u2026` : text;
|
|
45381
|
+
}
|
|
45382
|
+
function defaultCommandRunner(command, args) {
|
|
45383
|
+
const result = (0, import_node_child_process9.spawnSync)(command, args, {
|
|
45384
|
+
encoding: "utf-8",
|
|
45385
|
+
shell: process.platform === "win32",
|
|
45386
|
+
windowsHide: true,
|
|
45387
|
+
timeout: 18e4
|
|
45388
|
+
});
|
|
45389
|
+
return {
|
|
45390
|
+
status: result.status,
|
|
45391
|
+
stdout: typeof result.stdout === "string" ? result.stdout : "",
|
|
45392
|
+
stderr: typeof result.stderr === "string" ? result.stderr : "",
|
|
45393
|
+
error: result.error?.message ?? null
|
|
45394
|
+
};
|
|
45395
|
+
}
|
|
45396
|
+
function isRuntimeAgentId(value) {
|
|
45397
|
+
return value === "claude" || value === "codex";
|
|
45398
|
+
}
|
|
45399
|
+
function buildUpgradeArgs(agent, packageName) {
|
|
45400
|
+
const args = ["install", "-g", `${packageName}@latest`];
|
|
45401
|
+
if (agent === "claude") {
|
|
45402
|
+
args.push("--include=optional", "--ignore-scripts=false");
|
|
45403
|
+
}
|
|
45404
|
+
return args;
|
|
45405
|
+
}
|
|
45406
|
+
function upgradeRuntimeAgent(agent, options = {}) {
|
|
45407
|
+
const packageName = AGENT_PACKAGES[agent];
|
|
45408
|
+
if (!packageName) {
|
|
45409
|
+
throw new MeshyError("VALIDATION_ERROR", `Unsupported upgrade agent: ${agent}`, 400);
|
|
45410
|
+
}
|
|
45411
|
+
const command = "npm";
|
|
45412
|
+
const args = buildUpgradeArgs(agent, packageName);
|
|
45413
|
+
const result = (options.commandRunner ?? defaultCommandRunner)(command, args);
|
|
45414
|
+
const ok = result.status === 0 && !result.error;
|
|
45415
|
+
if (ok) {
|
|
45416
|
+
clearRuntimeToolUpdateCache(packageName);
|
|
45417
|
+
}
|
|
45418
|
+
const detail = result.error ?? (summarizeOutput(result.stderr) || "Agent upgrade failed");
|
|
45419
|
+
return {
|
|
45420
|
+
ok,
|
|
45421
|
+
agent,
|
|
45422
|
+
packageName,
|
|
45423
|
+
command,
|
|
45424
|
+
args,
|
|
45425
|
+
status: result.status,
|
|
45426
|
+
stdout: summarizeOutput(result.stdout),
|
|
45427
|
+
stderr: summarizeOutput(result.stderr),
|
|
45428
|
+
detail: ok ? null : detail
|
|
45429
|
+
};
|
|
45430
|
+
}
|
|
45431
|
+
function upgradeRuntimeAgentForDeps(deps, agent) {
|
|
45432
|
+
const result = deps.upgradeRuntimeAgent?.(agent) ?? upgradeRuntimeAgent(agent);
|
|
45433
|
+
if (result.ok) {
|
|
45434
|
+
const settingsSnapshot = deps.refreshSettingsSnapshot?.();
|
|
45435
|
+
if (settingsSnapshot) {
|
|
45436
|
+
deps.nodeRegistry.updateSettingsSnapshot(deps.nodeRegistry.getSelf().id, settingsSnapshot);
|
|
45437
|
+
return { ...result, settingsSnapshot };
|
|
45438
|
+
}
|
|
45439
|
+
}
|
|
45440
|
+
return result;
|
|
45441
|
+
}
|
|
45442
|
+
|
|
45147
45443
|
// ../../packages/api/src/node/worker-control.ts
|
|
45148
45444
|
function jsonResponse(requestId, statusCode, body) {
|
|
45149
45445
|
return {
|
|
@@ -45303,6 +45599,14 @@ async function executeWorkerControlRequest(deps, request) {
|
|
|
45303
45599
|
});
|
|
45304
45600
|
break;
|
|
45305
45601
|
}
|
|
45602
|
+
case "node.agent.upgrade": {
|
|
45603
|
+
const agent = payloadValue(request, "agent", "");
|
|
45604
|
+
if (!isRuntimeAgentId(agent)) {
|
|
45605
|
+
throw new MeshyError("VALIDATION_ERROR", `Unsupported upgrade agent: ${agent}`, 400);
|
|
45606
|
+
}
|
|
45607
|
+
response = jsonResponse(request.id, 200, upgradeRuntimeAgentForDeps(deps, agent));
|
|
45608
|
+
break;
|
|
45609
|
+
}
|
|
45306
45610
|
case "task.cancel": {
|
|
45307
45611
|
const taskId = payloadValue(request, "taskId", "");
|
|
45308
45612
|
const result = cancelTaskOnCurrentNode({
|
|
@@ -45446,6 +45750,84 @@ function sendLocalNodeNativeSessions(req, res, nodeId, options = {}) {
|
|
|
45446
45750
|
res.json(getLocalNodeNativeSessions(self2.id, query.agent, query.limit));
|
|
45447
45751
|
}
|
|
45448
45752
|
|
|
45753
|
+
// ../../packages/api/src/routes/node-agent-upgrade.ts
|
|
45754
|
+
function isRecord5(value) {
|
|
45755
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
45756
|
+
}
|
|
45757
|
+
function readSettingsSnapshot(value) {
|
|
45758
|
+
if (!isRecord5(value)) return void 0;
|
|
45759
|
+
const snapshot = value.settingsSnapshot;
|
|
45760
|
+
if (!isRecord5(snapshot)) return void 0;
|
|
45761
|
+
return snapshot;
|
|
45762
|
+
}
|
|
45763
|
+
function applySyncedSettingsSnapshot(deps, nodeId, body) {
|
|
45764
|
+
const settingsSnapshot = readSettingsSnapshot(body);
|
|
45765
|
+
if (settingsSnapshot) {
|
|
45766
|
+
deps.nodeRegistry.updateSettingsSnapshot(nodeId, settingsSnapshot);
|
|
45767
|
+
}
|
|
45768
|
+
}
|
|
45769
|
+
function parseAgent(value) {
|
|
45770
|
+
if (isRuntimeAgentId(value)) return value;
|
|
45771
|
+
throw new MeshyError("VALIDATION_ERROR", `Unsupported upgrade agent: ${value}`, 400);
|
|
45772
|
+
}
|
|
45773
|
+
function upgradeSelfNode(deps, nodeId, agent) {
|
|
45774
|
+
const result = upgradeRuntimeAgentForDeps(deps, agent);
|
|
45775
|
+
applySyncedSettingsSnapshot(deps, nodeId, result);
|
|
45776
|
+
return result;
|
|
45777
|
+
}
|
|
45778
|
+
async function fallbackUpgrade(deps, res, nodeId, agent) {
|
|
45779
|
+
if (!canRequestNodeMessage(deps.heartbeat)) {
|
|
45780
|
+
throw new MeshyError("NODE_OFFLINE", `Cannot reach node ${nodeId} to upgrade ${agent}`, 502);
|
|
45781
|
+
}
|
|
45782
|
+
const controlResponse = await requestFallbackNodeMessage(
|
|
45783
|
+
deps.heartbeat,
|
|
45784
|
+
nodeId,
|
|
45785
|
+
createNodeMessage("node.agent.upgrade", { agent }, { expectsResponse: true })
|
|
45786
|
+
);
|
|
45787
|
+
applySyncedSettingsSnapshot(deps, nodeId, controlResponse.body);
|
|
45788
|
+
sendWorkerControlResponse(res, controlResponse);
|
|
45789
|
+
}
|
|
45790
|
+
async function proxyUpgrade(deps, nodeId, agent) {
|
|
45791
|
+
const node = deps.nodeRegistry.getNode(nodeId);
|
|
45792
|
+
if (!node) {
|
|
45793
|
+
throw new MeshyError("NODE_NOT_FOUND", `Node ${nodeId} not found`, 404);
|
|
45794
|
+
}
|
|
45795
|
+
const { response } = await fetchNodeWithFallback(node, `/api/nodes/${nodeId}/agents/${agent}/upgrade`, {
|
|
45796
|
+
method: "POST",
|
|
45797
|
+
headers: { "Content-Type": "application/json" }
|
|
45798
|
+
}, void 0, void 0, { preferPublicEndpoint: true });
|
|
45799
|
+
const body = await response.json().catch(() => ({ error: response.statusText }));
|
|
45800
|
+
if (!response.ok) {
|
|
45801
|
+
throw new MeshyError("NODE_OFFLINE", `Remote node returned ${response.status}`, response.status, body);
|
|
45802
|
+
}
|
|
45803
|
+
applySyncedSettingsSnapshot(deps, nodeId, body);
|
|
45804
|
+
return body;
|
|
45805
|
+
}
|
|
45806
|
+
async function sendNodeAgentUpgrade(req, res, nodeId, agentParam) {
|
|
45807
|
+
const deps = req.app.locals.deps;
|
|
45808
|
+
const agent = parseAgent(agentParam);
|
|
45809
|
+
const self2 = deps.nodeRegistry.getSelf();
|
|
45810
|
+
const isSelf = nodeId === self2.id;
|
|
45811
|
+
if (!isSelf && !deps.election.isLeader()) {
|
|
45812
|
+
throw new MeshyError("NOT_LEADER", "Only the leader can upgrade agents on other nodes", 403);
|
|
45813
|
+
}
|
|
45814
|
+
if (isSelf) {
|
|
45815
|
+
res.json(upgradeSelfNode(deps, nodeId, agent));
|
|
45816
|
+
return;
|
|
45817
|
+
}
|
|
45818
|
+
const canPushToNode = deps.heartbeat?.canPushToNode?.(nodeId) ?? true;
|
|
45819
|
+
if (!canPushToNode) {
|
|
45820
|
+
await fallbackUpgrade(deps, res, nodeId, agent);
|
|
45821
|
+
return;
|
|
45822
|
+
}
|
|
45823
|
+
try {
|
|
45824
|
+
res.json(await proxyUpgrade(deps, nodeId, agent));
|
|
45825
|
+
} catch (err) {
|
|
45826
|
+
if (!canRequestNodeMessage(deps.heartbeat)) throw err;
|
|
45827
|
+
await fallbackUpgrade(deps, res, nodeId, agent);
|
|
45828
|
+
}
|
|
45829
|
+
}
|
|
45830
|
+
|
|
45449
45831
|
// ../../packages/api/src/routes/nodes.ts
|
|
45450
45832
|
var NODE_WORKDIR_PROXY_TIMEOUT_MS = 1e4;
|
|
45451
45833
|
var NODE_WORKDIR_BRANCH_PROXY_TIMEOUT_MS = 25e3;
|
|
@@ -45785,35 +46167,38 @@ function createNodeRoutes() {
|
|
|
45785
46167
|
const query = NodeListQuery.parse(req.query);
|
|
45786
46168
|
let nodes = nodeRegistry.getAllNodes();
|
|
45787
46169
|
if (query.status) {
|
|
45788
|
-
nodes = nodes.filter((
|
|
46170
|
+
nodes = nodes.filter((node) => node.status === query.status);
|
|
45789
46171
|
}
|
|
45790
|
-
|
|
46172
|
+
const capability = query.capability;
|
|
46173
|
+
if (capability) {
|
|
45791
46174
|
nodes = nodes.filter(
|
|
45792
|
-
(
|
|
46175
|
+
(node) => node.capabilities && node.capabilities.includes(capability)
|
|
45793
46176
|
);
|
|
45794
46177
|
}
|
|
45795
46178
|
res.json({ nodes });
|
|
45796
46179
|
}));
|
|
45797
46180
|
router.get("/:id", asyncHandler3(async (req, res) => {
|
|
45798
46181
|
const { nodeRegistry } = req.app.locals.deps;
|
|
45799
|
-
const
|
|
46182
|
+
const nodeId = req.params.id;
|
|
46183
|
+
const node = nodeRegistry.getNode(nodeId);
|
|
45800
46184
|
if (!node) {
|
|
45801
|
-
throw new MeshyError("NODE_NOT_FOUND", `Node ${
|
|
46185
|
+
throw new MeshyError("NODE_NOT_FOUND", `Node ${nodeId} not found`, 404);
|
|
45802
46186
|
}
|
|
45803
46187
|
res.json(node);
|
|
45804
46188
|
}));
|
|
45805
46189
|
router.get("/:id/status", asyncHandler3(async (req, res) => {
|
|
45806
46190
|
const { nodeRegistry, taskEngine } = req.app.locals.deps;
|
|
45807
|
-
const
|
|
46191
|
+
const nodeId = req.params.id;
|
|
46192
|
+
const node = nodeRegistry.getNode(nodeId);
|
|
45808
46193
|
if (!node) {
|
|
45809
|
-
throw new MeshyError("NODE_NOT_FOUND", `Node ${
|
|
45810
|
-
}
|
|
45811
|
-
const { tasks } = taskEngine.listTasks({ assignedTo:
|
|
45812
|
-
const taskSummary = tasks.map((
|
|
45813
|
-
id:
|
|
45814
|
-
title:
|
|
45815
|
-
status:
|
|
45816
|
-
priority:
|
|
46194
|
+
throw new MeshyError("NODE_NOT_FOUND", `Node ${nodeId} not found`, 404);
|
|
46195
|
+
}
|
|
46196
|
+
const { tasks } = taskEngine.listTasks({ assignedTo: nodeId });
|
|
46197
|
+
const taskSummary = tasks.map((task) => ({
|
|
46198
|
+
id: task.id,
|
|
46199
|
+
title: task.title,
|
|
46200
|
+
status: task.status,
|
|
46201
|
+
priority: task.priority
|
|
45817
46202
|
}));
|
|
45818
46203
|
res.json({ node, tasks: taskSummary });
|
|
45819
46204
|
}));
|
|
@@ -45849,6 +46234,9 @@ function createNodeRoutes() {
|
|
|
45849
46234
|
}
|
|
45850
46235
|
sendLocalNodeWorkDirBranchCreate(req, res, nodeId);
|
|
45851
46236
|
}));
|
|
46237
|
+
router.post("/:id/agents/:agent/upgrade", asyncHandler3(async (req, res) => {
|
|
46238
|
+
await sendNodeAgentUpgrade(req, res, req.params.id, req.params.agent);
|
|
46239
|
+
}));
|
|
45852
46240
|
router.patch("/:id", asyncHandler3(async (req, res) => {
|
|
45853
46241
|
const { nodeRegistry, persistNodeNamePreference } = req.app.locals.deps;
|
|
45854
46242
|
const updates = UpdateNodeBody.parse(req.body);
|
|
@@ -45874,14 +46262,15 @@ function createNodeRoutes() {
|
|
|
45874
46262
|
}));
|
|
45875
46263
|
router.delete("/:id", asyncHandler3(async (req, res) => {
|
|
45876
46264
|
const { nodeRegistry, election } = req.app.locals.deps;
|
|
46265
|
+
const nodeId = req.params.id;
|
|
45877
46266
|
if (!election.isLeader()) {
|
|
45878
46267
|
throw new MeshyError("NOT_LEADER", "Only the leader node can delete nodes", 403);
|
|
45879
46268
|
}
|
|
45880
|
-
const node = nodeRegistry.getNode(
|
|
46269
|
+
const node = nodeRegistry.getNode(nodeId);
|
|
45881
46270
|
if (!node) {
|
|
45882
|
-
throw new MeshyError("NODE_NOT_FOUND", `Node ${
|
|
46271
|
+
throw new MeshyError("NODE_NOT_FOUND", `Node ${nodeId} not found`, 404);
|
|
45883
46272
|
}
|
|
45884
|
-
nodeRegistry.removeNode(
|
|
46273
|
+
nodeRegistry.removeNode(nodeId);
|
|
45885
46274
|
res.json({ ok: true });
|
|
45886
46275
|
}));
|
|
45887
46276
|
router.post("/:id/devtunnel", asyncHandler3(async (req, res) => {
|
|
@@ -46371,14 +46760,15 @@ async function sendTaskLogsResponse(req, res, taskId) {
|
|
|
46371
46760
|
selfId
|
|
46372
46761
|
});
|
|
46373
46762
|
}
|
|
46374
|
-
|
|
46375
|
-
|
|
46763
|
+
const assignedTo = task.assignedTo;
|
|
46764
|
+
if (needsProxy && assignedTo) {
|
|
46765
|
+
const node = nodeRegistry.getNode(assignedTo);
|
|
46376
46766
|
log2.debug("proxy target", { nodeId: node?.id, endpoint: node?.endpoint, devtunnel: node?.devtunnelEndpoint, status: node?.status });
|
|
46377
46767
|
if (node) {
|
|
46378
46768
|
const seededLogs = await seedTaskSnapshotOnWorker(task, [], node, log2).catch((err) => {
|
|
46379
46769
|
log2.warn("failed to seed task snapshot before task logs proxy", {
|
|
46380
46770
|
taskId,
|
|
46381
|
-
assignedTo
|
|
46771
|
+
assignedTo,
|
|
46382
46772
|
...describeProxyError3(err)
|
|
46383
46773
|
});
|
|
46384
46774
|
return [];
|
|
@@ -46397,24 +46787,24 @@ async function sendTaskLogsResponse(req, res, taskId) {
|
|
|
46397
46787
|
const proxyUrl = `${endpoint}${proxyPath}`;
|
|
46398
46788
|
log2.info("proxying task logs request", {
|
|
46399
46789
|
taskId,
|
|
46400
|
-
assignedTo
|
|
46790
|
+
assignedTo,
|
|
46401
46791
|
endpoint,
|
|
46402
46792
|
proxyPath,
|
|
46403
46793
|
url: proxyUrl
|
|
46404
46794
|
});
|
|
46405
46795
|
if (!proxyRes.ok) throw new MeshyError("NODE_OFFLINE", `Worker log proxy failed (${proxyRes.status})`, 502);
|
|
46406
46796
|
const data = await proxyRes.json();
|
|
46407
|
-
log2.debug("proxy returned", { logs: data
|
|
46797
|
+
log2.debug("proxy returned", { logs: data.logs?.length ?? 0, total: data.total });
|
|
46408
46798
|
res.json(data);
|
|
46409
46799
|
return;
|
|
46410
46800
|
} catch (err) {
|
|
46411
46801
|
log2.warn("task logs proxy failed; falling back to keepalive control", {
|
|
46412
46802
|
taskId,
|
|
46413
|
-
assignedTo
|
|
46803
|
+
assignedTo,
|
|
46414
46804
|
timeoutMs: TASK_LOG_PROXY_TIMEOUT_MS,
|
|
46415
46805
|
...describeProxyError3(err)
|
|
46416
46806
|
});
|
|
46417
|
-
const fallback = await requestTaskLogsOverKeepalive(heartbeat,
|
|
46807
|
+
const fallback = await requestTaskLogsOverKeepalive(heartbeat, assignedTo, task, after);
|
|
46418
46808
|
if (fallback) {
|
|
46419
46809
|
sendWorkerControlResponse(res, fallback);
|
|
46420
46810
|
return;
|
|
@@ -47062,13 +47452,14 @@ function createTaskRoutes() {
|
|
|
47062
47452
|
const { taskEngine, nodeRegistry, logger: rootLogger } = req.app.locals.deps;
|
|
47063
47453
|
const log2 = rootLogger.child("tasks/patch");
|
|
47064
47454
|
const updates = UpdateTaskBody.parse(req.body);
|
|
47065
|
-
const
|
|
47455
|
+
const taskId = req.params.id;
|
|
47456
|
+
const existing = taskEngine.getTask(taskId);
|
|
47066
47457
|
if (!existing) {
|
|
47067
|
-
throw new MeshyError("TASK_NOT_FOUND", `Task ${
|
|
47458
|
+
throw new MeshyError("TASK_NOT_FOUND", `Task ${taskId} not found`, 404);
|
|
47068
47459
|
}
|
|
47069
47460
|
if (updates.status !== void 0 && TERMINAL_STATUSES3.has(existing.status) && ACTIVE_STATUSES.has(updates.status)) {
|
|
47070
47461
|
log2.warn("ignoring stale status regression for terminal task", {
|
|
47071
|
-
taskId
|
|
47462
|
+
taskId,
|
|
47072
47463
|
currentStatus: existing.status,
|
|
47073
47464
|
incomingStatus: updates.status
|
|
47074
47465
|
});
|
|
@@ -47084,33 +47475,35 @@ function createTaskRoutes() {
|
|
|
47084
47475
|
}
|
|
47085
47476
|
if (updates.status !== void 0 && existing.status === "archived" && updates.status !== "archived") {
|
|
47086
47477
|
log2.warn("ignoring status change for archived task", {
|
|
47087
|
-
taskId
|
|
47478
|
+
taskId,
|
|
47088
47479
|
currentStatus: existing.status,
|
|
47089
47480
|
incomingStatus: updates.status
|
|
47090
47481
|
});
|
|
47091
47482
|
res.json(withAssignedNodeMetadata(existing, nodeRegistry));
|
|
47092
47483
|
return;
|
|
47093
47484
|
}
|
|
47094
|
-
const task = taskEngine.updateTask(
|
|
47485
|
+
const task = taskEngine.updateTask(taskId, updates);
|
|
47095
47486
|
if (!task) {
|
|
47096
|
-
throw new MeshyError("TASK_NOT_FOUND", `Task ${
|
|
47487
|
+
throw new MeshyError("TASK_NOT_FOUND", `Task ${taskId} not found`, 404);
|
|
47097
47488
|
}
|
|
47098
47489
|
res.json(withAssignedNodeMetadata(task, nodeRegistry));
|
|
47099
47490
|
}));
|
|
47100
47491
|
router.delete("/:id", asyncHandler6(async (req, res) => {
|
|
47101
47492
|
const { taskEngine } = req.app.locals.deps;
|
|
47102
|
-
const
|
|
47493
|
+
const taskId = req.params.id;
|
|
47494
|
+
const result = taskEngine.deleteTask(taskId);
|
|
47103
47495
|
if (!result) {
|
|
47104
|
-
throw new MeshyError("TASK_NOT_FOUND", `Task ${
|
|
47496
|
+
throw new MeshyError("TASK_NOT_FOUND", `Task ${taskId} not found`, 404);
|
|
47105
47497
|
}
|
|
47106
47498
|
res.json({ ok: true });
|
|
47107
47499
|
}));
|
|
47108
47500
|
router.post("/:id/cancel", asyncHandler6(async (req, res) => {
|
|
47109
47501
|
const { taskEngine, nodeRegistry, engineRegistry, heartbeat, logger: rootLogger } = req.app.locals.deps;
|
|
47110
47502
|
const log2 = rootLogger.child("tasks/cancel");
|
|
47111
|
-
const
|
|
47503
|
+
const taskId = req.params.id;
|
|
47504
|
+
const task = taskEngine.getTask(taskId);
|
|
47112
47505
|
if (!task) {
|
|
47113
|
-
throw new MeshyError("TASK_NOT_FOUND", `Task ${
|
|
47506
|
+
throw new MeshyError("TASK_NOT_FOUND", `Task ${taskId} not found`, 404);
|
|
47114
47507
|
}
|
|
47115
47508
|
if (TERMINAL_STATUSES3.has(task.status)) {
|
|
47116
47509
|
throw new MeshyError("VALIDATION_ERROR", `Task ${task.id} cannot be cancelled (status: ${task.status})`, 400);
|
|
@@ -47160,9 +47553,10 @@ function createTaskRoutes() {
|
|
|
47160
47553
|
const { taskEngine, engineRegistry, nodeRegistry, heartbeat, logger: rootLogger } = req.app.locals.deps;
|
|
47161
47554
|
const log2 = rootLogger.child("tasks/message");
|
|
47162
47555
|
const body = SendMessageBody.parse(req.body);
|
|
47163
|
-
const
|
|
47556
|
+
const taskId = req.params.id;
|
|
47557
|
+
const task = taskEngine.getTask(taskId);
|
|
47164
47558
|
if (!task) {
|
|
47165
|
-
throw new MeshyError("TASK_NOT_FOUND", `Task ${
|
|
47559
|
+
throw new MeshyError("TASK_NOT_FOUND", `Task ${taskId} not found`, 404);
|
|
47166
47560
|
}
|
|
47167
47561
|
if (!supportsFollowUpAgent(task.agent)) {
|
|
47168
47562
|
throw new MeshyError("VALIDATION_ERROR", `Agent ${task.agent} does not support chat messages`, 400);
|
|
@@ -47594,123 +47988,6 @@ function normalizeNodeMessageResponse(value) {
|
|
|
47594
47988
|
|
|
47595
47989
|
// ../../packages/api/src/routes/system.ts
|
|
47596
47990
|
var import_express11 = __toESM(require_express2(), 1);
|
|
47597
|
-
|
|
47598
|
-
// ../../packages/api/src/app/system-info.ts
|
|
47599
|
-
var os6 = __toESM(require("os"), 1);
|
|
47600
|
-
var import_node_child_process8 = require("child_process");
|
|
47601
|
-
var RUNTIME_TOOLS = [
|
|
47602
|
-
{ id: "claude", label: "Claude Code", command: "claude" },
|
|
47603
|
-
{ id: "codex", label: "Codex", command: "codex" }
|
|
47604
|
-
];
|
|
47605
|
-
function normalizeOutput(output) {
|
|
47606
|
-
if (!output) {
|
|
47607
|
-
return null;
|
|
47608
|
-
}
|
|
47609
|
-
const firstLine = output.split(/\r?\n/).map((line) => line.trim()).find(Boolean);
|
|
47610
|
-
return firstLine ?? null;
|
|
47611
|
-
}
|
|
47612
|
-
function resolveCommandPath(command) {
|
|
47613
|
-
const lookupCommand = process.platform === "win32" ? "where" : "which";
|
|
47614
|
-
const result = (0, import_node_child_process8.spawnSync)(lookupCommand, [command], {
|
|
47615
|
-
encoding: "utf-8",
|
|
47616
|
-
shell: false,
|
|
47617
|
-
windowsHide: true,
|
|
47618
|
-
timeout: 1500
|
|
47619
|
-
});
|
|
47620
|
-
if (result.status === 0) {
|
|
47621
|
-
return { path: normalizeOutput(result.stdout) };
|
|
47622
|
-
}
|
|
47623
|
-
return {
|
|
47624
|
-
path: null,
|
|
47625
|
-
detail: normalizeOutput(result.stderr) ?? result.error?.message ?? null
|
|
47626
|
-
};
|
|
47627
|
-
}
|
|
47628
|
-
function inspectTool(definition) {
|
|
47629
|
-
const checkedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
47630
|
-
const resolved = resolveCommandPath(definition.command);
|
|
47631
|
-
if (!resolved.path) {
|
|
47632
|
-
return {
|
|
47633
|
-
id: definition.id,
|
|
47634
|
-
label: definition.label,
|
|
47635
|
-
command: definition.command,
|
|
47636
|
-
available: false,
|
|
47637
|
-
path: null,
|
|
47638
|
-
version: null,
|
|
47639
|
-
checkedAt,
|
|
47640
|
-
detail: resolved.detail ?? "Command not found on PATH"
|
|
47641
|
-
};
|
|
47642
|
-
}
|
|
47643
|
-
const versionResult = (0, import_node_child_process8.spawnSync)(definition.command, ["--version"], {
|
|
47644
|
-
encoding: "utf-8",
|
|
47645
|
-
shell: process.platform === "win32",
|
|
47646
|
-
windowsHide: true,
|
|
47647
|
-
timeout: 2500
|
|
47648
|
-
});
|
|
47649
|
-
const version2 = normalizeOutput(versionResult.stdout) ?? normalizeOutput(versionResult.stderr);
|
|
47650
|
-
const detail = versionResult.status === 0 ? null : normalizeOutput(versionResult.stderr) ?? versionResult.error?.message ?? "Version check failed";
|
|
47651
|
-
return {
|
|
47652
|
-
id: definition.id,
|
|
47653
|
-
label: definition.label,
|
|
47654
|
-
command: definition.command,
|
|
47655
|
-
available: true,
|
|
47656
|
-
path: resolved.path,
|
|
47657
|
-
version: version2,
|
|
47658
|
-
checkedAt,
|
|
47659
|
-
detail
|
|
47660
|
-
};
|
|
47661
|
-
}
|
|
47662
|
-
function inspectRuntimeTools() {
|
|
47663
|
-
return RUNTIME_TOOLS.map(inspectTool);
|
|
47664
|
-
}
|
|
47665
|
-
function getOsSnapshot() {
|
|
47666
|
-
const cpus2 = os6.cpus();
|
|
47667
|
-
return {
|
|
47668
|
-
platform: os6.platform(),
|
|
47669
|
-
release: os6.release(),
|
|
47670
|
-
arch: os6.arch(),
|
|
47671
|
-
hostname: os6.hostname(),
|
|
47672
|
-
cpuModel: cpus2[0]?.model ?? null,
|
|
47673
|
-
cpuCount: cpus2.length,
|
|
47674
|
-
totalMemoryBytes: os6.totalmem(),
|
|
47675
|
-
freeMemoryBytes: os6.freemem()
|
|
47676
|
-
};
|
|
47677
|
-
}
|
|
47678
|
-
function buildNodeSettingsSnapshot(options) {
|
|
47679
|
-
const uptime = process.uptime();
|
|
47680
|
-
const runtimeMetadata = options.runtimeMetadata;
|
|
47681
|
-
const agents = (options.inspectRuntimeTools?.() ?? inspectRuntimeTools()).map((agent) => ({
|
|
47682
|
-
...agent,
|
|
47683
|
-
metadataStatus: runtimeMetadata?.components?.[agent.id]?.status ?? null
|
|
47684
|
-
}));
|
|
47685
|
-
return {
|
|
47686
|
-
collectedAt: Date.now(),
|
|
47687
|
-
version: runtimeMetadata?.packageVersion ?? "0.1.0",
|
|
47688
|
-
packageName: runtimeMetadata?.packageName ?? "meshy",
|
|
47689
|
-
uptime,
|
|
47690
|
-
auth: options.auth,
|
|
47691
|
-
os: getOsSnapshot(),
|
|
47692
|
-
runtime: {
|
|
47693
|
-
nodeVersion: process.version,
|
|
47694
|
-
pid: process.pid,
|
|
47695
|
-
startedAt: Date.now() - Math.floor(uptime * 1e3),
|
|
47696
|
-
cwd: process.cwd(),
|
|
47697
|
-
workDir: options.workDir ?? null,
|
|
47698
|
-
storagePath: options.storagePath ?? null,
|
|
47699
|
-
localDashboardOrigin: options.localDashboardOrigin ?? null
|
|
47700
|
-
},
|
|
47701
|
-
agents,
|
|
47702
|
-
startupRequirements: {
|
|
47703
|
-
lastCheckedAt: runtimeMetadata?.startupRequirementsLastCheckedAt,
|
|
47704
|
-
lastCheckedOn: runtimeMetadata?.startupRequirementsLastCheckedOn,
|
|
47705
|
-
components: runtimeMetadata?.components ?? {}
|
|
47706
|
-
},
|
|
47707
|
-
components: runtimeMetadata?.components ?? {},
|
|
47708
|
-
repository: runtimeMetadata?.repository ?? {},
|
|
47709
|
-
packages: runtimeMetadata?.packages ?? {}
|
|
47710
|
-
};
|
|
47711
|
-
}
|
|
47712
|
-
|
|
47713
|
-
// ../../packages/api/src/routes/system.ts
|
|
47714
47991
|
function asyncHandler9(fn) {
|
|
47715
47992
|
return (req, res, next) => fn(req, res, next).catch(next);
|
|
47716
47993
|
}
|
|
@@ -47776,8 +48053,8 @@ function createSystemRoutes() {
|
|
|
47776
48053
|
return;
|
|
47777
48054
|
}
|
|
47778
48055
|
const { type } = req.body;
|
|
47779
|
-
if (!type || !["direct", "devtunnel"
|
|
47780
|
-
res.status(400).json({ error: "Invalid transport type. Must be: direct
|
|
48056
|
+
if (!type || !["direct", "devtunnel"].includes(type)) {
|
|
48057
|
+
res.status(400).json({ error: "Invalid transport type. Must be: direct or devtunnel" });
|
|
47781
48058
|
return;
|
|
47782
48059
|
}
|
|
47783
48060
|
const newEndpoint = await switchTransport(type);
|
|
@@ -47860,6 +48137,7 @@ function createEventRoutes() {
|
|
|
47860
48137
|
const router = (0, import_express12.Router)();
|
|
47861
48138
|
router.get("/", (req, res) => {
|
|
47862
48139
|
const { eventBus } = req.app.locals.deps;
|
|
48140
|
+
const stream = res;
|
|
47863
48141
|
const categories = parseFilter(req.query.filter);
|
|
47864
48142
|
res.writeHead(200, {
|
|
47865
48143
|
"Content-Type": "text/event-stream",
|
|
@@ -47876,20 +48154,14 @@ data: ${JSON.stringify(data)}
|
|
|
47876
48154
|
|
|
47877
48155
|
`;
|
|
47878
48156
|
res.write(payload);
|
|
47879
|
-
|
|
47880
|
-
;
|
|
47881
|
-
res.flush();
|
|
47882
|
-
}
|
|
48157
|
+
stream.flush?.();
|
|
47883
48158
|
};
|
|
47884
48159
|
listeners.set(eventName, listener);
|
|
47885
48160
|
eventBus.on(eventName, listener);
|
|
47886
48161
|
}
|
|
47887
48162
|
const heartbeatTimer = setInterval(() => {
|
|
47888
48163
|
res.write(": heartbeat\n\n");
|
|
47889
|
-
|
|
47890
|
-
;
|
|
47891
|
-
res.flush();
|
|
47892
|
-
}
|
|
48164
|
+
stream.flush?.();
|
|
47893
48165
|
}, HEARTBEAT_INTERVAL_MS);
|
|
47894
48166
|
req.on("close", () => {
|
|
47895
48167
|
clearInterval(heartbeatTimer);
|
|
@@ -48141,10 +48413,10 @@ var DirectTransport = class {
|
|
|
48141
48413
|
};
|
|
48142
48414
|
|
|
48143
48415
|
// ../../packages/transport/src/devtunnel.ts
|
|
48144
|
-
var
|
|
48416
|
+
var import_node_child_process10 = require("child_process");
|
|
48145
48417
|
function isInstalled(cmd) {
|
|
48146
48418
|
try {
|
|
48147
|
-
(0,
|
|
48419
|
+
(0, import_node_child_process10.execSync)(process.platform === "win32" ? `where ${cmd}` : `command -v ${cmd}`, { stdio: "pipe" });
|
|
48148
48420
|
return true;
|
|
48149
48421
|
} catch {
|
|
48150
48422
|
return false;
|
|
@@ -48167,14 +48439,14 @@ var DevTunnelTransport = class {
|
|
|
48167
48439
|
);
|
|
48168
48440
|
}
|
|
48169
48441
|
try {
|
|
48170
|
-
(0,
|
|
48442
|
+
(0, import_node_child_process10.execSync)("devtunnel user show", { stdio: "pipe" });
|
|
48171
48443
|
} catch {
|
|
48172
48444
|
throw new Error(
|
|
48173
48445
|
"Not logged in to devtunnel. Run: devtunnel user login"
|
|
48174
48446
|
);
|
|
48175
48447
|
}
|
|
48176
48448
|
const hostArgs = this.buildHostArgs(localPort);
|
|
48177
|
-
const child = (0,
|
|
48449
|
+
const child = (0, import_node_child_process10.spawn)("devtunnel", hostArgs, {
|
|
48178
48450
|
stdio: ["pipe", "pipe", "pipe"]
|
|
48179
48451
|
});
|
|
48180
48452
|
this.process = child;
|
|
@@ -48279,7 +48551,7 @@ ${lines.join("")}`
|
|
|
48279
48551
|
return;
|
|
48280
48552
|
}
|
|
48281
48553
|
try {
|
|
48282
|
-
(0,
|
|
48554
|
+
(0, import_node_child_process10.execFileSync)("devtunnel", ["access", "create", tunnelId, "--tenant"], { stdio: "pipe" });
|
|
48283
48555
|
} catch (err) {
|
|
48284
48556
|
if (isExistingTenantAccessError(err)) {
|
|
48285
48557
|
return;
|
|
@@ -48295,7 +48567,7 @@ ${lines.join("")}`
|
|
|
48295
48567
|
return void 0;
|
|
48296
48568
|
}
|
|
48297
48569
|
try {
|
|
48298
|
-
(0,
|
|
48570
|
+
(0, import_node_child_process10.execFileSync)("devtunnel", ["show", tunnelId], { stdio: "pipe" });
|
|
48299
48571
|
return tunnelId;
|
|
48300
48572
|
} catch {
|
|
48301
48573
|
const createArgs = ["create", tunnelId];
|
|
@@ -48303,7 +48575,7 @@ ${lines.join("")}`
|
|
|
48303
48575
|
createArgs.push("-a");
|
|
48304
48576
|
}
|
|
48305
48577
|
try {
|
|
48306
|
-
(0,
|
|
48578
|
+
(0, import_node_child_process10.execFileSync)("devtunnel", createArgs, { stdio: "pipe" });
|
|
48307
48579
|
return tunnelId;
|
|
48308
48580
|
} catch (err) {
|
|
48309
48581
|
throw new Error(
|
|
@@ -48315,13 +48587,13 @@ ${lines.join("")}`
|
|
|
48315
48587
|
ensureTunnelPort(tunnelId, localPort) {
|
|
48316
48588
|
const ports = this.listTunnelPorts(tunnelId);
|
|
48317
48589
|
for (const stalePort of ports.filter((p) => p !== localPort)) {
|
|
48318
|
-
(0,
|
|
48590
|
+
(0, import_node_child_process10.execFileSync)("devtunnel", ["port", "delete", tunnelId, "-p", String(stalePort)], { stdio: "pipe" });
|
|
48319
48591
|
}
|
|
48320
48592
|
if (ports.includes(localPort)) {
|
|
48321
48593
|
return;
|
|
48322
48594
|
}
|
|
48323
48595
|
try {
|
|
48324
|
-
(0,
|
|
48596
|
+
(0, import_node_child_process10.execFileSync)(
|
|
48325
48597
|
"devtunnel",
|
|
48326
48598
|
["port", "create", tunnelId, "-p", String(localPort), "--protocol", "http"],
|
|
48327
48599
|
{ stdio: "pipe" }
|
|
@@ -48337,7 +48609,7 @@ ${lines.join("")}`
|
|
|
48337
48609
|
}
|
|
48338
48610
|
listTunnelPorts(tunnelId) {
|
|
48339
48611
|
try {
|
|
48340
|
-
const output = (0,
|
|
48612
|
+
const output = (0, import_node_child_process10.execFileSync)("devtunnel", ["port", "list", tunnelId, "-j"], { stdio: "pipe" });
|
|
48341
48613
|
const parsed = JSON.parse(output.toString());
|
|
48342
48614
|
const items = Array.isArray(parsed) ? parsed : parsed && typeof parsed === "object" && Array.isArray(parsed.ports) ? parsed.ports : parsed && typeof parsed === "object" && Array.isArray(parsed.value) ? parsed.value : [];
|
|
48343
48615
|
return items.map((item) => getPortNumber(item)).filter((value) => value !== void 0);
|
|
@@ -48349,7 +48621,7 @@ ${lines.join("")}`
|
|
|
48349
48621
|
}
|
|
48350
48622
|
hasTunnelPort(tunnelId, localPort) {
|
|
48351
48623
|
try {
|
|
48352
|
-
(0,
|
|
48624
|
+
(0, import_node_child_process10.execFileSync)(
|
|
48353
48625
|
"devtunnel",
|
|
48354
48626
|
["port", "show", tunnelId, "-p", String(localPort), "-j"],
|
|
48355
48627
|
{ stdio: "pipe" }
|
|
@@ -48426,16 +48698,42 @@ function createTransport(config) {
|
|
|
48426
48698
|
}
|
|
48427
48699
|
}
|
|
48428
48700
|
|
|
48701
|
+
// src/bootstrap/terminal-writer.ts
|
|
48702
|
+
function formatDetail(detail) {
|
|
48703
|
+
if (detail instanceof Error) {
|
|
48704
|
+
return detail.stack ?? detail.message;
|
|
48705
|
+
}
|
|
48706
|
+
if (typeof detail === "string") {
|
|
48707
|
+
return detail;
|
|
48708
|
+
}
|
|
48709
|
+
try {
|
|
48710
|
+
return JSON.stringify(detail);
|
|
48711
|
+
} catch {
|
|
48712
|
+
return String(detail);
|
|
48713
|
+
}
|
|
48714
|
+
}
|
|
48715
|
+
var terminalWriter = {
|
|
48716
|
+
error(message, ...details) {
|
|
48717
|
+
const suffix = details.length > 0 ? ` ${details.map(formatDetail).join(" ")}` : "";
|
|
48718
|
+
process.stderr.write(`${message}${suffix}
|
|
48719
|
+
`);
|
|
48720
|
+
},
|
|
48721
|
+
line(message = "") {
|
|
48722
|
+
process.stdout.write(`${message}
|
|
48723
|
+
`);
|
|
48724
|
+
}
|
|
48725
|
+
};
|
|
48726
|
+
|
|
48429
48727
|
// src/startup.ts
|
|
48430
48728
|
var fs19 = __toESM(require("fs"), 1);
|
|
48431
48729
|
var path20 = __toESM(require("path"), 1);
|
|
48432
48730
|
var readline = __toESM(require("readline/promises"), 1);
|
|
48433
|
-
var
|
|
48731
|
+
var import_node_child_process11 = require("child_process");
|
|
48434
48732
|
function getDefaultNodeName() {
|
|
48435
48733
|
return getDeviceNodeName();
|
|
48436
48734
|
}
|
|
48437
48735
|
var DEFAULT_NODE_NAME = getDefaultNodeName();
|
|
48438
|
-
var SUPPORTED_TRANSPORTS = ["direct", "devtunnel"
|
|
48736
|
+
var SUPPORTED_TRANSPORTS = ["direct", "devtunnel"];
|
|
48439
48737
|
var STARTUP_REQUIREMENTS = ["az", "devtunnel", "claude", "codex"];
|
|
48440
48738
|
function createDefaultConfig(storagePath = resolveDefaultStoragePath(), nodeName = DEFAULT_NODE_NAME) {
|
|
48441
48739
|
return {
|
|
@@ -48476,7 +48774,7 @@ function createPromptSession(prompt) {
|
|
|
48476
48774
|
}
|
|
48477
48775
|
function createDefaultCommandRunner(platform2) {
|
|
48478
48776
|
return (command, args, interactive = false) => {
|
|
48479
|
-
const result = (0,
|
|
48777
|
+
const result = (0, import_node_child_process11.spawnSync)(command, args, {
|
|
48480
48778
|
encoding: "utf-8",
|
|
48481
48779
|
shell: platform2 === "win32",
|
|
48482
48780
|
stdio: interactive ? "inherit" : "pipe"
|
|
@@ -48505,7 +48803,7 @@ function writeStartupMetadataFile(storagePath, metadata) {
|
|
|
48505
48803
|
fs19.mkdirSync(storagePath, { recursive: true });
|
|
48506
48804
|
fs19.writeFileSync(getNodeMetadataPath2(storagePath), JSON.stringify(metadata, null, 2) + "\n", "utf-8");
|
|
48507
48805
|
}
|
|
48508
|
-
function
|
|
48806
|
+
function formatLocalDate2(now) {
|
|
48509
48807
|
const year = now.getFullYear();
|
|
48510
48808
|
const month = String(now.getMonth() + 1).padStart(2, "0");
|
|
48511
48809
|
const day = String(now.getDate()).padStart(2, "0");
|
|
@@ -48596,7 +48894,7 @@ function resolveStartupRequirementsMetadata(storagePath) {
|
|
|
48596
48894
|
}
|
|
48597
48895
|
function shouldSkipStartupRequirementsCheck(storagePath, now = /* @__PURE__ */ new Date()) {
|
|
48598
48896
|
const metadata = resolveStartupRequirementsMetadata(storagePath);
|
|
48599
|
-
if (metadata.lastCheckedOn !==
|
|
48897
|
+
if (metadata.lastCheckedOn !== formatLocalDate2(now)) {
|
|
48600
48898
|
return false;
|
|
48601
48899
|
}
|
|
48602
48900
|
return STARTUP_REQUIREMENTS.every((requirement) => isRequirementSatisfied(requirement, metadata.components?.[requirement]));
|
|
@@ -48680,7 +48978,7 @@ async function ensureStartupRequirements(storagePath, options = {}) {
|
|
|
48680
48978
|
await current.close();
|
|
48681
48979
|
};
|
|
48682
48980
|
const checkedAt = now.toISOString();
|
|
48683
|
-
const checkedOn =
|
|
48981
|
+
const checkedOn = formatLocalDate2(now);
|
|
48684
48982
|
const components = {};
|
|
48685
48983
|
try {
|
|
48686
48984
|
for (const requirement of STARTUP_REQUIREMENTS) {
|
|
@@ -48820,13 +49118,13 @@ async function promptStartOptions(args, fileConfig, defaults, prompt) {
|
|
|
48820
49118
|
result.port = port;
|
|
48821
49119
|
break;
|
|
48822
49120
|
}
|
|
48823
|
-
|
|
49121
|
+
terminalWriter.line("Invalid port. Enter a positive integer.");
|
|
48824
49122
|
}
|
|
48825
49123
|
}
|
|
48826
49124
|
if (result.transport === void 0) {
|
|
48827
49125
|
while (true) {
|
|
48828
49126
|
const input = normalizePromptValue(
|
|
48829
|
-
await ask(formatPrompt("Transport (direct/devtunnel
|
|
49127
|
+
await ask(formatPrompt("Transport (direct/devtunnel)", merged.transport.type))
|
|
48830
49128
|
);
|
|
48831
49129
|
if (!input) {
|
|
48832
49130
|
result.transport = merged.transport.type;
|
|
@@ -48836,7 +49134,7 @@ async function promptStartOptions(args, fileConfig, defaults, prompt) {
|
|
|
48836
49134
|
result.transport = input;
|
|
48837
49135
|
break;
|
|
48838
49136
|
}
|
|
48839
|
-
|
|
49137
|
+
terminalWriter.line("Invalid transport. Use direct or devtunnel.");
|
|
48840
49138
|
}
|
|
48841
49139
|
}
|
|
48842
49140
|
if (result.join === void 0) {
|
|
@@ -48924,7 +49222,7 @@ function formatLoadedStartMetadata(info, authEnabled) {
|
|
|
48924
49222
|
// src/runtime-metadata.ts
|
|
48925
49223
|
var fs20 = __toESM(require("fs"), 1);
|
|
48926
49224
|
var path21 = __toESM(require("path"), 1);
|
|
48927
|
-
var
|
|
49225
|
+
var import_node_child_process12 = require("child_process");
|
|
48928
49226
|
var runtimeDir = resolveRuntimeDir();
|
|
48929
49227
|
var appRoot = resolveAppRoot(runtimeDir);
|
|
48930
49228
|
var repoRoot = path21.resolve(appRoot, "../..");
|
|
@@ -49020,7 +49318,7 @@ function readRepositoryUrlFromManifest(manifest) {
|
|
|
49020
49318
|
}
|
|
49021
49319
|
function readGitValue(args) {
|
|
49022
49320
|
try {
|
|
49023
|
-
const output = (0,
|
|
49321
|
+
const output = (0, import_node_child_process12.execFileSync)("git", args, {
|
|
49024
49322
|
cwd: repoRoot,
|
|
49025
49323
|
encoding: "utf-8",
|
|
49026
49324
|
stdio: ["ignore", "pipe", "ignore"],
|
|
@@ -49069,11 +49367,7 @@ function buildRuntimeMetadata(storagePath) {
|
|
|
49069
49367
|
function createSettingsSnapshotProvider(options) {
|
|
49070
49368
|
let cachedSnapshot = null;
|
|
49071
49369
|
let cachedSnapshotAt = 0;
|
|
49072
|
-
|
|
49073
|
-
const now = Date.now();
|
|
49074
|
-
if (cachedSnapshot && now - cachedSnapshotAt < 3e4) {
|
|
49075
|
-
return structuredClone(cachedSnapshot);
|
|
49076
|
-
}
|
|
49370
|
+
function buildSnapshot() {
|
|
49077
49371
|
cachedSnapshot = buildNodeSettingsSnapshot({
|
|
49078
49372
|
auth: options.authMetadata,
|
|
49079
49373
|
localDashboardOrigin: options.localDashboardOrigin,
|
|
@@ -49081,8 +49375,23 @@ function createSettingsSnapshotProvider(options) {
|
|
|
49081
49375
|
storagePath: options.storagePath,
|
|
49082
49376
|
workDir: options.workDir
|
|
49083
49377
|
});
|
|
49084
|
-
cachedSnapshotAt = now;
|
|
49378
|
+
cachedSnapshotAt = Date.now();
|
|
49085
49379
|
return structuredClone(cachedSnapshot);
|
|
49380
|
+
}
|
|
49381
|
+
function getSettingsSnapshot() {
|
|
49382
|
+
const now = Date.now();
|
|
49383
|
+
if (cachedSnapshot && now - cachedSnapshotAt < 3e4) {
|
|
49384
|
+
return structuredClone(cachedSnapshot);
|
|
49385
|
+
}
|
|
49386
|
+
return buildSnapshot();
|
|
49387
|
+
}
|
|
49388
|
+
return {
|
|
49389
|
+
getSettingsSnapshot,
|
|
49390
|
+
refreshSettingsSnapshot: () => {
|
|
49391
|
+
cachedSnapshot = null;
|
|
49392
|
+
cachedSnapshotAt = 0;
|
|
49393
|
+
return buildSnapshot();
|
|
49394
|
+
}
|
|
49086
49395
|
};
|
|
49087
49396
|
}
|
|
49088
49397
|
async function resolveStartConfig(args) {
|
|
@@ -49369,13 +49678,13 @@ function registerShutdownHandlers(options) {
|
|
|
49369
49678
|
let shuttingDown = false;
|
|
49370
49679
|
async function shutdown() {
|
|
49371
49680
|
if (shuttingDown) {
|
|
49372
|
-
|
|
49681
|
+
terminalWriter.line("Force exit.");
|
|
49373
49682
|
process.exit(130);
|
|
49374
49683
|
}
|
|
49375
49684
|
shuttingDown = true;
|
|
49376
|
-
|
|
49685
|
+
terminalWriter.line("\nShutting down...");
|
|
49377
49686
|
const forceExitTimer = setTimeout(() => {
|
|
49378
|
-
|
|
49687
|
+
terminalWriter.line("Force exit.");
|
|
49379
49688
|
process.exit(0);
|
|
49380
49689
|
}, 1e4);
|
|
49381
49690
|
forceExitTimer.unref?.();
|
|
@@ -49385,10 +49694,10 @@ function registerShutdownHandlers(options) {
|
|
|
49385
49694
|
await options.tunnelManager.stop();
|
|
49386
49695
|
await options.meshyNode.stop();
|
|
49387
49696
|
clearTimeout(forceExitTimer);
|
|
49388
|
-
|
|
49697
|
+
terminalWriter.line("Goodbye!");
|
|
49389
49698
|
process.exit(0);
|
|
49390
49699
|
} catch (err) {
|
|
49391
|
-
|
|
49700
|
+
terminalWriter.error("Error during shutdown:", err);
|
|
49392
49701
|
process.exit(1);
|
|
49393
49702
|
}
|
|
49394
49703
|
}
|
|
@@ -49397,9 +49706,9 @@ function registerShutdownHandlers(options) {
|
|
|
49397
49706
|
}
|
|
49398
49707
|
async function startNode(args) {
|
|
49399
49708
|
const { authMetadata, config, hydratedArgs, runtimeMetadata, storageRoot } = await resolveStartConfig(args);
|
|
49400
|
-
|
|
49709
|
+
terminalWriter.line("Checking startup requirements (az, devtunnel, claude, codex)...");
|
|
49401
49710
|
const startupRequirements = await ensureStartupRequirements(config.storage.path);
|
|
49402
|
-
|
|
49711
|
+
terminalWriter.line(
|
|
49403
49712
|
startupRequirements.skipped ? "Startup requirements already verified today; skipping checks." : "Startup requirements check complete."
|
|
49404
49713
|
);
|
|
49405
49714
|
const localDashboardOrigin = `http://localhost:${config.node.port}`;
|
|
@@ -49413,9 +49722,9 @@ async function startNode(args) {
|
|
|
49413
49722
|
settingsProvider: () => authMetadata
|
|
49414
49723
|
});
|
|
49415
49724
|
if (hydratedArgs.loaded) {
|
|
49416
|
-
|
|
49417
|
-
|
|
49418
|
-
|
|
49725
|
+
terminalWriter.line("");
|
|
49726
|
+
terminalWriter.line(formatLoadedStartMetadata(hydratedArgs.loaded, authMetadata.enabled));
|
|
49727
|
+
terminalWriter.line("");
|
|
49419
49728
|
}
|
|
49420
49729
|
if (authMetadata.enabled) {
|
|
49421
49730
|
await nodeAuth.warmup();
|
|
@@ -49423,13 +49732,14 @@ async function startNode(args) {
|
|
|
49423
49732
|
} else {
|
|
49424
49733
|
setRequestAuthHeadersProvider(null);
|
|
49425
49734
|
}
|
|
49426
|
-
const
|
|
49735
|
+
const settingsSnapshotProvider = createSettingsSnapshotProvider({
|
|
49427
49736
|
authMetadata,
|
|
49428
49737
|
localDashboardOrigin,
|
|
49429
49738
|
runtimeMetadata,
|
|
49430
49739
|
storagePath: config.storage.path,
|
|
49431
49740
|
workDir: nodePath2.resolve(config.node.workDir ?? process.cwd())
|
|
49432
49741
|
});
|
|
49742
|
+
const { getSettingsSnapshot, refreshSettingsSnapshot } = settingsSnapshotProvider;
|
|
49433
49743
|
const meshyNode = new MeshyNode(config, {
|
|
49434
49744
|
logger: logger27,
|
|
49435
49745
|
transportFactory: createTransport,
|
|
@@ -49512,6 +49822,8 @@ async function startNode(args) {
|
|
|
49512
49822
|
},
|
|
49513
49823
|
isDevTunnelEnabled: () => meshyNode.isDevTunnelEnabled(),
|
|
49514
49824
|
localDashboardOrigin,
|
|
49825
|
+
upgradeRuntimeAgent,
|
|
49826
|
+
refreshSettingsSnapshot,
|
|
49515
49827
|
dashboardOrigin: tunnelManager.getDashboardOrigin(),
|
|
49516
49828
|
shareOrigin: tunnelManager.getShareOrigin(),
|
|
49517
49829
|
ensureShareTunnel: () => tunnelManager.ensureShareTunnel(),
|
|
@@ -49539,9 +49851,9 @@ async function startNode(args) {
|
|
|
49539
49851
|
port: config.node.port,
|
|
49540
49852
|
dashboardOrigin: tunnelManager.getDashboardOrigin()
|
|
49541
49853
|
});
|
|
49542
|
-
|
|
49543
|
-
|
|
49544
|
-
|
|
49854
|
+
terminalWriter.line("");
|
|
49855
|
+
terminalWriter.line(banner);
|
|
49856
|
+
terminalWriter.line("");
|
|
49545
49857
|
});
|
|
49546
49858
|
registerShutdownHandlers({
|
|
49547
49859
|
server,
|