@rubytech/create-maxy 1.0.764 → 1.0.766
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/package.json +1 -1
- package/payload/platform/plugins/docs/references/platform.md +1 -1
- package/payload/server/chunk-IO2WQEY4.js +9562 -0
- package/payload/server/chunk-TKYZ7AEB.js +3142 -0
- package/payload/server/client-pool-CX2MFW75.js +28 -0
- package/payload/server/maxy-edge.js +2 -2
- package/payload/server/public/assets/{Checkbox-BRLBdX7n.js → Checkbox-D4ru6Rnc.js} +1 -1
- package/payload/server/public/assets/admin-RgtF1AAZ.js +352 -0
- package/payload/server/public/assets/data-5fPP3RXM.js +1 -0
- package/payload/server/public/assets/graph-BLaHRtJ3.js +1 -0
- package/payload/server/public/assets/{jsx-runtime-BRkYVd7p.css → jsx-runtime-Rr9ViFRF.css} +1 -1
- package/payload/server/public/assets/page-DAKUQ1yb.js +50 -0
- package/payload/server/public/assets/{page-v5z5MBB6.js → page-Dw31Y-B8.js} +1 -1
- package/payload/server/public/assets/{public-CQ_WMUng.js → public-Xx3SnSxV.js} +1 -1
- package/payload/server/public/assets/{share-2-Cc99o2of.js → share-2-D8-hi3T3.js} +1 -1
- package/payload/server/public/assets/{useVoiceRecorder-C2CyyNiy.js → useVoiceRecorder-CXxtW1ks.js} +1 -1
- package/payload/server/public/data.html +5 -5
- package/payload/server/public/graph.html +6 -6
- package/payload/server/public/index.html +8 -8
- package/payload/server/public/public.html +5 -5
- package/payload/server/server.js +440 -163
- package/payload/server/public/assets/admin-V6NDkEoR.js +0 -352
- package/payload/server/public/assets/data-DVeGdjv2.js +0 -1
- package/payload/server/public/assets/graph-BHcUKzXh.js +0 -1
- package/payload/server/public/assets/page-DxH_Opxt.js +0 -50
- /package/payload/server/public/assets/{jsx-runtime-B4QFltsm.js → jsx-runtime-C96Yp1GB.js} +0 -0
package/payload/server/server.js
CHANGED
|
@@ -47,7 +47,7 @@ import {
|
|
|
47
47
|
vncLog,
|
|
48
48
|
waitForExit,
|
|
49
49
|
writeChromiumWrapper
|
|
50
|
-
} from "./chunk-
|
|
50
|
+
} from "./chunk-IO2WQEY4.js";
|
|
51
51
|
import {
|
|
52
52
|
ACCOUNTS_DIR,
|
|
53
53
|
GREETING_DIRECTIVE,
|
|
@@ -107,7 +107,7 @@ import {
|
|
|
107
107
|
validateSession,
|
|
108
108
|
verifyAndGetConversationUpdatedAt,
|
|
109
109
|
verifyConversationOwnership
|
|
110
|
-
} from "./chunk-
|
|
110
|
+
} from "./chunk-TKYZ7AEB.js";
|
|
111
111
|
|
|
112
112
|
// ../lib/graph-trash/dist/index.js
|
|
113
113
|
var require_dist = __commonJS({
|
|
@@ -606,8 +606,8 @@ var serveStatic = (options = { root: "" }) => {
|
|
|
606
606
|
};
|
|
607
607
|
|
|
608
608
|
// server/index.ts
|
|
609
|
-
import { readFileSync as readFileSync16, existsSync as
|
|
610
|
-
import { resolve as
|
|
609
|
+
import { readFileSync as readFileSync16, existsSync as existsSync22, watchFile } from "fs";
|
|
610
|
+
import { resolve as resolve23, join as join10, basename as basename7 } from "path";
|
|
611
611
|
import { homedir as homedir2 } from "os";
|
|
612
612
|
|
|
613
613
|
// app/lib/agent-slug-pattern.ts
|
|
@@ -1351,9 +1351,9 @@ function discoverAllSources(configDir2, accountLogDir2) {
|
|
|
1351
1351
|
}
|
|
1352
1352
|
function readNewLines(filepath, prev) {
|
|
1353
1353
|
if (!existsSync3(filepath)) return null;
|
|
1354
|
-
const
|
|
1355
|
-
const size =
|
|
1356
|
-
const inode =
|
|
1354
|
+
const stat7 = statSync3(filepath);
|
|
1355
|
+
const size = stat7.size;
|
|
1356
|
+
const inode = stat7.ino;
|
|
1357
1357
|
let startOffset = 0;
|
|
1358
1358
|
let rotated = false;
|
|
1359
1359
|
let truncated = false;
|
|
@@ -2692,7 +2692,7 @@ var credsSaveQueue = Promise.resolve();
|
|
|
2692
2692
|
async function drainCredsSaveQueue(timeoutMs = 5e3) {
|
|
2693
2693
|
console.error(`${TAG3} draining credential save queue\u2026`);
|
|
2694
2694
|
const timer2 = new Promise(
|
|
2695
|
-
(
|
|
2695
|
+
(resolve24) => setTimeout(() => resolve24("timeout"), timeoutMs)
|
|
2696
2696
|
);
|
|
2697
2697
|
const result = await Promise.race([
|
|
2698
2698
|
credsSaveQueue.then(() => "drained"),
|
|
@@ -2820,11 +2820,11 @@ async function createWaSocket(opts) {
|
|
|
2820
2820
|
return sock;
|
|
2821
2821
|
}
|
|
2822
2822
|
async function waitForConnection(sock) {
|
|
2823
|
-
return new Promise((
|
|
2823
|
+
return new Promise((resolve24, reject) => {
|
|
2824
2824
|
const handler = (update) => {
|
|
2825
2825
|
if (update.connection === "open") {
|
|
2826
2826
|
sock.ev.off("connection.update", handler);
|
|
2827
|
-
|
|
2827
|
+
resolve24();
|
|
2828
2828
|
}
|
|
2829
2829
|
if (update.connection === "close") {
|
|
2830
2830
|
sock.ev.off("connection.update", handler);
|
|
@@ -2938,14 +2938,14 @@ ${inspected}`;
|
|
|
2938
2938
|
return inspect2(err, INSPECT_OPTS2);
|
|
2939
2939
|
}
|
|
2940
2940
|
function withTimeout(label, promise, timeoutMs) {
|
|
2941
|
-
return new Promise((
|
|
2941
|
+
return new Promise((resolve24, reject) => {
|
|
2942
2942
|
const timer2 = setTimeout(() => {
|
|
2943
2943
|
reject(new Error(`${label} timed out after ${timeoutMs}ms`));
|
|
2944
2944
|
}, timeoutMs);
|
|
2945
2945
|
promise.then(
|
|
2946
2946
|
(value) => {
|
|
2947
2947
|
clearTimeout(timer2);
|
|
2948
|
-
|
|
2948
|
+
resolve24(value);
|
|
2949
2949
|
},
|
|
2950
2950
|
(err) => {
|
|
2951
2951
|
clearTimeout(timer2);
|
|
@@ -4159,11 +4159,11 @@ async function connectWithReconnect(conn) {
|
|
|
4159
4159
|
console.error(
|
|
4160
4160
|
`${TAG11} reconnecting account=${conn.accountId} in ${delay}ms (attempt ${decision.nextAttempts}/${maxAttempts})`
|
|
4161
4161
|
);
|
|
4162
|
-
await new Promise((
|
|
4163
|
-
const timer2 = setTimeout(
|
|
4162
|
+
await new Promise((resolve24) => {
|
|
4163
|
+
const timer2 = setTimeout(resolve24, delay);
|
|
4164
4164
|
conn.abortController.signal.addEventListener("abort", () => {
|
|
4165
4165
|
clearTimeout(timer2);
|
|
4166
|
-
|
|
4166
|
+
resolve24();
|
|
4167
4167
|
}, { once: true });
|
|
4168
4168
|
});
|
|
4169
4169
|
}
|
|
@@ -4171,16 +4171,16 @@ async function connectWithReconnect(conn) {
|
|
|
4171
4171
|
}
|
|
4172
4172
|
}
|
|
4173
4173
|
function waitForDisconnectEvent(conn) {
|
|
4174
|
-
return new Promise((
|
|
4174
|
+
return new Promise((resolve24) => {
|
|
4175
4175
|
if (!conn.sock) {
|
|
4176
|
-
|
|
4176
|
+
resolve24();
|
|
4177
4177
|
return;
|
|
4178
4178
|
}
|
|
4179
4179
|
const sock = conn.sock;
|
|
4180
4180
|
const handler = (update) => {
|
|
4181
4181
|
if (update.connection === "close") {
|
|
4182
4182
|
sock.ev.off("connection.update", handler);
|
|
4183
|
-
|
|
4183
|
+
resolve24();
|
|
4184
4184
|
}
|
|
4185
4185
|
};
|
|
4186
4186
|
sock.ev.on("connection.update", handler);
|
|
@@ -4397,8 +4397,8 @@ async function handleInboundMessage(conn, msg) {
|
|
|
4397
4397
|
const conversationKey = isGroup ? remoteJid : senderPhone;
|
|
4398
4398
|
const debounceKey = `${conn.accountId}:${conversationKey}:${senderPhone}`;
|
|
4399
4399
|
let resolvePending;
|
|
4400
|
-
const sttPending = new Promise((
|
|
4401
|
-
resolvePending =
|
|
4400
|
+
const sttPending = new Promise((resolve24) => {
|
|
4401
|
+
resolvePending = resolve24;
|
|
4402
4402
|
});
|
|
4403
4403
|
if (conn.debouncer) conn.debouncer.registerPending(debounceKey, sttPending);
|
|
4404
4404
|
try {
|
|
@@ -4511,20 +4511,20 @@ async function probeApiKey() {
|
|
|
4511
4511
|
return result.status;
|
|
4512
4512
|
}
|
|
4513
4513
|
function checkPort(port2, timeoutMs = 500) {
|
|
4514
|
-
return new Promise((
|
|
4514
|
+
return new Promise((resolve24) => {
|
|
4515
4515
|
const socket = createConnection(port2, "127.0.0.1");
|
|
4516
4516
|
socket.setTimeout(timeoutMs);
|
|
4517
4517
|
socket.once("connect", () => {
|
|
4518
4518
|
socket.destroy();
|
|
4519
|
-
|
|
4519
|
+
resolve24(true);
|
|
4520
4520
|
});
|
|
4521
4521
|
socket.once("error", () => {
|
|
4522
4522
|
socket.destroy();
|
|
4523
|
-
|
|
4523
|
+
resolve24(false);
|
|
4524
4524
|
});
|
|
4525
4525
|
socket.once("timeout", () => {
|
|
4526
4526
|
socket.destroy();
|
|
4527
|
-
|
|
4527
|
+
resolve24(false);
|
|
4528
4528
|
});
|
|
4529
4529
|
});
|
|
4530
4530
|
}
|
|
@@ -6734,8 +6734,8 @@ async function startLogin(opts) {
|
|
|
6734
6734
|
resetActiveLogin(accountId);
|
|
6735
6735
|
let resolveQr = null;
|
|
6736
6736
|
let rejectQr = null;
|
|
6737
|
-
const qrPromise = new Promise((
|
|
6738
|
-
resolveQr =
|
|
6737
|
+
const qrPromise = new Promise((resolve24, reject) => {
|
|
6738
|
+
resolveQr = resolve24;
|
|
6739
6739
|
rejectQr = reject;
|
|
6740
6740
|
});
|
|
6741
6741
|
const qrTimer = setTimeout(
|
|
@@ -8132,7 +8132,7 @@ var app11 = new Hono();
|
|
|
8132
8132
|
app11.post("/cancel", requireAdminSession, async (c) => {
|
|
8133
8133
|
const session_key = c.var.sessionKey;
|
|
8134
8134
|
try {
|
|
8135
|
-
const { interruptClient: interruptClient2 } = await import("./client-pool-
|
|
8135
|
+
const { interruptClient: interruptClient2 } = await import("./client-pool-CX2MFW75.js");
|
|
8136
8136
|
await interruptClient2(session_key);
|
|
8137
8137
|
return c.json({ ok: true });
|
|
8138
8138
|
} catch (err) {
|
|
@@ -8843,12 +8843,6 @@ var agents_default = app16;
|
|
|
8843
8843
|
import crypto2 from "crypto";
|
|
8844
8844
|
import { resolve as resolvePath } from "path";
|
|
8845
8845
|
import { appendFileSync as appendFileSync5 } from "fs";
|
|
8846
|
-
var PERSISTENT_COMPONENT_NAMES = /* @__PURE__ */ new Set([
|
|
8847
|
-
"action-list",
|
|
8848
|
-
"document-editor",
|
|
8849
|
-
"rich-content-editor",
|
|
8850
|
-
"grid-editor"
|
|
8851
|
-
]);
|
|
8852
8846
|
function reconstructAssistantEvents(content, components, conversationId, messageId, streamLogPath) {
|
|
8853
8847
|
if (components.length === 0) {
|
|
8854
8848
|
return {
|
|
@@ -8904,7 +8898,7 @@ function reconstructAssistantEvents(content, components, conversationId, message
|
|
|
8904
8898
|
valid += 1;
|
|
8905
8899
|
const eventIndex = events.length;
|
|
8906
8900
|
events.push({ type: "component", name: c.name, data: parsedData });
|
|
8907
|
-
if (c.submitted === true
|
|
8901
|
+
if (c.submitted === true) {
|
|
8908
8902
|
submittedEventIndices.push(eventIndex);
|
|
8909
8903
|
}
|
|
8910
8904
|
}
|
|
@@ -9049,8 +9043,7 @@ app17.post("/:id/resume", requireAdminSession, async (c) => {
|
|
|
9049
9043
|
events,
|
|
9050
9044
|
createdAt: m.createdAt,
|
|
9051
9045
|
// Submitted-event indices for client `submittedComponents` seed —
|
|
9052
|
-
//
|
|
9053
|
-
// from the wire payload to keep the response slim.
|
|
9046
|
+
// omitted from the wire payload when empty to keep the response slim.
|
|
9054
9047
|
...submittedEventIndices.length > 0 ? { submittedEventIndices } : {}
|
|
9055
9048
|
};
|
|
9056
9049
|
});
|
|
@@ -9704,8 +9697,8 @@ function resolveDataPath(raw) {
|
|
|
9704
9697
|
if (resolvedReal !== dataRootReal && !resolvedReal.startsWith(dataRootReal + sep)) {
|
|
9705
9698
|
return { ok: false, status: 403, error: "Path escapes DATA_ROOT", resolved: resolvedReal };
|
|
9706
9699
|
}
|
|
9707
|
-
const
|
|
9708
|
-
return { ok: true, absolute: resolvedReal, dataRootReal, relative:
|
|
9700
|
+
const relPath2 = relative(dataRootReal, resolvedReal) || ".";
|
|
9701
|
+
return { ok: true, absolute: resolvedReal, dataRootReal, relative: relPath2 };
|
|
9709
9702
|
}
|
|
9710
9703
|
|
|
9711
9704
|
// ../lib/graph-trash/src/index.ts
|
|
@@ -9939,8 +9932,8 @@ async function restoreNode(params) {
|
|
|
9939
9932
|
|
|
9940
9933
|
// app/lib/file-delete-cascade.ts
|
|
9941
9934
|
var UUID_RE2 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
9942
|
-
function parseAttachmentPath(
|
|
9943
|
-
const segments =
|
|
9935
|
+
function parseAttachmentPath(relPath2) {
|
|
9936
|
+
const segments = relPath2.split("/").filter(Boolean);
|
|
9944
9937
|
if (segments.length !== 4) return null;
|
|
9945
9938
|
if (segments[0] !== "uploads") return null;
|
|
9946
9939
|
const accountId = segments[1];
|
|
@@ -10083,9 +10076,9 @@ async function enrich(absolute, entry, accountNames) {
|
|
|
10083
10076
|
}
|
|
10084
10077
|
}
|
|
10085
10078
|
}
|
|
10086
|
-
function buildDisplayPath(
|
|
10087
|
-
if (
|
|
10088
|
-
return
|
|
10079
|
+
function buildDisplayPath(relPath2, accountNames) {
|
|
10080
|
+
if (relPath2 === "." || relPath2 === "") return [];
|
|
10081
|
+
return relPath2.split("/").filter(Boolean).map((seg) => {
|
|
10089
10082
|
const dn = UUID_RE3.test(seg) ? accountNames.get(seg) : void 0;
|
|
10090
10083
|
return dn ? { name: seg, displayName: dn } : { name: seg };
|
|
10091
10084
|
});
|
|
@@ -10105,7 +10098,7 @@ app22.get("/", requireAdminSession, async (c) => {
|
|
|
10105
10098
|
}
|
|
10106
10099
|
return c.json({ error: resolution.error }, resolution.status);
|
|
10107
10100
|
}
|
|
10108
|
-
const { absolute, relative:
|
|
10101
|
+
const { absolute, relative: relPath2 } = resolution;
|
|
10109
10102
|
try {
|
|
10110
10103
|
const info = await stat4(absolute);
|
|
10111
10104
|
if (!info.isDirectory()) {
|
|
@@ -10138,17 +10131,17 @@ app22.get("/", requireAdminSession, async (c) => {
|
|
|
10138
10131
|
const bKey = b.displayName ?? b.name;
|
|
10139
10132
|
return aKey.localeCompare(bKey);
|
|
10140
10133
|
});
|
|
10141
|
-
const displayPath = buildDisplayPath(
|
|
10142
|
-
console.error(`[data] file-list path="${
|
|
10143
|
-
return c.json({ path:
|
|
10134
|
+
const displayPath = buildDisplayPath(relPath2, accountNames);
|
|
10135
|
+
console.error(`[data] file-list path="${relPath2}" entries=${entries.length}`);
|
|
10136
|
+
return c.json({ path: relPath2, displayPath, entries });
|
|
10144
10137
|
} catch (err) {
|
|
10145
10138
|
const code = err.code;
|
|
10146
10139
|
if (code === "ENOENT") {
|
|
10147
|
-
console.error(`[data] file-list not-found path="${
|
|
10140
|
+
console.error(`[data] file-list not-found path="${relPath2}"`);
|
|
10148
10141
|
return c.json({ error: "Not found" }, 404);
|
|
10149
10142
|
}
|
|
10150
10143
|
const message = err instanceof Error ? err.message : String(err);
|
|
10151
|
-
console.error(`[data] file-list error path="${
|
|
10144
|
+
console.error(`[data] file-list error path="${relPath2}" err="${message}"`);
|
|
10152
10145
|
return c.json({ error: message }, 500);
|
|
10153
10146
|
}
|
|
10154
10147
|
});
|
|
@@ -10167,7 +10160,7 @@ app22.get("/download", requireAdminSession, async (c) => {
|
|
|
10167
10160
|
}
|
|
10168
10161
|
return c.json({ error: resolution.error }, resolution.status);
|
|
10169
10162
|
}
|
|
10170
|
-
const { absolute, relative:
|
|
10163
|
+
const { absolute, relative: relPath2 } = resolution;
|
|
10171
10164
|
try {
|
|
10172
10165
|
const info = await stat4(absolute);
|
|
10173
10166
|
if (!info.isFile()) {
|
|
@@ -10177,7 +10170,7 @@ app22.get("/download", requireAdminSession, async (c) => {
|
|
|
10177
10170
|
const mimeType = detectMimeType(absolute);
|
|
10178
10171
|
const nodeStream = createReadStream3(absolute);
|
|
10179
10172
|
const webStream = Readable2.toWeb(nodeStream);
|
|
10180
|
-
console.error(`[data] file-download path="${
|
|
10173
|
+
console.error(`[data] file-download path="${relPath2}" size=${info.size}`);
|
|
10181
10174
|
const safeQuotedName = filename.replace(/[\r\n"\\]/g, "_");
|
|
10182
10175
|
const encodedName = encodeURIComponent(filename);
|
|
10183
10176
|
return new Response(webStream, {
|
|
@@ -10192,11 +10185,11 @@ app22.get("/download", requireAdminSession, async (c) => {
|
|
|
10192
10185
|
} catch (err) {
|
|
10193
10186
|
const code = err.code;
|
|
10194
10187
|
if (code === "ENOENT") {
|
|
10195
|
-
console.error(`[data] file-download not-found path="${
|
|
10188
|
+
console.error(`[data] file-download not-found path="${relPath2}"`);
|
|
10196
10189
|
return c.json({ error: "Not found" }, 404);
|
|
10197
10190
|
}
|
|
10198
10191
|
const message = err instanceof Error ? err.message : String(err);
|
|
10199
|
-
console.error(`[data] file-download error path="${
|
|
10192
|
+
console.error(`[data] file-download error path="${relPath2}" err="${message}"`);
|
|
10200
10193
|
return c.json({ error: message }, 500);
|
|
10201
10194
|
}
|
|
10202
10195
|
});
|
|
@@ -10274,11 +10267,11 @@ app22.delete("/", requireAdminSession, async (c) => {
|
|
|
10274
10267
|
}
|
|
10275
10268
|
return c.json({ error: resolution.error }, resolution.status);
|
|
10276
10269
|
}
|
|
10277
|
-
const { absolute, relative:
|
|
10270
|
+
const { absolute, relative: relPath2 } = resolution;
|
|
10278
10271
|
const base = basename6(absolute);
|
|
10279
|
-
const segments =
|
|
10272
|
+
const segments = relPath2.split("/").filter(Boolean);
|
|
10280
10273
|
if (base === "account.json" || segments.includes(".git")) {
|
|
10281
|
-
console.error(`[data] file-delete blocked path="${
|
|
10274
|
+
console.error(`[data] file-delete blocked path="${relPath2}" reason="protected"`);
|
|
10282
10275
|
return c.json({ error: "Protected file \u2014 refusing to delete" }, 403);
|
|
10283
10276
|
}
|
|
10284
10277
|
try {
|
|
@@ -10299,29 +10292,29 @@ app22.delete("/", requireAdminSession, async (c) => {
|
|
|
10299
10292
|
} catch {
|
|
10300
10293
|
}
|
|
10301
10294
|
}
|
|
10302
|
-
console.error(`[data] file-delete path="${
|
|
10303
|
-
const parsed = parseAttachmentPath(
|
|
10295
|
+
console.error(`[data] file-delete path="${relPath2}" bytes=${info.size}`);
|
|
10296
|
+
const parsed = parseAttachmentPath(relPath2);
|
|
10304
10297
|
if (parsed) {
|
|
10305
10298
|
try {
|
|
10306
10299
|
const { nodes } = await cascadeDeleteDocument({
|
|
10307
10300
|
accountId,
|
|
10308
10301
|
attachmentId: parsed.attachmentId
|
|
10309
10302
|
});
|
|
10310
|
-
console.error(`[data] file-delete graph-cascade path="${
|
|
10303
|
+
console.error(`[data] file-delete graph-cascade path="${relPath2}" nodes=${nodes}`);
|
|
10311
10304
|
} catch (err) {
|
|
10312
10305
|
const message = err instanceof Error ? err.message : String(err);
|
|
10313
|
-
console.error(`[data] file-delete graph-cascade-failed path="${
|
|
10306
|
+
console.error(`[data] file-delete graph-cascade-failed path="${relPath2}" err="${message}"`);
|
|
10314
10307
|
}
|
|
10315
10308
|
}
|
|
10316
10309
|
return c.json({ ok: true });
|
|
10317
10310
|
} catch (err) {
|
|
10318
10311
|
const code = err.code;
|
|
10319
10312
|
if (code === "ENOENT") {
|
|
10320
|
-
console.error(`[data] file-delete not-found path="${
|
|
10313
|
+
console.error(`[data] file-delete not-found path="${relPath2}"`);
|
|
10321
10314
|
return c.json({ error: "Not found" }, 404);
|
|
10322
10315
|
}
|
|
10323
10316
|
const message = err instanceof Error ? err.message : String(err);
|
|
10324
|
-
console.error(`[data] file-delete error path="${
|
|
10317
|
+
console.error(`[data] file-delete error path="${relPath2}" err="${message}"`);
|
|
10325
10318
|
return c.json({ error: message }, 500);
|
|
10326
10319
|
}
|
|
10327
10320
|
});
|
|
@@ -11691,13 +11684,14 @@ app31.get("/", requireAdminSession, async (c) => {
|
|
|
11691
11684
|
const result = await session.run(
|
|
11692
11685
|
`MATCH (p:Project { accountId: $accountId })
|
|
11693
11686
|
WHERE NOT p:Trashed
|
|
11694
|
-
RETURN p.taskId AS id, p.name AS name, p.updatedAt AS updatedAt
|
|
11687
|
+
RETURN p.taskId AS id, elementId(p) AS elementId, p.name AS name, p.updatedAt AS updatedAt
|
|
11695
11688
|
ORDER BY p.updatedAt DESC
|
|
11696
11689
|
LIMIT $limit`,
|
|
11697
11690
|
{ accountId, limit: neo4j3.int(LIMIT) }
|
|
11698
11691
|
);
|
|
11699
11692
|
const projects = result.records.map((r) => ({
|
|
11700
11693
|
id: r.get("id"),
|
|
11694
|
+
elementId: r.get("elementId"),
|
|
11701
11695
|
name: r.get("name") ?? "",
|
|
11702
11696
|
updatedAt: r.get("updatedAt") ?? ""
|
|
11703
11697
|
}));
|
|
@@ -11717,10 +11711,12 @@ var sidebar_projects_default = app31;
|
|
|
11717
11711
|
|
|
11718
11712
|
// server/routes/admin/sidebar-artefacts.ts
|
|
11719
11713
|
import neo4j4 from "neo4j-driver";
|
|
11720
|
-
import { readFile as readFile5, readdir as readdir3 } from "fs/promises";
|
|
11721
|
-
import { resolve as resolve20 } from "path";
|
|
11714
|
+
import { readFile as readFile5, readdir as readdir3, stat as stat5 } from "fs/promises";
|
|
11715
|
+
import { resolve as resolve20, relative as relative2, isAbsolute } from "path";
|
|
11716
|
+
import { existsSync as existsSync19 } from "fs";
|
|
11722
11717
|
var LIMIT2 = 50;
|
|
11723
11718
|
var TEXT_MIME_PREFIXES = ["text/", "application/json", "application/markdown"];
|
|
11719
|
+
var ADMIN_AGENT_FILES = ["IDENTITY.md", "SOUL.md", "KNOWLEDGE.md"];
|
|
11724
11720
|
var app32 = new Hono();
|
|
11725
11721
|
app32.get("/", requireAdminSession, async (c) => {
|
|
11726
11722
|
const sessionKey = c.var.sessionKey;
|
|
@@ -11729,6 +11725,22 @@ app32.get("/", requireAdminSession, async (c) => {
|
|
|
11729
11725
|
return c.json({ error: "Account not found for session" }, 401);
|
|
11730
11726
|
}
|
|
11731
11727
|
const start = Date.now();
|
|
11728
|
+
const docs = await fetchKnowledgeDocs(accountId);
|
|
11729
|
+
if (docs === null) {
|
|
11730
|
+
return c.json({ error: "Failed to load artefacts" }, 500);
|
|
11731
|
+
}
|
|
11732
|
+
const accountDir = resolve20(ACCOUNTS_DIR, accountId);
|
|
11733
|
+
const agents = await fetchAgentTemplateRows(accountDir);
|
|
11734
|
+
const artefacts = [...docs, ...agents].sort(
|
|
11735
|
+
(a, b) => (b.updatedAt ?? "").localeCompare(a.updatedAt ?? "")
|
|
11736
|
+
).slice(0, LIMIT2);
|
|
11737
|
+
const ms = Date.now() - start;
|
|
11738
|
+
console.log(
|
|
11739
|
+
`[admin/sidebar-artefacts] account=${accountId} count=${artefacts.length} docs=${docs.length} agents=${agents.length} ms=${ms}`
|
|
11740
|
+
);
|
|
11741
|
+
return c.json({ artefacts });
|
|
11742
|
+
});
|
|
11743
|
+
async function fetchKnowledgeDocs(accountId) {
|
|
11732
11744
|
const session = getSession();
|
|
11733
11745
|
let metas = [];
|
|
11734
11746
|
try {
|
|
@@ -11749,72 +11761,337 @@ app32.get("/", requireAdminSession, async (c) => {
|
|
|
11749
11761
|
mimeType: r.get("mimeType") ?? ""
|
|
11750
11762
|
}));
|
|
11751
11763
|
} catch (err) {
|
|
11752
|
-
const ms2 = Date.now() - start;
|
|
11753
11764
|
const message = err instanceof Error ? err.message : String(err);
|
|
11754
|
-
console.error(`[admin/sidebar-artefacts] account=${accountId} error="${message}"
|
|
11765
|
+
console.error(`[admin/sidebar-artefacts] account=${accountId} error="${message}"`);
|
|
11755
11766
|
await session.close();
|
|
11756
|
-
return
|
|
11767
|
+
return null;
|
|
11757
11768
|
} finally {
|
|
11758
11769
|
await session.close();
|
|
11759
11770
|
}
|
|
11760
|
-
|
|
11761
|
-
const content = await readArtefactContent(accountId, m.attachmentId, m.mimeType);
|
|
11762
|
-
return {
|
|
11771
|
+
return Promise.all(metas.map(async (m) => {
|
|
11772
|
+
const { content, skipReason } = await readArtefactContent(accountId, m.attachmentId, m.mimeType, m.name);
|
|
11773
|
+
return {
|
|
11774
|
+
id: m.id,
|
|
11775
|
+
name: m.name,
|
|
11776
|
+
kind: "knowledge-doc",
|
|
11777
|
+
updatedAt: m.updatedAt,
|
|
11778
|
+
content,
|
|
11779
|
+
editable: skipReason === null,
|
|
11780
|
+
mimeType: m.mimeType,
|
|
11781
|
+
skipReason
|
|
11782
|
+
};
|
|
11763
11783
|
}));
|
|
11764
|
-
|
|
11765
|
-
|
|
11766
|
-
|
|
11767
|
-
|
|
11768
|
-
|
|
11769
|
-
|
|
11784
|
+
}
|
|
11785
|
+
async function readArtefactContent(accountId, attachmentId, mimeType, displayName) {
|
|
11786
|
+
if (!attachmentId) {
|
|
11787
|
+
logSkip(displayName, "null-attachmentId", mimeType);
|
|
11788
|
+
return { content: "", skipReason: "null-attachmentId" };
|
|
11789
|
+
}
|
|
11770
11790
|
const isText = TEXT_MIME_PREFIXES.some((p) => mimeType.startsWith(p));
|
|
11771
|
-
if (!isText)
|
|
11791
|
+
if (!isText) {
|
|
11792
|
+
logSkip(displayName, "non-text-mime", mimeType);
|
|
11793
|
+
return { content: "", skipReason: "non-text-mime" };
|
|
11794
|
+
}
|
|
11772
11795
|
const accountDir = resolve20(ATTACHMENTS_ROOT, accountId);
|
|
11773
11796
|
const dir = resolve20(accountDir, attachmentId);
|
|
11774
11797
|
try {
|
|
11775
11798
|
validateFilePathInAccount(dir, accountDir);
|
|
11776
11799
|
} catch {
|
|
11777
|
-
|
|
11800
|
+
logSkip(displayName, "containment-rejected", mimeType);
|
|
11801
|
+
return { content: "", skipReason: "containment-rejected" };
|
|
11778
11802
|
}
|
|
11779
11803
|
try {
|
|
11780
11804
|
const entries = await readdir3(dir);
|
|
11781
11805
|
const dataFile = entries.find((f) => !f.endsWith(".meta.json"));
|
|
11782
|
-
if (!dataFile)
|
|
11783
|
-
|
|
11806
|
+
if (!dataFile) {
|
|
11807
|
+
logSkip(displayName, "missing-on-disk", mimeType);
|
|
11808
|
+
return { content: "", skipReason: "missing-on-disk" };
|
|
11809
|
+
}
|
|
11810
|
+
return { content: await readFile5(resolve20(dir, dataFile), "utf-8"), skipReason: null };
|
|
11784
11811
|
} catch (err) {
|
|
11785
11812
|
const message = err instanceof Error ? err.message : String(err);
|
|
11786
11813
|
console.error(`[admin/sidebar-artefacts] read-failed attachmentId=${attachmentId.slice(0, 8)} error="${message}"`);
|
|
11787
|
-
|
|
11814
|
+
logSkip(displayName, "missing-on-disk", mimeType);
|
|
11815
|
+
return { content: "", skipReason: "missing-on-disk" };
|
|
11816
|
+
}
|
|
11817
|
+
}
|
|
11818
|
+
function logSkip(name, reason, mimeType) {
|
|
11819
|
+
console.log(
|
|
11820
|
+
`[admin/sidebar-artefacts] content-skipped name="${name}" reason=${reason} mimeType=${mimeType || "none"}`
|
|
11821
|
+
);
|
|
11822
|
+
}
|
|
11823
|
+
async function fetchAgentTemplateRows(accountDir) {
|
|
11824
|
+
const rows = [];
|
|
11825
|
+
for (const filename of ADMIN_AGENT_FILES) {
|
|
11826
|
+
const overridePath = resolve20(accountDir, "agents", "admin", filename);
|
|
11827
|
+
const bundledPath = resolve20(PLATFORM_ROOT, "templates", "agents", "admin", filename);
|
|
11828
|
+
const labelStem = filename.replace(/\.md$/, "");
|
|
11829
|
+
const row = await readAgentTemplateRow({
|
|
11830
|
+
id: `agent-template:admin:${filename}`,
|
|
11831
|
+
displayName: `Admin \xB7 ${labelStem}`,
|
|
11832
|
+
logName: `admin/${filename}`,
|
|
11833
|
+
overridePath,
|
|
11834
|
+
overrideRoot: accountDir,
|
|
11835
|
+
bundledPath,
|
|
11836
|
+
bundledRoot: PLATFORM_ROOT,
|
|
11837
|
+
editable: true
|
|
11838
|
+
});
|
|
11839
|
+
if (row) rows.push(row);
|
|
11840
|
+
}
|
|
11841
|
+
const overrideDir = resolve20(accountDir, "specialists", "agents");
|
|
11842
|
+
const bundledDir = resolve20(PLATFORM_ROOT, "templates", "specialists", "agents");
|
|
11843
|
+
const specialistNames = await unionSpecialistFilenames(overrideDir, bundledDir);
|
|
11844
|
+
for (const filename of specialistNames) {
|
|
11845
|
+
const overridePath = resolve20(overrideDir, filename);
|
|
11846
|
+
const bundledPath = resolve20(bundledDir, filename);
|
|
11847
|
+
const row = await readAgentTemplateRow({
|
|
11848
|
+
id: `agent-template:specialist:${filename}`,
|
|
11849
|
+
displayName: filename.replace(/\.md$/, ""),
|
|
11850
|
+
logName: `specialist/${filename}`,
|
|
11851
|
+
overridePath,
|
|
11852
|
+
overrideRoot: accountDir,
|
|
11853
|
+
bundledPath,
|
|
11854
|
+
bundledRoot: PLATFORM_ROOT,
|
|
11855
|
+
editable: false
|
|
11856
|
+
});
|
|
11857
|
+
if (row) rows.push(row);
|
|
11858
|
+
}
|
|
11859
|
+
return rows;
|
|
11860
|
+
}
|
|
11861
|
+
async function unionSpecialistFilenames(overrideDir, bundledDir) {
|
|
11862
|
+
const names = /* @__PURE__ */ new Set();
|
|
11863
|
+
for (const dir of [overrideDir, bundledDir]) {
|
|
11864
|
+
if (!existsSync19(dir)) continue;
|
|
11865
|
+
try {
|
|
11866
|
+
const entries = await readdir3(dir);
|
|
11867
|
+
for (const entry of entries) {
|
|
11868
|
+
if (entry.endsWith(".md")) names.add(entry);
|
|
11869
|
+
}
|
|
11870
|
+
} catch (err) {
|
|
11871
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
11872
|
+
console.error(`[admin/sidebar-artefacts] specialists-read-failed dir=${dir} error="${message}"`);
|
|
11873
|
+
}
|
|
11788
11874
|
}
|
|
11875
|
+
return [...names].sort();
|
|
11876
|
+
}
|
|
11877
|
+
async function readAgentTemplateRow(inp) {
|
|
11878
|
+
let chosenPath = null;
|
|
11879
|
+
if (existsSync19(inp.overridePath)) {
|
|
11880
|
+
try {
|
|
11881
|
+
validateFilePathInAccount(inp.overridePath, inp.overrideRoot);
|
|
11882
|
+
chosenPath = inp.overridePath;
|
|
11883
|
+
} catch (err) {
|
|
11884
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
11885
|
+
console.error(
|
|
11886
|
+
`[admin/sidebar-artefacts] agent-template-read-failed agent=${inp.displayName} kind=${inp.logName} error="${message}"`
|
|
11887
|
+
);
|
|
11888
|
+
return null;
|
|
11889
|
+
}
|
|
11890
|
+
} else if (existsSync19(inp.bundledPath)) {
|
|
11891
|
+
if (!isWithin(inp.bundledPath, inp.bundledRoot)) {
|
|
11892
|
+
console.error(
|
|
11893
|
+
`[admin/sidebar-artefacts] agent-template-read-failed agent=${inp.displayName} kind=${inp.logName} error="bundled path outside PLATFORM_ROOT"`
|
|
11894
|
+
);
|
|
11895
|
+
return null;
|
|
11896
|
+
}
|
|
11897
|
+
chosenPath = inp.bundledPath;
|
|
11898
|
+
}
|
|
11899
|
+
if (!chosenPath) return null;
|
|
11900
|
+
try {
|
|
11901
|
+
const [content, st] = await Promise.all([
|
|
11902
|
+
readFile5(chosenPath, "utf-8"),
|
|
11903
|
+
stat5(chosenPath)
|
|
11904
|
+
]);
|
|
11905
|
+
return {
|
|
11906
|
+
id: inp.id,
|
|
11907
|
+
name: inp.displayName,
|
|
11908
|
+
kind: "agent-template",
|
|
11909
|
+
updatedAt: st.mtime.toISOString(),
|
|
11910
|
+
content,
|
|
11911
|
+
editable: inp.editable,
|
|
11912
|
+
mimeType: "text/markdown",
|
|
11913
|
+
skipReason: null
|
|
11914
|
+
};
|
|
11915
|
+
} catch (err) {
|
|
11916
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
11917
|
+
console.error(
|
|
11918
|
+
`[admin/sidebar-artefacts] agent-template-read-failed agent=${inp.displayName} kind=${inp.logName} error="${message}"`
|
|
11919
|
+
);
|
|
11920
|
+
return null;
|
|
11921
|
+
}
|
|
11922
|
+
}
|
|
11923
|
+
function isWithin(target, root) {
|
|
11924
|
+
const rel = relative2(root, target);
|
|
11925
|
+
return !rel.startsWith("..") && !isAbsolute(rel);
|
|
11789
11926
|
}
|
|
11790
11927
|
var sidebar_artefacts_default = app32;
|
|
11791
11928
|
|
|
11792
|
-
// server/routes/admin/
|
|
11929
|
+
// server/routes/admin/sidebar-artefact-save.ts
|
|
11930
|
+
import { mkdir as mkdir4, readdir as readdir4, stat as stat6, writeFile as writeFile5 } from "fs/promises";
|
|
11931
|
+
import { resolve as resolve21 } from "path";
|
|
11932
|
+
import { existsSync as existsSync20 } from "fs";
|
|
11933
|
+
var ADMIN_AGENT_FILES2 = /* @__PURE__ */ new Set(["IDENTITY.md", "SOUL.md", "KNOWLEDGE.md"]);
|
|
11934
|
+
var UUID_RE4 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/;
|
|
11793
11935
|
var app33 = new Hono();
|
|
11794
|
-
app33.
|
|
11795
|
-
|
|
11796
|
-
|
|
11797
|
-
|
|
11798
|
-
|
|
11799
|
-
|
|
11800
|
-
|
|
11801
|
-
|
|
11802
|
-
|
|
11803
|
-
|
|
11804
|
-
|
|
11805
|
-
|
|
11806
|
-
|
|
11807
|
-
|
|
11808
|
-
|
|
11809
|
-
|
|
11810
|
-
|
|
11811
|
-
|
|
11812
|
-
|
|
11813
|
-
|
|
11814
|
-
|
|
11815
|
-
|
|
11816
|
-
|
|
11817
|
-
|
|
11936
|
+
app33.post("/", requireAdminSession, async (c) => {
|
|
11937
|
+
const sessionKey = c.var.sessionKey;
|
|
11938
|
+
const accountId = getAccountIdForSession(sessionKey);
|
|
11939
|
+
if (!accountId) return c.json({ error: "Account not found for session" }, 401);
|
|
11940
|
+
const body = await safeJson(c);
|
|
11941
|
+
if (!body || typeof body.id !== "string" || typeof body.content !== "string") {
|
|
11942
|
+
return c.json({ error: "id and content required" }, 400);
|
|
11943
|
+
}
|
|
11944
|
+
const accountDir = resolve21(ACCOUNTS_DIR, accountId);
|
|
11945
|
+
const resolved = await resolveSavePath(body.id, accountId, accountDir);
|
|
11946
|
+
if (resolved.kind === "reject") {
|
|
11947
|
+
console.error(
|
|
11948
|
+
`[admin/sidebar-artefact-save] auth-rejected reason=${resolved.reason} path=${body.id}`
|
|
11949
|
+
);
|
|
11950
|
+
return c.json({ error: resolved.reason }, resolved.status);
|
|
11951
|
+
}
|
|
11952
|
+
const start = Date.now();
|
|
11953
|
+
try {
|
|
11954
|
+
await writeFile5(resolved.path, body.content, "utf-8");
|
|
11955
|
+
} catch (err) {
|
|
11956
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
11957
|
+
console.error(
|
|
11958
|
+
`[admin/sidebar-artefact-save] write-failed path=${relPath(resolved.path, accountDir)} error="${message}"`
|
|
11959
|
+
);
|
|
11960
|
+
return c.json({ error: "Write failed" }, 500);
|
|
11961
|
+
}
|
|
11962
|
+
let updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
11963
|
+
try {
|
|
11964
|
+
const st = await stat6(resolved.path);
|
|
11965
|
+
updatedAt = st.mtime.toISOString();
|
|
11966
|
+
} catch {
|
|
11967
|
+
}
|
|
11968
|
+
const ms = Date.now() - start;
|
|
11969
|
+
console.log(
|
|
11970
|
+
`[admin/sidebar-artefact-save] account=${accountId} path=${relPath(resolved.path, accountDir)} bytes=${body.content.length} ms=${ms}`
|
|
11971
|
+
);
|
|
11972
|
+
return c.json({ updatedAt });
|
|
11973
|
+
});
|
|
11974
|
+
async function resolveSavePath(id, accountId, accountDir) {
|
|
11975
|
+
if (id.startsWith("agent-template:")) {
|
|
11976
|
+
const parts = id.split(":");
|
|
11977
|
+
if (parts.length !== 3) return { kind: "reject", status: 400, reason: "invalid-id" };
|
|
11978
|
+
const [, role, filename] = parts;
|
|
11979
|
+
if (role === "specialist") {
|
|
11980
|
+
return { kind: "reject", status: 403, reason: "specialist-write-blocked" };
|
|
11981
|
+
}
|
|
11982
|
+
if (role !== "admin" || !ADMIN_AGENT_FILES2.has(filename)) {
|
|
11983
|
+
return { kind: "reject", status: 400, reason: "invalid-id" };
|
|
11984
|
+
}
|
|
11985
|
+
const parent = resolve21(accountDir, "agents", "admin");
|
|
11986
|
+
await mkdir4(parent, { recursive: true });
|
|
11987
|
+
try {
|
|
11988
|
+
validateFilePathInAccount(parent, accountDir);
|
|
11989
|
+
} catch {
|
|
11990
|
+
return { kind: "reject", status: 400, reason: "containment-rejected" };
|
|
11991
|
+
}
|
|
11992
|
+
return { kind: "admin-template", path: resolve21(parent, filename) };
|
|
11993
|
+
}
|
|
11994
|
+
if (UUID_RE4.test(id)) {
|
|
11995
|
+
const dir = resolve21(ATTACHMENTS_ROOT, accountId, id);
|
|
11996
|
+
if (!existsSync20(dir)) {
|
|
11997
|
+
return { kind: "reject", status: 400, reason: "not-found" };
|
|
11998
|
+
}
|
|
11999
|
+
try {
|
|
12000
|
+
validateFilePathInAccount(dir, resolve21(ATTACHMENTS_ROOT, accountId));
|
|
12001
|
+
} catch {
|
|
12002
|
+
return { kind: "reject", status: 400, reason: "containment-rejected" };
|
|
12003
|
+
}
|
|
12004
|
+
const entries = await readdir4(dir);
|
|
12005
|
+
const dataFile = entries.find((f) => !f.endsWith(".meta.json"));
|
|
12006
|
+
if (!dataFile) {
|
|
12007
|
+
return { kind: "reject", status: 400, reason: "not-found" };
|
|
12008
|
+
}
|
|
12009
|
+
return { kind: "knowledge-doc", path: resolve21(dir, dataFile) };
|
|
12010
|
+
}
|
|
12011
|
+
return { kind: "reject", status: 400, reason: "invalid-id" };
|
|
12012
|
+
}
|
|
12013
|
+
function relPath(absPath, root) {
|
|
12014
|
+
return absPath.startsWith(root) ? absPath.slice(root.length + 1) : absPath;
|
|
12015
|
+
}
|
|
12016
|
+
var sidebar_artefact_save_default = app33;
|
|
12017
|
+
|
|
12018
|
+
// server/routes/admin/sidebar-artefact-content.ts
|
|
12019
|
+
import { readFile as readFile6, readdir as readdir5 } from "fs/promises";
|
|
12020
|
+
import { existsSync as existsSync21 } from "fs";
|
|
12021
|
+
import { resolve as resolve22 } from "path";
|
|
12022
|
+
var UUID_RE5 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/;
|
|
12023
|
+
var app34 = new Hono();
|
|
12024
|
+
app34.get("/", requireAdminSession, async (c) => {
|
|
12025
|
+
const sessionKey = c.var.sessionKey;
|
|
12026
|
+
const accountId = getAccountIdForSession(sessionKey);
|
|
12027
|
+
if (!accountId) return new Response("Unauthorized", { status: 401 });
|
|
12028
|
+
const id = c.req.query("id") ?? "";
|
|
12029
|
+
if (!UUID_RE5.test(id)) {
|
|
12030
|
+
console.error(`[admin/sidebar-artefact-content] not-found id=${id.slice(0, 8)}`);
|
|
12031
|
+
return new Response("Not found", { status: 404 });
|
|
12032
|
+
}
|
|
12033
|
+
const dir = resolve22(ATTACHMENTS_ROOT, accountId, id);
|
|
12034
|
+
if (!existsSync21(dir)) {
|
|
12035
|
+
console.error(`[admin/sidebar-artefact-content] not-found id=${id.slice(0, 8)}`);
|
|
12036
|
+
return new Response("Not found", { status: 404 });
|
|
12037
|
+
}
|
|
12038
|
+
let meta;
|
|
12039
|
+
try {
|
|
12040
|
+
meta = JSON.parse(await readFile6(resolve22(dir, `${id}.meta.json`), "utf-8"));
|
|
12041
|
+
} catch {
|
|
12042
|
+
console.error(`[admin/sidebar-artefact-content] not-found id=${id.slice(0, 8)}`);
|
|
12043
|
+
return new Response("Not found", { status: 404 });
|
|
12044
|
+
}
|
|
12045
|
+
const entries = await readdir5(dir);
|
|
12046
|
+
const dataFile = entries.find((f) => !f.endsWith(".meta.json"));
|
|
12047
|
+
if (!dataFile) {
|
|
12048
|
+
console.error(`[admin/sidebar-artefact-content] not-found id=${id.slice(0, 8)}`);
|
|
12049
|
+
return new Response("Not found", { status: 404 });
|
|
12050
|
+
}
|
|
12051
|
+
const start = Date.now();
|
|
12052
|
+
const buffer = await readFile6(resolve22(dir, dataFile));
|
|
12053
|
+
const ms = Date.now() - start;
|
|
12054
|
+
console.log(
|
|
12055
|
+
`[admin/sidebar-artefact-content] account=${accountId} id=${id.slice(0, 8)} mime=${meta.mimeType} bytes=${buffer.length} ms=${ms}`
|
|
12056
|
+
);
|
|
12057
|
+
return new Response(new Uint8Array(buffer), {
|
|
12058
|
+
headers: {
|
|
12059
|
+
"Content-Type": meta.mimeType,
|
|
12060
|
+
"Content-Disposition": `inline; filename="${meta.filename}"`,
|
|
12061
|
+
"Cache-Control": "private, max-age=3600"
|
|
12062
|
+
}
|
|
12063
|
+
});
|
|
12064
|
+
});
|
|
12065
|
+
var sidebar_artefact_content_default = app34;
|
|
12066
|
+
|
|
12067
|
+
// server/routes/admin/index.ts
|
|
12068
|
+
var app35 = new Hono();
|
|
12069
|
+
app35.route("/session", session_default2);
|
|
12070
|
+
app35.route("/chat", chat_default2);
|
|
12071
|
+
app35.route("/compact", compact_default);
|
|
12072
|
+
app35.route("/logs", logs_default);
|
|
12073
|
+
app35.route("/claude-info", claude_info_default);
|
|
12074
|
+
app35.route("/attachment", attachment_default);
|
|
12075
|
+
app35.route("/agents", agents_default);
|
|
12076
|
+
app35.route("/sessions", sessions_default);
|
|
12077
|
+
app35.route("/browser", browser_default);
|
|
12078
|
+
app35.route("/device-browser", device_browser_default);
|
|
12079
|
+
app35.route("/events", events_default);
|
|
12080
|
+
app35.route("/cloudflare", cloudflare_default);
|
|
12081
|
+
app35.route("/files", files_default);
|
|
12082
|
+
app35.route("/graph-search", graph_search_default);
|
|
12083
|
+
app35.route("/graph-subgraph", graph_subgraph_default);
|
|
12084
|
+
app35.route("/graph-delete", graph_delete_default);
|
|
12085
|
+
app35.route("/graph-restore", graph_restore_default);
|
|
12086
|
+
app35.route("/graph-labels-in-graph", graph_labels_in_graph_default);
|
|
12087
|
+
app35.route("/graph-default-view", graph_default_view_default);
|
|
12088
|
+
app35.route("/file-attach", file_attach_default);
|
|
12089
|
+
app35.route("/adherence", adherence_default);
|
|
12090
|
+
app35.route("/sidebar-projects", sidebar_projects_default);
|
|
12091
|
+
app35.route("/sidebar-artefacts", sidebar_artefacts_default);
|
|
12092
|
+
app35.route("/sidebar-artefact-save", sidebar_artefact_save_default);
|
|
12093
|
+
app35.route("/sidebar-artefact-content", sidebar_artefact_content_default);
|
|
12094
|
+
var admin_default = app35;
|
|
11818
12095
|
|
|
11819
12096
|
// app/lib/graph-health.ts
|
|
11820
12097
|
var HOUR_MS = 60 * 60 * 1e3;
|
|
@@ -11916,10 +12193,10 @@ function clientFrom(c) {
|
|
|
11916
12193
|
var PLATFORM_ROOT7 = process.env.MAXY_PLATFORM_ROOT || "";
|
|
11917
12194
|
var BRAND_JSON_PATH = PLATFORM_ROOT7 ? join10(PLATFORM_ROOT7, "config", "brand.json") : "";
|
|
11918
12195
|
var BRAND = { productName: "Maxy", hostname: "maxy", configDir: ".maxy", domain: "getmaxy.com" };
|
|
11919
|
-
if (BRAND_JSON_PATH && !
|
|
12196
|
+
if (BRAND_JSON_PATH && !existsSync22(BRAND_JSON_PATH)) {
|
|
11920
12197
|
console.error(`[brand] WARNING: brand.json not found at ${BRAND_JSON_PATH} \u2014 using Maxy defaults`);
|
|
11921
12198
|
}
|
|
11922
|
-
if (BRAND_JSON_PATH &&
|
|
12199
|
+
if (BRAND_JSON_PATH && existsSync22(BRAND_JSON_PATH)) {
|
|
11923
12200
|
try {
|
|
11924
12201
|
const parsed = JSON.parse(readFileSync16(BRAND_JSON_PATH, "utf-8"));
|
|
11925
12202
|
BRAND = { ...BRAND, ...parsed };
|
|
@@ -11943,7 +12220,7 @@ var brandLoginOpts = {
|
|
|
11943
12220
|
var ALIAS_DOMAINS_PATH2 = join10(homedir2(), BRAND.configDir, "alias-domains.json");
|
|
11944
12221
|
function loadAliasDomains() {
|
|
11945
12222
|
try {
|
|
11946
|
-
if (!
|
|
12223
|
+
if (!existsSync22(ALIAS_DOMAINS_PATH2)) return null;
|
|
11947
12224
|
const parsed = JSON.parse(readFileSync16(ALIAS_DOMAINS_PATH2, "utf-8"));
|
|
11948
12225
|
if (!Array.isArray(parsed)) {
|
|
11949
12226
|
console.error("[alias-domains] malformed alias-domains.json \u2014 expected array");
|
|
@@ -11968,9 +12245,9 @@ watchFile(ALIAS_DOMAINS_PATH2, { interval: 2e3 }, () => {
|
|
|
11968
12245
|
function isPublicHost(host) {
|
|
11969
12246
|
return host.startsWith("public.") || aliasDomains.has(host);
|
|
11970
12247
|
}
|
|
11971
|
-
var
|
|
11972
|
-
|
|
11973
|
-
|
|
12248
|
+
var app36 = new Hono();
|
|
12249
|
+
app36.use("*", clientIpMiddleware);
|
|
12250
|
+
app36.use("*", async (c, next) => {
|
|
11974
12251
|
await next();
|
|
11975
12252
|
c.header("X-Content-Type-Options", "nosniff");
|
|
11976
12253
|
c.header("Referrer-Policy", "strict-origin-when-cross-origin");
|
|
@@ -11993,7 +12270,7 @@ var PUBLIC_ALLOWED_PREFIXES = [
|
|
|
11993
12270
|
"/g/"
|
|
11994
12271
|
];
|
|
11995
12272
|
var PUBLIC_ALLOWED_EXACT = ["/favicon.ico"];
|
|
11996
|
-
|
|
12273
|
+
app36.use("*", async (c, next) => {
|
|
11997
12274
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
11998
12275
|
if (!isPublicHost(host)) {
|
|
11999
12276
|
await next();
|
|
@@ -12033,7 +12310,7 @@ function resolveRemoteAuthOpts() {
|
|
|
12033
12310
|
return brandLoginOpts;
|
|
12034
12311
|
}
|
|
12035
12312
|
var MAX_LOGIN_BODY = 8 * 1024;
|
|
12036
|
-
|
|
12313
|
+
app36.post("/__remote-auth/login", async (c) => {
|
|
12037
12314
|
const client = clientFrom(c);
|
|
12038
12315
|
const clientIp = client.ip || "unknown";
|
|
12039
12316
|
if (!requestIsTlsTerminated(c)) {
|
|
@@ -12077,7 +12354,7 @@ app34.post("/__remote-auth/login", async (c) => {
|
|
|
12077
12354
|
}
|
|
12078
12355
|
});
|
|
12079
12356
|
});
|
|
12080
|
-
|
|
12357
|
+
app36.get("/__remote-auth/logout", (c) => {
|
|
12081
12358
|
return new Response(null, {
|
|
12082
12359
|
status: 302,
|
|
12083
12360
|
headers: {
|
|
@@ -12087,7 +12364,7 @@ app34.get("/__remote-auth/logout", (c) => {
|
|
|
12087
12364
|
}
|
|
12088
12365
|
});
|
|
12089
12366
|
});
|
|
12090
|
-
|
|
12367
|
+
app36.post("/__remote-auth/change-password", async (c) => {
|
|
12091
12368
|
const client = clientFrom(c);
|
|
12092
12369
|
const clientIp = client.ip || "unknown";
|
|
12093
12370
|
const rateLimited = checkRateLimit(client);
|
|
@@ -12137,13 +12414,13 @@ app34.post("/__remote-auth/change-password", async (c) => {
|
|
|
12137
12414
|
return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(), mode: "change", changeError: "Failed to save password", redirect }), 200);
|
|
12138
12415
|
}
|
|
12139
12416
|
});
|
|
12140
|
-
|
|
12417
|
+
app36.get("/__remote-auth/setup", (c) => {
|
|
12141
12418
|
if (isRemoteAuthConfigured()) {
|
|
12142
12419
|
return c.redirect("/");
|
|
12143
12420
|
}
|
|
12144
12421
|
return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(), mode: "setup" }), 200);
|
|
12145
12422
|
});
|
|
12146
|
-
|
|
12423
|
+
app36.post("/__remote-auth/set-initial-password", async (c) => {
|
|
12147
12424
|
if (isRemoteAuthConfigured()) {
|
|
12148
12425
|
return c.redirect("/");
|
|
12149
12426
|
}
|
|
@@ -12179,10 +12456,10 @@ app34.post("/__remote-auth/set-initial-password", async (c) => {
|
|
|
12179
12456
|
return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(), mode: "setup", setupError: "Failed to save password. Please try again." }), 200);
|
|
12180
12457
|
}
|
|
12181
12458
|
});
|
|
12182
|
-
|
|
12459
|
+
app36.get("/api/remote-auth/status", (c) => {
|
|
12183
12460
|
return c.json({ configured: isRemoteAuthConfigured() });
|
|
12184
12461
|
});
|
|
12185
|
-
|
|
12462
|
+
app36.post("/api/remote-auth/set-password", async (c) => {
|
|
12186
12463
|
let body;
|
|
12187
12464
|
try {
|
|
12188
12465
|
body = await c.req.json();
|
|
@@ -12212,9 +12489,9 @@ app34.post("/api/remote-auth/set-password", async (c) => {
|
|
|
12212
12489
|
return c.json({ error: "Failed to save password" }, 500);
|
|
12213
12490
|
}
|
|
12214
12491
|
});
|
|
12215
|
-
|
|
12492
|
+
app36.route("/api/_client-error", client_error_default);
|
|
12216
12493
|
console.log("[client-error-route] mounted");
|
|
12217
|
-
|
|
12494
|
+
app36.use("*", async (c, next) => {
|
|
12218
12495
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
12219
12496
|
const path2 = c.req.path;
|
|
12220
12497
|
if (path2 === "/favicon.ico" || path2.startsWith("/assets/") || path2.startsWith("/brand/")) {
|
|
@@ -12247,15 +12524,15 @@ app34.use("*", async (c, next) => {
|
|
|
12247
12524
|
console.error(`[remote-auth] login required ip=${clientIp} path=${path2} ${disambig}`);
|
|
12248
12525
|
return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(), redirect: path2 }), 200);
|
|
12249
12526
|
});
|
|
12250
|
-
|
|
12251
|
-
|
|
12252
|
-
|
|
12253
|
-
|
|
12254
|
-
|
|
12255
|
-
|
|
12256
|
-
|
|
12257
|
-
|
|
12258
|
-
|
|
12527
|
+
app36.route("/api/health", health_default);
|
|
12528
|
+
app36.route("/api/session", session_default);
|
|
12529
|
+
app36.route("/api/chat", chat_default);
|
|
12530
|
+
app36.route("/api/group", group_default);
|
|
12531
|
+
app36.route("/api/access", access_default);
|
|
12532
|
+
app36.route("/api/telegram", telegram_default);
|
|
12533
|
+
app36.route("/api/whatsapp", whatsapp_default);
|
|
12534
|
+
app36.route("/api/onboarding", onboarding_default);
|
|
12535
|
+
app36.route("/api/admin", admin_default);
|
|
12259
12536
|
var SAFE_SLUG_RE = /^[a-z][a-z0-9-]{2,49}$/;
|
|
12260
12537
|
var SAFE_FILENAME_RE = /^[a-z0-9_][a-z0-9_.-]{0,99}$/i;
|
|
12261
12538
|
var IMAGE_MIME = {
|
|
@@ -12267,7 +12544,7 @@ var IMAGE_MIME = {
|
|
|
12267
12544
|
".svg": "image/svg+xml",
|
|
12268
12545
|
".ico": "image/x-icon"
|
|
12269
12546
|
};
|
|
12270
|
-
|
|
12547
|
+
app36.get("/agent-assets/:slug/:filename", (c) => {
|
|
12271
12548
|
const slug = c.req.param("slug");
|
|
12272
12549
|
const filename = c.req.param("filename");
|
|
12273
12550
|
if (!SAFE_SLUG_RE.test(slug)) {
|
|
@@ -12283,13 +12560,13 @@ app34.get("/agent-assets/:slug/:filename", (c) => {
|
|
|
12283
12560
|
console.error(`[agent-assets] no-account slug=${slug} file=${filename}`);
|
|
12284
12561
|
return c.text("Not found", 404);
|
|
12285
12562
|
}
|
|
12286
|
-
const filePath =
|
|
12287
|
-
const expectedDir =
|
|
12563
|
+
const filePath = resolve23(account.accountDir, "agents", slug, "assets", filename);
|
|
12564
|
+
const expectedDir = resolve23(account.accountDir, "agents", slug, "assets");
|
|
12288
12565
|
if (!filePath.startsWith(expectedDir + "/")) {
|
|
12289
12566
|
console.error(`[agent-assets] path-traversal-rejected slug=${slug} file=${filename}`);
|
|
12290
12567
|
return c.text("Forbidden", 403);
|
|
12291
12568
|
}
|
|
12292
|
-
if (!
|
|
12569
|
+
if (!existsSync22(filePath)) {
|
|
12293
12570
|
console.error(`[agent-assets] serve slug=${slug} file=${filename} status=404`);
|
|
12294
12571
|
return c.text("Not found", 404);
|
|
12295
12572
|
}
|
|
@@ -12302,7 +12579,7 @@ app34.get("/agent-assets/:slug/:filename", (c) => {
|
|
|
12302
12579
|
"Cache-Control": "public, max-age=3600"
|
|
12303
12580
|
});
|
|
12304
12581
|
});
|
|
12305
|
-
|
|
12582
|
+
app36.get("/generated/:filename", (c) => {
|
|
12306
12583
|
const filename = c.req.param("filename");
|
|
12307
12584
|
if (!SAFE_FILENAME_RE.test(filename) || filename.includes("..")) {
|
|
12308
12585
|
console.error(`[generated] serve file=${filename} status=403`);
|
|
@@ -12313,13 +12590,13 @@ app34.get("/generated/:filename", (c) => {
|
|
|
12313
12590
|
console.error(`[generated] serve file=${filename} status=404`);
|
|
12314
12591
|
return c.text("Not found", 404);
|
|
12315
12592
|
}
|
|
12316
|
-
const filePath =
|
|
12317
|
-
const expectedDir =
|
|
12593
|
+
const filePath = resolve23(account.accountDir, "generated", filename);
|
|
12594
|
+
const expectedDir = resolve23(account.accountDir, "generated");
|
|
12318
12595
|
if (!filePath.startsWith(expectedDir + "/")) {
|
|
12319
12596
|
console.error(`[generated] serve file=${filename} status=403`);
|
|
12320
12597
|
return c.text("Forbidden", 403);
|
|
12321
12598
|
}
|
|
12322
|
-
if (!
|
|
12599
|
+
if (!existsSync22(filePath)) {
|
|
12323
12600
|
console.error(`[generated] serve file=${filename} status=404`);
|
|
12324
12601
|
return c.text("Not found", 404);
|
|
12325
12602
|
}
|
|
@@ -12335,7 +12612,7 @@ app34.get("/generated/:filename", (c) => {
|
|
|
12335
12612
|
var htmlCache = /* @__PURE__ */ new Map();
|
|
12336
12613
|
var brandLogoPath = "/brand/maxy-monochrome.png";
|
|
12337
12614
|
var brandIconPath = "/brand/maxy-monochrome.png";
|
|
12338
|
-
if (BRAND_JSON_PATH &&
|
|
12615
|
+
if (BRAND_JSON_PATH && existsSync22(BRAND_JSON_PATH)) {
|
|
12339
12616
|
try {
|
|
12340
12617
|
const fullBrand = JSON.parse(readFileSync16(BRAND_JSON_PATH, "utf-8"));
|
|
12341
12618
|
if (fullBrand.assets?.logo) brandLogoPath = `/brand/${fullBrand.assets.logo}`;
|
|
@@ -12355,7 +12632,7 @@ function readInstalledVersion() {
|
|
|
12355
12632
|
try {
|
|
12356
12633
|
if (!PLATFORM_ROOT7) return "unknown";
|
|
12357
12634
|
const versionFile = join10(PLATFORM_ROOT7, "config", `.${BRAND.hostname}-version`);
|
|
12358
|
-
if (!
|
|
12635
|
+
if (!existsSync22(versionFile)) return "unknown";
|
|
12359
12636
|
const content = readFileSync16(versionFile, "utf-8").trim();
|
|
12360
12637
|
return content || "unknown";
|
|
12361
12638
|
} catch {
|
|
@@ -12397,7 +12674,7 @@ var clientErrorReporterScript = `<script>
|
|
|
12397
12674
|
function cachedHtml(file) {
|
|
12398
12675
|
let html = htmlCache.get(file);
|
|
12399
12676
|
if (!html) {
|
|
12400
|
-
html = readFileSync16(
|
|
12677
|
+
html = readFileSync16(resolve23(process.cwd(), "public", file), "utf-8");
|
|
12401
12678
|
const productNameEsc = escapeHtml(BRAND.productName);
|
|
12402
12679
|
html = html.replace(/<title>([^<]*)<\/title>/, (_match, inner) => `<title>${escapeHtml(inner).replace(/Maxy/g, productNameEsc)}</title>`);
|
|
12403
12680
|
html = html.replace('href="/favicon.ico"', `href="${escapeHtml(brandFaviconPath)}"`);
|
|
@@ -12416,12 +12693,12 @@ function loadBrandingCache(agentSlug) {
|
|
|
12416
12693
|
const configDir2 = join10(homedir2(), BRAND.configDir);
|
|
12417
12694
|
try {
|
|
12418
12695
|
const accountJsonPath = join10(configDir2, "account.json");
|
|
12419
|
-
if (!
|
|
12696
|
+
if (!existsSync22(accountJsonPath)) return null;
|
|
12420
12697
|
const account = JSON.parse(readFileSync16(accountJsonPath, "utf-8"));
|
|
12421
12698
|
const accountId = account.accountId;
|
|
12422
12699
|
if (!accountId) return null;
|
|
12423
12700
|
const cachePath = join10(configDir2, "branding-cache", accountId, `${agentSlug}.json`);
|
|
12424
|
-
if (!
|
|
12701
|
+
if (!existsSync22(cachePath)) return null;
|
|
12425
12702
|
return JSON.parse(readFileSync16(cachePath, "utf-8"));
|
|
12426
12703
|
} catch {
|
|
12427
12704
|
return null;
|
|
@@ -12431,7 +12708,7 @@ function resolveDefaultSlug() {
|
|
|
12431
12708
|
try {
|
|
12432
12709
|
const configDir2 = join10(homedir2(), BRAND.configDir);
|
|
12433
12710
|
const accountJsonPath = join10(configDir2, "account.json");
|
|
12434
|
-
if (!
|
|
12711
|
+
if (!existsSync22(accountJsonPath)) return null;
|
|
12435
12712
|
const account = JSON.parse(readFileSync16(accountJsonPath, "utf-8"));
|
|
12436
12713
|
return account.defaultAgent || null;
|
|
12437
12714
|
} catch {
|
|
@@ -12468,7 +12745,7 @@ function brandedPublicHtml(agentSlug) {
|
|
|
12468
12745
|
function escapeHtml(s) {
|
|
12469
12746
|
return s.replace(/&/g, "&").replace(/"/g, """).replace(/</g, "<").replace(/>/g, ">");
|
|
12470
12747
|
}
|
|
12471
|
-
|
|
12748
|
+
app36.get("/", (c) => {
|
|
12472
12749
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
12473
12750
|
if (isPublicHost(host)) {
|
|
12474
12751
|
const defaultSlug = resolveDefaultSlug();
|
|
@@ -12476,12 +12753,12 @@ app34.get("/", (c) => {
|
|
|
12476
12753
|
}
|
|
12477
12754
|
return c.html(cachedHtml("index.html"));
|
|
12478
12755
|
});
|
|
12479
|
-
|
|
12756
|
+
app36.get("/public", (c) => {
|
|
12480
12757
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
12481
12758
|
if (isPublicHost(host)) return c.text("Not found", 404);
|
|
12482
12759
|
return c.html(cachedHtml("public.html"));
|
|
12483
12760
|
});
|
|
12484
|
-
|
|
12761
|
+
app36.get("/chat", (c) => {
|
|
12485
12762
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
12486
12763
|
if (isPublicHost(host)) return c.text("Not found", 404);
|
|
12487
12764
|
return c.html(cachedHtml("public.html"));
|
|
@@ -12500,12 +12777,12 @@ async function logViewerFetch(c, next) {
|
|
|
12500
12777
|
duration_ms: Date.now() - start
|
|
12501
12778
|
});
|
|
12502
12779
|
}
|
|
12503
|
-
|
|
12504
|
-
|
|
12505
|
-
|
|
12780
|
+
app36.use("/vnc-viewer.html", logViewerFetch);
|
|
12781
|
+
app36.use("/vnc-popout.html", logViewerFetch);
|
|
12782
|
+
app36.get("/vnc-popout.html", (c) => {
|
|
12506
12783
|
let html = htmlCache.get("vnc-popout.html");
|
|
12507
12784
|
if (!html) {
|
|
12508
|
-
html = readFileSync16(
|
|
12785
|
+
html = readFileSync16(resolve23(process.cwd(), "public", "vnc-popout.html"), "utf-8");
|
|
12509
12786
|
const name = escapeHtml(BRAND.productName);
|
|
12510
12787
|
html = html.replace("<title>Browser \u2014 Maxy</title>", `<title>${name}</title>`);
|
|
12511
12788
|
html = html.replace("</head>", ` ${brandScript}
|
|
@@ -12515,7 +12792,7 @@ app34.get("/vnc-popout.html", (c) => {
|
|
|
12515
12792
|
}
|
|
12516
12793
|
return c.html(html);
|
|
12517
12794
|
});
|
|
12518
|
-
|
|
12795
|
+
app36.post("/api/vnc/client-event", async (c) => {
|
|
12519
12796
|
let body;
|
|
12520
12797
|
try {
|
|
12521
12798
|
body = await c.req.json();
|
|
@@ -12536,20 +12813,20 @@ app34.post("/api/vnc/client-event", async (c) => {
|
|
|
12536
12813
|
});
|
|
12537
12814
|
return c.json({ ok: true });
|
|
12538
12815
|
});
|
|
12539
|
-
|
|
12816
|
+
app36.get("/g/:slug", (c) => {
|
|
12540
12817
|
return c.html(brandedPublicHtml());
|
|
12541
12818
|
});
|
|
12542
|
-
|
|
12819
|
+
app36.get("/graph", (c) => {
|
|
12543
12820
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
12544
12821
|
if (isPublicHost(host)) return c.text("Not found", 404);
|
|
12545
12822
|
return c.html(cachedHtml("graph.html"));
|
|
12546
12823
|
});
|
|
12547
|
-
|
|
12824
|
+
app36.get("/data", (c) => {
|
|
12548
12825
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
12549
12826
|
if (isPublicHost(host)) return c.text("Not found", 404);
|
|
12550
12827
|
return c.html(cachedHtml("data.html"));
|
|
12551
12828
|
});
|
|
12552
|
-
|
|
12829
|
+
app36.get("/:slug", async (c, next) => {
|
|
12553
12830
|
const slug = c.req.param("slug");
|
|
12554
12831
|
if (AGENT_SLUG_PATTERN.test(`/${slug}`)) {
|
|
12555
12832
|
const branding = loadBrandingCache(slug);
|
|
@@ -12558,10 +12835,10 @@ app34.get("/:slug", async (c, next) => {
|
|
|
12558
12835
|
}
|
|
12559
12836
|
await next();
|
|
12560
12837
|
});
|
|
12561
|
-
|
|
12838
|
+
app36.use("/*", serveStatic({ root: "./public" }));
|
|
12562
12839
|
var port = parseInt(process.env.MAXY_UI_INTERNAL_PORT ?? process.env.PORT ?? "19199", 10);
|
|
12563
12840
|
var hostname = process.env.HOSTNAME ?? "127.0.0.1";
|
|
12564
|
-
var httpServer = serve({ fetch:
|
|
12841
|
+
var httpServer = serve({ fetch: app36.fetch, port, hostname });
|
|
12565
12842
|
console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
|
|
12566
12843
|
var SUBAPP_MANIFEST = [
|
|
12567
12844
|
{ prefix: "/api/health", file: "server/routes/health.ts", subapp: health_default },
|
|
@@ -12581,7 +12858,7 @@ for (const m of SUBAPP_MANIFEST) {
|
|
|
12581
12858
|
}
|
|
12582
12859
|
try {
|
|
12583
12860
|
const registered = [];
|
|
12584
|
-
for (const r of
|
|
12861
|
+
for (const r of app36.routes ?? []) {
|
|
12585
12862
|
if (typeof r.path !== "string" || r.path.includes(":") || r.path.includes("*")) continue;
|
|
12586
12863
|
if (AGENT_SLUG_PATTERN.test(r.path)) {
|
|
12587
12864
|
registered.push({ method: (r.method ?? "ALL").toUpperCase(), path: r.path });
|
|
@@ -12595,7 +12872,7 @@ try {
|
|
|
12595
12872
|
(async () => {
|
|
12596
12873
|
try {
|
|
12597
12874
|
let userId = "";
|
|
12598
|
-
if (
|
|
12875
|
+
if (existsSync22(USERS_FILE)) {
|
|
12599
12876
|
const users = JSON.parse(readFileSync16(USERS_FILE, "utf-8").trim() || "[]");
|
|
12600
12877
|
userId = users[0]?.userId ?? "";
|
|
12601
12878
|
}
|
|
@@ -12648,7 +12925,7 @@ if (bootAccountConfig?.whatsapp) {
|
|
|
12648
12925
|
}
|
|
12649
12926
|
init({
|
|
12650
12927
|
configDir: configDirForWhatsApp,
|
|
12651
|
-
platformRoot:
|
|
12928
|
+
platformRoot: resolve23(process.env.MAXY_PLATFORM_ROOT ?? join10(__dirname, "..")),
|
|
12652
12929
|
accountConfig: bootAccountConfig,
|
|
12653
12930
|
onMessage: async (msg) => {
|
|
12654
12931
|
try {
|