@rubytech/create-maxy 1.0.652 → 1.0.654
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/cloudflare/scripts/_stream-log.sh +19 -4
- package/payload/platform/plugins/cloudflare/scripts/list-cf-domains.ts +162 -63
- package/payload/platform/plugins/docs/references/platform.md +3 -1
- package/payload/platform/plugins/docs/references/plugins-guide.md +1 -1
- package/payload/platform/plugins/docs/references/troubleshooting.md +16 -0
- package/payload/server/public/assets/{admin-DQxieG3v.js → admin-CVZaji3A.js} +12 -12
- package/payload/server/public/assets/{arc-CRqJUbyK.js → arc-BMhgytDB.js} +1 -1
- package/payload/server/public/assets/architecture-YZFGNWBL-S9-oeq_x.js +1 -0
- package/payload/server/public/assets/{architectureDiagram-Q4EWVU46-DtICG195.js → architectureDiagram-Q4EWVU46-BePoi8XC.js} +1 -1
- package/payload/server/public/assets/{blockDiagram-DXYQGD6D-nw1V7I38.js → blockDiagram-DXYQGD6D-BkiwLTtq.js} +1 -1
- package/payload/server/public/assets/{c4Diagram-AHTNJAMY-C1eEC43O.js → c4Diagram-AHTNJAMY-bpjPj2Ln.js} +1 -1
- package/payload/server/public/assets/channel-D3U0_a1j.js +1 -0
- package/payload/server/public/assets/{chunk-2KRD3SAO-Bybqj-wj.js → chunk-2KRD3SAO-ZcHg_orY.js} +1 -1
- package/payload/server/public/assets/{chunk-336JU56O-Dszn2qEY.js → chunk-336JU56O-BpATJiGl.js} +2 -2
- package/payload/server/public/assets/chunk-426QAEUC-Wz6Bpsil.js +1 -0
- package/payload/server/public/assets/{chunk-4BX2VUAB-DrKtrnWH.js → chunk-4BX2VUAB-zJekz2NU.js} +1 -1
- package/payload/server/public/assets/{chunk-4TB4RGXK-CBFzVYqS.js → chunk-4TB4RGXK-CLXL19Wd.js} +1 -1
- package/payload/server/public/assets/{chunk-55IACEB6-BNsOFSNf.js → chunk-55IACEB6-CzqB8aoU.js} +1 -1
- package/payload/server/public/assets/{chunk-5FUZZQ4R-CXZykYh_.js → chunk-5FUZZQ4R-BoTfWHuW.js} +1 -1
- package/payload/server/public/assets/{chunk-5PVQY5BW-CLNppenz.js → chunk-5PVQY5BW-RhIfPCRB.js} +1 -1
- package/payload/server/public/assets/{chunk-67CJDMHE-DFyE0-n0.js → chunk-67CJDMHE-mM1sFmlz.js} +1 -1
- package/payload/server/public/assets/{chunk-7N4EOEYR-BIKZD1_4.js → chunk-7N4EOEYR-GUck0jv1.js} +1 -1
- package/payload/server/public/assets/{chunk-AA7GKIK3-D4_g24le.js → chunk-AA7GKIK3-BYhfUc1V.js} +1 -1
- package/payload/server/public/assets/{chunk-BSJP7CBP-Cd9H-V61.js → chunk-BSJP7CBP-CTsYuARh.js} +1 -1
- package/payload/server/public/assets/{chunk-CIAEETIT-CAU9PIQi.js → chunk-CIAEETIT-CGsGmUze.js} +1 -1
- package/payload/server/public/assets/{chunk-EDXVE4YY-CR1JfOwe.js → chunk-EDXVE4YY-utELKGQK.js} +1 -1
- package/payload/server/public/assets/{chunk-ENJZ2VHE-CuXW3Isg.js → chunk-ENJZ2VHE-CNHjq5xK.js} +1 -1
- package/payload/server/public/assets/{chunk-FMBD7UC4-BwGAtkIr.js → chunk-FMBD7UC4-DaRrfk3s.js} +1 -1
- package/payload/server/public/assets/{chunk-FOC6F5B3-Cn0552qP.js → chunk-FOC6F5B3-BaeLcJVt.js} +1 -1
- package/payload/server/public/assets/{chunk-ICPOFSXX-DEZT2XyQ.js → chunk-ICPOFSXX-Di63NBur.js} +2 -2
- package/payload/server/public/assets/{chunk-K5T4RW27-KwBFTzJ9.js → chunk-K5T4RW27-CTTOezMH.js} +1 -1
- package/payload/server/public/assets/{chunk-KGLVRYIC-1-3y582Z.js → chunk-KGLVRYIC-DCkohKP2.js} +1 -1
- package/payload/server/public/assets/{chunk-LIHQZDEY-DXIBsDHL.js → chunk-LIHQZDEY-osQO30uB.js} +1 -1
- package/payload/server/public/assets/{chunk-ORNJ4GCN-CRbOike7.js → chunk-ORNJ4GCN-DoLajOOe.js} +1 -1
- package/payload/server/public/assets/{chunk-OYMX7WX6-CVT9itnY.js → chunk-OYMX7WX6-BSPzqyxs.js} +1 -1
- package/payload/server/public/assets/chunk-QZHKN3VN-BAQp1OEl.js +1 -0
- package/payload/server/public/assets/{chunk-U2HBQHQK-BLgNHWFf.js → chunk-U2HBQHQK-BZnA7c4T.js} +1 -1
- package/payload/server/public/assets/{chunk-X2U36JSP-DHYLiYqc.js → chunk-X2U36JSP-DpQ2OA_c.js} +1 -1
- package/payload/server/public/assets/{chunk-XPW4576I-DBdiQ3Zy.js → chunk-XPW4576I-BccP1mlQ.js} +1 -1
- package/payload/server/public/assets/{chunk-YZCP3GAM-DXaosB5Z.js → chunk-YZCP3GAM-BAkNXu0G.js} +1 -1
- package/payload/server/public/assets/{chunk-ZZ45TVLE-B5dCmOpH.js → chunk-ZZ45TVLE-DBSm41oP.js} +1 -1
- package/payload/server/public/assets/classDiagram-6PBFFD2Q-6EGGLDD_.js +1 -0
- package/payload/server/public/assets/classDiagram-v2-HSJHXN6E-DfAV4tgE.js +1 -0
- package/payload/server/public/assets/clone-BoV8noAi.js +1 -0
- package/payload/server/public/assets/{cose-bilkent-S5V4N54A-DaHtPQvk.js → cose-bilkent-S5V4N54A-Boeb8aWs.js} +1 -1
- package/payload/server/public/assets/{dagre-KV5264BT-CAL9V_HR.js → dagre-KV5264BT-BkvWofSp.js} +1 -1
- package/payload/server/public/assets/{dagre-N8C5Xujx.js → dagre-nvPNAunb.js} +1 -1
- package/payload/server/public/assets/data-DgI19qYm.js +1 -0
- package/payload/server/public/assets/{diagram-5BDNPKRD-pzBSPqlM.js → diagram-5BDNPKRD-CMEgyt4E.js} +1 -1
- package/payload/server/public/assets/{diagram-G4DWMVQ6-DStdLqos.js → diagram-G4DWMVQ6-ChorrAF0.js} +1 -1
- package/payload/server/public/assets/{diagram-MMDJMWI5-D-SfeX-6.js → diagram-MMDJMWI5-D_iD27po.js} +1 -1
- package/payload/server/public/assets/{diagram-TYMM5635-Cdr1DQ84.js → diagram-TYMM5635-8qXI1ioG.js} +1 -1
- package/payload/server/public/assets/{erDiagram-SMLLAGMA-CIg1dDZT.js → erDiagram-SMLLAGMA-BFjtKDSB.js} +1 -1
- package/payload/server/public/assets/{file-dBmvpAuH.js → file-J1JpJF4E.js} +1 -1
- package/payload/server/public/assets/{flatten-CpKIi5d2.js → flatten-ya0TqRLc.js} +1 -1
- package/payload/server/public/assets/{flowDiagram-DWJPFMVM-CJtU1T6d.js → flowDiagram-DWJPFMVM-Bpd7IL9l.js} +1 -1
- package/payload/server/public/assets/{ganttDiagram-T4ZO3ILL-R4fuRAT1.js → ganttDiagram-T4ZO3ILL-CwOozU85.js} +1 -1
- package/payload/server/public/assets/gitGraph-7Q5UKJZL-BOC4CldZ.js +1 -0
- package/payload/server/public/assets/{gitGraphDiagram-UUTBAWPF-sifugSGn.js → gitGraphDiagram-UUTBAWPF-CcPILiC9.js} +1 -1
- package/payload/server/public/assets/{graph-3snSy3WW.js → graph-CFwxUVS0.js} +19 -19
- package/payload/server/public/assets/{graphlib-DrlxPM8j.js → graphlib-B_mcXEVr.js} +1 -1
- package/payload/server/public/assets/{house-IMEjNkQf.js → house-Dche6_m0.js} +1 -1
- package/payload/server/public/assets/info-OMHHGYJF-BSCPTUIx.js +1 -0
- package/payload/server/public/assets/infoDiagram-42DDH7IO-T2sn--WJ.js +2 -0
- package/payload/server/public/assets/{isEmpty-C3Vxk1It.js → isEmpty-h-wRi_o9.js} +1 -1
- package/payload/server/public/assets/{ishikawaDiagram-UXIWVN3A-CYUJOA2c.js → ishikawaDiagram-UXIWVN3A-DOP9-Q8H.js} +1 -1
- package/payload/server/public/assets/{journeyDiagram-VCZTEJTY-UltrLajs.js → journeyDiagram-VCZTEJTY-DGATg0WC.js} +1 -1
- package/payload/server/public/assets/{jsx-runtime-CXoJCO3U.js → jsx-runtime-BE1CBORz.js} +1 -1
- package/payload/server/public/assets/jsx-runtime-C7zbe_Pq.css +1 -0
- package/payload/server/public/assets/{kanban-definition-6JOO6SKY-BBaThtP3.js → kanban-definition-6JOO6SKY-C5PigmKg.js} +1 -1
- package/payload/server/public/assets/{line-BhOwLD_o.js → line-DlKKhwkO.js} +1 -1
- package/payload/server/public/assets/{linear-D76hoLvZ.js → linear-DD4JiB1l.js} +1 -1
- package/payload/server/public/assets/{mermaid-parser.core-D8n5xV7A.js → mermaid-parser.core-C8xGCa9p.js} +2 -2
- package/payload/server/public/assets/{mermaid.core-C3TZA9fX.js → mermaid.core-CCUSwZB_.js} +3 -3
- package/payload/server/public/assets/{mindmap-definition-QFDTVHPH-Bv1kghvk.js → mindmap-definition-QFDTVHPH-75k-IVhC.js} +1 -1
- package/payload/server/public/assets/{ordinal-BLrOss5K.js → ordinal-Dwxksj1B.js} +1 -1
- package/payload/server/public/assets/packet-4T2RLAQJ-pBa_ZhNI.js +1 -0
- package/payload/server/public/assets/pie-ZZUOXDRM-BzYOyiMb.js +1 -0
- package/payload/server/public/assets/{pieDiagram-DEJITSTG-BSYldcKa.js → pieDiagram-DEJITSTG-DN5RsDwZ.js} +1 -1
- package/payload/server/public/assets/public-LhnMTdDE.js +5 -0
- package/payload/server/public/assets/{quadrantDiagram-34T5L4WZ-lCDshgz1.js → quadrantDiagram-34T5L4WZ-Sd9x6pNe.js} +1 -1
- package/payload/server/public/assets/radar-PYXPWWZC-CTVOaAq6.js +1 -0
- package/payload/server/public/assets/{reduce-C5tBOlxC.js → reduce-BUuWaDl2.js} +1 -1
- package/payload/server/public/assets/{requirementDiagram-MS252O5E-C7j42RrO.js → requirementDiagram-MS252O5E-BDgifYzj.js} +1 -1
- package/payload/server/public/assets/{sankeyDiagram-XADWPNL6-plPbHhuF.js → sankeyDiagram-XADWPNL6-BX9VULNJ.js} +1 -1
- package/payload/server/public/assets/{sequenceDiagram-FGHM5R23-D3Y8MXiX.js → sequenceDiagram-FGHM5R23-z3vMxhgE.js} +1 -1
- package/payload/server/public/assets/{share-2-ARoCxH5K.js → share-2-6hJtFYgM.js} +1 -1
- package/payload/server/public/assets/{stateDiagram-FHFEXIEX-D4BdhMPy.js → stateDiagram-FHFEXIEX-DlP0hBxF.js} +1 -1
- package/payload/server/public/assets/stateDiagram-v2-QKLJ7IA2-DSddQStC.js +1 -0
- package/payload/server/public/assets/{timeline-definition-GMOUNBTQ-Lh9jrYCl.js → timeline-definition-GMOUNBTQ-DwQbhKCo.js} +1 -1
- package/payload/server/public/assets/treeView-SZITEDCU-OTnF4Qzw.js +1 -0
- package/payload/server/public/assets/treemap-W4RFUUIX-DlIRmHFb.js +1 -0
- package/payload/server/public/assets/{useVoiceRecorder-Cw8gxj1L.js → useVoiceRecorder-PUde6itK.js} +4 -4
- package/payload/server/public/assets/{vennDiagram-DHZGUBPP-Cx0v19iv.js → vennDiagram-DHZGUBPP-WTqmZWWa.js} +1 -1
- package/payload/server/public/assets/wardley-RL74JXVD-DwMXAC4U.js +1 -0
- package/payload/server/public/assets/{wardleyDiagram-NUSXRM2D-BYewCTre.js → wardleyDiagram-NUSXRM2D-BUY50x5T.js} +1 -1
- package/payload/server/public/assets/x-DmqRGGHj.js +1 -0
- package/payload/server/public/assets/{xychartDiagram-5P7HB3ND-CkfIdbJu.js → xychartDiagram-5P7HB3ND-Btdq-fDj.js} +1 -1
- package/payload/server/public/data.html +6 -7
- package/payload/server/public/graph.html +6 -6
- package/payload/server/public/index.html +8 -9
- package/payload/server/public/public.html +5 -6
- package/payload/server/server.js +409 -102
- package/payload/server/public/assets/architecture-YZFGNWBL-CXIHKKCa.js +0 -1
- package/payload/server/public/assets/channel-CA7njeKl.js +0 -1
- package/payload/server/public/assets/chunk-426QAEUC-tWQOa3-I.js +0 -1
- package/payload/server/public/assets/chunk-QZHKN3VN-BwkFBCAY.js +0 -1
- package/payload/server/public/assets/classDiagram-6PBFFD2Q-CUZ9BU_6.js +0 -1
- package/payload/server/public/assets/classDiagram-v2-HSJHXN6E-BGYsCDux.js +0 -1
- package/payload/server/public/assets/clone-BjouONkW.js +0 -1
- package/payload/server/public/assets/data-CAKMrPTQ.js +0 -1
- package/payload/server/public/assets/gitGraph-7Q5UKJZL-tvzbaNdg.js +0 -1
- package/payload/server/public/assets/info-OMHHGYJF-ByeBaFw5.js +0 -1
- package/payload/server/public/assets/infoDiagram-42DDH7IO-CjgCxerY.js +0 -2
- package/payload/server/public/assets/jsx-runtime-BJhXEiL3.css +0 -1
- package/payload/server/public/assets/packet-4T2RLAQJ-Csybj5RO.js +0 -1
- package/payload/server/public/assets/pie-ZZUOXDRM-Iw1du1Bn.js +0 -1
- package/payload/server/public/assets/public-b43rEAhq.js +0 -5
- package/payload/server/public/assets/radar-PYXPWWZC-rEet4TBV.js +0 -1
- package/payload/server/public/assets/stateDiagram-v2-QKLJ7IA2-DhKxVkX3.js +0 -1
- package/payload/server/public/assets/trash-2-D_Rm8z21.js +0 -1
- package/payload/server/public/assets/treeView-SZITEDCU-PaLYyjtc.js +0 -1
- package/payload/server/public/assets/treemap-W4RFUUIX-CEhGYFbO.js +0 -1
- package/payload/server/public/assets/wardley-RL74JXVD-xtJ4_o4d.js +0 -1
- package/payload/server/public/assets/x-CFPIrGuL.js +0 -1
- /package/payload/server/public/assets/{_baseFor-WfS9pKAn.js → _baseFor-Dn4GSmI6.js} +0 -0
- /package/payload/server/public/assets/{array-HeX70jSN.js → array-DJN9YAVf.js} +0 -0
- /package/payload/server/public/assets/{cytoscape.esm-CDZo0kst.js → cytoscape.esm-BcJTl1re.js} +0 -0
- /package/payload/server/public/assets/{defaultLocale-GJwWH1Jr.js → defaultLocale-B4F_XsBB.js} +0 -0
- /package/payload/server/public/assets/{dist-BKbAaes5.js → dist-CrzV1W3-.js} +0 -0
- /package/payload/server/public/assets/{init-BPLPMQ3Y.js → init-DX0Y1qU4.js} +0 -0
- /package/payload/server/public/assets/{katex-CKZ-HWMQ.js → katex-CjHJ1D7d.js} +0 -0
- /package/payload/server/public/assets/{path-YdFzr2W6.js → path-7vUsG-o2.js} +0 -0
- /package/payload/server/public/assets/{preload-helper-BEFjQwLd.js → preload-helper-qlgyTAkD.js} +0 -0
- /package/payload/server/public/assets/{rough.esm-HAx67Hnb.js → rough.esm-NLRoWnq-.js} +0 -0
- /package/payload/server/public/assets/{src-BvrHnOMG.js → src-Bo15iQ7w.js} +0 -0
package/payload/server/server.js
CHANGED
|
@@ -1201,14 +1201,14 @@ var Hono = class _Hono {
|
|
|
1201
1201
|
* app.route("/api", app2) // GET /api/user
|
|
1202
1202
|
* ```
|
|
1203
1203
|
*/
|
|
1204
|
-
route(path2,
|
|
1204
|
+
route(path2, app31) {
|
|
1205
1205
|
const subApp = this.basePath(path2);
|
|
1206
|
-
|
|
1206
|
+
app31.routes.map((r) => {
|
|
1207
1207
|
let handler;
|
|
1208
|
-
if (
|
|
1208
|
+
if (app31.errorHandler === errorHandler) {
|
|
1209
1209
|
handler = r.handler;
|
|
1210
1210
|
} else {
|
|
1211
|
-
handler = async (c, next) => (await compose([],
|
|
1211
|
+
handler = async (c, next) => (await compose([], app31.errorHandler)(c, () => r.handler(c, next))).res;
|
|
1212
1212
|
handler[COMPOSED_HANDLER] = r.handler;
|
|
1213
1213
|
}
|
|
1214
1214
|
subApp.#addRoute(r.method, r.path, handler);
|
|
@@ -10867,6 +10867,13 @@ ${block}`;
|
|
|
10867
10867
|
}
|
|
10868
10868
|
|
|
10869
10869
|
// server/routes/_helpers.ts
|
|
10870
|
+
async function safeJson(c) {
|
|
10871
|
+
try {
|
|
10872
|
+
return await c.req.json();
|
|
10873
|
+
} catch {
|
|
10874
|
+
return null;
|
|
10875
|
+
}
|
|
10876
|
+
}
|
|
10870
10877
|
async function resolveSessionKey(c) {
|
|
10871
10878
|
const fromQuery = c.req.query("session_key");
|
|
10872
10879
|
if (fromQuery) return fromQuery;
|
|
@@ -14801,6 +14808,20 @@ function checkPort(port2, timeoutMs = 500) {
|
|
|
14801
14808
|
});
|
|
14802
14809
|
});
|
|
14803
14810
|
}
|
|
14811
|
+
var TTYD_PROBE_CACHE_MS = 2e3;
|
|
14812
|
+
var TTYD_PROBE_TIMEOUT_MS = 200;
|
|
14813
|
+
var cachedTtydReady = null;
|
|
14814
|
+
async function probeTerminalReady() {
|
|
14815
|
+
if (cachedTtydReady && Date.now() - cachedTtydReady.checkedAt < TTYD_PROBE_CACHE_MS) {
|
|
14816
|
+
return cachedTtydReady.ok;
|
|
14817
|
+
}
|
|
14818
|
+
const ok = await checkPort(7681, TTYD_PROBE_TIMEOUT_MS);
|
|
14819
|
+
if (!cachedTtydReady || cachedTtydReady.ok !== ok) {
|
|
14820
|
+
console.log(`[health] terminal_ready: ${cachedTtydReady?.ok ?? "unknown"} \u2192 ${ok}`);
|
|
14821
|
+
}
|
|
14822
|
+
cachedTtydReady = { ok, checkedAt: Date.now() };
|
|
14823
|
+
return ok;
|
|
14824
|
+
}
|
|
14804
14825
|
var app = new Hono2();
|
|
14805
14826
|
app.get("/", async (c) => {
|
|
14806
14827
|
const browserTransport = resolveBrowserTransport(c.req.raw, c.env?.incoming?.socket?.remoteAddress);
|
|
@@ -14824,7 +14845,7 @@ app.get("/", async (c) => {
|
|
|
14824
14845
|
}
|
|
14825
14846
|
const claudeAuthenticated = authHealth.status === "ok" || authHealth.status === "expiring";
|
|
14826
14847
|
const vncRunning = await checkPort(6080);
|
|
14827
|
-
const terminalReady = await
|
|
14848
|
+
const terminalReady = await probeTerminalReady();
|
|
14828
14849
|
let apiKeyConfigured = false;
|
|
14829
14850
|
try {
|
|
14830
14851
|
apiKeyConfigured = existsSync11(keyFilePath());
|
|
@@ -20107,13 +20128,18 @@ var GRAPH_LABEL_COLOURS = {
|
|
|
20107
20128
|
var ALL_GRAPH_LABELS = Object.freeze(
|
|
20108
20129
|
Object.keys(GRAPH_LABEL_COLOURS)
|
|
20109
20130
|
);
|
|
20131
|
+
var HIDDEN_BY_DEFAULT_LABELS = Object.freeze(
|
|
20132
|
+
/* @__PURE__ */ new Set(["Chunk"])
|
|
20133
|
+
);
|
|
20110
20134
|
function isKnownLabel(label) {
|
|
20111
20135
|
return Object.prototype.hasOwnProperty.call(GRAPH_LABEL_COLOURS, label);
|
|
20112
20136
|
}
|
|
20137
|
+
function isHiddenByDefault(label) {
|
|
20138
|
+
return HIDDEN_BY_DEFAULT_LABELS.has(label);
|
|
20139
|
+
}
|
|
20113
20140
|
|
|
20114
20141
|
// server/routes/admin/graph-subgraph.ts
|
|
20115
|
-
var
|
|
20116
|
-
var MAX_LIMIT2 = 500;
|
|
20142
|
+
var CEILING = 2e3;
|
|
20117
20143
|
var STRIPPED_PROPERTIES = /* @__PURE__ */ new Set([
|
|
20118
20144
|
"embedding",
|
|
20119
20145
|
"passwordHash",
|
|
@@ -20129,12 +20155,41 @@ app26.get("/", requireAdminSession, async (c) => {
|
|
|
20129
20155
|
console.error('[graph-page] auth-rejected reason="no account for session"');
|
|
20130
20156
|
return c.json({ error: "Account not found for session" }, 401);
|
|
20131
20157
|
}
|
|
20132
|
-
const
|
|
20133
|
-
|
|
20134
|
-
|
|
20135
|
-
|
|
20136
|
-
|
|
20158
|
+
const mode = c.req.query("mode");
|
|
20159
|
+
if (mode !== "default" && mode !== "neighbourhood") {
|
|
20160
|
+
console.error(
|
|
20161
|
+
`[graph-page] load rejected reason=missing-mode account=${accountId} got=${mode ?? "null"}`
|
|
20162
|
+
);
|
|
20163
|
+
return c.json(
|
|
20164
|
+
{ error: "mode required: default | neighbourhood" },
|
|
20165
|
+
400
|
|
20166
|
+
);
|
|
20167
|
+
}
|
|
20168
|
+
if (mode === "default") return handleDefault(c, accountId);
|
|
20169
|
+
return handleNeighbourhood(c, accountId);
|
|
20170
|
+
});
|
|
20171
|
+
async function handleDefault(c, accountId) {
|
|
20172
|
+
const rawLabels = c.req.query("labels") ?? "";
|
|
20173
|
+
const labels = rawLabels.split(",").map((s) => s.trim()).filter(Boolean);
|
|
20174
|
+
if (labels.length === 0) {
|
|
20175
|
+
console.error(
|
|
20176
|
+
`[graph-page] load rejected reason=missing-filter account=${accountId} labels=`
|
|
20177
|
+
);
|
|
20178
|
+
return c.json(
|
|
20179
|
+
{ error: "labels required in default mode \u2014 pick at least one node type" },
|
|
20180
|
+
400
|
|
20181
|
+
);
|
|
20182
|
+
}
|
|
20137
20183
|
for (const label of labels) {
|
|
20184
|
+
if (isHiddenByDefault(label)) {
|
|
20185
|
+
console.error(
|
|
20186
|
+
`[graph-page] load rejected reason=chunk-label-requested account=${accountId} labels=${labels.join(",")}`
|
|
20187
|
+
);
|
|
20188
|
+
return c.json(
|
|
20189
|
+
{ error: `label "${label}" is hidden by default \u2014 it cannot be requested via mode=default` },
|
|
20190
|
+
400
|
|
20191
|
+
);
|
|
20192
|
+
}
|
|
20138
20193
|
if (!isKnownLabel(label)) {
|
|
20139
20194
|
return c.json(
|
|
20140
20195
|
{ error: `unknown label "${label}" \u2014 not registered in graph-labels.ts` },
|
|
@@ -20145,18 +20200,78 @@ app26.get("/", requireAdminSession, async (c) => {
|
|
|
20145
20200
|
const started = Date.now();
|
|
20146
20201
|
const session = getSession();
|
|
20147
20202
|
try {
|
|
20148
|
-
const
|
|
20149
|
-
|
|
20150
|
-
|
|
20151
|
-
|
|
20203
|
+
const result = await session.executeRead(async (tx) => {
|
|
20204
|
+
const countResult = await tx.run(DEFAULT_COUNT_CYPHER, { accountId, labels });
|
|
20205
|
+
const matchedRaw = countResult.records[0]?.get("matched");
|
|
20206
|
+
const matched = typeof matchedRaw === "bigint" ? Number(matchedRaw) : Number(matchedRaw ?? 0);
|
|
20207
|
+
if (matched > CEILING) {
|
|
20208
|
+
return { overLimit: true, matched };
|
|
20209
|
+
}
|
|
20210
|
+
const fetchResult = await tx.run(DEFAULT_FETCH_CYPHER, { accountId, labels });
|
|
20211
|
+
const record = fetchResult.records[0];
|
|
20212
|
+
const rawNodes = record?.get("nodes") ?? [];
|
|
20213
|
+
const rawEdges = record?.get("edges") ?? [];
|
|
20214
|
+
return { overLimit: false, matched, rawNodes, rawEdges };
|
|
20215
|
+
});
|
|
20216
|
+
const elapsed = Date.now() - started;
|
|
20217
|
+
if (result.overLimit) {
|
|
20218
|
+
console.error(
|
|
20219
|
+
`[graph-page] load rejected reason=ceiling-exceeded account=${accountId} labels=${labels.join(",")} matched=${result.matched} ceiling=${CEILING} ms=${elapsed}`
|
|
20220
|
+
);
|
|
20221
|
+
return c.json(
|
|
20222
|
+
{
|
|
20223
|
+
error: `Refine your filter \u2014 ${result.matched} matches exceed the ${CEILING} cap.`,
|
|
20224
|
+
matched: result.matched
|
|
20225
|
+
},
|
|
20226
|
+
413
|
|
20227
|
+
);
|
|
20228
|
+
}
|
|
20229
|
+
const nodes = result.rawNodes.map(pruneNode);
|
|
20230
|
+
const edges = result.rawEdges.filter((e) => e && e.id != null);
|
|
20231
|
+
console.error(
|
|
20232
|
+
`[graph-page] load mode=default account=${accountId} labels=${labels.join(",")} nodes=${nodes.length} edges=${edges.length} ms=${elapsed}`
|
|
20233
|
+
);
|
|
20234
|
+
return c.json({ nodes, edges });
|
|
20235
|
+
} catch (err) {
|
|
20236
|
+
const elapsed = Date.now() - started;
|
|
20237
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
20238
|
+
console.error(`[graph-page] error stage=fetch reason="${message}" ms=${elapsed}`);
|
|
20239
|
+
return c.json({ error: `Graph data unavailable: ${message}` }, 503);
|
|
20240
|
+
} finally {
|
|
20241
|
+
try {
|
|
20242
|
+
await session.close();
|
|
20243
|
+
} catch {
|
|
20244
|
+
}
|
|
20245
|
+
}
|
|
20246
|
+
}
|
|
20247
|
+
async function handleNeighbourhood(c, accountId) {
|
|
20248
|
+
const elementId = c.req.query("elementId");
|
|
20249
|
+
if (!elementId) {
|
|
20250
|
+
return c.json(
|
|
20251
|
+
{ error: "elementId required in neighbourhood mode" },
|
|
20252
|
+
400
|
|
20253
|
+
);
|
|
20254
|
+
}
|
|
20255
|
+
const started = Date.now();
|
|
20256
|
+
const session = getSession();
|
|
20257
|
+
try {
|
|
20258
|
+
const result = await session.executeRead(async (tx) => {
|
|
20259
|
+
return await tx.run(NEIGHBOURHOOD_CYPHER, { accountId, elementId });
|
|
20260
|
+
});
|
|
20152
20261
|
const record = result.records[0];
|
|
20153
20262
|
const rawNodes = record?.get("nodes") ?? [];
|
|
20154
20263
|
const rawEdges = record?.get("edges") ?? [];
|
|
20264
|
+
const elapsed = Date.now() - started;
|
|
20265
|
+
if (rawNodes.length === 0) {
|
|
20266
|
+
console.error(
|
|
20267
|
+
`[graph-page] load rejected reason=not-found account=${accountId} elementId=${elementId} ms=${elapsed}`
|
|
20268
|
+
);
|
|
20269
|
+
return c.json({ error: "Node not found" }, 404);
|
|
20270
|
+
}
|
|
20155
20271
|
const nodes = rawNodes.map(pruneNode);
|
|
20156
20272
|
const edges = rawEdges.filter((e) => e && e.id != null);
|
|
20157
|
-
const elapsed = Date.now() - started;
|
|
20158
20273
|
console.error(
|
|
20159
|
-
`[graph-page] load account=${accountId} nodes=${nodes.length} edges=${edges.length} ms=${elapsed}`
|
|
20274
|
+
`[graph-page] load mode=neighbourhood account=${accountId} elementId=${elementId} nodes=${nodes.length} edges=${edges.length} ms=${elapsed}`
|
|
20160
20275
|
);
|
|
20161
20276
|
return c.json({ nodes, edges });
|
|
20162
20277
|
} catch (err) {
|
|
@@ -20170,30 +20285,63 @@ app26.get("/", requireAdminSession, async (c) => {
|
|
|
20170
20285
|
} catch {
|
|
20171
20286
|
}
|
|
20172
20287
|
}
|
|
20173
|
-
});
|
|
20174
|
-
function buildCypher(filtered) {
|
|
20175
|
-
const labelGuard = filtered ? "AND any(lbl IN labels(n) WHERE lbl IN $labels)" : "";
|
|
20176
|
-
return `
|
|
20177
|
-
MATCH (n)
|
|
20178
|
-
WHERE n.accountId = $accountId ${labelGuard}
|
|
20179
|
-
WITH n ORDER BY coalesce(n.updatedAt, n.createdAt, '') DESC
|
|
20180
|
-
LIMIT toInteger($limit)
|
|
20181
|
-
WITH collect(n) AS nodes, collect(elementId(n)) AS nodeIds
|
|
20182
|
-
UNWIND nodes AS n
|
|
20183
|
-
OPTIONAL MATCH (n)-[r]-(m)
|
|
20184
|
-
WHERE elementId(m) IN nodeIds
|
|
20185
|
-
WITH nodes,
|
|
20186
|
-
collect(DISTINCT CASE WHEN r IS NULL THEN null ELSE {
|
|
20187
|
-
id: elementId(r),
|
|
20188
|
-
from: elementId(startNode(r)),
|
|
20189
|
-
to: elementId(endNode(r)),
|
|
20190
|
-
type: type(r)
|
|
20191
|
-
} END) AS rawEdges
|
|
20192
|
-
RETURN
|
|
20193
|
-
[x IN nodes | {id: elementId(x), labels: labels(x), properties: properties(x)}] AS nodes,
|
|
20194
|
-
[e IN rawEdges WHERE e IS NOT NULL] AS edges
|
|
20195
|
-
`;
|
|
20196
20288
|
}
|
|
20289
|
+
var DEFAULT_COUNT_CYPHER = `
|
|
20290
|
+
MATCH (n)
|
|
20291
|
+
WHERE n.accountId = $accountId
|
|
20292
|
+
AND any(lbl IN labels(n) WHERE lbl IN $labels)
|
|
20293
|
+
AND NOT n:Trashed
|
|
20294
|
+
AND n.deletedAt IS NULL
|
|
20295
|
+
RETURN count(n) AS matched
|
|
20296
|
+
`;
|
|
20297
|
+
var DEFAULT_FETCH_CYPHER = `
|
|
20298
|
+
MATCH (n)
|
|
20299
|
+
WHERE n.accountId = $accountId
|
|
20300
|
+
AND any(lbl IN labels(n) WHERE lbl IN $labels)
|
|
20301
|
+
AND NOT n:Trashed
|
|
20302
|
+
AND n.deletedAt IS NULL
|
|
20303
|
+
WITH collect(n) AS nodes, collect(elementId(n)) AS nodeIds
|
|
20304
|
+
UNWIND nodes AS n
|
|
20305
|
+
OPTIONAL MATCH (n)-[r]-(m)
|
|
20306
|
+
WHERE elementId(m) IN nodeIds
|
|
20307
|
+
WITH nodes,
|
|
20308
|
+
collect(DISTINCT CASE WHEN r IS NULL THEN null ELSE {
|
|
20309
|
+
id: elementId(r),
|
|
20310
|
+
from: elementId(startNode(r)),
|
|
20311
|
+
to: elementId(endNode(r)),
|
|
20312
|
+
type: type(r)
|
|
20313
|
+
} END) AS rawEdges
|
|
20314
|
+
RETURN
|
|
20315
|
+
[x IN nodes | {id: elementId(x), labels: labels(x), properties: properties(x)}] AS nodes,
|
|
20316
|
+
[e IN rawEdges WHERE e IS NOT NULL] AS edges
|
|
20317
|
+
`;
|
|
20318
|
+
var NEIGHBOURHOOD_CYPHER = `
|
|
20319
|
+
MATCH (n)
|
|
20320
|
+
WHERE elementId(n) = $elementId
|
|
20321
|
+
AND n.accountId = $accountId
|
|
20322
|
+
AND NOT n:Trashed
|
|
20323
|
+
AND n.deletedAt IS NULL
|
|
20324
|
+
OPTIONAL MATCH (n)-[]-(m)
|
|
20325
|
+
WHERE m.accountId = $accountId
|
|
20326
|
+
AND NOT m:Trashed
|
|
20327
|
+
AND m.deletedAt IS NULL
|
|
20328
|
+
WITH n, collect(DISTINCT m) AS neighbours
|
|
20329
|
+
WITH [n] + [x IN neighbours WHERE x IS NOT NULL] AS windowNodes
|
|
20330
|
+
WITH windowNodes, [x IN windowNodes | elementId(x)] AS windowIds
|
|
20331
|
+
UNWIND windowNodes AS w
|
|
20332
|
+
OPTIONAL MATCH (w)-[r]-(o)
|
|
20333
|
+
WHERE elementId(o) IN windowIds
|
|
20334
|
+
WITH windowNodes,
|
|
20335
|
+
collect(DISTINCT CASE WHEN r IS NULL THEN null ELSE {
|
|
20336
|
+
id: elementId(r),
|
|
20337
|
+
from: elementId(startNode(r)),
|
|
20338
|
+
to: elementId(endNode(r)),
|
|
20339
|
+
type: type(r)
|
|
20340
|
+
} END) AS rawEdges
|
|
20341
|
+
RETURN
|
|
20342
|
+
[x IN windowNodes | {id: elementId(x), labels: labels(x), properties: properties(x)}] AS nodes,
|
|
20343
|
+
[e IN rawEdges WHERE e IS NOT NULL] AS edges
|
|
20344
|
+
`;
|
|
20197
20345
|
function pruneNode(node) {
|
|
20198
20346
|
const properties = {};
|
|
20199
20347
|
for (const [key, value] of Object.entries(node.properties ?? {})) {
|
|
@@ -20204,9 +20352,167 @@ function pruneNode(node) {
|
|
|
20204
20352
|
}
|
|
20205
20353
|
var graph_subgraph_default = app26;
|
|
20206
20354
|
|
|
20207
|
-
//
|
|
20355
|
+
// ../lib/graph-trash/src/index.ts
|
|
20356
|
+
var UNIQUE_KEYS_BY_LABEL = {
|
|
20357
|
+
Person: ["email", "telephone"],
|
|
20358
|
+
Service: ["serviceId"],
|
|
20359
|
+
LocalBusiness: ["accountId"],
|
|
20360
|
+
Task: ["taskId"],
|
|
20361
|
+
Event: ["eventId"],
|
|
20362
|
+
KnowledgeDocument: ["attachmentId"],
|
|
20363
|
+
DigitalDocument: ["attachmentId"],
|
|
20364
|
+
Conversation: ["conversationId", "sessionKey"],
|
|
20365
|
+
Message: ["messageId"],
|
|
20366
|
+
OnboardingState: ["accountId"],
|
|
20367
|
+
Workflow: ["workflowId"],
|
|
20368
|
+
WorkflowStep: ["stepId"],
|
|
20369
|
+
WorkflowRun: ["runId"],
|
|
20370
|
+
Preference: ["preferenceId"],
|
|
20371
|
+
Email: ["emailId", "messageId"],
|
|
20372
|
+
AdminUser: ["userId"],
|
|
20373
|
+
ToolCall: ["callId"],
|
|
20374
|
+
// Composite component nulls — frees the composite constraint:
|
|
20375
|
+
AccessGrant: ["contactValue"],
|
|
20376
|
+
// composite (contactValue, agentSlug, accountId)
|
|
20377
|
+
UserProfile: ["userId"]
|
|
20378
|
+
// composite (accountId, userId)
|
|
20379
|
+
};
|
|
20380
|
+
async function trashNode(params) {
|
|
20381
|
+
const { session, accountId, elementId, by, reason } = params;
|
|
20382
|
+
const lookup = await session.run(
|
|
20383
|
+
`MATCH (n) WHERE elementId(n) = $eid AND n.accountId = $accountId
|
|
20384
|
+
RETURN labels(n) AS labels, properties(n) AS props`,
|
|
20385
|
+
{ eid: elementId, accountId }
|
|
20386
|
+
);
|
|
20387
|
+
if (lookup.records.length === 0) {
|
|
20388
|
+
throw new Error(
|
|
20389
|
+
`trashNode: node not found (elementId=${elementId} accountId=${accountId.slice(0, 8)}\u2026)`
|
|
20390
|
+
);
|
|
20391
|
+
}
|
|
20392
|
+
const allLabels = lookup.records[0].get("labels");
|
|
20393
|
+
const props = lookup.records[0].get("props");
|
|
20394
|
+
const baseLabels = allLabels.filter((l) => l !== "Trashed");
|
|
20395
|
+
if (allLabels.includes("Trashed")) {
|
|
20396
|
+
return {
|
|
20397
|
+
trashed: false,
|
|
20398
|
+
alreadyTrashed: true,
|
|
20399
|
+
nodeId: elementId,
|
|
20400
|
+
labels: baseLabels,
|
|
20401
|
+
trashedAt: String(props.trashedAt ?? ""),
|
|
20402
|
+
originalKeys: {}
|
|
20403
|
+
};
|
|
20404
|
+
}
|
|
20405
|
+
const uniqueKeys = /* @__PURE__ */ new Set();
|
|
20406
|
+
for (const label of baseLabels) {
|
|
20407
|
+
for (const key of UNIQUE_KEYS_BY_LABEL[label] ?? []) uniqueKeys.add(key);
|
|
20408
|
+
}
|
|
20409
|
+
const originalKeys = {};
|
|
20410
|
+
for (const k of uniqueKeys) {
|
|
20411
|
+
if (props[k] !== void 0 && props[k] !== null) originalKeys[k] = props[k];
|
|
20412
|
+
}
|
|
20413
|
+
const setNullClauses = Object.keys(originalKeys).map((k) => `n.\`${k}\` = null`).join(", ");
|
|
20414
|
+
const setNullSuffix = setNullClauses ? `, ${setNullClauses}` : "";
|
|
20415
|
+
const trashedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
20416
|
+
await session.run(
|
|
20417
|
+
`MATCH (n) WHERE elementId(n) = $eid
|
|
20418
|
+
SET n:Trashed,
|
|
20419
|
+
n.trashedAt = datetime($trashedAt),
|
|
20420
|
+
n.trashedBy = $by,
|
|
20421
|
+
n.trashReason = $reason,
|
|
20422
|
+
n._trashedKeys = $trashedKeysJson${setNullSuffix}`,
|
|
20423
|
+
{
|
|
20424
|
+
eid: elementId,
|
|
20425
|
+
trashedAt,
|
|
20426
|
+
by,
|
|
20427
|
+
reason: reason ?? null,
|
|
20428
|
+
trashedKeysJson: JSON.stringify(originalKeys)
|
|
20429
|
+
}
|
|
20430
|
+
);
|
|
20431
|
+
process.stderr.write(
|
|
20432
|
+
`[trash:marked] accountId=${accountId} elementId=${elementId} labels=${baseLabels.join(",")} by=${by} reason=${reason ?? "null"}
|
|
20433
|
+
`
|
|
20434
|
+
);
|
|
20435
|
+
return {
|
|
20436
|
+
trashed: true,
|
|
20437
|
+
alreadyTrashed: false,
|
|
20438
|
+
nodeId: elementId,
|
|
20439
|
+
labels: baseLabels,
|
|
20440
|
+
trashedAt,
|
|
20441
|
+
originalKeys
|
|
20442
|
+
};
|
|
20443
|
+
}
|
|
20444
|
+
|
|
20445
|
+
// server/routes/admin/graph-delete.ts
|
|
20208
20446
|
var app27 = new Hono2();
|
|
20209
|
-
app27.post("/", async (c) => {
|
|
20447
|
+
app27.post("/", requireAdminSession, async (c) => {
|
|
20448
|
+
const sessionKey = c.var.sessionKey;
|
|
20449
|
+
const accountId = getAccountIdForSession(sessionKey);
|
|
20450
|
+
if (!accountId) {
|
|
20451
|
+
console.error('[graph-page] delete auth-rejected reason="no account for session"');
|
|
20452
|
+
return c.json({ error: "Account not found for session" }, 401);
|
|
20453
|
+
}
|
|
20454
|
+
const body = await safeJson(c);
|
|
20455
|
+
if (!body) {
|
|
20456
|
+
return c.json({ error: "JSON body required" }, 400);
|
|
20457
|
+
}
|
|
20458
|
+
const elementId = typeof body.elementId === "string" ? body.elementId.trim() : "";
|
|
20459
|
+
if (!elementId) {
|
|
20460
|
+
return c.json({ error: "elementId required" }, 400);
|
|
20461
|
+
}
|
|
20462
|
+
const started = Date.now();
|
|
20463
|
+
const session = getSession();
|
|
20464
|
+
try {
|
|
20465
|
+
const lookup = await session.run(
|
|
20466
|
+
`MATCH (n)
|
|
20467
|
+
WHERE elementId(n) = $elementId AND n.accountId = $accountId
|
|
20468
|
+
RETURN labels(n) AS labels LIMIT 1`,
|
|
20469
|
+
{ elementId, accountId }
|
|
20470
|
+
);
|
|
20471
|
+
if (lookup.records.length === 0) {
|
|
20472
|
+
const elapsed2 = Date.now() - started;
|
|
20473
|
+
console.error(
|
|
20474
|
+
`[graph-page] delete account=${accountId} elementId=${elementId} labels= result=not-found ms=${elapsed2}`
|
|
20475
|
+
);
|
|
20476
|
+
return c.json({ error: "Node not found" }, 404);
|
|
20477
|
+
}
|
|
20478
|
+
const preflightLabels = lookup.records[0].get("labels") ?? [];
|
|
20479
|
+
const result = await trashNode({
|
|
20480
|
+
session,
|
|
20481
|
+
accountId,
|
|
20482
|
+
elementId,
|
|
20483
|
+
by: "graph-page"
|
|
20484
|
+
});
|
|
20485
|
+
const elapsed = Date.now() - started;
|
|
20486
|
+
const labelSummary = (result.labels.length > 0 ? result.labels : preflightLabels).join(",");
|
|
20487
|
+
console.error(
|
|
20488
|
+
`[graph-page] delete account=${accountId} elementId=${elementId} labels=${labelSummary} result=ok ms=${elapsed}`
|
|
20489
|
+
);
|
|
20490
|
+
const response = {
|
|
20491
|
+
elementId: result.nodeId,
|
|
20492
|
+
labels: result.labels.length > 0 ? result.labels : preflightLabels,
|
|
20493
|
+
trashedAt: result.trashedAt,
|
|
20494
|
+
alreadyTrashed: result.alreadyTrashed
|
|
20495
|
+
};
|
|
20496
|
+
return c.json(response);
|
|
20497
|
+
} catch (err) {
|
|
20498
|
+
const elapsed = Date.now() - started;
|
|
20499
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
20500
|
+
console.error(
|
|
20501
|
+
`[graph-page] delete account=${accountId} elementId=${elementId} labels= result=error ms=${elapsed} err="${message}"`
|
|
20502
|
+
);
|
|
20503
|
+
return c.json({ error: `Delete failed: ${message}` }, 503);
|
|
20504
|
+
} finally {
|
|
20505
|
+
try {
|
|
20506
|
+
await session.close();
|
|
20507
|
+
} catch {
|
|
20508
|
+
}
|
|
20509
|
+
}
|
|
20510
|
+
});
|
|
20511
|
+
var graph_delete_default = app27;
|
|
20512
|
+
|
|
20513
|
+
// server/routes/admin/file-attach.ts
|
|
20514
|
+
var app28 = new Hono2();
|
|
20515
|
+
app28.post("/", async (c) => {
|
|
20210
20516
|
try {
|
|
20211
20517
|
const body = await c.req.json();
|
|
20212
20518
|
const { filePath, accountId } = body;
|
|
@@ -20229,29 +20535,30 @@ app27.post("/", async (c) => {
|
|
|
20229
20535
|
return c.json({ error: message }, 500);
|
|
20230
20536
|
}
|
|
20231
20537
|
});
|
|
20232
|
-
var file_attach_default =
|
|
20538
|
+
var file_attach_default = app28;
|
|
20233
20539
|
|
|
20234
20540
|
// server/routes/admin/index.ts
|
|
20235
|
-
var
|
|
20236
|
-
|
|
20237
|
-
|
|
20238
|
-
|
|
20239
|
-
|
|
20240
|
-
|
|
20241
|
-
|
|
20242
|
-
|
|
20243
|
-
|
|
20244
|
-
|
|
20245
|
-
|
|
20246
|
-
|
|
20247
|
-
|
|
20248
|
-
|
|
20249
|
-
|
|
20250
|
-
|
|
20251
|
-
|
|
20252
|
-
|
|
20253
|
-
|
|
20254
|
-
|
|
20541
|
+
var app29 = new Hono2();
|
|
20542
|
+
app29.route("/session", session_default2);
|
|
20543
|
+
app29.route("/chat", chat_default2);
|
|
20544
|
+
app29.route("/compact", compact_default);
|
|
20545
|
+
app29.route("/logs", logs_default);
|
|
20546
|
+
app29.route("/claude-info", claude_info_default);
|
|
20547
|
+
app29.route("/attachment", attachment_default);
|
|
20548
|
+
app29.route("/account", account_default);
|
|
20549
|
+
app29.route("/agents", agents_default);
|
|
20550
|
+
app29.route("/version", version_default);
|
|
20551
|
+
app29.route("/sessions", sessions_default);
|
|
20552
|
+
app29.route("/browser", browser_default);
|
|
20553
|
+
app29.route("/device-browser", device_browser_default);
|
|
20554
|
+
app29.route("/events", events_default);
|
|
20555
|
+
app29.route("/cloudflare", cloudflare_default);
|
|
20556
|
+
app29.route("/files", files_default);
|
|
20557
|
+
app29.route("/graph-search", graph_search_default);
|
|
20558
|
+
app29.route("/graph-subgraph", graph_subgraph_default);
|
|
20559
|
+
app29.route("/graph-delete", graph_delete_default);
|
|
20560
|
+
app29.route("/file-attach", file_attach_default);
|
|
20561
|
+
var admin_default = app29;
|
|
20255
20562
|
|
|
20256
20563
|
// server/index.ts
|
|
20257
20564
|
var PLATFORM_ROOT11 = process.env.MAXY_PLATFORM_ROOT || "";
|
|
@@ -20309,9 +20616,9 @@ watchFile(ALIAS_DOMAINS_PATH2, { interval: 2e3 }, () => {
|
|
|
20309
20616
|
function isPublicHost(host) {
|
|
20310
20617
|
return host.startsWith("public.") || aliasDomains.has(host);
|
|
20311
20618
|
}
|
|
20312
|
-
var
|
|
20313
|
-
|
|
20314
|
-
|
|
20619
|
+
var app30 = new Hono2();
|
|
20620
|
+
app30.use("*", clientIpMiddleware);
|
|
20621
|
+
app30.use("*", async (c, next) => {
|
|
20315
20622
|
await next();
|
|
20316
20623
|
c.header("X-Content-Type-Options", "nosniff");
|
|
20317
20624
|
c.header("Referrer-Policy", "strict-origin-when-cross-origin");
|
|
@@ -20334,7 +20641,7 @@ var PUBLIC_ALLOWED_PREFIXES = [
|
|
|
20334
20641
|
"/g/"
|
|
20335
20642
|
];
|
|
20336
20643
|
var PUBLIC_ALLOWED_EXACT = ["/favicon.ico"];
|
|
20337
|
-
|
|
20644
|
+
app30.use("*", async (c, next) => {
|
|
20338
20645
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
20339
20646
|
if (!isPublicHost(host)) {
|
|
20340
20647
|
await next();
|
|
@@ -20374,7 +20681,7 @@ function resolveRemoteAuthOpts() {
|
|
|
20374
20681
|
return brandLoginOpts;
|
|
20375
20682
|
}
|
|
20376
20683
|
var MAX_LOGIN_BODY = 8 * 1024;
|
|
20377
|
-
|
|
20684
|
+
app30.post("/__remote-auth/login", async (c) => {
|
|
20378
20685
|
const clientIp = c.var.clientIp || "unknown";
|
|
20379
20686
|
const rateLimited = checkRateLimit(clientIp);
|
|
20380
20687
|
if (rateLimited) {
|
|
@@ -20410,7 +20717,7 @@ app29.post("/__remote-auth/login", async (c) => {
|
|
|
20410
20717
|
}
|
|
20411
20718
|
});
|
|
20412
20719
|
});
|
|
20413
|
-
|
|
20720
|
+
app30.get("/__remote-auth/logout", (c) => {
|
|
20414
20721
|
const cookieHeader = c.req.header("cookie");
|
|
20415
20722
|
const token = parseCookie(cookieHeader, "__remote_session");
|
|
20416
20723
|
if (token) invalidateRemoteSession(token);
|
|
@@ -20423,7 +20730,7 @@ app29.get("/__remote-auth/logout", (c) => {
|
|
|
20423
20730
|
}
|
|
20424
20731
|
});
|
|
20425
20732
|
});
|
|
20426
|
-
|
|
20733
|
+
app30.post("/__remote-auth/change-password", async (c) => {
|
|
20427
20734
|
const clientIp = c.var.clientIp || "unknown";
|
|
20428
20735
|
const rateLimited = checkRateLimit(clientIp);
|
|
20429
20736
|
if (rateLimited) {
|
|
@@ -20472,13 +20779,13 @@ app29.post("/__remote-auth/change-password", async (c) => {
|
|
|
20472
20779
|
return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(), mode: "change", changeError: "Failed to save password", redirect }), 200);
|
|
20473
20780
|
}
|
|
20474
20781
|
});
|
|
20475
|
-
|
|
20782
|
+
app30.get("/__remote-auth/setup", (c) => {
|
|
20476
20783
|
if (isRemoteAuthConfigured()) {
|
|
20477
20784
|
return c.redirect("/");
|
|
20478
20785
|
}
|
|
20479
20786
|
return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(), mode: "setup" }), 200);
|
|
20480
20787
|
});
|
|
20481
|
-
|
|
20788
|
+
app30.post("/__remote-auth/set-initial-password", async (c) => {
|
|
20482
20789
|
if (isRemoteAuthConfigured()) {
|
|
20483
20790
|
return c.redirect("/");
|
|
20484
20791
|
}
|
|
@@ -20514,10 +20821,10 @@ app29.post("/__remote-auth/set-initial-password", async (c) => {
|
|
|
20514
20821
|
return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(), mode: "setup", setupError: "Failed to save password. Please try again." }), 200);
|
|
20515
20822
|
}
|
|
20516
20823
|
});
|
|
20517
|
-
|
|
20824
|
+
app30.get("/api/remote-auth/status", (c) => {
|
|
20518
20825
|
return c.json({ configured: isRemoteAuthConfigured() });
|
|
20519
20826
|
});
|
|
20520
|
-
|
|
20827
|
+
app30.post("/api/remote-auth/set-password", async (c) => {
|
|
20521
20828
|
let body;
|
|
20522
20829
|
try {
|
|
20523
20830
|
body = await c.req.json();
|
|
@@ -20547,9 +20854,9 @@ app29.post("/api/remote-auth/set-password", async (c) => {
|
|
|
20547
20854
|
return c.json({ error: "Failed to save password" }, 500);
|
|
20548
20855
|
}
|
|
20549
20856
|
});
|
|
20550
|
-
|
|
20857
|
+
app30.route("/api/_client-error", client_error_default);
|
|
20551
20858
|
console.log("[client-error-route] mounted");
|
|
20552
|
-
|
|
20859
|
+
app30.use("*", async (c, next) => {
|
|
20553
20860
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
20554
20861
|
const path2 = c.req.path;
|
|
20555
20862
|
if (path2 === "/favicon.ico" || path2.startsWith("/assets/") || path2.startsWith("/brand/")) {
|
|
@@ -20589,15 +20896,15 @@ function parseCookie(cookieHeader, name) {
|
|
|
20589
20896
|
return null;
|
|
20590
20897
|
}
|
|
20591
20898
|
}
|
|
20592
|
-
|
|
20593
|
-
|
|
20594
|
-
|
|
20595
|
-
|
|
20596
|
-
|
|
20597
|
-
|
|
20598
|
-
|
|
20599
|
-
|
|
20600
|
-
|
|
20899
|
+
app30.route("/api/health", health_default);
|
|
20900
|
+
app30.route("/api/session", session_default);
|
|
20901
|
+
app30.route("/api/chat", chat_default);
|
|
20902
|
+
app30.route("/api/group", group_default);
|
|
20903
|
+
app30.route("/api/access", access_default);
|
|
20904
|
+
app30.route("/api/telegram", telegram_default);
|
|
20905
|
+
app30.route("/api/whatsapp", whatsapp_default);
|
|
20906
|
+
app30.route("/api/onboarding", onboarding_default);
|
|
20907
|
+
app30.route("/api/admin", admin_default);
|
|
20601
20908
|
var SAFE_SLUG_RE = /^[a-z][a-z0-9-]{2,49}$/;
|
|
20602
20909
|
var SAFE_FILENAME_RE = /^[a-z0-9_][a-z0-9_.-]{0,99}$/i;
|
|
20603
20910
|
var IMAGE_MIME = {
|
|
@@ -20609,7 +20916,7 @@ var IMAGE_MIME = {
|
|
|
20609
20916
|
".svg": "image/svg+xml",
|
|
20610
20917
|
".ico": "image/x-icon"
|
|
20611
20918
|
};
|
|
20612
|
-
|
|
20919
|
+
app30.get("/agent-assets/:slug/:filename", (c) => {
|
|
20613
20920
|
const slug = c.req.param("slug");
|
|
20614
20921
|
const filename = c.req.param("filename");
|
|
20615
20922
|
if (!SAFE_SLUG_RE.test(slug)) {
|
|
@@ -20644,7 +20951,7 @@ app29.get("/agent-assets/:slug/:filename", (c) => {
|
|
|
20644
20951
|
"Cache-Control": "public, max-age=3600"
|
|
20645
20952
|
});
|
|
20646
20953
|
});
|
|
20647
|
-
|
|
20954
|
+
app30.get("/generated/:filename", (c) => {
|
|
20648
20955
|
const filename = c.req.param("filename");
|
|
20649
20956
|
if (!SAFE_FILENAME_RE.test(filename) || filename.includes("..")) {
|
|
20650
20957
|
console.error(`[generated] serve file=${filename} status=403`);
|
|
@@ -20809,7 +21116,7 @@ function brandedPublicHtml(agentSlug) {
|
|
|
20809
21116
|
function escapeHtml2(s) {
|
|
20810
21117
|
return s.replace(/&/g, "&").replace(/"/g, """).replace(/</g, "<").replace(/>/g, ">");
|
|
20811
21118
|
}
|
|
20812
|
-
|
|
21119
|
+
app30.get("/", (c) => {
|
|
20813
21120
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
20814
21121
|
if (isPublicHost(host)) {
|
|
20815
21122
|
const defaultSlug = resolveDefaultSlug();
|
|
@@ -20817,12 +21124,12 @@ app29.get("/", (c) => {
|
|
|
20817
21124
|
}
|
|
20818
21125
|
return c.html(cachedHtml("index.html"));
|
|
20819
21126
|
});
|
|
20820
|
-
|
|
21127
|
+
app30.get("/public", (c) => {
|
|
20821
21128
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
20822
21129
|
if (isPublicHost(host)) return c.text("Not found", 404);
|
|
20823
21130
|
return c.html(cachedHtml("public.html"));
|
|
20824
21131
|
});
|
|
20825
|
-
|
|
21132
|
+
app30.get("/chat", (c) => {
|
|
20826
21133
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
20827
21134
|
if (isPublicHost(host)) return c.text("Not found", 404);
|
|
20828
21135
|
return c.html(cachedHtml("public.html"));
|
|
@@ -20841,9 +21148,9 @@ async function logViewerFetch(c, next) {
|
|
|
20841
21148
|
duration_ms: Date.now() - start
|
|
20842
21149
|
});
|
|
20843
21150
|
}
|
|
20844
|
-
|
|
20845
|
-
|
|
20846
|
-
|
|
21151
|
+
app30.use("/vnc-viewer.html", logViewerFetch);
|
|
21152
|
+
app30.use("/vnc-popout.html", logViewerFetch);
|
|
21153
|
+
app30.get("/vnc-popout.html", (c) => {
|
|
20847
21154
|
let html = htmlCache.get("vnc-popout.html");
|
|
20848
21155
|
if (!html) {
|
|
20849
21156
|
html = readFileSync25(resolve29(process.cwd(), "public", "vnc-popout.html"), "utf-8");
|
|
@@ -20856,7 +21163,7 @@ app29.get("/vnc-popout.html", (c) => {
|
|
|
20856
21163
|
}
|
|
20857
21164
|
return c.html(html);
|
|
20858
21165
|
});
|
|
20859
|
-
|
|
21166
|
+
app30.post("/api/vnc/client-event", async (c) => {
|
|
20860
21167
|
let body;
|
|
20861
21168
|
try {
|
|
20862
21169
|
body = await c.req.json();
|
|
@@ -20877,20 +21184,20 @@ app29.post("/api/vnc/client-event", async (c) => {
|
|
|
20877
21184
|
});
|
|
20878
21185
|
return c.json({ ok: true });
|
|
20879
21186
|
});
|
|
20880
|
-
|
|
21187
|
+
app30.get("/g/:slug", (c) => {
|
|
20881
21188
|
return c.html(brandedPublicHtml());
|
|
20882
21189
|
});
|
|
20883
|
-
|
|
21190
|
+
app30.get("/graph", (c) => {
|
|
20884
21191
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
20885
21192
|
if (isPublicHost(host)) return c.text("Not found", 404);
|
|
20886
21193
|
return c.html(cachedHtml("graph.html"));
|
|
20887
21194
|
});
|
|
20888
|
-
|
|
21195
|
+
app30.get("/data", (c) => {
|
|
20889
21196
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
20890
21197
|
if (isPublicHost(host)) return c.text("Not found", 404);
|
|
20891
21198
|
return c.html(cachedHtml("data.html"));
|
|
20892
21199
|
});
|
|
20893
|
-
|
|
21200
|
+
app30.get("/:slug", async (c, next) => {
|
|
20894
21201
|
const slug = c.req.param("slug");
|
|
20895
21202
|
if (AGENT_SLUG_PATTERN.test(`/${slug}`)) {
|
|
20896
21203
|
const branding = loadBrandingCache(slug);
|
|
@@ -20899,10 +21206,10 @@ app29.get("/:slug", async (c, next) => {
|
|
|
20899
21206
|
}
|
|
20900
21207
|
await next();
|
|
20901
21208
|
});
|
|
20902
|
-
|
|
21209
|
+
app30.use("/*", serveStatic({ root: "./public" }));
|
|
20903
21210
|
var port = parseInt(process.env.PORT ?? "19200", 10);
|
|
20904
21211
|
var hostname = process.env.HOSTNAME ?? "0.0.0.0";
|
|
20905
|
-
var httpServer = serve({ fetch:
|
|
21212
|
+
var httpServer = serve({ fetch: app30.fetch, port, hostname });
|
|
20906
21213
|
attachVncWsProxy(httpServer, {
|
|
20907
21214
|
isPublicHost,
|
|
20908
21215
|
upstreamHost: "127.0.0.1",
|
|
@@ -20948,7 +21255,7 @@ for (const m of SUBAPP_MANIFEST) {
|
|
|
20948
21255
|
}
|
|
20949
21256
|
try {
|
|
20950
21257
|
const registered = [];
|
|
20951
|
-
for (const r of
|
|
21258
|
+
for (const r of app30.routes ?? []) {
|
|
20952
21259
|
if (typeof r.path !== "string" || r.path.includes(":") || r.path.includes("*")) continue;
|
|
20953
21260
|
if (AGENT_SLUG_PATTERN.test(r.path)) {
|
|
20954
21261
|
registered.push({ method: (r.method ?? "ALL").toUpperCase(), path: r.path });
|