meshy-node 0.2.4 → 0.2.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dashboard/assets/DashboardPage-DeFE8aKR.js +120 -0
- package/dashboard/assets/DashboardShared-B08ZGEU3.js +59 -0
- package/dashboard/assets/{DiffTab-DZflzi04.js → DiffTab-D6XXV_vj.js} +3 -3
- package/dashboard/assets/{FilesTab-Ju38uner.js → FilesTab-DUebfVJo.js} +12 -12
- package/dashboard/assets/PreviewTab-CfNP0Ll3.js +16 -0
- package/dashboard/assets/SharedConversationPage-D2ncPenP.js +7 -0
- package/dashboard/assets/{file-Bp-JAQYC.js → file-C-p99c1E.js} +1 -1
- package/dashboard/assets/folder-C0oopt2q.js +11 -0
- package/dashboard/assets/{index-CxdvKkO7.js → index-B7PaE6U7.js} +26 -25
- package/dashboard/assets/index-CxJE8HAC.css +1 -0
- package/dashboard/index.html +2 -2
- package/main.cjs +486 -39
- package/package.json +1 -1
- package/runtime-metadata.json +5 -5
- package/dashboard/assets/DashboardPage-3CEGtmWK.js +0 -183
- package/dashboard/assets/PreviewTab-B0KcnZfd.js +0 -16
- package/dashboard/assets/index-Dl1FKoUn.css +0 -1
package/main.cjs
CHANGED
|
@@ -25760,7 +25760,7 @@ var require_application = __commonJS({
|
|
|
25760
25760
|
"../../node_modules/.pnpm/express@4.22.1/node_modules/express/lib/application.js"(exports2, module2) {
|
|
25761
25761
|
"use strict";
|
|
25762
25762
|
var finalhandler = require_finalhandler();
|
|
25763
|
-
var
|
|
25763
|
+
var Router12 = require_router();
|
|
25764
25764
|
var methods = require_methods();
|
|
25765
25765
|
var middleware = require_init();
|
|
25766
25766
|
var query = require_query();
|
|
@@ -25825,7 +25825,7 @@ var require_application = __commonJS({
|
|
|
25825
25825
|
};
|
|
25826
25826
|
app.lazyrouter = function lazyrouter() {
|
|
25827
25827
|
if (!this._router) {
|
|
25828
|
-
this._router = new
|
|
25828
|
+
this._router = new Router12({
|
|
25829
25829
|
caseSensitive: this.enabled("case sensitive routing"),
|
|
25830
25830
|
strict: this.enabled("strict routing")
|
|
25831
25831
|
});
|
|
@@ -27690,7 +27690,7 @@ var require_express = __commonJS({
|
|
|
27690
27690
|
var mixin = require_merge_descriptors();
|
|
27691
27691
|
var proto = require_application();
|
|
27692
27692
|
var Route = require_route();
|
|
27693
|
-
var
|
|
27693
|
+
var Router12 = require_router();
|
|
27694
27694
|
var req = require_request();
|
|
27695
27695
|
var res = require_response();
|
|
27696
27696
|
exports2 = module2.exports = createApplication;
|
|
@@ -27713,7 +27713,7 @@ var require_express = __commonJS({
|
|
|
27713
27713
|
exports2.request = req;
|
|
27714
27714
|
exports2.response = res;
|
|
27715
27715
|
exports2.Route = Route;
|
|
27716
|
-
exports2.Router =
|
|
27716
|
+
exports2.Router = Router12;
|
|
27717
27717
|
exports2.json = bodyParser.json;
|
|
27718
27718
|
exports2.query = require_query();
|
|
27719
27719
|
exports2.raw = bodyParser.raw;
|
|
@@ -32335,6 +32335,7 @@ var fs3 = __toESM(require("fs"), 1);
|
|
|
32335
32335
|
var path3 = __toESM(require("path"), 1);
|
|
32336
32336
|
|
|
32337
32337
|
// ../../packages/core/src/shared/types.ts
|
|
32338
|
+
var DEFAULT_TASK_SHARE_TENANT = "72f988bf-86f1-41af-91ab-2d7cd011db47";
|
|
32338
32339
|
var TASK_EXECUTION_MODES = ["bypass", "plan", "edit", "dangerous"];
|
|
32339
32340
|
var MeshyError = class extends Error {
|
|
32340
32341
|
constructor(code, message, statusCode, details) {
|
|
@@ -32387,6 +32388,7 @@ var FILE_NAMES = {
|
|
|
32387
32388
|
cluster: "cluster.json",
|
|
32388
32389
|
nodes: "nodes.json",
|
|
32389
32390
|
tasks: "tasks.json",
|
|
32391
|
+
shares: "shares.json",
|
|
32390
32392
|
election: "election.json"
|
|
32391
32393
|
};
|
|
32392
32394
|
var FileStore = class {
|
|
@@ -32395,6 +32397,7 @@ var FileStore = class {
|
|
|
32395
32397
|
cluster = null;
|
|
32396
32398
|
nodes = /* @__PURE__ */ new Map();
|
|
32397
32399
|
tasks = /* @__PURE__ */ new Map();
|
|
32400
|
+
shares = /* @__PURE__ */ new Map();
|
|
32398
32401
|
election = /* @__PURE__ */ new Map();
|
|
32399
32402
|
dirtySections = /* @__PURE__ */ new Set();
|
|
32400
32403
|
constructor(options = {}) {
|
|
@@ -32410,6 +32413,7 @@ var FileStore = class {
|
|
|
32410
32413
|
this.cluster = this.loadCluster();
|
|
32411
32414
|
this.replaceMap(this.nodes, this.loadNodes());
|
|
32412
32415
|
this.replaceMap(this.tasks, this.loadTasks());
|
|
32416
|
+
this.replaceMap(this.shares, this.loadTaskShares());
|
|
32413
32417
|
this.replaceMap(this.election, this.loadElection());
|
|
32414
32418
|
this.flushDirtySections();
|
|
32415
32419
|
}
|
|
@@ -32422,6 +32426,7 @@ var FileStore = class {
|
|
|
32422
32426
|
this.cluster = null;
|
|
32423
32427
|
this.nodes.clear();
|
|
32424
32428
|
this.tasks.clear();
|
|
32429
|
+
this.shares.clear();
|
|
32425
32430
|
this.election.clear();
|
|
32426
32431
|
this.dirtySections.clear();
|
|
32427
32432
|
}
|
|
@@ -32562,6 +32567,46 @@ var FileStore = class {
|
|
|
32562
32567
|
}
|
|
32563
32568
|
return metrics;
|
|
32564
32569
|
}
|
|
32570
|
+
createTaskShare(share) {
|
|
32571
|
+
this.ensureOpen();
|
|
32572
|
+
const copy = clone(share);
|
|
32573
|
+
this.shares.set(copy.id, copy);
|
|
32574
|
+
this.persistSection("shares");
|
|
32575
|
+
return clone(copy);
|
|
32576
|
+
}
|
|
32577
|
+
getTaskShare(id) {
|
|
32578
|
+
this.ensureOpen();
|
|
32579
|
+
const share = this.shares.get(id);
|
|
32580
|
+
return share === void 0 ? null : clone(share);
|
|
32581
|
+
}
|
|
32582
|
+
getTaskShareByTaskId(taskId) {
|
|
32583
|
+
this.ensureOpen();
|
|
32584
|
+
for (const share of this.shares.values()) {
|
|
32585
|
+
if (share.taskId === taskId && share.revokedAt === void 0) {
|
|
32586
|
+
return clone(share);
|
|
32587
|
+
}
|
|
32588
|
+
}
|
|
32589
|
+
return null;
|
|
32590
|
+
}
|
|
32591
|
+
getAllTaskShares() {
|
|
32592
|
+
this.ensureOpen();
|
|
32593
|
+
return Array.from(this.shares.values(), (share) => clone(share));
|
|
32594
|
+
}
|
|
32595
|
+
updateTaskShare(id, updates) {
|
|
32596
|
+
this.ensureOpen();
|
|
32597
|
+
const current = this.shares.get(id);
|
|
32598
|
+
if (current === void 0) {
|
|
32599
|
+
return null;
|
|
32600
|
+
}
|
|
32601
|
+
const merged = {
|
|
32602
|
+
...current,
|
|
32603
|
+
...clone(updates),
|
|
32604
|
+
id: current.id
|
|
32605
|
+
};
|
|
32606
|
+
this.shares.set(id, merged);
|
|
32607
|
+
this.persistSection("shares");
|
|
32608
|
+
return clone(merged);
|
|
32609
|
+
}
|
|
32565
32610
|
getElectionValue(key) {
|
|
32566
32611
|
this.ensureOpen();
|
|
32567
32612
|
return this.election.get(key) ?? null;
|
|
@@ -32633,6 +32678,26 @@ var FileStore = class {
|
|
|
32633
32678
|
}
|
|
32634
32679
|
return tasks;
|
|
32635
32680
|
}
|
|
32681
|
+
loadTaskShares() {
|
|
32682
|
+
const raw = this.readJsonFile("shares");
|
|
32683
|
+
if (!isPlainObject(raw)) {
|
|
32684
|
+
this.markDirty("shares");
|
|
32685
|
+
return /* @__PURE__ */ new Map();
|
|
32686
|
+
}
|
|
32687
|
+
const shares = /* @__PURE__ */ new Map();
|
|
32688
|
+
for (const [key, value] of Object.entries(raw)) {
|
|
32689
|
+
const share = parseTaskShare(value);
|
|
32690
|
+
if (share === null) {
|
|
32691
|
+
this.markDirty("shares");
|
|
32692
|
+
continue;
|
|
32693
|
+
}
|
|
32694
|
+
if (share.id !== key) {
|
|
32695
|
+
this.markDirty("shares");
|
|
32696
|
+
}
|
|
32697
|
+
shares.set(share.id, share);
|
|
32698
|
+
}
|
|
32699
|
+
return shares;
|
|
32700
|
+
}
|
|
32636
32701
|
loadElection() {
|
|
32637
32702
|
const raw = this.readJsonFile("election");
|
|
32638
32703
|
if (!isPlainObject(raw)) {
|
|
@@ -32698,6 +32763,8 @@ var FileStore = class {
|
|
|
32698
32763
|
return Object.fromEntries(sortEntries(this.nodes));
|
|
32699
32764
|
case "tasks":
|
|
32700
32765
|
return Object.fromEntries(sortEntries(this.tasks));
|
|
32766
|
+
case "shares":
|
|
32767
|
+
return Object.fromEntries(sortEntries(this.shares));
|
|
32701
32768
|
case "election":
|
|
32702
32769
|
return Object.fromEntries(sortEntries(this.election));
|
|
32703
32770
|
}
|
|
@@ -32824,6 +32891,29 @@ function parseTask(value) {
|
|
|
32824
32891
|
updatedAt: value.updatedAt
|
|
32825
32892
|
};
|
|
32826
32893
|
}
|
|
32894
|
+
function parseTaskShare(value) {
|
|
32895
|
+
if (!isPlainObject(value)) {
|
|
32896
|
+
return null;
|
|
32897
|
+
}
|
|
32898
|
+
if (typeof value.id !== "string" || typeof value.taskId !== "string" || typeof value.createdAt !== "number" || !Number.isFinite(value.createdAt) || value.revokedAt !== void 0 && (typeof value.revokedAt !== "number" || !Number.isFinite(value.revokedAt))) {
|
|
32899
|
+
return null;
|
|
32900
|
+
}
|
|
32901
|
+
return {
|
|
32902
|
+
id: value.id,
|
|
32903
|
+
taskId: value.taskId,
|
|
32904
|
+
tenant: asTaskShareTenant(value.tenant) ?? DEFAULT_TASK_SHARE_TENANT,
|
|
32905
|
+
scope: asTaskShareScope(value.scope) ?? "chat",
|
|
32906
|
+
createdAt: value.createdAt,
|
|
32907
|
+
revokedAt: typeof value.revokedAt === "number" ? value.revokedAt : void 0
|
|
32908
|
+
};
|
|
32909
|
+
}
|
|
32910
|
+
function asTaskShareTenant(value) {
|
|
32911
|
+
if (value === "microsoft") return DEFAULT_TASK_SHARE_TENANT;
|
|
32912
|
+
return typeof value === "string" && value.trim().length > 0 ? value.trim() : null;
|
|
32913
|
+
}
|
|
32914
|
+
function asTaskShareScope(value) {
|
|
32915
|
+
return value === "chat" || value === "filesPreview" ? value : null;
|
|
32916
|
+
}
|
|
32827
32917
|
function asNodeRole(value) {
|
|
32828
32918
|
return isNodeRole(value) ? value : null;
|
|
32829
32919
|
}
|
|
@@ -33887,6 +33977,19 @@ var TaskEngine = class {
|
|
|
33887
33977
|
getMetrics() {
|
|
33888
33978
|
return this.store.getTaskMetrics();
|
|
33889
33979
|
}
|
|
33980
|
+
// ── Task Shares ─────────────────────────────────────────────────────
|
|
33981
|
+
createTaskShare(share) {
|
|
33982
|
+
return this.store.createTaskShare(share);
|
|
33983
|
+
}
|
|
33984
|
+
getTaskShare(id) {
|
|
33985
|
+
return this.store.getTaskShare(id);
|
|
33986
|
+
}
|
|
33987
|
+
getTaskShareByTaskId(taskId) {
|
|
33988
|
+
return this.store.getTaskShareByTaskId(taskId);
|
|
33989
|
+
}
|
|
33990
|
+
updateTaskShare(id, updates) {
|
|
33991
|
+
return this.store.updateTaskShare(id, updates);
|
|
33992
|
+
}
|
|
33890
33993
|
// ── Helpers ──────────────────────────────────────────────────────────
|
|
33891
33994
|
/** Calculate exponential backoff: min(2^retryCount * 1000, 30000) ms */
|
|
33892
33995
|
getRetryBackoff(retryCount) {
|
|
@@ -41487,6 +41590,10 @@ var SendMessageBody = external_exports.union([
|
|
|
41487
41590
|
var TaskLogsQuery = external_exports.object({
|
|
41488
41591
|
after: external_exports.coerce.number().int().min(0).optional()
|
|
41489
41592
|
});
|
|
41593
|
+
var CreateTaskShareBody = external_exports.object({
|
|
41594
|
+
tenant: external_exports.string().trim().min(1).max(128).default(DEFAULT_TASK_SHARE_TENANT),
|
|
41595
|
+
scope: external_exports.enum(["chat", "filesPreview"]).default("chat")
|
|
41596
|
+
}).default({});
|
|
41490
41597
|
var TaskOutputTreeQuery = external_exports.object({
|
|
41491
41598
|
path: external_exports.string().default(".")
|
|
41492
41599
|
});
|
|
@@ -41504,7 +41611,7 @@ var BatchTaskIdsBody = external_exports.object({
|
|
|
41504
41611
|
// ../../packages/api/src/app/server.ts
|
|
41505
41612
|
var path17 = __toESM(require("path"), 1);
|
|
41506
41613
|
var fs15 = __toESM(require("fs"), 1);
|
|
41507
|
-
var
|
|
41614
|
+
var import_express12 = __toESM(require_express2(), 1);
|
|
41508
41615
|
|
|
41509
41616
|
// ../../packages/api/src/middleware/auth.ts
|
|
41510
41617
|
var SKIP_AUTH_PATHS = ["/api/system/health"];
|
|
@@ -44033,6 +44140,7 @@ async function handleTaskMessage(deps, message) {
|
|
|
44033
44140
|
|
|
44034
44141
|
// ../../packages/api/src/routes/tasks.ts
|
|
44035
44142
|
var import_express7 = __toESM(require_express2(), 1);
|
|
44143
|
+
var import_node_crypto7 = require("crypto");
|
|
44036
44144
|
|
|
44037
44145
|
// ../../packages/api/src/tasks/task-remote-cancellation.ts
|
|
44038
44146
|
async function cancelRemoteTaskExecution(deps) {
|
|
@@ -44595,6 +44703,25 @@ function withAssignedNodeMetadata(task, nodeRegistry) {
|
|
|
44595
44703
|
assignedNodeAvailable: node?.status !== "offline" && Boolean(node)
|
|
44596
44704
|
};
|
|
44597
44705
|
}
|
|
44706
|
+
function withShareMetadata(task, taskEngine, shareOrigin) {
|
|
44707
|
+
const share = taskEngine.getTaskShareByTaskId?.(task.id) ?? null;
|
|
44708
|
+
if (!share) return task;
|
|
44709
|
+
return {
|
|
44710
|
+
...task,
|
|
44711
|
+
activeShare: {
|
|
44712
|
+
shareId: share.id,
|
|
44713
|
+
tenant: share.tenant,
|
|
44714
|
+
scope: share.scope,
|
|
44715
|
+
...shareOrigin ? { url: buildShareUrl(shareOrigin, share.id) } : {}
|
|
44716
|
+
}
|
|
44717
|
+
};
|
|
44718
|
+
}
|
|
44719
|
+
function toTaskResponse(task, nodeRegistry, taskEngine, shareOrigin) {
|
|
44720
|
+
return withShareMetadata(withAssignedNodeMetadata(task, nodeRegistry), taskEngine, shareOrigin);
|
|
44721
|
+
}
|
|
44722
|
+
function buildShareUrl(origin, shareId) {
|
|
44723
|
+
return `${origin.replace(/\/+$/, "")}/shared/tasks/${encodeURIComponent(shareId)}`;
|
|
44724
|
+
}
|
|
44598
44725
|
function createTaskRoutes() {
|
|
44599
44726
|
const router = (0, import_express7.Router)();
|
|
44600
44727
|
router.post("/", asyncHandler6(async (req, res) => {
|
|
@@ -44620,7 +44747,7 @@ function createTaskRoutes() {
|
|
|
44620
44747
|
res.status(201).json(withAssignedNodeMetadata(task, nodeRegistry));
|
|
44621
44748
|
}));
|
|
44622
44749
|
router.get("/", asyncHandler6(async (req, res) => {
|
|
44623
|
-
const { taskEngine, nodeRegistry } = req.app.locals.deps;
|
|
44750
|
+
const { taskEngine, nodeRegistry, shareOrigin } = req.app.locals.deps;
|
|
44624
44751
|
const query = TaskListQuery.parse(req.query);
|
|
44625
44752
|
const filter = {};
|
|
44626
44753
|
if (query.status) filter.status = query.status;
|
|
@@ -44630,7 +44757,7 @@ function createTaskRoutes() {
|
|
|
44630
44757
|
if (query.offset) filter.offset = query.offset;
|
|
44631
44758
|
const result = taskEngine.listTasks(filter);
|
|
44632
44759
|
res.json({
|
|
44633
|
-
tasks: result.tasks.map((task) =>
|
|
44760
|
+
tasks: result.tasks.map((task) => toTaskResponse(task, nodeRegistry, taskEngine, shareOrigin)),
|
|
44634
44761
|
total: result.total
|
|
44635
44762
|
});
|
|
44636
44763
|
}));
|
|
@@ -44666,12 +44793,59 @@ function createTaskRoutes() {
|
|
|
44666
44793
|
res.json({ results });
|
|
44667
44794
|
}));
|
|
44668
44795
|
router.get("/:id", asyncHandler6(async (req, res) => {
|
|
44669
|
-
const { taskEngine, nodeRegistry } = req.app.locals.deps;
|
|
44670
|
-
const
|
|
44796
|
+
const { taskEngine, nodeRegistry, shareOrigin } = req.app.locals.deps;
|
|
44797
|
+
const taskId = req.params.id;
|
|
44798
|
+
const task = taskEngine.getTask(taskId);
|
|
44671
44799
|
if (!task) {
|
|
44672
|
-
throw new MeshyError("TASK_NOT_FOUND", `Task ${
|
|
44800
|
+
throw new MeshyError("TASK_NOT_FOUND", `Task ${taskId} not found`, 404);
|
|
44673
44801
|
}
|
|
44674
|
-
res.json(
|
|
44802
|
+
res.json(toTaskResponse(task, nodeRegistry, taskEngine, shareOrigin));
|
|
44803
|
+
}));
|
|
44804
|
+
router.post("/:id/share", asyncHandler6(async (req, res) => {
|
|
44805
|
+
const { taskEngine, ensureShareTunnel } = req.app.locals.deps;
|
|
44806
|
+
const body = CreateTaskShareBody.parse(req.body ?? {});
|
|
44807
|
+
const taskId = req.params.id;
|
|
44808
|
+
const task = taskEngine.getTask(taskId);
|
|
44809
|
+
if (!task) {
|
|
44810
|
+
throw new MeshyError("TASK_NOT_FOUND", `Task ${taskId} not found`, 404);
|
|
44811
|
+
}
|
|
44812
|
+
if (!ensureShareTunnel) {
|
|
44813
|
+
throw new MeshyError("VALIDATION_ERROR", "Share tunnel is not available", 503);
|
|
44814
|
+
}
|
|
44815
|
+
const shareOrigin = await ensureShareTunnel();
|
|
44816
|
+
const existing = taskEngine.getTaskShareByTaskId(task.id);
|
|
44817
|
+
if (existing) {
|
|
44818
|
+
const updated = taskEngine.updateTaskShare(existing.id, {
|
|
44819
|
+
tenant: body.tenant,
|
|
44820
|
+
scope: body.scope
|
|
44821
|
+
}) ?? existing;
|
|
44822
|
+
res.json({ shareId: updated.id, tenant: updated.tenant, scope: updated.scope, url: buildShareUrl(shareOrigin, updated.id) });
|
|
44823
|
+
return;
|
|
44824
|
+
}
|
|
44825
|
+
const share = taskEngine.createTaskShare({
|
|
44826
|
+
id: (0, import_node_crypto7.randomUUID)(),
|
|
44827
|
+
taskId: task.id,
|
|
44828
|
+
tenant: body.tenant,
|
|
44829
|
+
scope: body.scope,
|
|
44830
|
+
createdAt: Date.now()
|
|
44831
|
+
});
|
|
44832
|
+
res.status(201).json({ shareId: share.id, tenant: share.tenant, scope: share.scope, url: buildShareUrl(shareOrigin, share.id) });
|
|
44833
|
+
}));
|
|
44834
|
+
router.delete("/:id/share", asyncHandler6(async (req, res) => {
|
|
44835
|
+
const { taskEngine } = req.app.locals.deps;
|
|
44836
|
+
const taskId = req.params.id;
|
|
44837
|
+
const task = taskEngine.getTask(taskId);
|
|
44838
|
+
if (!task) {
|
|
44839
|
+
throw new MeshyError("TASK_NOT_FOUND", `Task ${taskId} not found`, 404);
|
|
44840
|
+
}
|
|
44841
|
+
const existing = taskEngine.getTaskShareByTaskId(task.id);
|
|
44842
|
+
if (!existing) {
|
|
44843
|
+
res.json({ ok: true, stopped: false });
|
|
44844
|
+
return;
|
|
44845
|
+
}
|
|
44846
|
+
const revokedAt = Date.now();
|
|
44847
|
+
const updated = taskEngine.updateTaskShare(existing.id, { revokedAt }) ?? { ...existing, revokedAt };
|
|
44848
|
+
res.json({ ok: true, stopped: true, shareId: updated.id });
|
|
44675
44849
|
}));
|
|
44676
44850
|
router.patch("/:id", asyncHandler6(async (req, res) => {
|
|
44677
44851
|
const { taskEngine, nodeRegistry, logger: rootLogger } = req.app.locals.deps;
|
|
@@ -44914,20 +45088,174 @@ function createTaskRoutes() {
|
|
|
44914
45088
|
return router;
|
|
44915
45089
|
}
|
|
44916
45090
|
|
|
44917
|
-
// ../../packages/api/src/routes/
|
|
45091
|
+
// ../../packages/api/src/routes/shared.ts
|
|
44918
45092
|
var import_express8 = __toESM(require_express2(), 1);
|
|
45093
|
+
function asyncHandler7(fn) {
|
|
45094
|
+
return (req, res, next) => fn(req, res, next).catch(next);
|
|
45095
|
+
}
|
|
45096
|
+
function assertActiveShare(share) {
|
|
45097
|
+
if (!share) {
|
|
45098
|
+
throw new MeshyError("TASK_NOT_FOUND", "Shared conversation not found", 404);
|
|
45099
|
+
}
|
|
45100
|
+
if (share.revokedAt !== void 0) {
|
|
45101
|
+
throw new MeshyError("VALIDATION_ERROR", "Shared conversation has been revoked", 410);
|
|
45102
|
+
}
|
|
45103
|
+
return share;
|
|
45104
|
+
}
|
|
45105
|
+
function assertFilesPreviewShare(share) {
|
|
45106
|
+
if (share.scope !== "filesPreview") {
|
|
45107
|
+
throw new MeshyError("VALIDATION_ERROR", "Shared conversation does not include files or preview", 403);
|
|
45108
|
+
}
|
|
45109
|
+
}
|
|
45110
|
+
function getTaskPayloadForShare(task) {
|
|
45111
|
+
return task.payload.initialMessage === void 0 ? {} : { initialMessage: task.payload.initialMessage };
|
|
45112
|
+
}
|
|
45113
|
+
function toSharedConversation(share, task) {
|
|
45114
|
+
return {
|
|
45115
|
+
id: task.id,
|
|
45116
|
+
shareId: share.id,
|
|
45117
|
+
title: task.title,
|
|
45118
|
+
description: task.description,
|
|
45119
|
+
agent: task.agent,
|
|
45120
|
+
status: task.status,
|
|
45121
|
+
priority: task.priority,
|
|
45122
|
+
assignedNodeName: task.assignedNodeName ?? null,
|
|
45123
|
+
tenant: share.tenant,
|
|
45124
|
+
scope: share.scope,
|
|
45125
|
+
payload: getTaskPayloadForShare(task),
|
|
45126
|
+
createdAt: task.createdAt,
|
|
45127
|
+
updatedAt: task.updatedAt
|
|
45128
|
+
};
|
|
45129
|
+
}
|
|
45130
|
+
function createSharedRoutes() {
|
|
45131
|
+
const router = (0, import_express8.Router)();
|
|
45132
|
+
router.get("/conversations/:shareId", asyncHandler7(async (req, res) => {
|
|
45133
|
+
const { taskEngine } = req.app.locals.deps;
|
|
45134
|
+
const shareId = req.params.shareId;
|
|
45135
|
+
const share = assertActiveShare(taskEngine.getTaskShare(shareId));
|
|
45136
|
+
const task = taskEngine.getTask(share.taskId);
|
|
45137
|
+
if (!task) {
|
|
45138
|
+
throw new MeshyError("TASK_NOT_FOUND", "Shared conversation task not found", 404);
|
|
45139
|
+
}
|
|
45140
|
+
res.json(toSharedConversation(share, task));
|
|
45141
|
+
}));
|
|
45142
|
+
router.get("/conversations/:shareId/logs", asyncHandler7(async (req, res) => {
|
|
45143
|
+
const { taskEngine, engineRegistry } = req.app.locals.deps;
|
|
45144
|
+
const query = TaskLogsQuery.parse(req.query);
|
|
45145
|
+
const shareId = req.params.shareId;
|
|
45146
|
+
const share = assertActiveShare(taskEngine.getTaskShare(shareId));
|
|
45147
|
+
const task = taskEngine.getTask(share.taskId);
|
|
45148
|
+
if (!task) {
|
|
45149
|
+
throw new MeshyError("TASK_NOT_FOUND", "Shared conversation task not found", 404);
|
|
45150
|
+
}
|
|
45151
|
+
res.json(readLocalTaskLogs(engineRegistry, task.id, query.after ?? 0, task.agent));
|
|
45152
|
+
}));
|
|
45153
|
+
router.get("/conversations/:shareId/output", asyncHandler7(async (req, res) => {
|
|
45154
|
+
const { taskEngine } = req.app.locals.deps;
|
|
45155
|
+
const shareId = req.params.shareId;
|
|
45156
|
+
const share = assertActiveShare(taskEngine.getTaskShare(shareId));
|
|
45157
|
+
assertFilesPreviewShare(share);
|
|
45158
|
+
const handled = await maybeHandleRemoteTaskOutputRequest(
|
|
45159
|
+
req,
|
|
45160
|
+
res,
|
|
45161
|
+
share.taskId,
|
|
45162
|
+
"",
|
|
45163
|
+
void 0,
|
|
45164
|
+
createNodeMessage("task.output.summary", { taskId: share.taskId }, { expectsResponse: true })
|
|
45165
|
+
);
|
|
45166
|
+
if (handled) return;
|
|
45167
|
+
res.json(getLocalTaskOutputSummary(req.app.locals.deps.taskEngine, share.taskId));
|
|
45168
|
+
}));
|
|
45169
|
+
router.get("/conversations/:shareId/output/tree", asyncHandler7(async (req, res) => {
|
|
45170
|
+
const { taskEngine } = req.app.locals.deps;
|
|
45171
|
+
const query = TaskOutputTreeQuery.parse(req.query);
|
|
45172
|
+
const shareId = req.params.shareId;
|
|
45173
|
+
const share = assertActiveShare(taskEngine.getTaskShare(shareId));
|
|
45174
|
+
assertFilesPreviewShare(share);
|
|
45175
|
+
const handled = await maybeHandleRemoteTaskOutputRequest(
|
|
45176
|
+
req,
|
|
45177
|
+
res,
|
|
45178
|
+
share.taskId,
|
|
45179
|
+
"/tree",
|
|
45180
|
+
void 0,
|
|
45181
|
+
createNodeMessage("task.output.tree", { taskId: share.taskId, path: query.path }, { expectsResponse: true })
|
|
45182
|
+
);
|
|
45183
|
+
if (handled) return;
|
|
45184
|
+
res.json(getLocalTaskOutputTree(req.app.locals.deps.taskEngine, share.taskId, query.path));
|
|
45185
|
+
}));
|
|
45186
|
+
router.get("/conversations/:shareId/output/content", asyncHandler7(async (req, res) => {
|
|
45187
|
+
const { taskEngine } = req.app.locals.deps;
|
|
45188
|
+
const query = TaskOutputContentQuery.parse(req.query);
|
|
45189
|
+
const shareId = req.params.shareId;
|
|
45190
|
+
const share = assertActiveShare(taskEngine.getTaskShare(shareId));
|
|
45191
|
+
assertFilesPreviewShare(share);
|
|
45192
|
+
const handled = await maybeHandleRemoteTaskOutputRequest(
|
|
45193
|
+
req,
|
|
45194
|
+
res,
|
|
45195
|
+
share.taskId,
|
|
45196
|
+
"/content",
|
|
45197
|
+
void 0,
|
|
45198
|
+
createNodeMessage("task.output.content", { taskId: share.taskId, path: query.path }, { expectsResponse: true })
|
|
45199
|
+
);
|
|
45200
|
+
if (handled) return;
|
|
45201
|
+
const content = getLocalTaskOutputContent(req.app.locals.deps.taskEngine, share.taskId, query.path);
|
|
45202
|
+
res.json({
|
|
45203
|
+
...content,
|
|
45204
|
+
downloadUrl: `/api/shared/conversations/${encodeURIComponent(share.id)}/output/download?path=${encodeURIComponent(query.path)}`
|
|
45205
|
+
});
|
|
45206
|
+
}));
|
|
45207
|
+
router.get("/conversations/:shareId/output/download", asyncHandler7(async (req, res) => {
|
|
45208
|
+
const { taskEngine } = req.app.locals.deps;
|
|
45209
|
+
const query = TaskOutputDownloadQuery.parse(req.query);
|
|
45210
|
+
const shareId = req.params.shareId;
|
|
45211
|
+
const share = assertActiveShare(taskEngine.getTaskShare(shareId));
|
|
45212
|
+
assertFilesPreviewShare(share);
|
|
45213
|
+
const handled = await maybeHandleRemoteTaskOutputRequest(
|
|
45214
|
+
req,
|
|
45215
|
+
res,
|
|
45216
|
+
share.taskId,
|
|
45217
|
+
"/download",
|
|
45218
|
+
void 0,
|
|
45219
|
+
createNodeMessage("task.output.download", { taskId: share.taskId, path: query.path }, { expectsResponse: true })
|
|
45220
|
+
);
|
|
45221
|
+
if (handled) return;
|
|
45222
|
+
const download = getLocalTaskOutputDownload(req.app.locals.deps.taskEngine, share.taskId, query.path);
|
|
45223
|
+
for (const [key, value] of Object.entries(download.headers)) {
|
|
45224
|
+
res.setHeader(key, value);
|
|
45225
|
+
}
|
|
45226
|
+
res.send(download.content);
|
|
45227
|
+
}));
|
|
45228
|
+
router.post("/conversations/:shareId/output/preview-sessions", asyncHandler7(async (req, res) => {
|
|
45229
|
+
const { taskEngine } = req.app.locals.deps;
|
|
45230
|
+
const body = TaskPreviewSessionBody.parse(req.body ?? {});
|
|
45231
|
+
const shareId = req.params.shareId;
|
|
45232
|
+
const share = assertActiveShare(taskEngine.getTaskShare(shareId));
|
|
45233
|
+
assertFilesPreviewShare(share);
|
|
45234
|
+
const handled = await maybeHandleRemoteTaskOutputRequest(req, res, share.taskId, "/preview-sessions", {
|
|
45235
|
+
method: "POST",
|
|
45236
|
+
headers: { "Content-Type": "application/json" },
|
|
45237
|
+
body: JSON.stringify(body)
|
|
45238
|
+
}, createNodeMessage("task.preview.create", { taskId: share.taskId, path: body.path }, { expectsResponse: true }));
|
|
45239
|
+
if (handled) return;
|
|
45240
|
+
res.json(await createPreviewSessionPayload(req.app.locals.deps, share.taskId, body.path, resolveRequestOrigin(req)));
|
|
45241
|
+
}));
|
|
45242
|
+
return router;
|
|
45243
|
+
}
|
|
45244
|
+
|
|
45245
|
+
// ../../packages/api/src/routes/worker.ts
|
|
45246
|
+
var import_express9 = __toESM(require_express2(), 1);
|
|
44919
45247
|
var WorkerMessageBody = external_exports.object({
|
|
44920
45248
|
taskId: external_exports.string().min(1)
|
|
44921
45249
|
}).and(SendMessageBody);
|
|
44922
45250
|
var WorkerTaskBody = external_exports.object({
|
|
44923
45251
|
taskId: external_exports.string().min(1)
|
|
44924
45252
|
});
|
|
44925
|
-
function
|
|
45253
|
+
function asyncHandler8(fn) {
|
|
44926
45254
|
return (req, res, next) => fn(req, res, next).catch(next);
|
|
44927
45255
|
}
|
|
44928
45256
|
function createWorkerRoutes() {
|
|
44929
|
-
const router = (0,
|
|
44930
|
-
router.post("/execute",
|
|
45257
|
+
const router = (0, import_express9.Router)();
|
|
45258
|
+
router.post("/execute", asyncHandler8(async (req, res) => {
|
|
44931
45259
|
const { taskEngine, engineRegistry, nodeRegistry, eventBus, logger: rootLogger, workDir } = req.app.locals.deps;
|
|
44932
45260
|
const log2 = rootLogger.child("worker/execute");
|
|
44933
45261
|
const task = req.body;
|
|
@@ -44944,7 +45272,7 @@ function createWorkerRoutes() {
|
|
|
44944
45272
|
});
|
|
44945
45273
|
res.json({ ok: true });
|
|
44946
45274
|
}));
|
|
44947
|
-
router.post("/message",
|
|
45275
|
+
router.post("/message", asyncHandler8(async (req, res) => {
|
|
44948
45276
|
const { engineRegistry, taskEngine, nodeRegistry, eventBus, logger: rootLogger } = req.app.locals.deps;
|
|
44949
45277
|
const log2 = rootLogger.child("worker/message");
|
|
44950
45278
|
const body = WorkerMessageBody.parse(req.body);
|
|
@@ -44994,7 +45322,7 @@ function createWorkerRoutes() {
|
|
|
44994
45322
|
}
|
|
44995
45323
|
res.json({ ok: true });
|
|
44996
45324
|
}));
|
|
44997
|
-
router.post("/cancel",
|
|
45325
|
+
router.post("/cancel", asyncHandler8(async (req, res) => {
|
|
44998
45326
|
const { taskEngine, engineRegistry, logger: rootLogger } = req.app.locals.deps;
|
|
44999
45327
|
const log2 = rootLogger.child("worker/cancel");
|
|
45000
45328
|
const body = WorkerTaskBody.parse(req.body);
|
|
@@ -45014,7 +45342,7 @@ function createWorkerRoutes() {
|
|
|
45014
45342
|
terminal: result.terminal
|
|
45015
45343
|
});
|
|
45016
45344
|
}));
|
|
45017
|
-
router.post("/output",
|
|
45345
|
+
router.post("/output", asyncHandler8(async (req, res) => {
|
|
45018
45346
|
const { eventBus, engineRegistry, taskEngine, logger: rootLogger } = req.app.locals.deps;
|
|
45019
45347
|
const log2 = rootLogger.child("worker/output");
|
|
45020
45348
|
const { taskId, event } = req.body;
|
|
@@ -45029,7 +45357,7 @@ function createWorkerRoutes() {
|
|
|
45029
45357
|
}
|
|
45030
45358
|
res.json({ ok: true });
|
|
45031
45359
|
}));
|
|
45032
|
-
router.post("/heartbeat",
|
|
45360
|
+
router.post("/heartbeat", asyncHandler8(async (req, res) => {
|
|
45033
45361
|
const { heartbeat, logger: rootLogger } = req.app.locals.deps;
|
|
45034
45362
|
const log2 = rootLogger.child("worker/heartbeat");
|
|
45035
45363
|
const body = req.body;
|
|
@@ -45046,7 +45374,7 @@ function createWorkerRoutes() {
|
|
|
45046
45374
|
});
|
|
45047
45375
|
res.json(response);
|
|
45048
45376
|
}));
|
|
45049
|
-
router.post("/keepalive",
|
|
45377
|
+
router.post("/keepalive", asyncHandler8(async (req, res) => {
|
|
45050
45378
|
const { heartbeat, logger: rootLogger } = req.app.locals.deps;
|
|
45051
45379
|
const log2 = rootLogger.child("worker/keepalive");
|
|
45052
45380
|
const body = req.body;
|
|
@@ -45064,17 +45392,17 @@ function createWorkerRoutes() {
|
|
|
45064
45392
|
});
|
|
45065
45393
|
res.json(response);
|
|
45066
45394
|
}));
|
|
45067
|
-
router.post("/vote",
|
|
45395
|
+
router.post("/vote", asyncHandler8(async (req, res) => {
|
|
45068
45396
|
const { election } = req.app.locals.deps;
|
|
45069
45397
|
const response = election.handleVoteRequest(req.body);
|
|
45070
45398
|
res.json(response);
|
|
45071
45399
|
}));
|
|
45072
|
-
router.post("/announce",
|
|
45400
|
+
router.post("/announce", asyncHandler8(async (req, res) => {
|
|
45073
45401
|
const { election } = req.app.locals.deps;
|
|
45074
45402
|
election.handleLeaderAnnounce(req.body);
|
|
45075
45403
|
res.json({ ok: true });
|
|
45076
45404
|
}));
|
|
45077
|
-
router.post("/preview-session",
|
|
45405
|
+
router.post("/preview-session", asyncHandler8(async (req, res) => {
|
|
45078
45406
|
const { logger: rootLogger } = req.app.locals.deps;
|
|
45079
45407
|
const log2 = rootLogger.child("worker/preview-session");
|
|
45080
45408
|
const body = TaskPreviewSessionBody.extend({
|
|
@@ -45089,7 +45417,7 @@ function createWorkerRoutes() {
|
|
|
45089
45417
|
log2.info("created preview session", { taskId: body.taskId, entryPath: payload.entryPath });
|
|
45090
45418
|
res.json(payload);
|
|
45091
45419
|
}));
|
|
45092
|
-
router.get("/preview-asset",
|
|
45420
|
+
router.get("/preview-asset", asyncHandler8(async (req, res) => {
|
|
45093
45421
|
const { previewSessionManager } = req.app.locals.deps;
|
|
45094
45422
|
if (!previewSessionManager) {
|
|
45095
45423
|
throw new MeshyError("VALIDATION_ERROR", "Preview not available on this node", 400);
|
|
@@ -45098,7 +45426,7 @@ function createWorkerRoutes() {
|
|
|
45098
45426
|
const requestedPath = typeof req.query.path === "string" && req.query.path.length > 0 ? req.query.path : void 0;
|
|
45099
45427
|
sendPreviewAssetResponse(previewSessionManager, token, requestedPath, res);
|
|
45100
45428
|
}));
|
|
45101
|
-
router.post("/control-response",
|
|
45429
|
+
router.post("/control-response", asyncHandler8(async (req, res) => {
|
|
45102
45430
|
const { heartbeat, logger: rootLogger } = req.app.locals.deps;
|
|
45103
45431
|
const log2 = rootLogger.child("worker/control-response");
|
|
45104
45432
|
const body = normalizeNodeMessageResponse(req.body);
|
|
@@ -45125,7 +45453,7 @@ function normalizeNodeMessageResponse(value) {
|
|
|
45125
45453
|
}
|
|
45126
45454
|
|
|
45127
45455
|
// ../../packages/api/src/routes/system.ts
|
|
45128
|
-
var
|
|
45456
|
+
var import_express10 = __toESM(require_express2(), 1);
|
|
45129
45457
|
|
|
45130
45458
|
// ../../packages/api/src/app/system-info.ts
|
|
45131
45459
|
var os5 = __toESM(require("os"), 1);
|
|
@@ -45243,12 +45571,12 @@ function buildNodeSettingsSnapshot(options) {
|
|
|
45243
45571
|
}
|
|
45244
45572
|
|
|
45245
45573
|
// ../../packages/api/src/routes/system.ts
|
|
45246
|
-
function
|
|
45574
|
+
function asyncHandler9(fn) {
|
|
45247
45575
|
return (req, res, next) => fn(req, res, next).catch(next);
|
|
45248
45576
|
}
|
|
45249
45577
|
function createSystemRoutes() {
|
|
45250
|
-
const router = (0,
|
|
45251
|
-
router.get("/health",
|
|
45578
|
+
const router = (0, import_express10.Router)();
|
|
45579
|
+
router.get("/health", asyncHandler9(async (req, res) => {
|
|
45252
45580
|
const { logger: rootLogger } = req.app.locals.deps;
|
|
45253
45581
|
rootLogger.child("system/health").info("received system health API call", {
|
|
45254
45582
|
method: req.method,
|
|
@@ -45257,7 +45585,7 @@ function createSystemRoutes() {
|
|
|
45257
45585
|
});
|
|
45258
45586
|
res.json({ status: "ok", timestamp: Date.now() });
|
|
45259
45587
|
}));
|
|
45260
|
-
router.get("/info",
|
|
45588
|
+
router.get("/info", asyncHandler9(async (req, res) => {
|
|
45261
45589
|
const {
|
|
45262
45590
|
nodeRegistry,
|
|
45263
45591
|
getTransportType,
|
|
@@ -45301,7 +45629,7 @@ function createSystemRoutes() {
|
|
|
45301
45629
|
packages: settingsSnapshot.packages
|
|
45302
45630
|
});
|
|
45303
45631
|
}));
|
|
45304
|
-
router.post("/transport",
|
|
45632
|
+
router.post("/transport", asyncHandler9(async (req, res) => {
|
|
45305
45633
|
const { switchTransport } = req.app.locals.deps;
|
|
45306
45634
|
if (!switchTransport) {
|
|
45307
45635
|
res.status(501).json({ error: "Transport switching not available" });
|
|
@@ -45315,7 +45643,7 @@ function createSystemRoutes() {
|
|
|
45315
45643
|
const newEndpoint = await switchTransport(type);
|
|
45316
45644
|
res.json({ ok: true, transportType: type, endpoint: newEndpoint });
|
|
45317
45645
|
}));
|
|
45318
|
-
router.post("/devtunnel",
|
|
45646
|
+
router.post("/devtunnel", asyncHandler9(async (req, res) => {
|
|
45319
45647
|
const { enableDevTunnel, disableDevTunnel, nodeRegistry, taskEngine } = req.app.locals.deps;
|
|
45320
45648
|
if (!enableDevTunnel || !disableDevTunnel) {
|
|
45321
45649
|
res.status(501).json({ error: "DevTunnel control not available" });
|
|
@@ -45344,7 +45672,7 @@ function createSystemRoutes() {
|
|
|
45344
45672
|
});
|
|
45345
45673
|
}
|
|
45346
45674
|
}));
|
|
45347
|
-
router.get("/metrics",
|
|
45675
|
+
router.get("/metrics", asyncHandler9(async (req, res) => {
|
|
45348
45676
|
const { taskEngine } = req.app.locals.deps;
|
|
45349
45677
|
const metrics = taskEngine.getMetrics();
|
|
45350
45678
|
res.json(metrics);
|
|
@@ -45353,7 +45681,7 @@ function createSystemRoutes() {
|
|
|
45353
45681
|
}
|
|
45354
45682
|
|
|
45355
45683
|
// ../../packages/api/src/routes/events.ts
|
|
45356
|
-
var
|
|
45684
|
+
var import_express11 = __toESM(require_express2(), 1);
|
|
45357
45685
|
var HEARTBEAT_INTERVAL_MS = 15e3;
|
|
45358
45686
|
var CATEGORY_MAP = {
|
|
45359
45687
|
tasks: "task.",
|
|
@@ -45389,7 +45717,7 @@ function shouldIncludeEvent(eventName, categories) {
|
|
|
45389
45717
|
});
|
|
45390
45718
|
}
|
|
45391
45719
|
function createEventRoutes() {
|
|
45392
|
-
const router = (0,
|
|
45720
|
+
const router = (0, import_express11.Router)();
|
|
45393
45721
|
router.get("/", (req, res) => {
|
|
45394
45722
|
const { eventBus } = req.app.locals.deps;
|
|
45395
45723
|
const categories = parseFilter(req.query.filter);
|
|
@@ -45437,6 +45765,40 @@ data: ${JSON.stringify(data)}
|
|
|
45437
45765
|
// ../../packages/api/src/app/server.ts
|
|
45438
45766
|
var JSON_BODY_LIMIT = "1mb";
|
|
45439
45767
|
var JSON_BODY_LIMIT_LARGE = "25mb";
|
|
45768
|
+
var TRUSTED_LOCAL_HOSTS2 = /* @__PURE__ */ new Set(["localhost", "127.0.0.1", "[::1]", "::1"]);
|
|
45769
|
+
function normalizeHost2(value) {
|
|
45770
|
+
const trimmed = value?.trim().toLowerCase();
|
|
45771
|
+
return trimmed ? trimmed.replace(/:\d+$/, "") : void 0;
|
|
45772
|
+
}
|
|
45773
|
+
function collectForwardedHosts(value) {
|
|
45774
|
+
if (typeof value !== "string") {
|
|
45775
|
+
return [];
|
|
45776
|
+
}
|
|
45777
|
+
return value.split(",").map((item) => normalizeHost2(item)).filter((host) => Boolean(host));
|
|
45778
|
+
}
|
|
45779
|
+
function getRequestHosts2(req) {
|
|
45780
|
+
const forwardedHosts = collectForwardedHosts(req.headers["x-forwarded-host"]);
|
|
45781
|
+
if (forwardedHosts.length > 0) {
|
|
45782
|
+
return forwardedHosts;
|
|
45783
|
+
}
|
|
45784
|
+
return [normalizeHost2(req.hostname), normalizeHost2(typeof req.headers.host === "string" ? req.headers.host : void 0)].filter((host) => Boolean(host));
|
|
45785
|
+
}
|
|
45786
|
+
function getOriginHost(origin) {
|
|
45787
|
+
if (!origin) return void 0;
|
|
45788
|
+
try {
|
|
45789
|
+
return normalizeHost2(new URL(origin).host);
|
|
45790
|
+
} catch {
|
|
45791
|
+
return void 0;
|
|
45792
|
+
}
|
|
45793
|
+
}
|
|
45794
|
+
function isShareHostRequest(req, shareOrigin) {
|
|
45795
|
+
const shareHost = getOriginHost(shareOrigin);
|
|
45796
|
+
if (!shareHost) return false;
|
|
45797
|
+
return getRequestHosts2(req).some((host) => !TRUSTED_LOCAL_HOSTS2.has(host) && host === shareHost);
|
|
45798
|
+
}
|
|
45799
|
+
function isAllowedSharePath(pathname) {
|
|
45800
|
+
return pathname === "/favicon.ico" || pathname === "/api/shared" || pathname.startsWith("/api/shared/") || pathname === "/preview" || pathname.startsWith("/preview/") || pathname === "/shared" || pathname.startsWith("/shared/") || pathname === "/assets" || pathname.startsWith("/assets/");
|
|
45801
|
+
}
|
|
45440
45802
|
function resolveRuntimeBaseDir() {
|
|
45441
45803
|
const entryPath = process.argv[1];
|
|
45442
45804
|
if (typeof entryPath === "string" && entryPath.length > 0) {
|
|
@@ -45467,7 +45829,7 @@ function resolveStaticDir(baseDir) {
|
|
|
45467
45829
|
return null;
|
|
45468
45830
|
}
|
|
45469
45831
|
function createServer2(deps) {
|
|
45470
|
-
const app = (0,
|
|
45832
|
+
const app = (0, import_express12.default)();
|
|
45471
45833
|
app.locals.deps = deps;
|
|
45472
45834
|
if (typeof deps.heartbeat.setNodeMessageHandler === "function") {
|
|
45473
45835
|
deps.heartbeat.setNodeMessageHandler((message) => handleNodeMessage(deps, message));
|
|
@@ -45483,15 +45845,32 @@ function createServer2(deps) {
|
|
|
45483
45845
|
} catch {
|
|
45484
45846
|
}
|
|
45485
45847
|
}
|
|
45848
|
+
if (deps.shareOrigin) {
|
|
45849
|
+
try {
|
|
45850
|
+
trustedHosts.push(new URL(deps.shareOrigin).host);
|
|
45851
|
+
} catch {
|
|
45852
|
+
}
|
|
45853
|
+
}
|
|
45486
45854
|
return trustedHosts;
|
|
45487
45855
|
}
|
|
45488
45856
|
};
|
|
45489
45857
|
const isApiRequest = (req) => req.path === "/api" || req.path.startsWith("/api/");
|
|
45490
45858
|
const canServeDashboard = (req) => !deps.config.validateBearerToken || isTrustedDashboardRequest(req, authConfig);
|
|
45859
|
+
app.use((req, res, next) => {
|
|
45860
|
+
if (!isShareHostRequest(req, deps.shareOrigin)) {
|
|
45861
|
+
next();
|
|
45862
|
+
return;
|
|
45863
|
+
}
|
|
45864
|
+
if (isAllowedSharePath(req.path)) {
|
|
45865
|
+
next();
|
|
45866
|
+
return;
|
|
45867
|
+
}
|
|
45868
|
+
res.status(404).type("text/plain").send("Not Found");
|
|
45869
|
+
});
|
|
45491
45870
|
const runtimeBaseDir = resolveRuntimeBaseDir();
|
|
45492
45871
|
const staticDir = resolveStaticDir(runtimeBaseDir);
|
|
45493
45872
|
if (staticDir) {
|
|
45494
|
-
const staticMiddleware =
|
|
45873
|
+
const staticMiddleware = import_express12.default.static(staticDir);
|
|
45495
45874
|
app.use((req, res, next) => {
|
|
45496
45875
|
if (isApiRequest(req)) {
|
|
45497
45876
|
next();
|
|
@@ -45504,7 +45883,7 @@ function createServer2(deps) {
|
|
|
45504
45883
|
staticMiddleware(req, res, next);
|
|
45505
45884
|
});
|
|
45506
45885
|
}
|
|
45507
|
-
app.use(
|
|
45886
|
+
app.use(import_express12.default.json({ limit: JSON_BODY_LIMIT }));
|
|
45508
45887
|
app.use(createAuthMiddleware(authConfig));
|
|
45509
45888
|
app.use((req, res, next) => {
|
|
45510
45889
|
void (async () => {
|
|
@@ -45526,12 +45905,13 @@ function createServer2(deps) {
|
|
|
45526
45905
|
})().catch(next);
|
|
45527
45906
|
});
|
|
45528
45907
|
app.use(createRoutingMiddleware(deps.dataRouter));
|
|
45529
|
-
const largeBodyParser =
|
|
45908
|
+
const largeBodyParser = import_express12.default.json({ limit: JSON_BODY_LIMIT_LARGE });
|
|
45530
45909
|
app.use("/api/cluster", createClusterRoutes());
|
|
45531
45910
|
app.use("/api/cluster-control", createClusterControlRoutes());
|
|
45532
45911
|
app.use("/api/node", largeBodyParser, createNodeMessageRoutes());
|
|
45533
45912
|
app.use("/api/nodes", createNodeRoutes());
|
|
45534
45913
|
app.use("/api/tasks", largeBodyParser, createTaskRoutes());
|
|
45914
|
+
app.use("/api/shared", createSharedRoutes());
|
|
45535
45915
|
app.use("/api/worker", largeBodyParser, createWorkerRoutes());
|
|
45536
45916
|
app.use("/api/system", createSystemRoutes());
|
|
45537
45917
|
app.use("/api/events", createEventRoutes());
|
|
@@ -45751,8 +46131,24 @@ ${lines.join("")}`
|
|
|
45751
46131
|
return args;
|
|
45752
46132
|
}
|
|
45753
46133
|
this.ensureTunnelPort(tunnelId, localPort);
|
|
46134
|
+
this.ensureTunnelAccess(tunnelId);
|
|
45754
46135
|
return ["host", tunnelId];
|
|
45755
46136
|
}
|
|
46137
|
+
ensureTunnelAccess(tunnelId) {
|
|
46138
|
+
if (this.config.access !== "tenant") {
|
|
46139
|
+
return;
|
|
46140
|
+
}
|
|
46141
|
+
try {
|
|
46142
|
+
(0, import_node_child_process9.execFileSync)("devtunnel", ["access", "create", tunnelId, "--tenant"], { stdio: "pipe" });
|
|
46143
|
+
} catch (err) {
|
|
46144
|
+
if (isExistingTenantAccessError(err)) {
|
|
46145
|
+
return;
|
|
46146
|
+
}
|
|
46147
|
+
throw new Error(
|
|
46148
|
+
`Failed to configure tenant access for devtunnel "${tunnelId}": ${formatCommandError(err)}`
|
|
46149
|
+
);
|
|
46150
|
+
}
|
|
46151
|
+
}
|
|
45756
46152
|
ensureTunnelExists() {
|
|
45757
46153
|
const tunnelId = this.config.id.trim();
|
|
45758
46154
|
if (!tunnelId) {
|
|
@@ -45847,6 +46243,10 @@ function normalizeDevTunnelUrl(value) {
|
|
|
45847
46243
|
return null;
|
|
45848
46244
|
}
|
|
45849
46245
|
}
|
|
46246
|
+
function isExistingTenantAccessError(error) {
|
|
46247
|
+
const message = formatCommandError(error).toLowerCase();
|
|
46248
|
+
return message.includes("already exists") || message.includes("conflict") || message.includes("duplicate");
|
|
46249
|
+
}
|
|
45850
46250
|
function formatCommandError(error) {
|
|
45851
46251
|
if (!error || typeof error !== "object") {
|
|
45852
46252
|
return String(error);
|
|
@@ -46624,7 +47024,9 @@ async function main() {
|
|
|
46624
47024
|
const previewSessionManager = new PreviewSessionManager();
|
|
46625
47025
|
const previewProxyManager = new PreviewProxyManager();
|
|
46626
47026
|
let dashboardTransport = null;
|
|
47027
|
+
let shareTransport = null;
|
|
46627
47028
|
let dashboardOrigin;
|
|
47029
|
+
let shareOrigin;
|
|
46628
47030
|
let deps;
|
|
46629
47031
|
async function closeServer(server2) {
|
|
46630
47032
|
if (!server2) {
|
|
@@ -46653,11 +47055,29 @@ async function main() {
|
|
|
46653
47055
|
}
|
|
46654
47056
|
};
|
|
46655
47057
|
}
|
|
47058
|
+
function createShareTransportConfig() {
|
|
47059
|
+
return {
|
|
47060
|
+
type: "devtunnel",
|
|
47061
|
+
devtunnel: {
|
|
47062
|
+
id: resolveOrCreateDevTunnelId(
|
|
47063
|
+
config.storage.path,
|
|
47064
|
+
meshyNode.getNodeRegistry().getSelf().id,
|
|
47065
|
+
"share"
|
|
47066
|
+
),
|
|
47067
|
+
allowAnonymous: false,
|
|
47068
|
+
access: "tenant"
|
|
47069
|
+
}
|
|
47070
|
+
};
|
|
47071
|
+
}
|
|
46656
47072
|
function setAdvertisedDashboardOrigin(origin) {
|
|
46657
47073
|
dashboardOrigin = origin;
|
|
46658
47074
|
deps.dashboardOrigin = origin;
|
|
46659
47075
|
meshyNode.getNodeRegistry().updateDashboardOrigin(meshyNode.getNodeRegistry().getSelf().id, origin);
|
|
46660
47076
|
}
|
|
47077
|
+
function setShareOrigin(origin) {
|
|
47078
|
+
shareOrigin = origin;
|
|
47079
|
+
deps.shareOrigin = origin;
|
|
47080
|
+
}
|
|
46661
47081
|
function shouldPublishDashboardTunnel() {
|
|
46662
47082
|
return authMetadata.enabled && (meshyNode.getTransportType() === "devtunnel" || meshyNode.isDevTunnelEnabled());
|
|
46663
47083
|
}
|
|
@@ -46739,6 +47159,27 @@ async function main() {
|
|
|
46739
47159
|
}
|
|
46740
47160
|
await restartDashboardTransport(reason);
|
|
46741
47161
|
}
|
|
47162
|
+
async function ensureShareTunnel() {
|
|
47163
|
+
if (shareTransport && shareOrigin && await shareTransport.isHealthy().catch(() => false)) {
|
|
47164
|
+
return shareOrigin;
|
|
47165
|
+
}
|
|
47166
|
+
if (shareTransport) {
|
|
47167
|
+
await shareTransport.stop().catch(() => void 0);
|
|
47168
|
+
shareTransport = null;
|
|
47169
|
+
setShareOrigin(void 0);
|
|
47170
|
+
}
|
|
47171
|
+
const nextTransport = createTransport(createShareTransportConfig());
|
|
47172
|
+
await nextTransport.start(config.node.port);
|
|
47173
|
+
const nextOrigin = await nextTransport.getEndpoint();
|
|
47174
|
+
shareTransport = nextTransport;
|
|
47175
|
+
setShareOrigin(nextOrigin);
|
|
47176
|
+
meshyNode.getLogger().info("started share tunnel", {
|
|
47177
|
+
shareOrigin: nextOrigin,
|
|
47178
|
+
tenantAccess: true,
|
|
47179
|
+
stableUrl: true
|
|
47180
|
+
});
|
|
47181
|
+
return nextOrigin;
|
|
47182
|
+
}
|
|
46742
47183
|
deps = {
|
|
46743
47184
|
dataRouter: meshyNode.getDataRouter(),
|
|
46744
47185
|
taskEngine: meshyNode.getTaskEngine(),
|
|
@@ -46791,11 +47232,14 @@ async function main() {
|
|
|
46791
47232
|
isDevTunnelEnabled: () => meshyNode.isDevTunnelEnabled(),
|
|
46792
47233
|
localDashboardOrigin,
|
|
46793
47234
|
dashboardOrigin,
|
|
47235
|
+
shareOrigin,
|
|
47236
|
+
ensureShareTunnel,
|
|
46794
47237
|
runtimeMetadata
|
|
46795
47238
|
};
|
|
46796
47239
|
deps.previewSessionManager = previewSessionManager;
|
|
46797
47240
|
deps.previewProxyManager = previewProxyManager;
|
|
46798
47241
|
deps.dashboardOrigin = dashboardOrigin;
|
|
47242
|
+
deps.shareOrigin = shareOrigin;
|
|
46799
47243
|
meshyNode.getLogger().info("configured node auth mode", {
|
|
46800
47244
|
authEnabled: authMetadata.enabled,
|
|
46801
47245
|
allowSameTenant: authMetadata.allowSameTenant,
|
|
@@ -46869,6 +47313,9 @@ async function main() {
|
|
|
46869
47313
|
if (dashboardTransport) {
|
|
46870
47314
|
await dashboardTransport.stop();
|
|
46871
47315
|
}
|
|
47316
|
+
if (shareTransport) {
|
|
47317
|
+
await shareTransport.stop();
|
|
47318
|
+
}
|
|
46872
47319
|
await meshyNode.stop();
|
|
46873
47320
|
await closeServer(server);
|
|
46874
47321
|
console.log("Goodbye!");
|