meshy-node 0.2.4 → 0.2.6
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 +489 -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"];
|
|
@@ -44595,6 +44702,25 @@ function withAssignedNodeMetadata(task, nodeRegistry) {
|
|
|
44595
44702
|
assignedNodeAvailable: node?.status !== "offline" && Boolean(node)
|
|
44596
44703
|
};
|
|
44597
44704
|
}
|
|
44705
|
+
function withShareMetadata(task, taskEngine, shareOrigin) {
|
|
44706
|
+
const share = taskEngine.getTaskShareByTaskId?.(task.id) ?? null;
|
|
44707
|
+
if (!share) return task;
|
|
44708
|
+
return {
|
|
44709
|
+
...task,
|
|
44710
|
+
activeShare: {
|
|
44711
|
+
shareId: share.id,
|
|
44712
|
+
tenant: share.tenant,
|
|
44713
|
+
scope: share.scope,
|
|
44714
|
+
...shareOrigin ? { url: buildShareUrl(shareOrigin, share.id) } : {}
|
|
44715
|
+
}
|
|
44716
|
+
};
|
|
44717
|
+
}
|
|
44718
|
+
function toTaskResponse(task, nodeRegistry, taskEngine, shareOrigin) {
|
|
44719
|
+
return withShareMetadata(withAssignedNodeMetadata(task, nodeRegistry), taskEngine, shareOrigin);
|
|
44720
|
+
}
|
|
44721
|
+
function buildShareUrl(origin, shareId) {
|
|
44722
|
+
return `${origin.replace(/\/+$/, "")}/shared/tasks/${encodeURIComponent(shareId)}`;
|
|
44723
|
+
}
|
|
44598
44724
|
function createTaskRoutes() {
|
|
44599
44725
|
const router = (0, import_express7.Router)();
|
|
44600
44726
|
router.post("/", asyncHandler6(async (req, res) => {
|
|
@@ -44620,7 +44746,7 @@ function createTaskRoutes() {
|
|
|
44620
44746
|
res.status(201).json(withAssignedNodeMetadata(task, nodeRegistry));
|
|
44621
44747
|
}));
|
|
44622
44748
|
router.get("/", asyncHandler6(async (req, res) => {
|
|
44623
|
-
const { taskEngine, nodeRegistry } = req.app.locals.deps;
|
|
44749
|
+
const { taskEngine, nodeRegistry, shareOrigin } = req.app.locals.deps;
|
|
44624
44750
|
const query = TaskListQuery.parse(req.query);
|
|
44625
44751
|
const filter = {};
|
|
44626
44752
|
if (query.status) filter.status = query.status;
|
|
@@ -44630,7 +44756,7 @@ function createTaskRoutes() {
|
|
|
44630
44756
|
if (query.offset) filter.offset = query.offset;
|
|
44631
44757
|
const result = taskEngine.listTasks(filter);
|
|
44632
44758
|
res.json({
|
|
44633
|
-
tasks: result.tasks.map((task) =>
|
|
44759
|
+
tasks: result.tasks.map((task) => toTaskResponse(task, nodeRegistry, taskEngine, shareOrigin)),
|
|
44634
44760
|
total: result.total
|
|
44635
44761
|
});
|
|
44636
44762
|
}));
|
|
@@ -44666,12 +44792,63 @@ function createTaskRoutes() {
|
|
|
44666
44792
|
res.json({ results });
|
|
44667
44793
|
}));
|
|
44668
44794
|
router.get("/:id", asyncHandler6(async (req, res) => {
|
|
44669
|
-
const { taskEngine, nodeRegistry } = req.app.locals.deps;
|
|
44670
|
-
const
|
|
44795
|
+
const { taskEngine, nodeRegistry, shareOrigin } = req.app.locals.deps;
|
|
44796
|
+
const taskId = req.params.id;
|
|
44797
|
+
const task = taskEngine.getTask(taskId);
|
|
44671
44798
|
if (!task) {
|
|
44672
|
-
throw new MeshyError("TASK_NOT_FOUND", `Task ${
|
|
44799
|
+
throw new MeshyError("TASK_NOT_FOUND", `Task ${taskId} not found`, 404);
|
|
44673
44800
|
}
|
|
44674
|
-
res.json(
|
|
44801
|
+
res.json(toTaskResponse(task, nodeRegistry, taskEngine, shareOrigin));
|
|
44802
|
+
}));
|
|
44803
|
+
router.post("/:id/share", asyncHandler6(async (req, res) => {
|
|
44804
|
+
const { taskEngine, ensureShareTunnel } = req.app.locals.deps;
|
|
44805
|
+
const body = CreateTaskShareBody.parse(req.body ?? {});
|
|
44806
|
+
const taskId = req.params.id;
|
|
44807
|
+
const task = taskEngine.getTask(taskId);
|
|
44808
|
+
if (!task) {
|
|
44809
|
+
throw new MeshyError("TASK_NOT_FOUND", `Task ${taskId} not found`, 404);
|
|
44810
|
+
}
|
|
44811
|
+
if (!ensureShareTunnel) {
|
|
44812
|
+
throw new MeshyError("VALIDATION_ERROR", "Share tunnel is not available", 503);
|
|
44813
|
+
}
|
|
44814
|
+
const shareOrigin = await ensureShareTunnel();
|
|
44815
|
+
const shareId = task.id;
|
|
44816
|
+
const existing = taskEngine.getTaskShareByTaskId(task.id);
|
|
44817
|
+
if (existing?.id === shareId) {
|
|
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
|
+
if (existing) {
|
|
44826
|
+
taskEngine.updateTaskShare(existing.id, { revokedAt: Date.now() });
|
|
44827
|
+
}
|
|
44828
|
+
const share = taskEngine.createTaskShare({
|
|
44829
|
+
id: shareId,
|
|
44830
|
+
taskId: task.id,
|
|
44831
|
+
tenant: body.tenant,
|
|
44832
|
+
scope: body.scope,
|
|
44833
|
+
createdAt: Date.now()
|
|
44834
|
+
});
|
|
44835
|
+
res.status(existing ? 200 : 201).json({ shareId: share.id, tenant: share.tenant, scope: share.scope, url: buildShareUrl(shareOrigin, share.id) });
|
|
44836
|
+
}));
|
|
44837
|
+
router.delete("/:id/share", asyncHandler6(async (req, res) => {
|
|
44838
|
+
const { taskEngine } = req.app.locals.deps;
|
|
44839
|
+
const taskId = req.params.id;
|
|
44840
|
+
const task = taskEngine.getTask(taskId);
|
|
44841
|
+
if (!task) {
|
|
44842
|
+
throw new MeshyError("TASK_NOT_FOUND", `Task ${taskId} not found`, 404);
|
|
44843
|
+
}
|
|
44844
|
+
const existing = taskEngine.getTaskShareByTaskId(task.id);
|
|
44845
|
+
if (!existing) {
|
|
44846
|
+
res.json({ ok: true, stopped: false });
|
|
44847
|
+
return;
|
|
44848
|
+
}
|
|
44849
|
+
const revokedAt = Date.now();
|
|
44850
|
+
const updated = taskEngine.updateTaskShare(existing.id, { revokedAt }) ?? { ...existing, revokedAt };
|
|
44851
|
+
res.json({ ok: true, stopped: true, shareId: updated.id });
|
|
44675
44852
|
}));
|
|
44676
44853
|
router.patch("/:id", asyncHandler6(async (req, res) => {
|
|
44677
44854
|
const { taskEngine, nodeRegistry, logger: rootLogger } = req.app.locals.deps;
|
|
@@ -44914,20 +45091,174 @@ function createTaskRoutes() {
|
|
|
44914
45091
|
return router;
|
|
44915
45092
|
}
|
|
44916
45093
|
|
|
44917
|
-
// ../../packages/api/src/routes/
|
|
45094
|
+
// ../../packages/api/src/routes/shared.ts
|
|
44918
45095
|
var import_express8 = __toESM(require_express2(), 1);
|
|
45096
|
+
function asyncHandler7(fn) {
|
|
45097
|
+
return (req, res, next) => fn(req, res, next).catch(next);
|
|
45098
|
+
}
|
|
45099
|
+
function assertActiveShare(share) {
|
|
45100
|
+
if (!share) {
|
|
45101
|
+
throw new MeshyError("TASK_NOT_FOUND", "Shared conversation not found", 404);
|
|
45102
|
+
}
|
|
45103
|
+
if (share.revokedAt !== void 0) {
|
|
45104
|
+
throw new MeshyError("VALIDATION_ERROR", "Shared conversation has been revoked", 410);
|
|
45105
|
+
}
|
|
45106
|
+
return share;
|
|
45107
|
+
}
|
|
45108
|
+
function assertFilesPreviewShare(share) {
|
|
45109
|
+
if (share.scope !== "filesPreview") {
|
|
45110
|
+
throw new MeshyError("VALIDATION_ERROR", "Shared conversation does not include files or preview", 403);
|
|
45111
|
+
}
|
|
45112
|
+
}
|
|
45113
|
+
function getTaskPayloadForShare(task) {
|
|
45114
|
+
return task.payload.initialMessage === void 0 ? {} : { initialMessage: task.payload.initialMessage };
|
|
45115
|
+
}
|
|
45116
|
+
function toSharedConversation(share, task) {
|
|
45117
|
+
return {
|
|
45118
|
+
id: task.id,
|
|
45119
|
+
shareId: share.id,
|
|
45120
|
+
title: task.title,
|
|
45121
|
+
description: task.description,
|
|
45122
|
+
agent: task.agent,
|
|
45123
|
+
status: task.status,
|
|
45124
|
+
priority: task.priority,
|
|
45125
|
+
assignedNodeName: task.assignedNodeName ?? null,
|
|
45126
|
+
tenant: share.tenant,
|
|
45127
|
+
scope: share.scope,
|
|
45128
|
+
payload: getTaskPayloadForShare(task),
|
|
45129
|
+
createdAt: task.createdAt,
|
|
45130
|
+
updatedAt: task.updatedAt
|
|
45131
|
+
};
|
|
45132
|
+
}
|
|
45133
|
+
function createSharedRoutes() {
|
|
45134
|
+
const router = (0, import_express8.Router)();
|
|
45135
|
+
router.get("/conversations/:shareId", asyncHandler7(async (req, res) => {
|
|
45136
|
+
const { taskEngine } = req.app.locals.deps;
|
|
45137
|
+
const shareId = req.params.shareId;
|
|
45138
|
+
const share = assertActiveShare(taskEngine.getTaskShare(shareId));
|
|
45139
|
+
const task = taskEngine.getTask(share.taskId);
|
|
45140
|
+
if (!task) {
|
|
45141
|
+
throw new MeshyError("TASK_NOT_FOUND", "Shared conversation task not found", 404);
|
|
45142
|
+
}
|
|
45143
|
+
res.json(toSharedConversation(share, task));
|
|
45144
|
+
}));
|
|
45145
|
+
router.get("/conversations/:shareId/logs", asyncHandler7(async (req, res) => {
|
|
45146
|
+
const { taskEngine, engineRegistry } = req.app.locals.deps;
|
|
45147
|
+
const query = TaskLogsQuery.parse(req.query);
|
|
45148
|
+
const shareId = req.params.shareId;
|
|
45149
|
+
const share = assertActiveShare(taskEngine.getTaskShare(shareId));
|
|
45150
|
+
const task = taskEngine.getTask(share.taskId);
|
|
45151
|
+
if (!task) {
|
|
45152
|
+
throw new MeshyError("TASK_NOT_FOUND", "Shared conversation task not found", 404);
|
|
45153
|
+
}
|
|
45154
|
+
res.json(readLocalTaskLogs(engineRegistry, task.id, query.after ?? 0, task.agent));
|
|
45155
|
+
}));
|
|
45156
|
+
router.get("/conversations/:shareId/output", asyncHandler7(async (req, res) => {
|
|
45157
|
+
const { taskEngine } = req.app.locals.deps;
|
|
45158
|
+
const shareId = req.params.shareId;
|
|
45159
|
+
const share = assertActiveShare(taskEngine.getTaskShare(shareId));
|
|
45160
|
+
assertFilesPreviewShare(share);
|
|
45161
|
+
const handled = await maybeHandleRemoteTaskOutputRequest(
|
|
45162
|
+
req,
|
|
45163
|
+
res,
|
|
45164
|
+
share.taskId,
|
|
45165
|
+
"",
|
|
45166
|
+
void 0,
|
|
45167
|
+
createNodeMessage("task.output.summary", { taskId: share.taskId }, { expectsResponse: true })
|
|
45168
|
+
);
|
|
45169
|
+
if (handled) return;
|
|
45170
|
+
res.json(getLocalTaskOutputSummary(req.app.locals.deps.taskEngine, share.taskId));
|
|
45171
|
+
}));
|
|
45172
|
+
router.get("/conversations/:shareId/output/tree", asyncHandler7(async (req, res) => {
|
|
45173
|
+
const { taskEngine } = req.app.locals.deps;
|
|
45174
|
+
const query = TaskOutputTreeQuery.parse(req.query);
|
|
45175
|
+
const shareId = req.params.shareId;
|
|
45176
|
+
const share = assertActiveShare(taskEngine.getTaskShare(shareId));
|
|
45177
|
+
assertFilesPreviewShare(share);
|
|
45178
|
+
const handled = await maybeHandleRemoteTaskOutputRequest(
|
|
45179
|
+
req,
|
|
45180
|
+
res,
|
|
45181
|
+
share.taskId,
|
|
45182
|
+
"/tree",
|
|
45183
|
+
void 0,
|
|
45184
|
+
createNodeMessage("task.output.tree", { taskId: share.taskId, path: query.path }, { expectsResponse: true })
|
|
45185
|
+
);
|
|
45186
|
+
if (handled) return;
|
|
45187
|
+
res.json(getLocalTaskOutputTree(req.app.locals.deps.taskEngine, share.taskId, query.path));
|
|
45188
|
+
}));
|
|
45189
|
+
router.get("/conversations/:shareId/output/content", asyncHandler7(async (req, res) => {
|
|
45190
|
+
const { taskEngine } = req.app.locals.deps;
|
|
45191
|
+
const query = TaskOutputContentQuery.parse(req.query);
|
|
45192
|
+
const shareId = req.params.shareId;
|
|
45193
|
+
const share = assertActiveShare(taskEngine.getTaskShare(shareId));
|
|
45194
|
+
assertFilesPreviewShare(share);
|
|
45195
|
+
const handled = await maybeHandleRemoteTaskOutputRequest(
|
|
45196
|
+
req,
|
|
45197
|
+
res,
|
|
45198
|
+
share.taskId,
|
|
45199
|
+
"/content",
|
|
45200
|
+
void 0,
|
|
45201
|
+
createNodeMessage("task.output.content", { taskId: share.taskId, path: query.path }, { expectsResponse: true })
|
|
45202
|
+
);
|
|
45203
|
+
if (handled) return;
|
|
45204
|
+
const content = getLocalTaskOutputContent(req.app.locals.deps.taskEngine, share.taskId, query.path);
|
|
45205
|
+
res.json({
|
|
45206
|
+
...content,
|
|
45207
|
+
downloadUrl: `/api/shared/conversations/${encodeURIComponent(share.id)}/output/download?path=${encodeURIComponent(query.path)}`
|
|
45208
|
+
});
|
|
45209
|
+
}));
|
|
45210
|
+
router.get("/conversations/:shareId/output/download", asyncHandler7(async (req, res) => {
|
|
45211
|
+
const { taskEngine } = req.app.locals.deps;
|
|
45212
|
+
const query = TaskOutputDownloadQuery.parse(req.query);
|
|
45213
|
+
const shareId = req.params.shareId;
|
|
45214
|
+
const share = assertActiveShare(taskEngine.getTaskShare(shareId));
|
|
45215
|
+
assertFilesPreviewShare(share);
|
|
45216
|
+
const handled = await maybeHandleRemoteTaskOutputRequest(
|
|
45217
|
+
req,
|
|
45218
|
+
res,
|
|
45219
|
+
share.taskId,
|
|
45220
|
+
"/download",
|
|
45221
|
+
void 0,
|
|
45222
|
+
createNodeMessage("task.output.download", { taskId: share.taskId, path: query.path }, { expectsResponse: true })
|
|
45223
|
+
);
|
|
45224
|
+
if (handled) return;
|
|
45225
|
+
const download = getLocalTaskOutputDownload(req.app.locals.deps.taskEngine, share.taskId, query.path);
|
|
45226
|
+
for (const [key, value] of Object.entries(download.headers)) {
|
|
45227
|
+
res.setHeader(key, value);
|
|
45228
|
+
}
|
|
45229
|
+
res.send(download.content);
|
|
45230
|
+
}));
|
|
45231
|
+
router.post("/conversations/:shareId/output/preview-sessions", asyncHandler7(async (req, res) => {
|
|
45232
|
+
const { taskEngine } = req.app.locals.deps;
|
|
45233
|
+
const body = TaskPreviewSessionBody.parse(req.body ?? {});
|
|
45234
|
+
const shareId = req.params.shareId;
|
|
45235
|
+
const share = assertActiveShare(taskEngine.getTaskShare(shareId));
|
|
45236
|
+
assertFilesPreviewShare(share);
|
|
45237
|
+
const handled = await maybeHandleRemoteTaskOutputRequest(req, res, share.taskId, "/preview-sessions", {
|
|
45238
|
+
method: "POST",
|
|
45239
|
+
headers: { "Content-Type": "application/json" },
|
|
45240
|
+
body: JSON.stringify(body)
|
|
45241
|
+
}, createNodeMessage("task.preview.create", { taskId: share.taskId, path: body.path }, { expectsResponse: true }));
|
|
45242
|
+
if (handled) return;
|
|
45243
|
+
res.json(await createPreviewSessionPayload(req.app.locals.deps, share.taskId, body.path, resolveRequestOrigin(req)));
|
|
45244
|
+
}));
|
|
45245
|
+
return router;
|
|
45246
|
+
}
|
|
45247
|
+
|
|
45248
|
+
// ../../packages/api/src/routes/worker.ts
|
|
45249
|
+
var import_express9 = __toESM(require_express2(), 1);
|
|
44919
45250
|
var WorkerMessageBody = external_exports.object({
|
|
44920
45251
|
taskId: external_exports.string().min(1)
|
|
44921
45252
|
}).and(SendMessageBody);
|
|
44922
45253
|
var WorkerTaskBody = external_exports.object({
|
|
44923
45254
|
taskId: external_exports.string().min(1)
|
|
44924
45255
|
});
|
|
44925
|
-
function
|
|
45256
|
+
function asyncHandler8(fn) {
|
|
44926
45257
|
return (req, res, next) => fn(req, res, next).catch(next);
|
|
44927
45258
|
}
|
|
44928
45259
|
function createWorkerRoutes() {
|
|
44929
|
-
const router = (0,
|
|
44930
|
-
router.post("/execute",
|
|
45260
|
+
const router = (0, import_express9.Router)();
|
|
45261
|
+
router.post("/execute", asyncHandler8(async (req, res) => {
|
|
44931
45262
|
const { taskEngine, engineRegistry, nodeRegistry, eventBus, logger: rootLogger, workDir } = req.app.locals.deps;
|
|
44932
45263
|
const log2 = rootLogger.child("worker/execute");
|
|
44933
45264
|
const task = req.body;
|
|
@@ -44944,7 +45275,7 @@ function createWorkerRoutes() {
|
|
|
44944
45275
|
});
|
|
44945
45276
|
res.json({ ok: true });
|
|
44946
45277
|
}));
|
|
44947
|
-
router.post("/message",
|
|
45278
|
+
router.post("/message", asyncHandler8(async (req, res) => {
|
|
44948
45279
|
const { engineRegistry, taskEngine, nodeRegistry, eventBus, logger: rootLogger } = req.app.locals.deps;
|
|
44949
45280
|
const log2 = rootLogger.child("worker/message");
|
|
44950
45281
|
const body = WorkerMessageBody.parse(req.body);
|
|
@@ -44994,7 +45325,7 @@ function createWorkerRoutes() {
|
|
|
44994
45325
|
}
|
|
44995
45326
|
res.json({ ok: true });
|
|
44996
45327
|
}));
|
|
44997
|
-
router.post("/cancel",
|
|
45328
|
+
router.post("/cancel", asyncHandler8(async (req, res) => {
|
|
44998
45329
|
const { taskEngine, engineRegistry, logger: rootLogger } = req.app.locals.deps;
|
|
44999
45330
|
const log2 = rootLogger.child("worker/cancel");
|
|
45000
45331
|
const body = WorkerTaskBody.parse(req.body);
|
|
@@ -45014,7 +45345,7 @@ function createWorkerRoutes() {
|
|
|
45014
45345
|
terminal: result.terminal
|
|
45015
45346
|
});
|
|
45016
45347
|
}));
|
|
45017
|
-
router.post("/output",
|
|
45348
|
+
router.post("/output", asyncHandler8(async (req, res) => {
|
|
45018
45349
|
const { eventBus, engineRegistry, taskEngine, logger: rootLogger } = req.app.locals.deps;
|
|
45019
45350
|
const log2 = rootLogger.child("worker/output");
|
|
45020
45351
|
const { taskId, event } = req.body;
|
|
@@ -45029,7 +45360,7 @@ function createWorkerRoutes() {
|
|
|
45029
45360
|
}
|
|
45030
45361
|
res.json({ ok: true });
|
|
45031
45362
|
}));
|
|
45032
|
-
router.post("/heartbeat",
|
|
45363
|
+
router.post("/heartbeat", asyncHandler8(async (req, res) => {
|
|
45033
45364
|
const { heartbeat, logger: rootLogger } = req.app.locals.deps;
|
|
45034
45365
|
const log2 = rootLogger.child("worker/heartbeat");
|
|
45035
45366
|
const body = req.body;
|
|
@@ -45046,7 +45377,7 @@ function createWorkerRoutes() {
|
|
|
45046
45377
|
});
|
|
45047
45378
|
res.json(response);
|
|
45048
45379
|
}));
|
|
45049
|
-
router.post("/keepalive",
|
|
45380
|
+
router.post("/keepalive", asyncHandler8(async (req, res) => {
|
|
45050
45381
|
const { heartbeat, logger: rootLogger } = req.app.locals.deps;
|
|
45051
45382
|
const log2 = rootLogger.child("worker/keepalive");
|
|
45052
45383
|
const body = req.body;
|
|
@@ -45064,17 +45395,17 @@ function createWorkerRoutes() {
|
|
|
45064
45395
|
});
|
|
45065
45396
|
res.json(response);
|
|
45066
45397
|
}));
|
|
45067
|
-
router.post("/vote",
|
|
45398
|
+
router.post("/vote", asyncHandler8(async (req, res) => {
|
|
45068
45399
|
const { election } = req.app.locals.deps;
|
|
45069
45400
|
const response = election.handleVoteRequest(req.body);
|
|
45070
45401
|
res.json(response);
|
|
45071
45402
|
}));
|
|
45072
|
-
router.post("/announce",
|
|
45403
|
+
router.post("/announce", asyncHandler8(async (req, res) => {
|
|
45073
45404
|
const { election } = req.app.locals.deps;
|
|
45074
45405
|
election.handleLeaderAnnounce(req.body);
|
|
45075
45406
|
res.json({ ok: true });
|
|
45076
45407
|
}));
|
|
45077
|
-
router.post("/preview-session",
|
|
45408
|
+
router.post("/preview-session", asyncHandler8(async (req, res) => {
|
|
45078
45409
|
const { logger: rootLogger } = req.app.locals.deps;
|
|
45079
45410
|
const log2 = rootLogger.child("worker/preview-session");
|
|
45080
45411
|
const body = TaskPreviewSessionBody.extend({
|
|
@@ -45089,7 +45420,7 @@ function createWorkerRoutes() {
|
|
|
45089
45420
|
log2.info("created preview session", { taskId: body.taskId, entryPath: payload.entryPath });
|
|
45090
45421
|
res.json(payload);
|
|
45091
45422
|
}));
|
|
45092
|
-
router.get("/preview-asset",
|
|
45423
|
+
router.get("/preview-asset", asyncHandler8(async (req, res) => {
|
|
45093
45424
|
const { previewSessionManager } = req.app.locals.deps;
|
|
45094
45425
|
if (!previewSessionManager) {
|
|
45095
45426
|
throw new MeshyError("VALIDATION_ERROR", "Preview not available on this node", 400);
|
|
@@ -45098,7 +45429,7 @@ function createWorkerRoutes() {
|
|
|
45098
45429
|
const requestedPath = typeof req.query.path === "string" && req.query.path.length > 0 ? req.query.path : void 0;
|
|
45099
45430
|
sendPreviewAssetResponse(previewSessionManager, token, requestedPath, res);
|
|
45100
45431
|
}));
|
|
45101
|
-
router.post("/control-response",
|
|
45432
|
+
router.post("/control-response", asyncHandler8(async (req, res) => {
|
|
45102
45433
|
const { heartbeat, logger: rootLogger } = req.app.locals.deps;
|
|
45103
45434
|
const log2 = rootLogger.child("worker/control-response");
|
|
45104
45435
|
const body = normalizeNodeMessageResponse(req.body);
|
|
@@ -45125,7 +45456,7 @@ function normalizeNodeMessageResponse(value) {
|
|
|
45125
45456
|
}
|
|
45126
45457
|
|
|
45127
45458
|
// ../../packages/api/src/routes/system.ts
|
|
45128
|
-
var
|
|
45459
|
+
var import_express10 = __toESM(require_express2(), 1);
|
|
45129
45460
|
|
|
45130
45461
|
// ../../packages/api/src/app/system-info.ts
|
|
45131
45462
|
var os5 = __toESM(require("os"), 1);
|
|
@@ -45243,12 +45574,12 @@ function buildNodeSettingsSnapshot(options) {
|
|
|
45243
45574
|
}
|
|
45244
45575
|
|
|
45245
45576
|
// ../../packages/api/src/routes/system.ts
|
|
45246
|
-
function
|
|
45577
|
+
function asyncHandler9(fn) {
|
|
45247
45578
|
return (req, res, next) => fn(req, res, next).catch(next);
|
|
45248
45579
|
}
|
|
45249
45580
|
function createSystemRoutes() {
|
|
45250
|
-
const router = (0,
|
|
45251
|
-
router.get("/health",
|
|
45581
|
+
const router = (0, import_express10.Router)();
|
|
45582
|
+
router.get("/health", asyncHandler9(async (req, res) => {
|
|
45252
45583
|
const { logger: rootLogger } = req.app.locals.deps;
|
|
45253
45584
|
rootLogger.child("system/health").info("received system health API call", {
|
|
45254
45585
|
method: req.method,
|
|
@@ -45257,7 +45588,7 @@ function createSystemRoutes() {
|
|
|
45257
45588
|
});
|
|
45258
45589
|
res.json({ status: "ok", timestamp: Date.now() });
|
|
45259
45590
|
}));
|
|
45260
|
-
router.get("/info",
|
|
45591
|
+
router.get("/info", asyncHandler9(async (req, res) => {
|
|
45261
45592
|
const {
|
|
45262
45593
|
nodeRegistry,
|
|
45263
45594
|
getTransportType,
|
|
@@ -45301,7 +45632,7 @@ function createSystemRoutes() {
|
|
|
45301
45632
|
packages: settingsSnapshot.packages
|
|
45302
45633
|
});
|
|
45303
45634
|
}));
|
|
45304
|
-
router.post("/transport",
|
|
45635
|
+
router.post("/transport", asyncHandler9(async (req, res) => {
|
|
45305
45636
|
const { switchTransport } = req.app.locals.deps;
|
|
45306
45637
|
if (!switchTransport) {
|
|
45307
45638
|
res.status(501).json({ error: "Transport switching not available" });
|
|
@@ -45315,7 +45646,7 @@ function createSystemRoutes() {
|
|
|
45315
45646
|
const newEndpoint = await switchTransport(type);
|
|
45316
45647
|
res.json({ ok: true, transportType: type, endpoint: newEndpoint });
|
|
45317
45648
|
}));
|
|
45318
|
-
router.post("/devtunnel",
|
|
45649
|
+
router.post("/devtunnel", asyncHandler9(async (req, res) => {
|
|
45319
45650
|
const { enableDevTunnel, disableDevTunnel, nodeRegistry, taskEngine } = req.app.locals.deps;
|
|
45320
45651
|
if (!enableDevTunnel || !disableDevTunnel) {
|
|
45321
45652
|
res.status(501).json({ error: "DevTunnel control not available" });
|
|
@@ -45344,7 +45675,7 @@ function createSystemRoutes() {
|
|
|
45344
45675
|
});
|
|
45345
45676
|
}
|
|
45346
45677
|
}));
|
|
45347
|
-
router.get("/metrics",
|
|
45678
|
+
router.get("/metrics", asyncHandler9(async (req, res) => {
|
|
45348
45679
|
const { taskEngine } = req.app.locals.deps;
|
|
45349
45680
|
const metrics = taskEngine.getMetrics();
|
|
45350
45681
|
res.json(metrics);
|
|
@@ -45353,7 +45684,7 @@ function createSystemRoutes() {
|
|
|
45353
45684
|
}
|
|
45354
45685
|
|
|
45355
45686
|
// ../../packages/api/src/routes/events.ts
|
|
45356
|
-
var
|
|
45687
|
+
var import_express11 = __toESM(require_express2(), 1);
|
|
45357
45688
|
var HEARTBEAT_INTERVAL_MS = 15e3;
|
|
45358
45689
|
var CATEGORY_MAP = {
|
|
45359
45690
|
tasks: "task.",
|
|
@@ -45389,7 +45720,7 @@ function shouldIncludeEvent(eventName, categories) {
|
|
|
45389
45720
|
});
|
|
45390
45721
|
}
|
|
45391
45722
|
function createEventRoutes() {
|
|
45392
|
-
const router = (0,
|
|
45723
|
+
const router = (0, import_express11.Router)();
|
|
45393
45724
|
router.get("/", (req, res) => {
|
|
45394
45725
|
const { eventBus } = req.app.locals.deps;
|
|
45395
45726
|
const categories = parseFilter(req.query.filter);
|
|
@@ -45437,6 +45768,40 @@ data: ${JSON.stringify(data)}
|
|
|
45437
45768
|
// ../../packages/api/src/app/server.ts
|
|
45438
45769
|
var JSON_BODY_LIMIT = "1mb";
|
|
45439
45770
|
var JSON_BODY_LIMIT_LARGE = "25mb";
|
|
45771
|
+
var TRUSTED_LOCAL_HOSTS2 = /* @__PURE__ */ new Set(["localhost", "127.0.0.1", "[::1]", "::1"]);
|
|
45772
|
+
function normalizeHost2(value) {
|
|
45773
|
+
const trimmed = value?.trim().toLowerCase();
|
|
45774
|
+
return trimmed ? trimmed.replace(/:\d+$/, "") : void 0;
|
|
45775
|
+
}
|
|
45776
|
+
function collectForwardedHosts(value) {
|
|
45777
|
+
if (typeof value !== "string") {
|
|
45778
|
+
return [];
|
|
45779
|
+
}
|
|
45780
|
+
return value.split(",").map((item) => normalizeHost2(item)).filter((host) => Boolean(host));
|
|
45781
|
+
}
|
|
45782
|
+
function getRequestHosts2(req) {
|
|
45783
|
+
const forwardedHosts = collectForwardedHosts(req.headers["x-forwarded-host"]);
|
|
45784
|
+
if (forwardedHosts.length > 0) {
|
|
45785
|
+
return forwardedHosts;
|
|
45786
|
+
}
|
|
45787
|
+
return [normalizeHost2(req.hostname), normalizeHost2(typeof req.headers.host === "string" ? req.headers.host : void 0)].filter((host) => Boolean(host));
|
|
45788
|
+
}
|
|
45789
|
+
function getOriginHost(origin) {
|
|
45790
|
+
if (!origin) return void 0;
|
|
45791
|
+
try {
|
|
45792
|
+
return normalizeHost2(new URL(origin).host);
|
|
45793
|
+
} catch {
|
|
45794
|
+
return void 0;
|
|
45795
|
+
}
|
|
45796
|
+
}
|
|
45797
|
+
function isShareHostRequest(req, shareOrigin) {
|
|
45798
|
+
const shareHost = getOriginHost(shareOrigin);
|
|
45799
|
+
if (!shareHost) return false;
|
|
45800
|
+
return getRequestHosts2(req).some((host) => !TRUSTED_LOCAL_HOSTS2.has(host) && host === shareHost);
|
|
45801
|
+
}
|
|
45802
|
+
function isAllowedSharePath(pathname) {
|
|
45803
|
+
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/");
|
|
45804
|
+
}
|
|
45440
45805
|
function resolveRuntimeBaseDir() {
|
|
45441
45806
|
const entryPath = process.argv[1];
|
|
45442
45807
|
if (typeof entryPath === "string" && entryPath.length > 0) {
|
|
@@ -45467,7 +45832,7 @@ function resolveStaticDir(baseDir) {
|
|
|
45467
45832
|
return null;
|
|
45468
45833
|
}
|
|
45469
45834
|
function createServer2(deps) {
|
|
45470
|
-
const app = (0,
|
|
45835
|
+
const app = (0, import_express12.default)();
|
|
45471
45836
|
app.locals.deps = deps;
|
|
45472
45837
|
if (typeof deps.heartbeat.setNodeMessageHandler === "function") {
|
|
45473
45838
|
deps.heartbeat.setNodeMessageHandler((message) => handleNodeMessage(deps, message));
|
|
@@ -45483,15 +45848,32 @@ function createServer2(deps) {
|
|
|
45483
45848
|
} catch {
|
|
45484
45849
|
}
|
|
45485
45850
|
}
|
|
45851
|
+
if (deps.shareOrigin) {
|
|
45852
|
+
try {
|
|
45853
|
+
trustedHosts.push(new URL(deps.shareOrigin).host);
|
|
45854
|
+
} catch {
|
|
45855
|
+
}
|
|
45856
|
+
}
|
|
45486
45857
|
return trustedHosts;
|
|
45487
45858
|
}
|
|
45488
45859
|
};
|
|
45489
45860
|
const isApiRequest = (req) => req.path === "/api" || req.path.startsWith("/api/");
|
|
45490
45861
|
const canServeDashboard = (req) => !deps.config.validateBearerToken || isTrustedDashboardRequest(req, authConfig);
|
|
45862
|
+
app.use((req, res, next) => {
|
|
45863
|
+
if (!isShareHostRequest(req, deps.shareOrigin)) {
|
|
45864
|
+
next();
|
|
45865
|
+
return;
|
|
45866
|
+
}
|
|
45867
|
+
if (isAllowedSharePath(req.path)) {
|
|
45868
|
+
next();
|
|
45869
|
+
return;
|
|
45870
|
+
}
|
|
45871
|
+
res.status(404).type("text/plain").send("Not Found");
|
|
45872
|
+
});
|
|
45491
45873
|
const runtimeBaseDir = resolveRuntimeBaseDir();
|
|
45492
45874
|
const staticDir = resolveStaticDir(runtimeBaseDir);
|
|
45493
45875
|
if (staticDir) {
|
|
45494
|
-
const staticMiddleware =
|
|
45876
|
+
const staticMiddleware = import_express12.default.static(staticDir);
|
|
45495
45877
|
app.use((req, res, next) => {
|
|
45496
45878
|
if (isApiRequest(req)) {
|
|
45497
45879
|
next();
|
|
@@ -45504,7 +45886,7 @@ function createServer2(deps) {
|
|
|
45504
45886
|
staticMiddleware(req, res, next);
|
|
45505
45887
|
});
|
|
45506
45888
|
}
|
|
45507
|
-
app.use(
|
|
45889
|
+
app.use(import_express12.default.json({ limit: JSON_BODY_LIMIT }));
|
|
45508
45890
|
app.use(createAuthMiddleware(authConfig));
|
|
45509
45891
|
app.use((req, res, next) => {
|
|
45510
45892
|
void (async () => {
|
|
@@ -45526,12 +45908,13 @@ function createServer2(deps) {
|
|
|
45526
45908
|
})().catch(next);
|
|
45527
45909
|
});
|
|
45528
45910
|
app.use(createRoutingMiddleware(deps.dataRouter));
|
|
45529
|
-
const largeBodyParser =
|
|
45911
|
+
const largeBodyParser = import_express12.default.json({ limit: JSON_BODY_LIMIT_LARGE });
|
|
45530
45912
|
app.use("/api/cluster", createClusterRoutes());
|
|
45531
45913
|
app.use("/api/cluster-control", createClusterControlRoutes());
|
|
45532
45914
|
app.use("/api/node", largeBodyParser, createNodeMessageRoutes());
|
|
45533
45915
|
app.use("/api/nodes", createNodeRoutes());
|
|
45534
45916
|
app.use("/api/tasks", largeBodyParser, createTaskRoutes());
|
|
45917
|
+
app.use("/api/shared", createSharedRoutes());
|
|
45535
45918
|
app.use("/api/worker", largeBodyParser, createWorkerRoutes());
|
|
45536
45919
|
app.use("/api/system", createSystemRoutes());
|
|
45537
45920
|
app.use("/api/events", createEventRoutes());
|
|
@@ -45751,8 +46134,24 @@ ${lines.join("")}`
|
|
|
45751
46134
|
return args;
|
|
45752
46135
|
}
|
|
45753
46136
|
this.ensureTunnelPort(tunnelId, localPort);
|
|
46137
|
+
this.ensureTunnelAccess(tunnelId);
|
|
45754
46138
|
return ["host", tunnelId];
|
|
45755
46139
|
}
|
|
46140
|
+
ensureTunnelAccess(tunnelId) {
|
|
46141
|
+
if (this.config.access !== "tenant") {
|
|
46142
|
+
return;
|
|
46143
|
+
}
|
|
46144
|
+
try {
|
|
46145
|
+
(0, import_node_child_process9.execFileSync)("devtunnel", ["access", "create", tunnelId, "--tenant"], { stdio: "pipe" });
|
|
46146
|
+
} catch (err) {
|
|
46147
|
+
if (isExistingTenantAccessError(err)) {
|
|
46148
|
+
return;
|
|
46149
|
+
}
|
|
46150
|
+
throw new Error(
|
|
46151
|
+
`Failed to configure tenant access for devtunnel "${tunnelId}": ${formatCommandError(err)}`
|
|
46152
|
+
);
|
|
46153
|
+
}
|
|
46154
|
+
}
|
|
45756
46155
|
ensureTunnelExists() {
|
|
45757
46156
|
const tunnelId = this.config.id.trim();
|
|
45758
46157
|
if (!tunnelId) {
|
|
@@ -45847,6 +46246,10 @@ function normalizeDevTunnelUrl(value) {
|
|
|
45847
46246
|
return null;
|
|
45848
46247
|
}
|
|
45849
46248
|
}
|
|
46249
|
+
function isExistingTenantAccessError(error) {
|
|
46250
|
+
const message = formatCommandError(error).toLowerCase();
|
|
46251
|
+
return message.includes("already exists") || message.includes("conflict") || message.includes("duplicate");
|
|
46252
|
+
}
|
|
45850
46253
|
function formatCommandError(error) {
|
|
45851
46254
|
if (!error || typeof error !== "object") {
|
|
45852
46255
|
return String(error);
|
|
@@ -46624,7 +47027,9 @@ async function main() {
|
|
|
46624
47027
|
const previewSessionManager = new PreviewSessionManager();
|
|
46625
47028
|
const previewProxyManager = new PreviewProxyManager();
|
|
46626
47029
|
let dashboardTransport = null;
|
|
47030
|
+
let shareTransport = null;
|
|
46627
47031
|
let dashboardOrigin;
|
|
47032
|
+
let shareOrigin;
|
|
46628
47033
|
let deps;
|
|
46629
47034
|
async function closeServer(server2) {
|
|
46630
47035
|
if (!server2) {
|
|
@@ -46653,11 +47058,29 @@ async function main() {
|
|
|
46653
47058
|
}
|
|
46654
47059
|
};
|
|
46655
47060
|
}
|
|
47061
|
+
function createShareTransportConfig() {
|
|
47062
|
+
return {
|
|
47063
|
+
type: "devtunnel",
|
|
47064
|
+
devtunnel: {
|
|
47065
|
+
id: resolveOrCreateDevTunnelId(
|
|
47066
|
+
config.storage.path,
|
|
47067
|
+
meshyNode.getNodeRegistry().getSelf().id,
|
|
47068
|
+
"share"
|
|
47069
|
+
),
|
|
47070
|
+
allowAnonymous: false,
|
|
47071
|
+
access: "tenant"
|
|
47072
|
+
}
|
|
47073
|
+
};
|
|
47074
|
+
}
|
|
46656
47075
|
function setAdvertisedDashboardOrigin(origin) {
|
|
46657
47076
|
dashboardOrigin = origin;
|
|
46658
47077
|
deps.dashboardOrigin = origin;
|
|
46659
47078
|
meshyNode.getNodeRegistry().updateDashboardOrigin(meshyNode.getNodeRegistry().getSelf().id, origin);
|
|
46660
47079
|
}
|
|
47080
|
+
function setShareOrigin(origin) {
|
|
47081
|
+
shareOrigin = origin;
|
|
47082
|
+
deps.shareOrigin = origin;
|
|
47083
|
+
}
|
|
46661
47084
|
function shouldPublishDashboardTunnel() {
|
|
46662
47085
|
return authMetadata.enabled && (meshyNode.getTransportType() === "devtunnel" || meshyNode.isDevTunnelEnabled());
|
|
46663
47086
|
}
|
|
@@ -46739,6 +47162,27 @@ async function main() {
|
|
|
46739
47162
|
}
|
|
46740
47163
|
await restartDashboardTransport(reason);
|
|
46741
47164
|
}
|
|
47165
|
+
async function ensureShareTunnel() {
|
|
47166
|
+
if (shareTransport && shareOrigin && await shareTransport.isHealthy().catch(() => false)) {
|
|
47167
|
+
return shareOrigin;
|
|
47168
|
+
}
|
|
47169
|
+
if (shareTransport) {
|
|
47170
|
+
await shareTransport.stop().catch(() => void 0);
|
|
47171
|
+
shareTransport = null;
|
|
47172
|
+
setShareOrigin(void 0);
|
|
47173
|
+
}
|
|
47174
|
+
const nextTransport = createTransport(createShareTransportConfig());
|
|
47175
|
+
await nextTransport.start(config.node.port);
|
|
47176
|
+
const nextOrigin = await nextTransport.getEndpoint();
|
|
47177
|
+
shareTransport = nextTransport;
|
|
47178
|
+
setShareOrigin(nextOrigin);
|
|
47179
|
+
meshyNode.getLogger().info("started share tunnel", {
|
|
47180
|
+
shareOrigin: nextOrigin,
|
|
47181
|
+
tenantAccess: true,
|
|
47182
|
+
stableUrl: true
|
|
47183
|
+
});
|
|
47184
|
+
return nextOrigin;
|
|
47185
|
+
}
|
|
46742
47186
|
deps = {
|
|
46743
47187
|
dataRouter: meshyNode.getDataRouter(),
|
|
46744
47188
|
taskEngine: meshyNode.getTaskEngine(),
|
|
@@ -46791,11 +47235,14 @@ async function main() {
|
|
|
46791
47235
|
isDevTunnelEnabled: () => meshyNode.isDevTunnelEnabled(),
|
|
46792
47236
|
localDashboardOrigin,
|
|
46793
47237
|
dashboardOrigin,
|
|
47238
|
+
shareOrigin,
|
|
47239
|
+
ensureShareTunnel,
|
|
46794
47240
|
runtimeMetadata
|
|
46795
47241
|
};
|
|
46796
47242
|
deps.previewSessionManager = previewSessionManager;
|
|
46797
47243
|
deps.previewProxyManager = previewProxyManager;
|
|
46798
47244
|
deps.dashboardOrigin = dashboardOrigin;
|
|
47245
|
+
deps.shareOrigin = shareOrigin;
|
|
46799
47246
|
meshyNode.getLogger().info("configured node auth mode", {
|
|
46800
47247
|
authEnabled: authMetadata.enabled,
|
|
46801
47248
|
allowSameTenant: authMetadata.allowSameTenant,
|
|
@@ -46869,6 +47316,9 @@ async function main() {
|
|
|
46869
47316
|
if (dashboardTransport) {
|
|
46870
47317
|
await dashboardTransport.stop();
|
|
46871
47318
|
}
|
|
47319
|
+
if (shareTransport) {
|
|
47320
|
+
await shareTransport.stop();
|
|
47321
|
+
}
|
|
46872
47322
|
await meshyNode.stop();
|
|
46873
47323
|
await closeServer(server);
|
|
46874
47324
|
console.log("Goodbye!");
|