@rubytech/create-maxy-code 0.1.35 → 0.1.37
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/admin/PLUGIN.md +12 -0
- package/payload/platform/plugins/admin/hooks/__tests__/turn-completed-graph-write.test.sh +109 -0
- package/payload/platform/plugins/admin/hooks/turn-completed-graph-write.sh +114 -0
- package/payload/platform/plugins/admin/skills/unzip-attachment/SKILL.md +1 -1
- package/payload/platform/plugins/contacts/PLUGIN.md +11 -0
- package/payload/platform/plugins/docs/references/internals.md +10 -0
- package/payload/platform/plugins/docs/references/platform.md +11 -4
- package/payload/platform/plugins/email/PLUGIN.md +11 -0
- package/payload/platform/plugins/linkedin-import/.claude-plugin/plugin.json +1 -1
- package/payload/platform/plugins/linkedin-import/PLUGIN.md +5 -5
- package/payload/platform/plugins/linkedin-import/skills/linkedin-import/SKILL.md +3 -1
- package/payload/platform/plugins/linkedin-import/skills/linkedin-import/references/connections.md +2 -2
- package/payload/platform/plugins/memory/PLUGIN.md +11 -0
- package/payload/platform/plugins/memory/skills/conversation-archive/SKILL.md +2 -0
- package/payload/platform/plugins/memory/skills/conversation-archive-enrich/SKILL.md +2 -0
- package/payload/platform/plugins/memory/skills/document-ingest/SKILL.md +6 -4
- package/payload/platform/plugins/outlook/PLUGIN.md +11 -0
- package/payload/platform/plugins/replicate/PLUGIN.md +11 -0
- package/payload/platform/plugins/scheduling/PLUGIN.md +11 -0
- package/payload/platform/plugins/tasks/PLUGIN.md +11 -0
- package/payload/platform/plugins/telegram/PLUGIN.md +11 -0
- package/payload/platform/plugins/waitlist/PLUGIN.md +11 -0
- package/payload/platform/plugins/whatsapp/PLUGIN.md +11 -0
- package/payload/platform/plugins/workflows/PLUGIN.md +11 -0
- package/payload/platform/scripts/seed-neo4j.sh +14 -0
- package/payload/platform/scripts/verify-skill-tool-surface.sh +5 -3
- package/payload/platform/services/claude-session-manager/dist/config.d.ts +0 -5
- package/payload/platform/services/claude-session-manager/dist/config.d.ts.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/config.js +16 -6
- package/payload/platform/services/claude-session-manager/dist/config.js.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/http-server.d.ts +0 -5
- package/payload/platform/services/claude-session-manager/dist/http-server.d.ts.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/http-server.js +109 -139
- package/payload/platform/services/claude-session-manager/dist/http-server.js.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/index.js +63 -4
- package/payload/platform/services/claude-session-manager/dist/index.js.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/pty-spawner.d.ts +47 -61
- package/payload/platform/services/claude-session-manager/dist/pty-spawner.d.ts.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/pty-spawner.js +191 -131
- package/payload/platform/services/claude-session-manager/dist/pty-spawner.js.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/session-store.d.ts +43 -37
- package/payload/platform/services/claude-session-manager/dist/session-store.d.ts.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/session-store.js +72 -61
- package/payload/platform/services/claude-session-manager/dist/session-store.js.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/tool-surface.d.ts +34 -4
- package/payload/platform/services/claude-session-manager/dist/tool-surface.d.ts.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/tool-surface.js +125 -27
- package/payload/platform/services/claude-session-manager/dist/tool-surface.js.map +1 -1
- package/payload/platform/templates/agents/admin/IDENTITY.md +9 -18
- package/payload/platform/templates/specialists/agents/database-operator.md +27 -70
- package/payload/platform/templates/specialists/agents/librarian.md +55 -0
- package/payload/server/public/assets/{Checkbox-8mOR8-gV.js → Checkbox-DAki3vDW.js} +1 -1
- package/payload/server/public/assets/{admin-CK4V-B9A.js → admin-CyAZtsYZ.js} +1 -1
- package/payload/server/public/assets/{architectureDiagram-Q4EWVU46-2DgPtOot.js → architectureDiagram-Q4EWVU46-C-hla3Ip.js} +1 -1
- package/payload/server/public/assets/{blockDiagram-DXYQGD6D-BilycXVZ.js → blockDiagram-DXYQGD6D-CbzjtNs3.js} +1 -1
- package/payload/server/public/assets/{brand-1_DraUIv.css → brand-Cun0PBrA.css} +1 -1
- package/payload/server/public/assets/{c4Diagram-AHTNJAMY-CGiIFO5U.js → c4Diagram-AHTNJAMY-B87UblA0.js} +1 -1
- package/payload/server/public/assets/channel-CTNo72W7.js +1 -0
- package/payload/server/public/assets/{chunk-336JU56O-DxTg1h50.js → chunk-336JU56O-2a2pVlSg.js} +2 -2
- package/payload/server/public/assets/{chunk-426QAEUC-DkGPjs0P.js → chunk-426QAEUC-j9NOD8_a.js} +1 -1
- package/payload/server/public/assets/{chunk-4TB4RGXK-D2JaxD6r.js → chunk-4TB4RGXK-Cs872xAq.js} +1 -1
- package/payload/server/public/assets/{chunk-5FUZZQ4R-Do3pbAGo.js → chunk-5FUZZQ4R-BnDFbZ_I.js} +1 -1
- package/payload/server/public/assets/{chunk-5PVQY5BW-np5moZSl.js → chunk-5PVQY5BW-Bu5B3Hyf.js} +1 -1
- package/payload/server/public/assets/{chunk-EDXVE4YY-BUFLWwRP.js → chunk-EDXVE4YY-B96Fw4FF.js} +1 -1
- package/payload/server/public/assets/{chunk-ENJZ2VHE-BE7Gt41s.js → chunk-ENJZ2VHE-CcGrGQim.js} +1 -1
- package/payload/server/public/assets/{chunk-ICPOFSXX-gOBkROMP.js → chunk-ICPOFSXX-ZRvcI4Ai.js} +1 -1
- package/payload/server/public/assets/{chunk-OYMX7WX6-DR-BkNZa.js → chunk-OYMX7WX6-B6RI9Fbf.js} +1 -1
- package/payload/server/public/assets/{chunk-U2HBQHQK-qLp-uSVE.js → chunk-U2HBQHQK-BYGHVYyo.js} +1 -1
- package/payload/server/public/assets/{chunk-X2U36JSP-DQiKti0J.js → chunk-X2U36JSP-rwNs-gTO.js} +1 -1
- package/payload/server/public/assets/{chunk-YZCP3GAM-Cd0JhpTo.js → chunk-YZCP3GAM-jPttJRap.js} +1 -1
- package/payload/server/public/assets/{chunk-ZZ45TVLE-8u01H3Hy.js → chunk-ZZ45TVLE-DLykWOT5.js} +1 -1
- package/payload/server/public/assets/classDiagram-6PBFFD2Q-BaV5nDmT.js +1 -0
- package/payload/server/public/assets/classDiagram-v2-HSJHXN6E-DOKlCKjY.js +1 -0
- package/payload/server/public/assets/clone-sQSwlSln.js +1 -0
- package/payload/server/public/assets/{dagre-KV5264BT-BBF_zxbi.js → dagre-KV5264BT-C6wSzHX2.js} +1 -1
- package/payload/server/public/assets/{dagre-BfVsOYOv.js → dagre-jnQDnF-5.js} +1 -1
- package/payload/server/public/assets/data-DbkuXcPb.js +1 -0
- package/payload/server/public/assets/{device-url-actions-CJBD3ecO.js → device-url-actions-y1tXNDZx.js} +1 -1
- package/payload/server/public/assets/{diagram-5BDNPKRD-BFHk2a7t.js → diagram-5BDNPKRD-N3X-n90h.js} +1 -1
- package/payload/server/public/assets/{diagram-G4DWMVQ6-Be3_qYl2.js → diagram-G4DWMVQ6-vfmbzdPd.js} +1 -1
- package/payload/server/public/assets/{diagram-MMDJMWI5-B3r4XVcu.js → diagram-MMDJMWI5-BETmPx_w.js} +1 -1
- package/payload/server/public/assets/{diagram-TYMM5635-BW5EIT4D.js → diagram-TYMM5635-BSUGM4wG.js} +1 -1
- package/payload/server/public/assets/{erDiagram-SMLLAGMA-DTu4_1Kb.js → erDiagram-SMLLAGMA-CWZ9OwMb.js} +1 -1
- package/payload/server/public/assets/{flowDiagram-DWJPFMVM-CadrjLcA.js → flowDiagram-DWJPFMVM-BpQOQS1a.js} +1 -1
- package/payload/server/public/assets/{ganttDiagram-T4ZO3ILL-Cn0npD0L.js → ganttDiagram-T4ZO3ILL-Dc59igCS.js} +1 -1
- package/payload/server/public/assets/{gitGraphDiagram-UUTBAWPF-CK3gG5Qm.js → gitGraphDiagram-UUTBAWPF-D6lXg3zl.js} +1 -1
- package/payload/server/public/assets/graph-CC5_6-dg.js +1 -0
- package/payload/server/public/assets/{graph-labels-CPzF6Gbk.js → graph-labels-DFyNH0jb.js} +1 -1
- package/payload/server/public/assets/{graphlib-DFIOO59N.js → graphlib-yG7kH8Fr.js} +1 -1
- package/payload/server/public/assets/{infoDiagram-42DDH7IO-BohUsXnN.js → infoDiagram-42DDH7IO-TS9Pv8Os.js} +1 -1
- package/payload/server/public/assets/{ishikawaDiagram-UXIWVN3A-tjmA4BU8.js → ishikawaDiagram-UXIWVN3A-BJiJJTq6.js} +1 -1
- package/payload/server/public/assets/{journeyDiagram-VCZTEJTY-DzBlFESM.js → journeyDiagram-VCZTEJTY-C7PW4fmw.js} +1 -1
- package/payload/server/public/assets/{kanban-definition-6JOO6SKY-BTw9BxK8.js → kanban-definition-6JOO6SKY-BEk21ciD.js} +1 -1
- package/payload/server/public/assets/{line-BYPL6wAj.js → line-DusyVWDE.js} +1 -1
- package/payload/server/public/assets/{mermaid-parser.core-Dmu4fWCS.js → mermaid-parser.core-DeeojQSb.js} +1 -1
- package/payload/server/public/assets/{mermaid.core-Z9vvieC2.js → mermaid.core-p65Lo7Sj.js} +3 -3
- package/payload/server/public/assets/{mindmap-definition-QFDTVHPH-BccAnfJ4.js → mindmap-definition-QFDTVHPH-B0jxFxdS.js} +1 -1
- package/payload/server/public/assets/{page-CBTlFm3b.js → page-BeYGnDzI.js} +1 -1
- package/payload/server/public/assets/{page-CDrsNrDO.js → page-x5khmfRx.js} +1 -1
- package/payload/server/public/assets/{pieDiagram-DEJITSTG-CZwxH1nJ.js → pieDiagram-DEJITSTG-DJ5GKYt6.js} +1 -1
- package/payload/server/public/assets/{public-MKWxjwiF.js → public-cnoUs7vq.js} +3 -3
- package/payload/server/public/assets/{quadrantDiagram-34T5L4WZ-BWT4DItX.js → quadrantDiagram-34T5L4WZ-BV7R-kwV.js} +1 -1
- package/payload/server/public/assets/{requirementDiagram-MS252O5E-CHYkWUEy.js → requirementDiagram-MS252O5E-DRiLzlGN.js} +1 -1
- package/payload/server/public/assets/{sankeyDiagram-XADWPNL6-km7p45Ng.js → sankeyDiagram-XADWPNL6-C5-6_cCI.js} +1 -1
- package/payload/server/public/assets/{sequenceDiagram-FGHM5R23-BT1C0Dw-.js → sequenceDiagram-FGHM5R23-5FXm_VYM.js} +1 -1
- package/payload/server/public/assets/{stateDiagram-FHFEXIEX-hibC19DY.js → stateDiagram-FHFEXIEX-FCQTaGqV.js} +1 -1
- package/payload/server/public/assets/stateDiagram-v2-QKLJ7IA2-BdpPhdqg.js +1 -0
- package/payload/server/public/assets/{timeline-definition-GMOUNBTQ-Cnm86NfE.js → timeline-definition-GMOUNBTQ-tvtq62ef.js} +1 -1
- package/payload/server/public/assets/{vennDiagram-DHZGUBPP-ByjQPLzS.js → vennDiagram-DHZGUBPP-Dk-k7CE4.js} +1 -1
- package/payload/server/public/assets/{wardleyDiagram-NUSXRM2D-CMVrWw7l.js → wardleyDiagram-NUSXRM2D-CZSrqniY.js} +1 -1
- package/payload/server/public/assets/{xychartDiagram-5P7HB3ND-Mpc1u3FV.js → xychartDiagram-5P7HB3ND-CpGLpk7Q.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 +128 -106
- package/payload/server/public/assets/channel-DYpIZW3Q.js +0 -1
- package/payload/server/public/assets/classDiagram-6PBFFD2Q-nkfy9gg7.js +0 -1
- package/payload/server/public/assets/classDiagram-v2-HSJHXN6E-B-pMmeCC.js +0 -1
- package/payload/server/public/assets/clone-jiTzIER6.js +0 -1
- package/payload/server/public/assets/data-BIOaDoqe.js +0 -1
- package/payload/server/public/assets/graph-ClfU7t1k.js +0 -1
- package/payload/server/public/assets/stateDiagram-v2-QKLJ7IA2-MuJZxjmU.js +0 -1
- /package/payload/server/public/assets/{brand-CENN2zdq.js → brand-lj7EhWRg.js} +0 -0
package/payload/server/server.js
CHANGED
|
@@ -595,8 +595,8 @@ var serveStatic = (options = { root: "" }) => {
|
|
|
595
595
|
};
|
|
596
596
|
|
|
597
597
|
// server/index.ts
|
|
598
|
-
import { readFileSync as
|
|
599
|
-
import { resolve as
|
|
598
|
+
import { readFileSync as readFileSync20, existsSync as existsSync22, watchFile } from "fs";
|
|
599
|
+
import { resolve as resolve23, join as join12, basename as basename5 } from "path";
|
|
600
600
|
import { homedir as homedir4 } from "os";
|
|
601
601
|
|
|
602
602
|
// app/lib/agent-slug-pattern.ts
|
|
@@ -1416,7 +1416,7 @@ var credsSaveQueue = Promise.resolve();
|
|
|
1416
1416
|
async function drainCredsSaveQueue(timeoutMs = 5e3) {
|
|
1417
1417
|
console.error(`${TAG3} draining credential save queue\u2026`);
|
|
1418
1418
|
const timer2 = new Promise(
|
|
1419
|
-
(
|
|
1419
|
+
(resolve24) => setTimeout(() => resolve24("timeout"), timeoutMs)
|
|
1420
1420
|
);
|
|
1421
1421
|
const result = await Promise.race([
|
|
1422
1422
|
credsSaveQueue.then(() => "drained"),
|
|
@@ -1544,11 +1544,11 @@ async function createWaSocket(opts) {
|
|
|
1544
1544
|
return sock;
|
|
1545
1545
|
}
|
|
1546
1546
|
async function waitForConnection(sock) {
|
|
1547
|
-
return new Promise((
|
|
1547
|
+
return new Promise((resolve24, reject) => {
|
|
1548
1548
|
const handler = (update) => {
|
|
1549
1549
|
if (update.connection === "open") {
|
|
1550
1550
|
sock.ev.off("connection.update", handler);
|
|
1551
|
-
|
|
1551
|
+
resolve24();
|
|
1552
1552
|
}
|
|
1553
1553
|
if (update.connection === "close") {
|
|
1554
1554
|
sock.ev.off("connection.update", handler);
|
|
@@ -1662,14 +1662,14 @@ ${inspected}`;
|
|
|
1662
1662
|
return inspect2(err, INSPECT_OPTS2);
|
|
1663
1663
|
}
|
|
1664
1664
|
function withTimeout(label, promise, timeoutMs) {
|
|
1665
|
-
return new Promise((
|
|
1665
|
+
return new Promise((resolve24, reject) => {
|
|
1666
1666
|
const timer2 = setTimeout(() => {
|
|
1667
1667
|
reject(new Error(`${label} timed out after ${timeoutMs}ms`));
|
|
1668
1668
|
}, timeoutMs);
|
|
1669
1669
|
promise.then(
|
|
1670
1670
|
(value) => {
|
|
1671
1671
|
clearTimeout(timer2);
|
|
1672
|
-
|
|
1672
|
+
resolve24(value);
|
|
1673
1673
|
},
|
|
1674
1674
|
(err) => {
|
|
1675
1675
|
clearTimeout(timer2);
|
|
@@ -2204,8 +2204,8 @@ async function persistWhatsAppMessage(input) {
|
|
|
2204
2204
|
const { givenName, familyName } = splitName(input.pushName);
|
|
2205
2205
|
const prev = sessionWriteLocks.get(input.cacheKey);
|
|
2206
2206
|
let release;
|
|
2207
|
-
const mine = new Promise((
|
|
2208
|
-
release =
|
|
2207
|
+
const mine = new Promise((resolve24) => {
|
|
2208
|
+
release = resolve24;
|
|
2209
2209
|
});
|
|
2210
2210
|
const chained = (prev ?? Promise.resolve()).then(() => mine);
|
|
2211
2211
|
sessionWriteLocks.set(input.cacheKey, chained);
|
|
@@ -3242,11 +3242,11 @@ async function connectWithReconnect(conn) {
|
|
|
3242
3242
|
console.error(
|
|
3243
3243
|
`${TAG13} reconnecting account=${conn.accountId} in ${delay}ms (attempt ${decision.nextAttempts}/${maxAttempts})`
|
|
3244
3244
|
);
|
|
3245
|
-
await new Promise((
|
|
3246
|
-
const timer2 = setTimeout(
|
|
3245
|
+
await new Promise((resolve24) => {
|
|
3246
|
+
const timer2 = setTimeout(resolve24, delay);
|
|
3247
3247
|
conn.abortController.signal.addEventListener("abort", () => {
|
|
3248
3248
|
clearTimeout(timer2);
|
|
3249
|
-
|
|
3249
|
+
resolve24();
|
|
3250
3250
|
}, { once: true });
|
|
3251
3251
|
});
|
|
3252
3252
|
}
|
|
@@ -3254,16 +3254,16 @@ async function connectWithReconnect(conn) {
|
|
|
3254
3254
|
}
|
|
3255
3255
|
}
|
|
3256
3256
|
function waitForDisconnectEvent(conn) {
|
|
3257
|
-
return new Promise((
|
|
3257
|
+
return new Promise((resolve24) => {
|
|
3258
3258
|
if (!conn.sock) {
|
|
3259
|
-
|
|
3259
|
+
resolve24();
|
|
3260
3260
|
return;
|
|
3261
3261
|
}
|
|
3262
3262
|
const sock = conn.sock;
|
|
3263
3263
|
const handler = (update) => {
|
|
3264
3264
|
if (update.connection === "close") {
|
|
3265
3265
|
sock.ev.off("connection.update", handler);
|
|
3266
|
-
|
|
3266
|
+
resolve24();
|
|
3267
3267
|
}
|
|
3268
3268
|
};
|
|
3269
3269
|
sock.ev.on("connection.update", handler);
|
|
@@ -3525,8 +3525,8 @@ async function handleInboundMessage(conn, msg) {
|
|
|
3525
3525
|
const conversationKey = isGroup ? remoteJid : senderPhone;
|
|
3526
3526
|
const debounceKey = `${conn.accountId}:${conversationKey}:${senderPhone}`;
|
|
3527
3527
|
let resolvePending;
|
|
3528
|
-
const sttPending = new Promise((
|
|
3529
|
-
resolvePending =
|
|
3528
|
+
const sttPending = new Promise((resolve24) => {
|
|
3529
|
+
resolvePending = resolve24;
|
|
3530
3530
|
});
|
|
3531
3531
|
if (conn.debouncer) conn.debouncer.registerPending(debounceKey, sttPending);
|
|
3532
3532
|
try {
|
|
@@ -3930,20 +3930,20 @@ function buildX11Env(chromiumWrapperPath, transport = "vnc") {
|
|
|
3930
3930
|
|
|
3931
3931
|
// server/routes/health.ts
|
|
3932
3932
|
function checkPort(port2, timeoutMs = 500) {
|
|
3933
|
-
return new Promise((
|
|
3933
|
+
return new Promise((resolve24) => {
|
|
3934
3934
|
const socket = createConnection2(port2, "127.0.0.1");
|
|
3935
3935
|
socket.setTimeout(timeoutMs);
|
|
3936
3936
|
socket.once("connect", () => {
|
|
3937
3937
|
socket.destroy();
|
|
3938
|
-
|
|
3938
|
+
resolve24(true);
|
|
3939
3939
|
});
|
|
3940
3940
|
socket.once("error", () => {
|
|
3941
3941
|
socket.destroy();
|
|
3942
|
-
|
|
3942
|
+
resolve24(false);
|
|
3943
3943
|
});
|
|
3944
3944
|
socket.once("timeout", () => {
|
|
3945
3945
|
socket.destroy();
|
|
3946
|
-
|
|
3946
|
+
resolve24(false);
|
|
3947
3947
|
});
|
|
3948
3948
|
});
|
|
3949
3949
|
}
|
|
@@ -5019,12 +5019,12 @@ async function dispatchOnce(input) {
|
|
|
5019
5019
|
});
|
|
5020
5020
|
if (!entry) return { error: "spawn-failed" };
|
|
5021
5021
|
entry.lastInboundAt = Date.now();
|
|
5022
|
-
let
|
|
5022
|
+
let resolve24;
|
|
5023
5023
|
const turnPromise = new Promise((r) => {
|
|
5024
|
-
|
|
5024
|
+
resolve24 = r;
|
|
5025
5025
|
});
|
|
5026
5026
|
const listener = (text) => {
|
|
5027
|
-
|
|
5027
|
+
resolve24(text);
|
|
5028
5028
|
};
|
|
5029
5029
|
entry.subscribers.add(listener);
|
|
5030
5030
|
const writeOk = await writeInput(entry, input.text);
|
|
@@ -5387,8 +5387,8 @@ async function startLogin(opts) {
|
|
|
5387
5387
|
resetActiveLogin(accountId);
|
|
5388
5388
|
let resolveQr = null;
|
|
5389
5389
|
let rejectQr = null;
|
|
5390
|
-
const qrPromise = new Promise((
|
|
5391
|
-
resolveQr =
|
|
5390
|
+
const qrPromise = new Promise((resolve24, reject) => {
|
|
5391
|
+
resolveQr = resolve24;
|
|
5392
5392
|
rejectQr = reject;
|
|
5393
5393
|
});
|
|
5394
5394
|
const qrTimer = setTimeout(
|
|
@@ -7957,6 +7957,23 @@ function computeDormantPlugins(accountId) {
|
|
|
7957
7957
|
}
|
|
7958
7958
|
|
|
7959
7959
|
// server/routes/admin/claude-sessions.ts
|
|
7960
|
+
import { readFileSync as readFileSync14 } from "fs";
|
|
7961
|
+
import { resolve as resolve12 } from "path";
|
|
7962
|
+
function resolveTunnelUrl() {
|
|
7963
|
+
const platformRoot = process.env.MAXY_PLATFORM_ROOT ?? process.env.PLATFORM_ROOT ?? resolve12(process.cwd(), "..");
|
|
7964
|
+
let brand;
|
|
7965
|
+
try {
|
|
7966
|
+
brand = JSON.parse(readFileSync14(resolve12(platformRoot, "config", "brand.json"), "utf-8"));
|
|
7967
|
+
} catch {
|
|
7968
|
+
return null;
|
|
7969
|
+
}
|
|
7970
|
+
const hostname2 = typeof brand.hostname === "string" && brand.hostname ? brand.hostname : null;
|
|
7971
|
+
const configDir2 = typeof brand.configDir === "string" && brand.configDir ? brand.configDir : null;
|
|
7972
|
+
if (!hostname2 || !configDir2) return null;
|
|
7973
|
+
const state = readTunnelState(configDir2);
|
|
7974
|
+
if (!state) return null;
|
|
7975
|
+
return `https://${hostname2}.${state.domain}`;
|
|
7976
|
+
}
|
|
7960
7977
|
var TAG18 = "[claude-session-manager:wrapper]";
|
|
7961
7978
|
function managerBase2() {
|
|
7962
7979
|
const port2 = Number(process.env.CLAUDE_SESSION_MANAGER_PORT ?? "19400");
|
|
@@ -7990,6 +8007,8 @@ app15.post("/", async (c) => {
|
|
|
7990
8007
|
const dormantStart = Date.now();
|
|
7991
8008
|
const dormantPlugins = computeDormantPlugins(senderId);
|
|
7992
8009
|
console.log(`${TAG18} dormant-plugins-computed count=${Array.isArray(dormantPlugins) ? dormantPlugins.length : 0} ms=${Date.now() - dormantStart}`);
|
|
8010
|
+
const tunnelUrl = resolveTunnelUrl();
|
|
8011
|
+
console.log(`${TAG18} tunnel-url-resolved value=${tunnelUrl ?? "null"}`);
|
|
7993
8012
|
const forwardStart = Date.now();
|
|
7994
8013
|
const upstreamPayload = JSON.stringify({
|
|
7995
8014
|
senderId,
|
|
@@ -7997,7 +8016,8 @@ app15.post("/", async (c) => {
|
|
|
7997
8016
|
channel,
|
|
7998
8017
|
permissionMode,
|
|
7999
8018
|
aboutOwner,
|
|
8000
|
-
dormantPlugins
|
|
8019
|
+
dormantPlugins,
|
|
8020
|
+
tunnelUrl
|
|
8001
8021
|
});
|
|
8002
8022
|
console.log(`${TAG18} forward-spawn-start managerBase=${managerBase2()} bytes=${upstreamPayload.length}`);
|
|
8003
8023
|
const upstream = await fetch(`${managerBase2()}/spawn`, {
|
|
@@ -8058,6 +8078,7 @@ app15.post("/resume", async (c) => {
|
|
|
8058
8078
|
const channel = typeof body.channel === "string" ? body.channel : "browser";
|
|
8059
8079
|
const aboutOwner = await resolveOwnerProfileBlock(senderId, userId);
|
|
8060
8080
|
const dormantPlugins = computeDormantPlugins(senderId);
|
|
8081
|
+
const tunnelUrl = resolveTunnelUrl();
|
|
8061
8082
|
const upstream = await fetch(`${managerBase2()}/resume`, {
|
|
8062
8083
|
method: "POST",
|
|
8063
8084
|
headers: { "content-type": "application/json" },
|
|
@@ -8067,7 +8088,8 @@ app15.post("/resume", async (c) => {
|
|
|
8067
8088
|
channel,
|
|
8068
8089
|
claudeSessionId: body.claudeSessionId,
|
|
8069
8090
|
aboutOwner,
|
|
8070
|
-
dormantPlugins
|
|
8091
|
+
dormantPlugins,
|
|
8092
|
+
tunnelUrl
|
|
8071
8093
|
})
|
|
8072
8094
|
}).catch((err) => {
|
|
8073
8095
|
console.error(`${TAG18} fetch-failed op=resume message=${err instanceof Error ? err.message : String(err)}`);
|
|
@@ -8404,8 +8426,8 @@ var events_default = app19;
|
|
|
8404
8426
|
|
|
8405
8427
|
// server/routes/admin/cloudflare.ts
|
|
8406
8428
|
import { homedir as homedir3 } from "os";
|
|
8407
|
-
import { resolve as
|
|
8408
|
-
import { readFileSync as
|
|
8429
|
+
import { resolve as resolve14 } from "path";
|
|
8430
|
+
import { readFileSync as readFileSync16 } from "fs";
|
|
8409
8431
|
|
|
8410
8432
|
// app/lib/dns-label.ts
|
|
8411
8433
|
var VALID_LABEL = /^[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?$/;
|
|
@@ -8421,14 +8443,14 @@ function isValidDomain(value) {
|
|
|
8421
8443
|
}
|
|
8422
8444
|
|
|
8423
8445
|
// app/lib/alias-domains.ts
|
|
8424
|
-
import { existsSync as existsSync15, mkdirSync as mkdirSync4, readFileSync as
|
|
8446
|
+
import { existsSync as existsSync15, mkdirSync as mkdirSync4, readFileSync as readFileSync15, writeFileSync as writeFileSync8 } from "fs";
|
|
8425
8447
|
import { dirname as dirname2 } from "path";
|
|
8426
|
-
import { resolve as
|
|
8427
|
-
var ALIAS_DOMAINS_PATH =
|
|
8448
|
+
import { resolve as resolve13 } from "path";
|
|
8449
|
+
var ALIAS_DOMAINS_PATH = resolve13(MAXY_DIR, "alias-domains.json");
|
|
8428
8450
|
function readExisting() {
|
|
8429
8451
|
if (!existsSync15(ALIAS_DOMAINS_PATH)) return /* @__PURE__ */ new Set();
|
|
8430
8452
|
try {
|
|
8431
|
-
const parsed = JSON.parse(
|
|
8453
|
+
const parsed = JSON.parse(readFileSync15(ALIAS_DOMAINS_PATH, "utf-8"));
|
|
8432
8454
|
if (!Array.isArray(parsed)) return /* @__PURE__ */ new Set();
|
|
8433
8455
|
return new Set(parsed.filter((h) => typeof h === "string"));
|
|
8434
8456
|
} catch {
|
|
@@ -8695,7 +8717,7 @@ var CLOUDFLARE_SETUP_FORM_SCHEMA = {
|
|
|
8695
8717
|
|
|
8696
8718
|
// server/routes/admin/cloudflare.ts
|
|
8697
8719
|
function cloudflareStreamLogPath(accountId, correlationId) {
|
|
8698
|
-
return
|
|
8720
|
+
return resolve14(ACCOUNTS_DIR, accountId, "cloudflare-stream-logs", `${correlationId}.log`);
|
|
8699
8721
|
}
|
|
8700
8722
|
var SETUP_TIMEOUT_MS = 10 * 60 * 1e3;
|
|
8701
8723
|
var DOMAINS_TIMEOUT_MS = 40 * 1e3;
|
|
@@ -8725,10 +8747,10 @@ function readDiscoveryResults(accountId) {
|
|
|
8725
8747
|
return { tunnels: entry.tunnels, domains: entry.domains };
|
|
8726
8748
|
}
|
|
8727
8749
|
function loadBrandInfo() {
|
|
8728
|
-
const platformRoot = process.env.MAXY_PLATFORM_ROOT ??
|
|
8729
|
-
const brandPath =
|
|
8750
|
+
const platformRoot = process.env.MAXY_PLATFORM_ROOT ?? resolve14(process.cwd(), "..");
|
|
8751
|
+
const brandPath = resolve14(platformRoot, "config", "brand.json");
|
|
8730
8752
|
try {
|
|
8731
|
-
const parsed = JSON.parse(
|
|
8753
|
+
const parsed = JSON.parse(readFileSync16(brandPath, "utf-8"));
|
|
8732
8754
|
const hostname2 = typeof parsed.hostname === "string" && parsed.hostname ? parsed.hostname : "maxy";
|
|
8733
8755
|
const configDir2 = typeof parsed.configDir === "string" && parsed.configDir ? parsed.configDir : ".maxy";
|
|
8734
8756
|
return { hostname: hostname2, configDir: configDir2 };
|
|
@@ -8856,7 +8878,7 @@ app20.get("/domains", requireAdminSession, async (c) => {
|
|
|
8856
8878
|
streamLogPath = cloudflareStreamLogPath(accountId, correlationId);
|
|
8857
8879
|
log(`phase=stream-log-resolved path=${streamLogPath}`);
|
|
8858
8880
|
const brand = loadBrandInfo();
|
|
8859
|
-
const scriptPath =
|
|
8881
|
+
const scriptPath = resolve14(homedir3(), "list-cf-domains.sh");
|
|
8860
8882
|
const result = await runFormSpawn({
|
|
8861
8883
|
scriptPath,
|
|
8862
8884
|
args: [brand.hostname],
|
|
@@ -8947,7 +8969,7 @@ app20.get("/tunnels", requireAdminSession, async (c) => {
|
|
|
8947
8969
|
if (!accountId) return err("session", "No account bound to session \u2014 refresh chat.");
|
|
8948
8970
|
if (!correlationId) return err("session", "No active conversation for session \u2014 refresh chat.");
|
|
8949
8971
|
streamLogPath = cloudflareStreamLogPath(accountId, correlationId);
|
|
8950
|
-
const certPath =
|
|
8972
|
+
const certPath = resolve14(homedir3(), brand.configDir, "cloudflared", "cert.pem");
|
|
8951
8973
|
const { existsSync: existsSync23 } = await import("fs");
|
|
8952
8974
|
if (!existsSync23(certPath)) {
|
|
8953
8975
|
return err("cert", `Cloudflare origin certificate is not on disk yet (${certPath}). Complete the Cloudflare login first by submitting the form once \u2014 the OAuth flow writes cert.pem.`);
|
|
@@ -9273,17 +9295,17 @@ var cloudflare_default = app20;
|
|
|
9273
9295
|
import { createReadStream as createReadStream3 } from "fs";
|
|
9274
9296
|
import { readdir as readdir2, readFile as readFile4, stat as stat4, mkdir as mkdir3, writeFile as writeFile4, unlink as unlink2 } from "fs/promises";
|
|
9275
9297
|
import { realpathSync as realpathSync4 } from "fs";
|
|
9276
|
-
import { basename as basename4, dirname as dirname4, join as join10, resolve as
|
|
9298
|
+
import { basename as basename4, dirname as dirname4, join as join10, resolve as resolve16, sep as sep3 } from "path";
|
|
9277
9299
|
import { Readable as Readable2 } from "stream";
|
|
9278
9300
|
|
|
9279
9301
|
// app/lib/data-path.ts
|
|
9280
9302
|
import { realpathSync as realpathSync3 } from "fs";
|
|
9281
|
-
import { resolve as
|
|
9282
|
-
var PLATFORM_ROOT5 = process.env.MAXY_PLATFORM_ROOT ??
|
|
9283
|
-
var DATA_ROOT =
|
|
9303
|
+
import { resolve as resolve15, normalize, sep as sep2, relative } from "path";
|
|
9304
|
+
var PLATFORM_ROOT5 = process.env.MAXY_PLATFORM_ROOT ?? resolve15(process.cwd(), "../platform");
|
|
9305
|
+
var DATA_ROOT = resolve15(PLATFORM_ROOT5, "..", "data");
|
|
9284
9306
|
function resolveDataPath(raw) {
|
|
9285
9307
|
const cleaned = normalize("/" + (raw ?? "").replace(/\\/g, "/")).replace(/^\/+/, "");
|
|
9286
|
-
const absolute =
|
|
9308
|
+
const absolute = resolve15(DATA_ROOT, cleaned);
|
|
9287
9309
|
let dataRootReal;
|
|
9288
9310
|
try {
|
|
9289
9311
|
dataRootReal = realpathSync3(DATA_ROOT);
|
|
@@ -9641,7 +9663,7 @@ async function readMeta(absDir, baseName) {
|
|
|
9641
9663
|
}
|
|
9642
9664
|
async function readAccountNames() {
|
|
9643
9665
|
const map = /* @__PURE__ */ new Map();
|
|
9644
|
-
const accountsDir =
|
|
9666
|
+
const accountsDir = resolve16(DATA_ROOT, "accounts");
|
|
9645
9667
|
let names;
|
|
9646
9668
|
try {
|
|
9647
9669
|
names = await readdir2(accountsDir);
|
|
@@ -9650,7 +9672,7 @@ async function readAccountNames() {
|
|
|
9650
9672
|
}
|
|
9651
9673
|
for (const name of names) {
|
|
9652
9674
|
if (!UUID_RE4.test(name)) continue;
|
|
9653
|
-
const configPath2 =
|
|
9675
|
+
const configPath2 = resolve16(accountsDir, name, "account.json");
|
|
9654
9676
|
try {
|
|
9655
9677
|
const raw = await readFile4(configPath2, "utf8");
|
|
9656
9678
|
const parsed = JSON.parse(raw);
|
|
@@ -9841,8 +9863,8 @@ app21.post("/upload", requireAdminSession, async (c) => {
|
|
|
9841
9863
|
}
|
|
9842
9864
|
const safeName = basename4(file.name).replace(/[\0/\\]/g, "_");
|
|
9843
9865
|
const finalName = `${Date.now()}-${safeName}`;
|
|
9844
|
-
const destDir =
|
|
9845
|
-
const destPath =
|
|
9866
|
+
const destDir = resolve16(DATA_ROOT, "uploads", accountId);
|
|
9867
|
+
const destPath = resolve16(destDir, finalName);
|
|
9846
9868
|
try {
|
|
9847
9869
|
await mkdir3(destDir, { recursive: true });
|
|
9848
9870
|
const dataRootReal = realpathSync4(DATA_ROOT);
|
|
@@ -11561,7 +11583,7 @@ var file_attach_default = app28;
|
|
|
11561
11583
|
// server/routes/admin/sidebar-artefacts.ts
|
|
11562
11584
|
import neo4j2 from "neo4j-driver";
|
|
11563
11585
|
import { readFile as readFile5, readdir as readdir3, stat as stat5 } from "fs/promises";
|
|
11564
|
-
import { resolve as
|
|
11586
|
+
import { resolve as resolve17, relative as relative2, isAbsolute } from "path";
|
|
11565
11587
|
import { existsSync as existsSync16 } from "fs";
|
|
11566
11588
|
var LIMIT = 50;
|
|
11567
11589
|
var TEXT_MIME_PREFIXES = ["text/", "application/json", "application/markdown"];
|
|
@@ -11578,7 +11600,7 @@ app29.get("/", requireAdminSession, async (c) => {
|
|
|
11578
11600
|
if (docs === null) {
|
|
11579
11601
|
return c.json({ error: "Failed to load artefacts" }, 500);
|
|
11580
11602
|
}
|
|
11581
|
-
const accountDir =
|
|
11603
|
+
const accountDir = resolve17(ACCOUNTS_DIR, accountId);
|
|
11582
11604
|
const agents = await fetchAgentTemplateRows(accountDir);
|
|
11583
11605
|
const artefacts = [...docs, ...agents].sort(
|
|
11584
11606
|
(a, b) => (b.updatedAt ?? "").localeCompare(a.updatedAt ?? "")
|
|
@@ -11641,8 +11663,8 @@ async function readArtefactContent(accountId, attachmentId, mimeType, displayNam
|
|
|
11641
11663
|
logSkip(displayName, "non-text-mime", mimeType);
|
|
11642
11664
|
return { content: "", skipReason: "non-text-mime" };
|
|
11643
11665
|
}
|
|
11644
|
-
const accountDir =
|
|
11645
|
-
const dir =
|
|
11666
|
+
const accountDir = resolve17(ATTACHMENTS_ROOT, accountId);
|
|
11667
|
+
const dir = resolve17(accountDir, attachmentId);
|
|
11646
11668
|
try {
|
|
11647
11669
|
validateFilePathInAccount(dir, accountDir);
|
|
11648
11670
|
} catch {
|
|
@@ -11656,7 +11678,7 @@ async function readArtefactContent(accountId, attachmentId, mimeType, displayNam
|
|
|
11656
11678
|
logSkip(displayName, "missing-on-disk", mimeType);
|
|
11657
11679
|
return { content: "", skipReason: "missing-on-disk" };
|
|
11658
11680
|
}
|
|
11659
|
-
return { content: await readFile5(
|
|
11681
|
+
return { content: await readFile5(resolve17(dir, dataFile), "utf-8"), skipReason: null };
|
|
11660
11682
|
} catch (err) {
|
|
11661
11683
|
const message = err instanceof Error ? err.message : String(err);
|
|
11662
11684
|
console.error(`[admin/sidebar-artefacts] read-failed attachmentId=${attachmentId.slice(0, 8)} error="${message}"`);
|
|
@@ -11672,8 +11694,8 @@ function logSkip(name, reason, mimeType) {
|
|
|
11672
11694
|
async function fetchAgentTemplateRows(accountDir) {
|
|
11673
11695
|
const rows = [];
|
|
11674
11696
|
for (const filename of ADMIN_AGENT_FILES) {
|
|
11675
|
-
const overridePath =
|
|
11676
|
-
const bundledPath =
|
|
11697
|
+
const overridePath = resolve17(accountDir, "agents", "admin", filename);
|
|
11698
|
+
const bundledPath = resolve17(PLATFORM_ROOT, "templates", "agents", "admin", filename);
|
|
11677
11699
|
const labelStem = filename.replace(/\.md$/, "");
|
|
11678
11700
|
const row = await readAgentTemplateRow({
|
|
11679
11701
|
id: `agent-template:admin:${filename}`,
|
|
@@ -11687,12 +11709,12 @@ async function fetchAgentTemplateRows(accountDir) {
|
|
|
11687
11709
|
});
|
|
11688
11710
|
if (row) rows.push(row);
|
|
11689
11711
|
}
|
|
11690
|
-
const overrideDir =
|
|
11691
|
-
const bundledDir =
|
|
11712
|
+
const overrideDir = resolve17(accountDir, "specialists", "agents");
|
|
11713
|
+
const bundledDir = resolve17(PLATFORM_ROOT, "templates", "specialists", "agents");
|
|
11692
11714
|
const specialistNames = await unionSpecialistFilenames(overrideDir, bundledDir);
|
|
11693
11715
|
for (const filename of specialistNames) {
|
|
11694
|
-
const overridePath =
|
|
11695
|
-
const bundledPath =
|
|
11716
|
+
const overridePath = resolve17(overrideDir, filename);
|
|
11717
|
+
const bundledPath = resolve17(bundledDir, filename);
|
|
11696
11718
|
const row = await readAgentTemplateRow({
|
|
11697
11719
|
id: `agent-template:specialist:${filename}`,
|
|
11698
11720
|
displayName: filename.replace(/\.md$/, ""),
|
|
@@ -11777,7 +11799,7 @@ var sidebar_artefacts_default = app29;
|
|
|
11777
11799
|
|
|
11778
11800
|
// server/routes/admin/sidebar-artefact-save.ts
|
|
11779
11801
|
import { mkdir as mkdir4, readdir as readdir4, stat as stat6, writeFile as writeFile5 } from "fs/promises";
|
|
11780
|
-
import { resolve as
|
|
11802
|
+
import { resolve as resolve18 } from "path";
|
|
11781
11803
|
import { existsSync as existsSync17 } from "fs";
|
|
11782
11804
|
var ADMIN_AGENT_FILES2 = /* @__PURE__ */ new Set(["IDENTITY.md", "SOUL.md", "KNOWLEDGE.md"]);
|
|
11783
11805
|
var UUID_RE5 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/;
|
|
@@ -11790,7 +11812,7 @@ app30.post("/", requireAdminSession, async (c) => {
|
|
|
11790
11812
|
if (!body || typeof body.id !== "string" || typeof body.content !== "string") {
|
|
11791
11813
|
return c.json({ error: "id and content required" }, 400);
|
|
11792
11814
|
}
|
|
11793
|
-
const accountDir =
|
|
11815
|
+
const accountDir = resolve18(ACCOUNTS_DIR, accountId);
|
|
11794
11816
|
const resolved = await resolveSavePath(body.id, accountId, accountDir);
|
|
11795
11817
|
if (resolved.kind === "heal-race") {
|
|
11796
11818
|
c.header("Retry-After", "2");
|
|
@@ -11835,17 +11857,17 @@ async function resolveSavePath(id, accountId, accountDir) {
|
|
|
11835
11857
|
if (role !== "admin" || !ADMIN_AGENT_FILES2.has(filename)) {
|
|
11836
11858
|
return { kind: "reject", status: 400, reason: "invalid-id" };
|
|
11837
11859
|
}
|
|
11838
|
-
const parent =
|
|
11860
|
+
const parent = resolve18(accountDir, "agents", "admin");
|
|
11839
11861
|
await mkdir4(parent, { recursive: true });
|
|
11840
11862
|
try {
|
|
11841
11863
|
validateFilePathInAccount(parent, accountDir);
|
|
11842
11864
|
} catch {
|
|
11843
11865
|
return { kind: "reject", status: 400, reason: "containment-rejected" };
|
|
11844
11866
|
}
|
|
11845
|
-
return { kind: "admin-template", path:
|
|
11867
|
+
return { kind: "admin-template", path: resolve18(parent, filename) };
|
|
11846
11868
|
}
|
|
11847
11869
|
if (UUID_RE5.test(id)) {
|
|
11848
|
-
const dir =
|
|
11870
|
+
const dir = resolve18(ATTACHMENTS_ROOT, accountId, id);
|
|
11849
11871
|
if (!existsSync17(dir)) {
|
|
11850
11872
|
const attShort = id.slice(0, 8);
|
|
11851
11873
|
if (isHealPending(accountId, id)) {
|
|
@@ -11878,7 +11900,7 @@ async function resolveSavePath(id, accountId, accountDir) {
|
|
|
11878
11900
|
}
|
|
11879
11901
|
}
|
|
11880
11902
|
try {
|
|
11881
|
-
validateFilePathInAccount(dir,
|
|
11903
|
+
validateFilePathInAccount(dir, resolve18(ATTACHMENTS_ROOT, accountId));
|
|
11882
11904
|
} catch {
|
|
11883
11905
|
return { kind: "reject", status: 400, reason: "containment-rejected" };
|
|
11884
11906
|
}
|
|
@@ -11887,7 +11909,7 @@ async function resolveSavePath(id, accountId, accountDir) {
|
|
|
11887
11909
|
if (!dataFile) {
|
|
11888
11910
|
return { kind: "reject", status: 400, reason: "not-found" };
|
|
11889
11911
|
}
|
|
11890
|
-
return { kind: "knowledge-doc", path:
|
|
11912
|
+
return { kind: "knowledge-doc", path: resolve18(dir, dataFile) };
|
|
11891
11913
|
}
|
|
11892
11914
|
return { kind: "reject", status: 400, reason: "invalid-id" };
|
|
11893
11915
|
}
|
|
@@ -11899,7 +11921,7 @@ var sidebar_artefact_save_default = app30;
|
|
|
11899
11921
|
// server/routes/admin/sidebar-artefact-content.ts
|
|
11900
11922
|
import { readFile as readFile6, readdir as readdir5 } from "fs/promises";
|
|
11901
11923
|
import { existsSync as existsSync18 } from "fs";
|
|
11902
|
-
import { resolve as
|
|
11924
|
+
import { resolve as resolve19 } from "path";
|
|
11903
11925
|
var UUID_RE6 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/;
|
|
11904
11926
|
var app31 = new Hono();
|
|
11905
11927
|
app31.get("/", requireAdminSession, async (c) => {
|
|
@@ -11911,14 +11933,14 @@ app31.get("/", requireAdminSession, async (c) => {
|
|
|
11911
11933
|
console.error(`[admin/sidebar-artefact-content] not-found id=${id.slice(0, 8)}`);
|
|
11912
11934
|
return new Response("Not found", { status: 404 });
|
|
11913
11935
|
}
|
|
11914
|
-
const dir =
|
|
11936
|
+
const dir = resolve19(ATTACHMENTS_ROOT, accountId, id);
|
|
11915
11937
|
if (!existsSync18(dir)) {
|
|
11916
11938
|
console.error(`[admin/sidebar-artefact-content] not-found id=${id.slice(0, 8)}`);
|
|
11917
11939
|
return new Response("Not found", { status: 404 });
|
|
11918
11940
|
}
|
|
11919
11941
|
let meta;
|
|
11920
11942
|
try {
|
|
11921
|
-
meta = JSON.parse(await readFile6(
|
|
11943
|
+
meta = JSON.parse(await readFile6(resolve19(dir, `${id}.meta.json`), "utf-8"));
|
|
11922
11944
|
} catch {
|
|
11923
11945
|
console.error(`[admin/sidebar-artefact-content] not-found id=${id.slice(0, 8)}`);
|
|
11924
11946
|
return new Response("Not found", { status: 404 });
|
|
@@ -11930,7 +11952,7 @@ app31.get("/", requireAdminSession, async (c) => {
|
|
|
11930
11952
|
return new Response("Not found", { status: 404 });
|
|
11931
11953
|
}
|
|
11932
11954
|
const start = Date.now();
|
|
11933
|
-
const buffer = await readFile6(
|
|
11955
|
+
const buffer = await readFile6(resolve19(dir, dataFile));
|
|
11934
11956
|
const ms = Date.now() - start;
|
|
11935
11957
|
console.log(
|
|
11936
11958
|
`[admin/sidebar-artefact-content] account=${accountId} id=${id.slice(0, 8)} mime=${meta.mimeType} bytes=${buffer.length} ms=${ms}`
|
|
@@ -11946,24 +11968,24 @@ app31.get("/", requireAdminSession, async (c) => {
|
|
|
11946
11968
|
var sidebar_artefact_content_default = app31;
|
|
11947
11969
|
|
|
11948
11970
|
// server/routes/admin/health.ts
|
|
11949
|
-
import { existsSync as existsSync19, readFileSync as
|
|
11950
|
-
import { resolve as
|
|
11951
|
-
var PLATFORM_ROOT6 = process.env.MAXY_PLATFORM_ROOT ??
|
|
11971
|
+
import { existsSync as existsSync19, readFileSync as readFileSync17 } from "fs";
|
|
11972
|
+
import { resolve as resolve20, join as join11 } from "path";
|
|
11973
|
+
var PLATFORM_ROOT6 = process.env.MAXY_PLATFORM_ROOT ?? resolve20(process.cwd(), "..");
|
|
11952
11974
|
var brandHostname = "maxy";
|
|
11953
11975
|
var brandJsonPath = join11(PLATFORM_ROOT6, "config", "brand.json");
|
|
11954
11976
|
if (existsSync19(brandJsonPath)) {
|
|
11955
11977
|
try {
|
|
11956
|
-
const brand = JSON.parse(
|
|
11978
|
+
const brand = JSON.parse(readFileSync17(brandJsonPath, "utf-8"));
|
|
11957
11979
|
if (brand.hostname) brandHostname = brand.hostname;
|
|
11958
11980
|
} catch {
|
|
11959
11981
|
}
|
|
11960
11982
|
}
|
|
11961
|
-
var VERSION_FILE =
|
|
11983
|
+
var VERSION_FILE = resolve20(PLATFORM_ROOT6, `config/.${brandHostname}-version`);
|
|
11962
11984
|
var PROCESS_STARTED_AT = (/* @__PURE__ */ new Date()).toISOString();
|
|
11963
11985
|
var PROBE_TIMEOUT_MS = 1e3;
|
|
11964
11986
|
function readVersion() {
|
|
11965
11987
|
if (!existsSync19(VERSION_FILE)) return "unknown";
|
|
11966
|
-
return
|
|
11988
|
+
return readFileSync17(VERSION_FILE, "utf-8").trim() || "unknown";
|
|
11967
11989
|
}
|
|
11968
11990
|
async function probeConversationDb() {
|
|
11969
11991
|
let session;
|
|
@@ -12045,8 +12067,8 @@ app33.route("/health-brand", health_default2);
|
|
|
12045
12067
|
var admin_default = app33;
|
|
12046
12068
|
|
|
12047
12069
|
// server/routes/sites.ts
|
|
12048
|
-
import { existsSync as existsSync20, readFileSync as
|
|
12049
|
-
import { resolve as
|
|
12070
|
+
import { existsSync as existsSync20, readFileSync as readFileSync18, realpathSync as realpathSync5, statSync as statSync7 } from "fs";
|
|
12071
|
+
import { resolve as resolve21 } from "path";
|
|
12050
12072
|
var SAFE_SEG_RE = /^[a-z0-9_][a-z0-9_.-]{0,99}$/i;
|
|
12051
12073
|
var MIME = {
|
|
12052
12074
|
".html": "text/html; charset=utf-8",
|
|
@@ -12103,8 +12125,8 @@ app34.get("/:rel{.*}", (c) => {
|
|
|
12103
12125
|
}
|
|
12104
12126
|
segments.push(seg);
|
|
12105
12127
|
}
|
|
12106
|
-
const rootDir =
|
|
12107
|
-
let filePath = segments.length === 0 ? rootDir :
|
|
12128
|
+
const rootDir = resolve21(account.accountDir, "sites");
|
|
12129
|
+
let filePath = segments.length === 0 ? rootDir : resolve21(rootDir, ...segments);
|
|
12108
12130
|
if (filePath !== rootDir && !filePath.startsWith(rootDir + "/")) {
|
|
12109
12131
|
console.error(`[sites] path-traversal-rejected path=${reqPath} reason=escape status=403`);
|
|
12110
12132
|
return c.text("Forbidden", 403);
|
|
@@ -12124,7 +12146,7 @@ app34.get("/:rel{.*}", (c) => {
|
|
|
12124
12146
|
return c.redirect(target, 301);
|
|
12125
12147
|
}
|
|
12126
12148
|
if (stat7?.isDirectory()) {
|
|
12127
|
-
filePath =
|
|
12149
|
+
filePath = resolve21(filePath, "index.html");
|
|
12128
12150
|
}
|
|
12129
12151
|
if (!filePath.startsWith(rootDir + "/")) {
|
|
12130
12152
|
console.error(`[sites] path-traversal-rejected path=${reqPath} reason=escape status=403`);
|
|
@@ -12149,7 +12171,7 @@ app34.get("/:rel{.*}", (c) => {
|
|
|
12149
12171
|
}
|
|
12150
12172
|
let body;
|
|
12151
12173
|
try {
|
|
12152
|
-
body =
|
|
12174
|
+
body = readFileSync18(realPath);
|
|
12153
12175
|
} catch (err) {
|
|
12154
12176
|
const code = err?.code;
|
|
12155
12177
|
if (code === "EISDIR") {
|
|
@@ -12295,8 +12317,8 @@ function startReaper2() {
|
|
|
12295
12317
|
|
|
12296
12318
|
// ../lib/entitlement/src/index.ts
|
|
12297
12319
|
import { createPublicKey, createHash as createHash3, verify as cryptoVerify } from "crypto";
|
|
12298
|
-
import { existsSync as existsSync21, readFileSync as
|
|
12299
|
-
import { resolve as
|
|
12320
|
+
import { existsSync as existsSync21, readFileSync as readFileSync19, statSync as statSync8 } from "fs";
|
|
12321
|
+
import { resolve as resolve22 } from "path";
|
|
12300
12322
|
|
|
12301
12323
|
// ../lib/entitlement/src/canonicalize.ts
|
|
12302
12324
|
function canonicalize(value) {
|
|
@@ -12331,7 +12353,7 @@ var PUBKEY_SHA256 = "8eee6bcb33545fd13b16d3199a5735ca5db5062834c7b49dfe4f23801d9
|
|
|
12331
12353
|
var GRACE_DAYS = 7;
|
|
12332
12354
|
var GRACE_MS = GRACE_DAYS * 24 * 60 * 60 * 1e3;
|
|
12333
12355
|
function pubkeyPath(brand) {
|
|
12334
|
-
return
|
|
12356
|
+
return resolve22(brand.platformRoot, "lib", "entitlement", "rubytech-pubkey.pem");
|
|
12335
12357
|
}
|
|
12336
12358
|
var memo = null;
|
|
12337
12359
|
function memoKey(mtimeMs, account) {
|
|
@@ -12343,7 +12365,7 @@ function resolveEntitlement(brand, account) {
|
|
|
12343
12365
|
if (brand.commercialMode !== true) {
|
|
12344
12366
|
return logResolved(implicitTrust(account), null);
|
|
12345
12367
|
}
|
|
12346
|
-
const entitlementPath =
|
|
12368
|
+
const entitlementPath = resolve22(brand.configDir, "entitlement.json");
|
|
12347
12369
|
if (!existsSync21(entitlementPath)) {
|
|
12348
12370
|
return logResolved(anonymousFallback("missing"), { reason: "missing" });
|
|
12349
12371
|
}
|
|
@@ -12359,7 +12381,7 @@ function resolveEntitlement(brand, account) {
|
|
|
12359
12381
|
function verifyAndResolve(brand, entitlementPath, account) {
|
|
12360
12382
|
let pubkeyPem;
|
|
12361
12383
|
try {
|
|
12362
|
-
pubkeyPem =
|
|
12384
|
+
pubkeyPem = readFileSync19(pubkeyPath(brand), "utf-8");
|
|
12363
12385
|
} catch (err) {
|
|
12364
12386
|
return logResolved(anonymousFallback("pubkey-missing"), {
|
|
12365
12387
|
reason: "pubkey-missing"
|
|
@@ -12373,7 +12395,7 @@ function verifyAndResolve(brand, entitlementPath, account) {
|
|
|
12373
12395
|
}
|
|
12374
12396
|
let envelope;
|
|
12375
12397
|
try {
|
|
12376
|
-
envelope = JSON.parse(
|
|
12398
|
+
envelope = JSON.parse(readFileSync19(entitlementPath, "utf-8"));
|
|
12377
12399
|
} catch {
|
|
12378
12400
|
return logResolved(anonymousFallback("malformed"), { reason: "malformed" });
|
|
12379
12401
|
}
|
|
@@ -12541,7 +12563,7 @@ if (BRAND_JSON_PATH && !existsSync22(BRAND_JSON_PATH)) {
|
|
|
12541
12563
|
}
|
|
12542
12564
|
if (BRAND_JSON_PATH && existsSync22(BRAND_JSON_PATH)) {
|
|
12543
12565
|
try {
|
|
12544
|
-
const parsed = JSON.parse(
|
|
12566
|
+
const parsed = JSON.parse(readFileSync20(BRAND_JSON_PATH, "utf-8"));
|
|
12545
12567
|
BRAND = { ...BRAND, ...parsed };
|
|
12546
12568
|
} catch (err) {
|
|
12547
12569
|
console.error(`[brand] Failed to parse brand.json: ${err.message}`);
|
|
@@ -12564,7 +12586,7 @@ var ALIAS_DOMAINS_PATH2 = join12(homedir4(), BRAND.configDir, "alias-domains.jso
|
|
|
12564
12586
|
function loadAliasDomains() {
|
|
12565
12587
|
try {
|
|
12566
12588
|
if (!existsSync22(ALIAS_DOMAINS_PATH2)) return null;
|
|
12567
|
-
const parsed = JSON.parse(
|
|
12589
|
+
const parsed = JSON.parse(readFileSync20(ALIAS_DOMAINS_PATH2, "utf-8"));
|
|
12568
12590
|
if (!Array.isArray(parsed)) {
|
|
12569
12591
|
console.error("[alias-domains] malformed alias-domains.json \u2014 expected array");
|
|
12570
12592
|
return null;
|
|
@@ -12934,8 +12956,8 @@ app35.get("/agent-assets/:slug/:filename", (c) => {
|
|
|
12934
12956
|
console.error(`[agent-assets] no-account slug=${slug} file=${filename}`);
|
|
12935
12957
|
return c.text("Not found", 404);
|
|
12936
12958
|
}
|
|
12937
|
-
const filePath =
|
|
12938
|
-
const expectedDir =
|
|
12959
|
+
const filePath = resolve23(account.accountDir, "agents", slug, "assets", filename);
|
|
12960
|
+
const expectedDir = resolve23(account.accountDir, "agents", slug, "assets");
|
|
12939
12961
|
if (!filePath.startsWith(expectedDir + "/")) {
|
|
12940
12962
|
console.error(`[agent-assets] path-traversal-rejected slug=${slug} file=${filename}`);
|
|
12941
12963
|
return c.text("Forbidden", 403);
|
|
@@ -12947,7 +12969,7 @@ app35.get("/agent-assets/:slug/:filename", (c) => {
|
|
|
12947
12969
|
const ext = "." + filename.split(".").pop()?.toLowerCase();
|
|
12948
12970
|
const contentType = IMAGE_MIME[ext] || "application/octet-stream";
|
|
12949
12971
|
console.log(`[agent-assets] serve slug=${slug} file=${filename} status=200`);
|
|
12950
|
-
const body =
|
|
12972
|
+
const body = readFileSync20(filePath);
|
|
12951
12973
|
return c.body(body, 200, {
|
|
12952
12974
|
"Content-Type": contentType,
|
|
12953
12975
|
"Cache-Control": "public, max-age=3600"
|
|
@@ -12964,8 +12986,8 @@ app35.get("/generated/:filename", (c) => {
|
|
|
12964
12986
|
console.error(`[generated] serve file=${filename} status=404`);
|
|
12965
12987
|
return c.text("Not found", 404);
|
|
12966
12988
|
}
|
|
12967
|
-
const filePath =
|
|
12968
|
-
const expectedDir =
|
|
12989
|
+
const filePath = resolve23(account.accountDir, "generated", filename);
|
|
12990
|
+
const expectedDir = resolve23(account.accountDir, "generated");
|
|
12969
12991
|
if (!filePath.startsWith(expectedDir + "/")) {
|
|
12970
12992
|
console.error(`[generated] serve file=${filename} status=403`);
|
|
12971
12993
|
return c.text("Forbidden", 403);
|
|
@@ -12977,7 +12999,7 @@ app35.get("/generated/:filename", (c) => {
|
|
|
12977
12999
|
const ext = "." + filename.split(".").pop()?.toLowerCase();
|
|
12978
13000
|
const contentType = IMAGE_MIME[ext] || "application/octet-stream";
|
|
12979
13001
|
console.log(`[generated] serve file=${filename} status=200`);
|
|
12980
|
-
const body =
|
|
13002
|
+
const body = readFileSync20(filePath);
|
|
12981
13003
|
return c.body(body, 200, {
|
|
12982
13004
|
"Content-Type": contentType,
|
|
12983
13005
|
"Cache-Control": "public, max-age=86400"
|
|
@@ -12989,7 +13011,7 @@ var brandLogoPath = "/brand/maxy-monochrome.png";
|
|
|
12989
13011
|
var brandIconPath = "/brand/maxy-monochrome.png";
|
|
12990
13012
|
if (BRAND_JSON_PATH && existsSync22(BRAND_JSON_PATH)) {
|
|
12991
13013
|
try {
|
|
12992
|
-
const fullBrand = JSON.parse(
|
|
13014
|
+
const fullBrand = JSON.parse(readFileSync20(BRAND_JSON_PATH, "utf-8"));
|
|
12993
13015
|
if (fullBrand.assets?.logo) brandLogoPath = `/brand/${fullBrand.assets.logo}`;
|
|
12994
13016
|
brandIconPath = fullBrand.assets?.icon ? `/brand/${fullBrand.assets.icon}` : brandLogoPath;
|
|
12995
13017
|
} catch {
|
|
@@ -13008,7 +13030,7 @@ function readInstalledVersion() {
|
|
|
13008
13030
|
if (!PLATFORM_ROOT7) return "unknown";
|
|
13009
13031
|
const versionFile = join12(PLATFORM_ROOT7, "config", `.${BRAND.hostname}-version`);
|
|
13010
13032
|
if (!existsSync22(versionFile)) return "unknown";
|
|
13011
|
-
const content =
|
|
13033
|
+
const content = readFileSync20(versionFile, "utf-8").trim();
|
|
13012
13034
|
return content || "unknown";
|
|
13013
13035
|
} catch {
|
|
13014
13036
|
return "unknown";
|
|
@@ -13049,7 +13071,7 @@ var clientErrorReporterScript = `<script>
|
|
|
13049
13071
|
function cachedHtml(file) {
|
|
13050
13072
|
let html = htmlCache.get(file);
|
|
13051
13073
|
if (!html) {
|
|
13052
|
-
html =
|
|
13074
|
+
html = readFileSync20(resolve23(process.cwd(), "public", file), "utf-8");
|
|
13053
13075
|
const productNameEsc = escapeHtml(BRAND.productName);
|
|
13054
13076
|
html = html.replace(/<title>([^<]*)<\/title>/, (_match, inner) => `<title>${escapeHtml(inner).replace(/Maxy/g, productNameEsc)}</title>`);
|
|
13055
13077
|
html = html.replace('href="/favicon.ico"', `href="${escapeHtml(brandFaviconPath)}"`);
|
|
@@ -13069,12 +13091,12 @@ function loadBrandingCache(agentSlug) {
|
|
|
13069
13091
|
try {
|
|
13070
13092
|
const accountJsonPath = join12(configDir2, "account.json");
|
|
13071
13093
|
if (!existsSync22(accountJsonPath)) return null;
|
|
13072
|
-
const account = JSON.parse(
|
|
13094
|
+
const account = JSON.parse(readFileSync20(accountJsonPath, "utf-8"));
|
|
13073
13095
|
const accountId = account.accountId;
|
|
13074
13096
|
if (!accountId) return null;
|
|
13075
13097
|
const cachePath = join12(configDir2, "branding-cache", accountId, `${agentSlug}.json`);
|
|
13076
13098
|
if (!existsSync22(cachePath)) return null;
|
|
13077
|
-
return JSON.parse(
|
|
13099
|
+
return JSON.parse(readFileSync20(cachePath, "utf-8"));
|
|
13078
13100
|
} catch {
|
|
13079
13101
|
return null;
|
|
13080
13102
|
}
|
|
@@ -13084,7 +13106,7 @@ function resolveDefaultSlug() {
|
|
|
13084
13106
|
const configDir2 = join12(homedir4(), BRAND.configDir);
|
|
13085
13107
|
const accountJsonPath = join12(configDir2, "account.json");
|
|
13086
13108
|
if (!existsSync22(accountJsonPath)) return null;
|
|
13087
|
-
const account = JSON.parse(
|
|
13109
|
+
const account = JSON.parse(readFileSync20(accountJsonPath, "utf-8"));
|
|
13088
13110
|
return account.defaultAgent || null;
|
|
13089
13111
|
} catch {
|
|
13090
13112
|
return null;
|
|
@@ -13157,7 +13179,7 @@ app35.use("/vnc-popout.html", logViewerFetch);
|
|
|
13157
13179
|
app35.get("/vnc-popout.html", (c) => {
|
|
13158
13180
|
let html = htmlCache.get("vnc-popout.html");
|
|
13159
13181
|
if (!html) {
|
|
13160
|
-
html =
|
|
13182
|
+
html = readFileSync20(resolve23(process.cwd(), "public", "vnc-popout.html"), "utf-8");
|
|
13161
13183
|
const name = escapeHtml(BRAND.productName);
|
|
13162
13184
|
html = html.replace("<title>Browser \u2014 Maxy</title>", `<title>${name}</title>`);
|
|
13163
13185
|
html = html.replace("</head>", ` ${brandScript}
|
|
@@ -13264,7 +13286,7 @@ try {
|
|
|
13264
13286
|
(async () => {
|
|
13265
13287
|
try {
|
|
13266
13288
|
if (!existsSync22(USERS_FILE)) return;
|
|
13267
|
-
const usersRaw =
|
|
13289
|
+
const usersRaw = readFileSync20(USERS_FILE, "utf-8").trim();
|
|
13268
13290
|
if (!usersRaw) return;
|
|
13269
13291
|
const users = JSON.parse(usersRaw);
|
|
13270
13292
|
const userId = users[0]?.userId;
|
|
@@ -13390,7 +13412,7 @@ if (bootAccountConfig?.whatsapp) {
|
|
|
13390
13412
|
}
|
|
13391
13413
|
init({
|
|
13392
13414
|
configDir: configDirForWhatsApp,
|
|
13393
|
-
platformRoot:
|
|
13415
|
+
platformRoot: resolve23(process.env.MAXY_PLATFORM_ROOT ?? join12(__dirname, "..")),
|
|
13394
13416
|
accountConfig: bootAccountConfig,
|
|
13395
13417
|
onMessage: async (msg) => {
|
|
13396
13418
|
if (process.env.WHATSAPP_PTY_BRIDGE_ENABLED === "true" && msg.text && !msg.isOwnerMirror) {
|