@rubytech/create-maxy-code 0.1.187 → 0.1.188
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/lib/graph-mcp/dist/index.js +4 -3
- package/payload/platform/lib/graph-mcp/dist/index.js.map +1 -1
- package/payload/platform/lib/graph-mcp/src/index.ts +4 -3
- package/payload/platform/package.json +1 -0
- package/payload/platform/plugins/.claude-plugin/marketplace.json +5 -0
- package/payload/platform/plugins/admin/PLUGIN.md +1 -0
- package/payload/platform/plugins/admin/hooks/lib/maxy-mcp-plugins.txt +16 -0
- package/payload/platform/plugins/admin/hooks/mcp-tool-missing.sh +94 -0
- package/payload/platform/plugins/admin/hooks/turn-completed-graph-write.sh +7 -0
- package/payload/platform/plugins/admin/skills/publish-site/SKILL.md +3 -3
- package/payload/platform/plugins/admin/skills/stream-log-review/references/analysis-patterns.md +11 -7
- package/payload/platform/plugins/docs/references/admin-ui.md +3 -4
- package/payload/platform/plugins/docs/references/deployment.md +1 -1
- package/payload/platform/plugins/docs/references/internals.md +6 -4
- package/payload/platform/plugins/docs/references/plugins-guide.md +2 -2
- package/payload/platform/plugins/graph/.claude-plugin/plugin.json +8 -0
- package/payload/platform/plugins/graph/PLUGIN.md +37 -0
- package/payload/platform/plugins/memory/PLUGIN.md +2 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/conversation-archive-derive-insights.d.ts +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/conversation-archive-derive-insights.js +1 -1
- package/payload/platform/plugins/memory/references/graph-primitives.md +36 -27
- package/payload/platform/plugins/obsidian-import/PLUGIN.md +1 -1
- package/payload/platform/scripts/check-canonical-tool-names.mjs +110 -0
- package/payload/platform/scripts/generate-canonical-tool-names.mjs +63 -0
- package/payload/platform/scripts/lib/canonical-tool-names.mjs +88 -0
- package/payload/platform/scripts/setup-account.sh +6 -0
- package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.d.ts +7 -0
- package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.d.ts.map +1 -0
- package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.d.ts +5 -0
- package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.d.ts.map +1 -0
- package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.js +204 -0
- package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.js.map +1 -0
- package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.js +23 -0
- package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.js.map +1 -0
- package/payload/platform/services/claude-session-manager/dist/index.js +30 -6
- package/payload/platform/services/claude-session-manager/dist/index.js.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/mcp-tools-probe.d.ts +6 -4
- package/payload/platform/services/claude-session-manager/dist/mcp-tools-probe.d.ts.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/mcp-tools-probe.js.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/pty-spawner.d.ts +1 -0
- 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 +50 -26
- package/payload/platform/services/claude-session-manager/dist/pty-spawner.js.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/rc-daemon.d.ts +40 -0
- package/payload/platform/services/claude-session-manager/dist/rc-daemon.d.ts.map +1 -0
- package/payload/platform/services/claude-session-manager/dist/rc-daemon.js +200 -0
- package/payload/platform/services/claude-session-manager/dist/rc-daemon.js.map +1 -0
- package/payload/platform/services/claude-session-manager/dist/specialist-drift.d.ts.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/specialist-drift.js +50 -34
- package/payload/platform/services/claude-session-manager/dist/specialist-drift.js.map +1 -1
- 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 +23 -13
- package/payload/platform/services/claude-session-manager/dist/tool-surface.js.map +1 -1
- package/payload/platform/templates/specialists/agents/content-producer.md +3 -3
- package/payload/platform/templates/specialists/agents/librarian.md +2 -2
- package/payload/platform/templates/specialists/agents/personal-assistant.md +1 -1
- package/payload/platform/templates/specialists/agents/project-manager.md +1 -1
- package/payload/platform/templates/specialists/agents/research-assistant.md +1 -1
- package/payload/server/{chunk-EFJ2EXZK.js → chunk-WWD4TCJJ.js} +0 -16
- package/payload/server/maxy-edge.js +1 -1
- package/payload/server/public/assets/Checkbox-ChWmQ7if.js +1 -0
- package/payload/server/public/assets/admin-BLi_fAKQ.js +216 -0
- package/payload/server/public/assets/{architectureDiagram-Q4EWVU46-DZoOzmjE.js → architectureDiagram-Q4EWVU46-DSqzB21V.js} +1 -1
- package/payload/server/public/assets/{blockDiagram-DXYQGD6D-DG3yufCR.js → blockDiagram-DXYQGD6D--otTO_UB.js} +1 -1
- package/payload/server/public/assets/brand-Djtb-tLQ.js +9 -0
- package/payload/server/public/assets/{c4Diagram-AHTNJAMY-BBx5wXuZ.js → c4Diagram-AHTNJAMY-CBszqa9W.js} +1 -1
- package/payload/server/public/assets/channel-C-SJYogg.js +1 -0
- package/payload/server/public/assets/{chunk-336JU56O-DwP7g5ns.js → chunk-336JU56O-ClAJP2KY.js} +2 -2
- package/payload/server/public/assets/{chunk-426QAEUC-DXzGdc22.js → chunk-426QAEUC-CgLucS4H.js} +1 -1
- package/payload/server/public/assets/{chunk-4TB4RGXK-1LDRjk0E.js → chunk-4TB4RGXK-BvOX6mSk.js} +1 -1
- package/payload/server/public/assets/{chunk-5FUZZQ4R-BHjWhwhn.js → chunk-5FUZZQ4R-uyN4XtrW.js} +1 -1
- package/payload/server/public/assets/{chunk-5PVQY5BW-CwPHRVN8.js → chunk-5PVQY5BW-B6xHEzh2.js} +1 -1
- package/payload/server/public/assets/{chunk-EDXVE4YY-7443hrYZ.js → chunk-EDXVE4YY-9objw8tW.js} +1 -1
- package/payload/server/public/assets/{chunk-ENJZ2VHE-BTnmmnmX.js → chunk-ENJZ2VHE-pQpbHIJL.js} +1 -1
- package/payload/server/public/assets/{chunk-ICPOFSXX-CPnMJplL.js → chunk-ICPOFSXX-qS23jC3x.js} +1 -1
- package/payload/server/public/assets/{chunk-OYMX7WX6-DCQ5Q4RS.js → chunk-OYMX7WX6-C9YUwGqp.js} +1 -1
- package/payload/server/public/assets/{chunk-U2HBQHQK-BmfZG8e4.js → chunk-U2HBQHQK-D_pYedRJ.js} +1 -1
- package/payload/server/public/assets/{chunk-X2U36JSP-Da2yJL2u.js → chunk-X2U36JSP-nxf6GHD-.js} +1 -1
- package/payload/server/public/assets/{chunk-YZCP3GAM-BdUmMUJ6.js → chunk-YZCP3GAM-DqKT124V.js} +1 -1
- package/payload/server/public/assets/{chunk-ZZ45TVLE-abkGirrZ.js → chunk-ZZ45TVLE-CLwvpbvu.js} +1 -1
- package/payload/server/public/assets/classDiagram-6PBFFD2Q-OBkxl5to.js +1 -0
- package/payload/server/public/assets/classDiagram-v2-HSJHXN6E-CkTyus-1.js +1 -0
- package/payload/server/public/assets/clone-VufdPzJ-.js +1 -0
- package/payload/server/public/assets/{dagre-BVVuAEsU.js → dagre-COCXt23n.js} +1 -1
- package/payload/server/public/assets/{dagre-KV5264BT-VG2kNj19.js → dagre-KV5264BT-DmuVMrt4.js} +1 -1
- package/payload/server/public/assets/data-TlJbMIfa.js +1 -0
- package/payload/server/public/assets/{diagram-5BDNPKRD-DRiVy69K.js → diagram-5BDNPKRD-DOiLSgj_.js} +1 -1
- package/payload/server/public/assets/{diagram-G4DWMVQ6-DtpiRTYX.js → diagram-G4DWMVQ6-quY6PSZQ.js} +1 -1
- package/payload/server/public/assets/{diagram-MMDJMWI5-Da3t99fY.js → diagram-MMDJMWI5-tN2yiz0C.js} +1 -1
- package/payload/server/public/assets/{diagram-TYMM5635-BzQmLTJQ.js → diagram-TYMM5635-CjrRQNQ0.js} +1 -1
- package/payload/server/public/assets/{erDiagram-SMLLAGMA-D3Ll-GDw.js → erDiagram-SMLLAGMA-CrNNMxkA.js} +1 -1
- package/payload/server/public/assets/{flowDiagram-DWJPFMVM-D17bje6d.js → flowDiagram-DWJPFMVM-CCUsJph7.js} +1 -1
- package/payload/server/public/assets/{ganttDiagram-T4ZO3ILL-BjeQ-Bun.js → ganttDiagram-T4ZO3ILL-18276bri.js} +1 -1
- package/payload/server/public/assets/{gitGraphDiagram-UUTBAWPF-LtX4pvZS.js → gitGraphDiagram-UUTBAWPF-CsLsKMjN.js} +1 -1
- package/payload/server/public/assets/graph-D2Yvni5R.js +1 -0
- package/payload/server/public/assets/graph-labels-uksnCgSC.js +1 -0
- package/payload/server/public/assets/{graphlib-CzwsfZOw.js → graphlib-CmtUzIni.js} +1 -1
- package/payload/server/public/assets/{infoDiagram-42DDH7IO-DOgH4i52.js → infoDiagram-42DDH7IO-Dny_ZNz3.js} +1 -1
- package/payload/server/public/assets/{ishikawaDiagram-UXIWVN3A-DYqy5BFj.js → ishikawaDiagram-UXIWVN3A-kUhIUQE-.js} +1 -1
- package/payload/server/public/assets/{journeyDiagram-VCZTEJTY-CsFpIULJ.js → journeyDiagram-VCZTEJTY-DekMvAKB.js} +1 -1
- package/payload/server/public/assets/{kanban-definition-6JOO6SKY-5uZuArw7.js → kanban-definition-6JOO6SKY-st0HNZZo.js} +1 -1
- package/payload/server/public/assets/lib-Ca7uCvl9.js +33 -0
- package/payload/server/public/assets/{line-BY8PmCSW.js → line-BaNk-I7J.js} +1 -1
- package/payload/server/public/assets/{mermaid-parser.core-CJ_9xqwK.js → mermaid-parser.core-CRCHYQ_F.js} +1 -1
- package/payload/server/public/assets/{mermaid.core-CXznBkX7.js → mermaid.core-BaIYEciF.js} +3 -3
- package/payload/server/public/assets/{mindmap-definition-QFDTVHPH-DZbHBud5.js → mindmap-definition-QFDTVHPH-D4u4KU2v.js} +1 -1
- package/payload/server/public/assets/{page-CfN7nw1J.js → page-DayPduMN.js} +2 -2
- package/payload/server/public/assets/page-QQmuB04w.js +1 -0
- package/payload/server/public/assets/{pieDiagram-DEJITSTG-QmOi4DRG.js → pieDiagram-DEJITSTG-BItWEilY.js} +1 -1
- package/payload/server/public/assets/public-Dze4yArS.js +7 -0
- package/payload/server/public/assets/{quadrantDiagram-34T5L4WZ-Cpidq6Xj.js → quadrantDiagram-34T5L4WZ-CeWDBvmH.js} +1 -1
- package/payload/server/public/assets/{requirementDiagram-MS252O5E-CBqtfbzR.js → requirementDiagram-MS252O5E-CcosjedW.js} +1 -1
- package/payload/server/public/assets/{sankeyDiagram-XADWPNL6-4BiY4dV9.js → sankeyDiagram-XADWPNL6-DNGeFpUj.js} +1 -1
- package/payload/server/public/assets/{sequenceDiagram-FGHM5R23-DVlL-l2u.js → sequenceDiagram-FGHM5R23-Cqy_deB6.js} +1 -1
- package/payload/server/public/assets/{stateDiagram-FHFEXIEX-CAm9dW68.js → stateDiagram-FHFEXIEX-2yoAqEsA.js} +1 -1
- package/payload/server/public/assets/stateDiagram-v2-QKLJ7IA2-Dc5siYvu.js +1 -0
- package/payload/server/public/assets/{timeline-definition-GMOUNBTQ-CD-tZc4y.js → timeline-definition-GMOUNBTQ-Dmeghpw1.js} +1 -1
- package/payload/server/public/assets/{vennDiagram-DHZGUBPP-Davcm0TF.js → vennDiagram-DHZGUBPP-TX5D-Zzp.js} +1 -1
- package/payload/server/public/assets/{wardleyDiagram-NUSXRM2D-40LBYw_Y.js → wardleyDiagram-NUSXRM2D-B7mcpl5E.js} +1 -1
- package/payload/server/public/assets/{xychartDiagram-5P7HB3ND-DEPT-__v.js → xychartDiagram-5P7HB3ND-DH77CxKf.js} +1 -1
- package/payload/server/public/brand/Archive/favicon.ico +0 -0
- package/payload/server/public/brand/Archive/maxy-black.png +0 -0
- package/payload/server/public/brand/Archive/maxy-horizontal.png +0 -0
- package/payload/server/public/brand/Archive/maxy-monochrome.png +0 -0
- package/payload/server/public/brand/Archive/maxy-square.png +0 -0
- package/payload/server/public/brand/Archive/maxy.png +0 -0
- package/payload/server/public/brand/Archive/star.png +0 -0
- package/payload/server/public/brand/Archive.zip +0 -0
- 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 +312 -793
- package/payload/server/public/assets/ChatInput-CvRaT05l.js +0 -13
- package/payload/server/public/assets/Checkbox-BJKNkUYu.js +0 -1
- package/payload/server/public/assets/admin-BNy4N2d6.js +0 -217
- package/payload/server/public/assets/channel-DdtUtt5g.js +0 -1
- package/payload/server/public/assets/classDiagram-6PBFFD2Q-CKk2DFZe.js +0 -1
- package/payload/server/public/assets/classDiagram-v2-HSJHXN6E--YvfDQCh.js +0 -1
- package/payload/server/public/assets/clone-Cw6UfPGM.js +0 -1
- package/payload/server/public/assets/data-uBpwaldK.js +0 -1
- package/payload/server/public/assets/graph-labels-Cn9jAE6I.js +0 -1
- package/payload/server/public/assets/graph-tvTPvBaz.js +0 -1
- package/payload/server/public/assets/lib-p4ylk2XS.js +0 -29
- package/payload/server/public/assets/page-B3VYaBcf.js +0 -1
- package/payload/server/public/assets/public-Bbew78md.js +0 -7
- package/payload/server/public/assets/stateDiagram-v2-QKLJ7IA2-B2EzXi50.js +0 -1
- /package/payload/server/public/assets/{ChatInput-DzacFNMk.css → brand-DzacFNMk.css} +0 -0
package/payload/server/server.js
CHANGED
|
@@ -38,7 +38,6 @@ import {
|
|
|
38
38
|
getRecentMessages,
|
|
39
39
|
getRoleForSession,
|
|
40
40
|
getSession,
|
|
41
|
-
getSessionIdByClaudeSessionId,
|
|
42
41
|
getSessionIdForSession,
|
|
43
42
|
getSessionKeyBySessionId,
|
|
44
43
|
getUserIdForSession,
|
|
@@ -84,7 +83,7 @@ import {
|
|
|
84
83
|
vncLog,
|
|
85
84
|
walkPremiumBundles,
|
|
86
85
|
writeAdminUserAndPerson
|
|
87
|
-
} from "./chunk-
|
|
86
|
+
} from "./chunk-WWD4TCJJ.js";
|
|
88
87
|
import {
|
|
89
88
|
__commonJS,
|
|
90
89
|
__toESM
|
|
@@ -816,9 +815,9 @@ var serveStatic = (options = { root: "" }) => {
|
|
|
816
815
|
};
|
|
817
816
|
|
|
818
817
|
// server/index.ts
|
|
819
|
-
import { readFileSync as
|
|
820
|
-
import { resolve as resolve22, join as
|
|
821
|
-
import { homedir as
|
|
818
|
+
import { readFileSync as readFileSync20, existsSync as existsSync23, watchFile } from "fs";
|
|
819
|
+
import { resolve as resolve22, join as join14, basename as basename5 } from "path";
|
|
820
|
+
import { homedir as homedir2 } from "os";
|
|
822
821
|
import { monitorEventLoopDelay } from "perf_hooks";
|
|
823
822
|
|
|
824
823
|
// app/lib/agent-slug-pattern.ts
|
|
@@ -6780,64 +6779,6 @@ app6.post("/", async (c) => {
|
|
|
6780
6779
|
});
|
|
6781
6780
|
var session_default = app6;
|
|
6782
6781
|
|
|
6783
|
-
// server/routes/admin/new-session-failure.ts
|
|
6784
|
-
var REASON_VALUES = /* @__PURE__ */ new Set(["server-status", "network-error"]);
|
|
6785
|
-
var ISO_RE = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d{1,3})?(?:Z|[+-]\d{2}:\d{2})$/;
|
|
6786
|
-
var app7 = new Hono();
|
|
6787
|
-
app7.post("/", requireAdminSession, async (c) => {
|
|
6788
|
-
let body;
|
|
6789
|
-
try {
|
|
6790
|
-
body = await c.req.json();
|
|
6791
|
-
} catch {
|
|
6792
|
-
console.error(`[admin-chat] new-conversation outcome=fail reason=schema:body-not-json`);
|
|
6793
|
-
return c.json({ ok: false, reason: "body-not-json" }, 400);
|
|
6794
|
-
}
|
|
6795
|
-
if (typeof body.reason !== "string" || !REASON_VALUES.has(body.reason)) {
|
|
6796
|
-
console.error(`[admin-chat] new-conversation outcome=fail reason=schema:reason`);
|
|
6797
|
-
return c.json({ ok: false, reason: "schema:reason" }, 400);
|
|
6798
|
-
}
|
|
6799
|
-
if (typeof body.at !== "string" || !ISO_RE.test(body.at)) {
|
|
6800
|
-
console.error(`[admin-chat] new-conversation outcome=fail reason=schema:at`);
|
|
6801
|
-
return c.json({ ok: false, reason: "schema:at" }, 400);
|
|
6802
|
-
}
|
|
6803
|
-
let statusToken;
|
|
6804
|
-
if (body.reason === "server-status") {
|
|
6805
|
-
if (typeof body.status !== "number" || !Number.isInteger(body.status) || body.status < 100 || body.status > 599) {
|
|
6806
|
-
console.error(`[admin-chat] new-conversation outcome=fail reason=schema:status`);
|
|
6807
|
-
return c.json({ ok: false, reason: "schema:status" }, 400);
|
|
6808
|
-
}
|
|
6809
|
-
statusToken = String(body.status);
|
|
6810
|
-
} else {
|
|
6811
|
-
statusToken = "net";
|
|
6812
|
-
}
|
|
6813
|
-
const cacheKey = c.var.cacheKey;
|
|
6814
|
-
const cacheKeyTag = cacheKey.slice(0, 8);
|
|
6815
|
-
console.log(`[admin-chat] new-conversation outcome=fail cacheKey=${cacheKeyTag} status=${statusToken} reason=${body.reason} at=${body.at}`);
|
|
6816
|
-
return c.body(null, 204);
|
|
6817
|
-
});
|
|
6818
|
-
var new_session_failure_default = app7;
|
|
6819
|
-
|
|
6820
|
-
// server/routes/admin/new-session-submit.ts
|
|
6821
|
-
var ISO_RE2 = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d{1,3})?(?:Z|[+-]\d{2}:\d{2})$/;
|
|
6822
|
-
var app8 = new Hono();
|
|
6823
|
-
app8.post("/", requireAdminSession, async (c) => {
|
|
6824
|
-
let body;
|
|
6825
|
-
try {
|
|
6826
|
-
body = await c.req.json();
|
|
6827
|
-
} catch {
|
|
6828
|
-
console.error(`[admin-chat] new-conversation outcome=submit reason=schema:body-not-json`);
|
|
6829
|
-
return c.json({ ok: false, reason: "body-not-json" }, 400);
|
|
6830
|
-
}
|
|
6831
|
-
if (typeof body.at !== "string" || !ISO_RE2.test(body.at)) {
|
|
6832
|
-
console.error(`[admin-chat] new-conversation outcome=submit reason=schema:at`);
|
|
6833
|
-
return c.json({ ok: false, reason: "schema:at" }, 400);
|
|
6834
|
-
}
|
|
6835
|
-
const cacheKey = c.var.cacheKey;
|
|
6836
|
-
console.log(`[admin-chat] new-conversation outcome=submit cacheKey=${cacheKey.slice(0, 8)} at=${body.at}`);
|
|
6837
|
-
return c.body(null, 204);
|
|
6838
|
-
});
|
|
6839
|
-
var new_session_submit_default = app8;
|
|
6840
|
-
|
|
6841
6782
|
// server/routes/admin/logs.ts
|
|
6842
6783
|
import { existsSync as existsSync10, readdirSync as readdirSync5, readFileSync as readFileSync10, statSync as statSync5 } from "fs";
|
|
6843
6784
|
import { resolve as resolve7, basename as basename3 } from "path";
|
|
@@ -6859,8 +6800,8 @@ function resolveSessionLogPaths(filename, logDirs) {
|
|
|
6859
6800
|
|
|
6860
6801
|
// server/routes/admin/logs.ts
|
|
6861
6802
|
var TAIL_BYTES = 8192;
|
|
6862
|
-
var
|
|
6863
|
-
|
|
6803
|
+
var app7 = new Hono();
|
|
6804
|
+
app7.get("/", async (c) => {
|
|
6864
6805
|
const fileParam = c.req.query("file");
|
|
6865
6806
|
const typeParam = c.req.query("type");
|
|
6866
6807
|
const sessionIdParam = c.req.query("sessionId");
|
|
@@ -7002,12 +6943,12 @@ app9.get("/", async (c) => {
|
|
|
7002
6943
|
}
|
|
7003
6944
|
return c.json({ logs });
|
|
7004
6945
|
});
|
|
7005
|
-
var logs_default =
|
|
6946
|
+
var logs_default = app7;
|
|
7006
6947
|
|
|
7007
6948
|
// server/routes/admin/claude-info.ts
|
|
7008
6949
|
import { execFileSync as execFileSync3 } from "child_process";
|
|
7009
|
-
var
|
|
7010
|
-
|
|
6950
|
+
var app8 = new Hono();
|
|
6951
|
+
app8.get("/", (c) => {
|
|
7011
6952
|
let version = "unknown";
|
|
7012
6953
|
try {
|
|
7013
6954
|
const raw = execFileSync3("claude", ["--version"], { encoding: "utf-8", timeout: 5e3 });
|
|
@@ -7025,55 +6966,14 @@ app10.get("/", (c) => {
|
|
|
7025
6966
|
const thinkingView = resolvedAccount?.config.thinkingView ?? "default";
|
|
7026
6967
|
return c.json({ version, account, model, thinkingView });
|
|
7027
6968
|
});
|
|
7028
|
-
var claude_info_default =
|
|
7029
|
-
|
|
7030
|
-
// server/routes/admin/claude-capabilities.ts
|
|
7031
|
-
import { existsSync as existsSync11, readFileSync as readFileSync11 } from "fs";
|
|
7032
|
-
import { dirname as dirname2, join as join10 } from "path";
|
|
7033
|
-
import { homedir } from "os";
|
|
7034
|
-
var app11 = new Hono();
|
|
7035
|
-
function resolveClaudeJsonPath() {
|
|
7036
|
-
const configDir2 = process.env.CLAUDE_CONFIG_DIR ?? join10(homedir(), ".claude");
|
|
7037
|
-
return join10(dirname2(configDir2), ".claude.json");
|
|
7038
|
-
}
|
|
7039
|
-
function readSeatTier(path2) {
|
|
7040
|
-
if (!existsSync11(path2)) return null;
|
|
7041
|
-
let raw;
|
|
7042
|
-
try {
|
|
7043
|
-
raw = readFileSync11(path2, "utf8");
|
|
7044
|
-
} catch {
|
|
7045
|
-
return null;
|
|
7046
|
-
}
|
|
7047
|
-
let parsed;
|
|
7048
|
-
try {
|
|
7049
|
-
parsed = JSON.parse(raw);
|
|
7050
|
-
} catch {
|
|
7051
|
-
return null;
|
|
7052
|
-
}
|
|
7053
|
-
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return null;
|
|
7054
|
-
const oauth = parsed.oauthAccount;
|
|
7055
|
-
if (!oauth || typeof oauth !== "object" || Array.isArray(oauth)) return null;
|
|
7056
|
-
const seatTier = oauth.seatTier;
|
|
7057
|
-
if (typeof seatTier !== "string") return null;
|
|
7058
|
-
return seatTier;
|
|
7059
|
-
}
|
|
7060
|
-
app11.get("/", (c) => {
|
|
7061
|
-
const path2 = resolveClaudeJsonPath();
|
|
7062
|
-
const seatTier = readSeatTier(path2);
|
|
7063
|
-
const body = {
|
|
7064
|
-
seatTier,
|
|
7065
|
-
autoModeAvailable: typeof seatTier === "string" && seatTier.length > 0
|
|
7066
|
-
};
|
|
7067
|
-
return c.json(body);
|
|
7068
|
-
});
|
|
7069
|
-
var claude_capabilities_default = app11;
|
|
6969
|
+
var claude_info_default = app8;
|
|
7070
6970
|
|
|
7071
6971
|
// server/routes/admin/attachment.ts
|
|
7072
6972
|
import { readFile as readFile3, readdir } from "fs/promises";
|
|
7073
|
-
import { existsSync as
|
|
6973
|
+
import { existsSync as existsSync11 } from "fs";
|
|
7074
6974
|
import { resolve as resolve8 } from "path";
|
|
7075
|
-
var
|
|
7076
|
-
|
|
6975
|
+
var app9 = new Hono();
|
|
6976
|
+
app9.get("/:attachmentId", requireAdminSession, async (c) => {
|
|
7077
6977
|
const attachmentId = c.req.param("attachmentId");
|
|
7078
6978
|
const cacheKey = c.var.cacheKey;
|
|
7079
6979
|
const accountId = getAccountIdForSession(cacheKey);
|
|
@@ -7084,11 +6984,11 @@ app12.get("/:attachmentId", requireAdminSession, async (c) => {
|
|
|
7084
6984
|
return new Response("Not found", { status: 404 });
|
|
7085
6985
|
}
|
|
7086
6986
|
const dir = resolve8(ATTACHMENTS_ROOT, accountId, attachmentId);
|
|
7087
|
-
if (!
|
|
6987
|
+
if (!existsSync11(dir)) {
|
|
7088
6988
|
return new Response("Not found", { status: 404 });
|
|
7089
6989
|
}
|
|
7090
6990
|
const metaPath = resolve8(dir, `${attachmentId}.meta.json`);
|
|
7091
|
-
if (!
|
|
6991
|
+
if (!existsSync11(metaPath)) {
|
|
7092
6992
|
return new Response("Not found", { status: 404 });
|
|
7093
6993
|
}
|
|
7094
6994
|
let meta;
|
|
@@ -7112,17 +7012,17 @@ app12.get("/:attachmentId", requireAdminSession, async (c) => {
|
|
|
7112
7012
|
}
|
|
7113
7013
|
});
|
|
7114
7014
|
});
|
|
7115
|
-
var attachment_default =
|
|
7015
|
+
var attachment_default = app9;
|
|
7116
7016
|
|
|
7117
7017
|
// server/routes/admin/agents.ts
|
|
7118
7018
|
import { resolve as resolve9 } from "path";
|
|
7119
|
-
import { readdirSync as readdirSync6, readFileSync as
|
|
7120
|
-
var
|
|
7121
|
-
|
|
7019
|
+
import { readdirSync as readdirSync6, readFileSync as readFileSync11, existsSync as existsSync12, rmSync } from "fs";
|
|
7020
|
+
var app10 = new Hono();
|
|
7021
|
+
app10.get("/", (c) => {
|
|
7122
7022
|
const account = resolveAccount();
|
|
7123
7023
|
if (!account) return c.json({ agents: [] });
|
|
7124
7024
|
const agentsDir = resolve9(account.accountDir, "agents");
|
|
7125
|
-
if (!
|
|
7025
|
+
if (!existsSync12(agentsDir)) return c.json({ agents: [] });
|
|
7126
7026
|
const agents = [];
|
|
7127
7027
|
try {
|
|
7128
7028
|
const entries = readdirSync6(agentsDir, { withFileTypes: true });
|
|
@@ -7130,9 +7030,9 @@ app13.get("/", (c) => {
|
|
|
7130
7030
|
if (!entry.isDirectory()) continue;
|
|
7131
7031
|
if (entry.name === "admin") continue;
|
|
7132
7032
|
const configPath2 = resolve9(agentsDir, entry.name, "config.json");
|
|
7133
|
-
if (!
|
|
7033
|
+
if (!existsSync12(configPath2)) continue;
|
|
7134
7034
|
try {
|
|
7135
|
-
const config = JSON.parse(
|
|
7035
|
+
const config = JSON.parse(readFileSync11(configPath2, "utf-8"));
|
|
7136
7036
|
agents.push({
|
|
7137
7037
|
slug: entry.name,
|
|
7138
7038
|
displayName: config.displayName ?? entry.name,
|
|
@@ -7148,7 +7048,7 @@ app13.get("/", (c) => {
|
|
|
7148
7048
|
}
|
|
7149
7049
|
return c.json({ agents });
|
|
7150
7050
|
});
|
|
7151
|
-
|
|
7051
|
+
app10.delete("/:slug", async (c) => {
|
|
7152
7052
|
const slug = c.req.param("slug");
|
|
7153
7053
|
const account = resolveAccount();
|
|
7154
7054
|
if (!account) return c.json({ error: "No account resolved" }, 400);
|
|
@@ -7159,7 +7059,7 @@ app13.delete("/:slug", async (c) => {
|
|
|
7159
7059
|
return c.json({ error: "Invalid agent slug" }, 400);
|
|
7160
7060
|
}
|
|
7161
7061
|
const agentDir = resolve9(account.accountDir, "agents", slug);
|
|
7162
|
-
if (!
|
|
7062
|
+
if (!existsSync12(agentDir)) {
|
|
7163
7063
|
return c.json({ error: "Agent not found" }, 404);
|
|
7164
7064
|
}
|
|
7165
7065
|
try {
|
|
@@ -7178,7 +7078,7 @@ app13.delete("/:slug", async (c) => {
|
|
|
7178
7078
|
return c.json({ error: "Failed to delete agent" }, 500);
|
|
7179
7079
|
}
|
|
7180
7080
|
});
|
|
7181
|
-
|
|
7081
|
+
app10.post("/:slug/project", async (c) => {
|
|
7182
7082
|
const slug = c.req.param("slug");
|
|
7183
7083
|
const account = resolveAccount();
|
|
7184
7084
|
if (!account) return c.json({ error: "No account resolved" }, 400);
|
|
@@ -7189,7 +7089,7 @@ app13.post("/:slug/project", async (c) => {
|
|
|
7189
7089
|
return c.json({ error: "Invalid agent slug" }, 400);
|
|
7190
7090
|
}
|
|
7191
7091
|
const agentDir = resolve9(account.accountDir, "agents", slug);
|
|
7192
|
-
if (!
|
|
7092
|
+
if (!existsSync12(agentDir)) {
|
|
7193
7093
|
return c.json({ error: "Agent not found on disk" }, 404);
|
|
7194
7094
|
}
|
|
7195
7095
|
try {
|
|
@@ -7200,12 +7100,12 @@ app13.post("/:slug/project", async (c) => {
|
|
|
7200
7100
|
return c.json({ error: `Projection failed: ${msg}` }, 500);
|
|
7201
7101
|
}
|
|
7202
7102
|
});
|
|
7203
|
-
var agents_default =
|
|
7103
|
+
var agents_default = app10;
|
|
7204
7104
|
|
|
7205
7105
|
// server/routes/admin/sessions.ts
|
|
7206
7106
|
import crypto from "crypto";
|
|
7207
7107
|
import { resolve as resolvePath } from "path";
|
|
7208
|
-
import { existsSync as
|
|
7108
|
+
import { existsSync as existsSync13, mkdirSync as mkdirSync3, createWriteStream } from "fs";
|
|
7209
7109
|
|
|
7210
7110
|
// ../lib/admin-conversation-purge/src/index.ts
|
|
7211
7111
|
async function purgeAdminConversationJsonls(args) {
|
|
@@ -7343,7 +7243,7 @@ var replayJsonl = (..._args) => null;
|
|
|
7343
7243
|
var resolveJsonlPath = (..._args) => null;
|
|
7344
7244
|
|
|
7345
7245
|
// server/routes/admin/sessions.ts
|
|
7346
|
-
import { homedir
|
|
7246
|
+
import { homedir } from "os";
|
|
7347
7247
|
|
|
7348
7248
|
// app/lib/claude-agent/component-attachment.ts
|
|
7349
7249
|
var pickComponentBytes = (..._args) => null;
|
|
@@ -7383,7 +7283,7 @@ function validateAndShapeAttachments(raws, conversationAccountId, sessionId, mes
|
|
|
7383
7283
|
let reason = null;
|
|
7384
7284
|
if (!a.attachmentId || !a.filename || !a.mimeType || !a.storagePath) reason = "schema-fail";
|
|
7385
7285
|
else if (a.accountId !== conversationAccountId) reason = "account-mismatch";
|
|
7386
|
-
else if (!
|
|
7286
|
+
else if (!existsSync13(a.storagePath)) reason = "missing-file";
|
|
7387
7287
|
if (reason) {
|
|
7388
7288
|
invalid++;
|
|
7389
7289
|
try {
|
|
@@ -7490,8 +7390,8 @@ function formatAge(updatedAtStr) {
|
|
|
7490
7390
|
return "unknown";
|
|
7491
7391
|
}
|
|
7492
7392
|
}
|
|
7493
|
-
var
|
|
7494
|
-
|
|
7393
|
+
var app11 = new Hono();
|
|
7394
|
+
app11.get("/", requireAdminSession, async (c) => {
|
|
7495
7395
|
const cacheKey = c.var.cacheKey;
|
|
7496
7396
|
const accountId = getAccountIdForSession(cacheKey);
|
|
7497
7397
|
if (!accountId) return c.json({ error: "Account not found for session" }, 401);
|
|
@@ -7521,7 +7421,7 @@ app14.get("/", requireAdminSession, async (c) => {
|
|
|
7521
7421
|
return c.json({ error: "Failed to fetch sessions" }, 500);
|
|
7522
7422
|
}
|
|
7523
7423
|
});
|
|
7524
|
-
|
|
7424
|
+
app11.post("/new", requireAdminSession, async (c) => {
|
|
7525
7425
|
const oldCacheKey = c.var.cacheKey;
|
|
7526
7426
|
console.log(`[admin-chat] new-conversation outcome=ingress cacheKey=${oldCacheKey.slice(0, 8)}`);
|
|
7527
7427
|
const accountId = getAccountIdForSession(oldCacheKey);
|
|
@@ -7538,7 +7438,7 @@ app14.post("/new", requireAdminSession, async (c) => {
|
|
|
7538
7438
|
console.log(`[admin-chat] new-conversation outcome=ok oldKey=${oldCacheKey.slice(0, 8)} newKey=${newCacheKey.slice(0, 8)}`);
|
|
7539
7439
|
return c.json({ session_key: newSignedSessionToken, sessionId: null });
|
|
7540
7440
|
});
|
|
7541
|
-
|
|
7441
|
+
app11.post("/switch", requireAdminSession, async (c) => {
|
|
7542
7442
|
const cacheKey = c.var.cacheKey;
|
|
7543
7443
|
const accountId = getAccountIdForSession(cacheKey);
|
|
7544
7444
|
const userId = getUserIdForSession(cacheKey);
|
|
@@ -7566,7 +7466,7 @@ app14.post("/switch", requireAdminSession, async (c) => {
|
|
|
7566
7466
|
console.log(`[session-switch] from=${cacheKey.slice(0, 8)} to=${targetCacheKey.slice(0, 8)} targetConvId=${targetSessionId?.slice(0, 8) ?? "none"} accountId=${accountId.slice(0, 8)}`);
|
|
7567
7467
|
return c.json({ session_key: targetSignedSessionToken, sessionId: targetSessionId });
|
|
7568
7468
|
});
|
|
7569
|
-
|
|
7469
|
+
app11.delete("/:id", requireAdminSession, async (c) => {
|
|
7570
7470
|
const sessionId = c.req.param("id");
|
|
7571
7471
|
const cacheKey = c.var.cacheKey;
|
|
7572
7472
|
const accountId = getAccountIdForSession(cacheKey);
|
|
@@ -7612,7 +7512,7 @@ app14.delete("/:id", requireAdminSession, async (c) => {
|
|
|
7612
7512
|
500
|
|
7613
7513
|
);
|
|
7614
7514
|
});
|
|
7615
|
-
|
|
7515
|
+
app11.post("/:id/resume", async (c) => {
|
|
7616
7516
|
const sessionId = c.req.param("id");
|
|
7617
7517
|
const t0 = Date.now();
|
|
7618
7518
|
const signedSessionToken = c.req.query("session_key") ?? "";
|
|
@@ -7677,7 +7577,7 @@ app14.post("/:id/resume", async (c) => {
|
|
|
7677
7577
|
return c.json({ error: "Failed to load conversation messages" }, 500);
|
|
7678
7578
|
}
|
|
7679
7579
|
if (persistedAgentSessionId) {
|
|
7680
|
-
const jsonlPath = resolveJsonlPath(
|
|
7580
|
+
const jsonlPath = resolveJsonlPath(homedir(), resolvePath(ACCOUNTS_DIR, accountId), persistedAgentSessionId);
|
|
7681
7581
|
const replay = replayJsonl(jsonlPath);
|
|
7682
7582
|
jsonlMissing = replay.jsonlMissing;
|
|
7683
7583
|
jsonlMalformedLines = replay.malformedLines;
|
|
@@ -7885,7 +7785,7 @@ app14.post("/:id/resume", async (c) => {
|
|
|
7885
7785
|
}
|
|
7886
7786
|
});
|
|
7887
7787
|
});
|
|
7888
|
-
|
|
7788
|
+
app11.put("/:id/label", requireAdminSession, async (c) => {
|
|
7889
7789
|
const sessionId = c.req.param("id");
|
|
7890
7790
|
const cacheKey = c.var.cacheKey;
|
|
7891
7791
|
let body;
|
|
@@ -7911,11 +7811,11 @@ app14.put("/:id/label", requireAdminSession, async (c) => {
|
|
|
7911
7811
|
return c.json({ error: "Failed to rename session" }, 500);
|
|
7912
7812
|
}
|
|
7913
7813
|
});
|
|
7914
|
-
var sessions_default =
|
|
7814
|
+
var sessions_default = app11;
|
|
7915
7815
|
|
|
7916
7816
|
// app/lib/claude-agent/spawn-context.ts
|
|
7917
|
-
import { existsSync as
|
|
7918
|
-
import { dirname as
|
|
7817
|
+
import { existsSync as existsSync14, readFileSync as readFileSync12, readdirSync as readdirSync7, statSync as statSync6 } from "fs";
|
|
7818
|
+
import { dirname as dirname2, resolve as resolve10, join as join10 } from "path";
|
|
7919
7819
|
async function resolveOwnerProfileBlock(accountId, userId) {
|
|
7920
7820
|
if (!userId) return { ok: false, reason: "missing-user-id" };
|
|
7921
7821
|
try {
|
|
@@ -7944,14 +7844,14 @@ function frontmatterField(manifest, field) {
|
|
|
7944
7844
|
function extractPluginToolDescriptions(pluginDir) {
|
|
7945
7845
|
const out = /* @__PURE__ */ new Map();
|
|
7946
7846
|
const candidates = [
|
|
7947
|
-
|
|
7948
|
-
|
|
7847
|
+
join10(pluginDir, "mcp/dist/index.js"),
|
|
7848
|
+
join10(pluginDir, "mcp/src/index.ts")
|
|
7949
7849
|
];
|
|
7950
7850
|
let raw = null;
|
|
7951
7851
|
for (const path2 of candidates) {
|
|
7952
|
-
if (!
|
|
7852
|
+
if (!existsSync14(path2)) continue;
|
|
7953
7853
|
try {
|
|
7954
|
-
raw =
|
|
7854
|
+
raw = readFileSync12(path2, "utf-8");
|
|
7955
7855
|
break;
|
|
7956
7856
|
} catch {
|
|
7957
7857
|
}
|
|
@@ -8001,23 +7901,23 @@ function parseSkillPathsFromFrontmatter(fm) {
|
|
|
8001
7901
|
function listPluginDirs() {
|
|
8002
7902
|
const out = /* @__PURE__ */ new Map();
|
|
8003
7903
|
const platformPlugins = resolve10(PLATFORM_ROOT, "plugins");
|
|
8004
|
-
if (
|
|
7904
|
+
if (existsSync14(platformPlugins)) {
|
|
8005
7905
|
for (const name of readdirSync7(platformPlugins)) {
|
|
8006
|
-
const dir =
|
|
7906
|
+
const dir = join10(platformPlugins, name);
|
|
8007
7907
|
try {
|
|
8008
7908
|
if (statSync6(dir).isDirectory()) out.set(name, dir);
|
|
8009
7909
|
} catch {
|
|
8010
7910
|
}
|
|
8011
7911
|
}
|
|
8012
7912
|
}
|
|
8013
|
-
const premiumRoot = resolve10(
|
|
8014
|
-
if (
|
|
7913
|
+
const premiumRoot = resolve10(dirname2(PLATFORM_ROOT), "premium-plugins");
|
|
7914
|
+
if (existsSync14(premiumRoot)) {
|
|
8015
7915
|
for (const bundle of readdirSync7(premiumRoot)) {
|
|
8016
|
-
const bundlePlugins =
|
|
8017
|
-
if (!
|
|
7916
|
+
const bundlePlugins = join10(premiumRoot, bundle, "plugins");
|
|
7917
|
+
if (!existsSync14(bundlePlugins)) continue;
|
|
8018
7918
|
try {
|
|
8019
7919
|
for (const name of readdirSync7(bundlePlugins)) {
|
|
8020
|
-
const dir =
|
|
7920
|
+
const dir = join10(bundlePlugins, name);
|
|
8021
7921
|
try {
|
|
8022
7922
|
if (statSync6(dir).isDirectory()) out.set(name, dir);
|
|
8023
7923
|
} catch {
|
|
@@ -8031,9 +7931,9 @@ function listPluginDirs() {
|
|
|
8031
7931
|
}
|
|
8032
7932
|
function readEnabledPlugins(accountId) {
|
|
8033
7933
|
const accountFile = resolve10(PLATFORM_ROOT, "..", "data/accounts", accountId, "account.json");
|
|
8034
|
-
if (!
|
|
7934
|
+
if (!existsSync14(accountFile)) return /* @__PURE__ */ new Set();
|
|
8035
7935
|
try {
|
|
8036
|
-
const parsed = JSON.parse(
|
|
7936
|
+
const parsed = JSON.parse(readFileSync12(accountFile, "utf-8"));
|
|
8037
7937
|
return new Set(
|
|
8038
7938
|
Array.isArray(parsed.enabledPlugins) ? parsed.enabledPlugins.filter((p) => typeof p === "string") : []
|
|
8039
7939
|
);
|
|
@@ -8042,10 +7942,10 @@ function readEnabledPlugins(accountId) {
|
|
|
8042
7942
|
}
|
|
8043
7943
|
}
|
|
8044
7944
|
function readFrontmatter(path2) {
|
|
8045
|
-
if (!
|
|
7945
|
+
if (!existsSync14(path2)) return null;
|
|
8046
7946
|
let raw;
|
|
8047
7947
|
try {
|
|
8048
|
-
raw =
|
|
7948
|
+
raw = readFileSync12(path2, "utf-8");
|
|
8049
7949
|
} catch {
|
|
8050
7950
|
return null;
|
|
8051
7951
|
}
|
|
@@ -8060,7 +7960,7 @@ function computeActivePlugins(accountId) {
|
|
|
8060
7960
|
for (const name of Array.from(enabled).sort()) {
|
|
8061
7961
|
const dir = pluginDirs.get(name);
|
|
8062
7962
|
if (!dir) continue;
|
|
8063
|
-
const fm = readFrontmatter(
|
|
7963
|
+
const fm = readFrontmatter(join10(dir, "PLUGIN.md"));
|
|
8064
7964
|
if (!fm) continue;
|
|
8065
7965
|
const description = frontmatterField(`---
|
|
8066
7966
|
${fm}
|
|
@@ -8077,7 +7977,7 @@ ${fm}
|
|
|
8077
7977
|
`plugin-manifest-tool-coverage plugin=${name} tools=${tools.length} with-desc=${withDesc}`
|
|
8078
7978
|
);
|
|
8079
7979
|
if (toolNames.length > 0 && descMap.size === 0) {
|
|
8080
|
-
const hasSource =
|
|
7980
|
+
const hasSource = existsSync14(join10(dir, "mcp/dist/index.js")) || existsSync14(join10(dir, "mcp/src/index.ts"));
|
|
8081
7981
|
if (hasSource) {
|
|
8082
7982
|
console.warn(
|
|
8083
7983
|
`[spawn-context] WARN plugin=${name} mcp source present but tool-description regex matched zero entries \u2014 SDK upgrade may have changed the registration shape`
|
|
@@ -8087,7 +7987,7 @@ ${fm}
|
|
|
8087
7987
|
const skillPaths = parseSkillPathsFromFrontmatter(fm);
|
|
8088
7988
|
const skills = [];
|
|
8089
7989
|
for (const relPath2 of skillPaths) {
|
|
8090
|
-
const skillPath =
|
|
7990
|
+
const skillPath = join10(dir, relPath2);
|
|
8091
7991
|
const skillFm = readFrontmatter(skillPath);
|
|
8092
7992
|
if (!skillFm) continue;
|
|
8093
7993
|
const skillName = frontmatterField(`---
|
|
@@ -8104,7 +8004,7 @@ ${skillFm}
|
|
|
8104
8004
|
}
|
|
8105
8005
|
function computeSpecialistDomains(accountId) {
|
|
8106
8006
|
const specialistsDir = resolve10(PLATFORM_ROOT, "..", "data/accounts", accountId, "specialists", "agents");
|
|
8107
|
-
if (!
|
|
8007
|
+
if (!existsSync14(specialistsDir)) return [];
|
|
8108
8008
|
let entries;
|
|
8109
8009
|
try {
|
|
8110
8010
|
entries = readdirSync7(specialistsDir);
|
|
@@ -8131,7 +8031,7 @@ function computeSpecialistDomains(accountId) {
|
|
|
8131
8031
|
const out = [];
|
|
8132
8032
|
for (const file of entries.sort()) {
|
|
8133
8033
|
if (!file.endsWith(".md")) continue;
|
|
8134
|
-
const fm = readFrontmatter(
|
|
8034
|
+
const fm = readFrontmatter(join10(specialistsDir, file));
|
|
8135
8035
|
if (!fm) continue;
|
|
8136
8036
|
const wrapped = `---
|
|
8137
8037
|
${fm}
|
|
@@ -8150,10 +8050,10 @@ ${fm}
|
|
|
8150
8050
|
}
|
|
8151
8051
|
function computeDormantPlugins(accountId) {
|
|
8152
8052
|
const accountFile = resolve10(PLATFORM_ROOT, "..", "data/accounts", accountId, "account.json");
|
|
8153
|
-
if (!
|
|
8053
|
+
if (!existsSync14(accountFile)) return [];
|
|
8154
8054
|
let enabled;
|
|
8155
8055
|
try {
|
|
8156
|
-
const raw =
|
|
8056
|
+
const raw = readFileSync12(accountFile, "utf-8");
|
|
8157
8057
|
const parsed = JSON.parse(raw);
|
|
8158
8058
|
enabled = new Set(
|
|
8159
8059
|
Array.isArray(parsed.enabledPlugins) ? parsed.enabledPlugins.filter((p) => typeof p === "string") : []
|
|
@@ -8165,7 +8065,7 @@ function computeDormantPlugins(accountId) {
|
|
|
8165
8065
|
return [];
|
|
8166
8066
|
}
|
|
8167
8067
|
const pluginsDir = resolve10(PLATFORM_ROOT, "plugins");
|
|
8168
|
-
if (!
|
|
8068
|
+
if (!existsSync14(pluginsDir)) return [];
|
|
8169
8069
|
let entries;
|
|
8170
8070
|
try {
|
|
8171
8071
|
entries = readdirSync7(pluginsDir);
|
|
@@ -8176,10 +8076,10 @@ function computeDormantPlugins(accountId) {
|
|
|
8176
8076
|
for (const name of entries) {
|
|
8177
8077
|
if (enabled.has(name)) continue;
|
|
8178
8078
|
const manifestPath = resolve10(pluginsDir, name, "PLUGIN.md");
|
|
8179
|
-
if (!
|
|
8079
|
+
if (!existsSync14(manifestPath)) continue;
|
|
8180
8080
|
let manifest;
|
|
8181
8081
|
try {
|
|
8182
|
-
manifest =
|
|
8082
|
+
manifest = readFileSync12(manifestPath, "utf-8");
|
|
8183
8083
|
} catch {
|
|
8184
8084
|
continue;
|
|
8185
8085
|
}
|
|
@@ -8193,13 +8093,13 @@ function computeDormantPlugins(accountId) {
|
|
|
8193
8093
|
}
|
|
8194
8094
|
|
|
8195
8095
|
// server/routes/admin/claude-sessions.ts
|
|
8196
|
-
import { existsSync as
|
|
8096
|
+
import { existsSync as existsSync15, readFileSync as readFileSync13 } from "fs";
|
|
8197
8097
|
import { resolve as resolve11 } from "path";
|
|
8198
8098
|
function readTunnelState(brandConfigDir) {
|
|
8199
8099
|
const statePath = `${process.env.HOME ?? ""}/${brandConfigDir}/cloudflared/tunnel.state`;
|
|
8200
|
-
if (!
|
|
8100
|
+
if (!existsSync15(statePath)) return null;
|
|
8201
8101
|
try {
|
|
8202
|
-
const parsed = JSON.parse(
|
|
8102
|
+
const parsed = JSON.parse(readFileSync13(statePath, "utf-8"));
|
|
8203
8103
|
const tunnelId = typeof parsed.tunnelId === "string" ? parsed.tunnelId : null;
|
|
8204
8104
|
const tunnelName = typeof parsed.tunnelName === "string" ? parsed.tunnelName : null;
|
|
8205
8105
|
const domain = typeof parsed.domain === "string" ? parsed.domain : null;
|
|
@@ -8213,7 +8113,7 @@ function resolveTunnelUrl() {
|
|
|
8213
8113
|
const platformRoot = process.env.MAXY_PLATFORM_ROOT ?? process.env.PLATFORM_ROOT ?? resolve11(process.cwd(), "..");
|
|
8214
8114
|
let brand;
|
|
8215
8115
|
try {
|
|
8216
|
-
brand = JSON.parse(
|
|
8116
|
+
brand = JSON.parse(readFileSync13(resolve11(platformRoot, "config", "brand.json"), "utf-8"));
|
|
8217
8117
|
} catch {
|
|
8218
8118
|
return null;
|
|
8219
8119
|
}
|
|
@@ -8240,7 +8140,7 @@ function managerBase3() {
|
|
|
8240
8140
|
const port2 = requirePortEnv("CLAUDE_SESSION_MANAGER_PORT", { tag: "claude-session-manager:wrapper" });
|
|
8241
8141
|
return `http://127.0.0.1:${port2}`;
|
|
8242
8142
|
}
|
|
8243
|
-
var
|
|
8143
|
+
var app12 = new Hono();
|
|
8244
8144
|
var UUID_PATTERN = /^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$/;
|
|
8245
8145
|
async function performSpawnWithInitialMessage(args) {
|
|
8246
8146
|
const ownerStart = Date.now();
|
|
@@ -8327,8 +8227,8 @@ var requireAdminSessionUnlessLoopbackSpawn = async (c, next) => {
|
|
|
8327
8227
|
}
|
|
8328
8228
|
return requireAdminSession(c, next);
|
|
8329
8229
|
};
|
|
8330
|
-
|
|
8331
|
-
|
|
8230
|
+
app12.use("*", requireAdminSessionUnlessLoopbackSpawn);
|
|
8231
|
+
app12.post("/", async (c) => {
|
|
8332
8232
|
const routeStart = Date.now();
|
|
8333
8233
|
const cacheKey = c.get("cacheKey") ?? "";
|
|
8334
8234
|
let body = {};
|
|
@@ -8361,10 +8261,14 @@ app15.post("/", async (c) => {
|
|
|
8361
8261
|
console.error(`${TAG18} fetch-failed op=operator-meta-lookup message=${err instanceof Error ? err.message : String(err)}`);
|
|
8362
8262
|
return null;
|
|
8363
8263
|
});
|
|
8364
|
-
const
|
|
8264
|
+
const metaSenderId = operatorMeta && typeof operatorMeta.senderId === "string" && operatorMeta.senderId.length > 0 ? operatorMeta.senderId : null;
|
|
8265
|
+
const bodyAccountId = typeof body.accountId === "string" && UUID_PATTERN.test(body.accountId) ? body.accountId : null;
|
|
8266
|
+
const operatorSenderId = metaSenderId ?? bodyAccountId;
|
|
8365
8267
|
if (!operatorSenderId) {
|
|
8268
|
+
console.error(`${TAG18} reject reason=no-sender-id adminSessionId=${lookupSessionId.slice(0, 8)} metaSenderId=${metaSenderId ? "present" : "absent"} bodyAccountId=${bodyAccountId ? "present" : "absent"}`);
|
|
8366
8269
|
return c.json({ error: "admin-session-not-found" }, 404);
|
|
8367
8270
|
}
|
|
8271
|
+
console.log(`${TAG18} loopback-sender-resolved source=${metaSenderId ? "meta" : "body-accountId"} accountId=${operatorSenderId.slice(0, 8)}`);
|
|
8368
8272
|
senderId = operatorSenderId;
|
|
8369
8273
|
userId = void 0;
|
|
8370
8274
|
}
|
|
@@ -8395,271 +8299,18 @@ app15.post("/", async (c) => {
|
|
|
8395
8299
|
console.log(`${TAG18} route-done surface=${authSurface} status=${response.status} route-ms=${Date.now() - routeStart}`);
|
|
8396
8300
|
return response;
|
|
8397
8301
|
});
|
|
8398
|
-
|
|
8399
|
-
const upstream = await fetch(`${managerBase3()}/events`, {
|
|
8400
|
-
headers: { accept: "text/event-stream" }
|
|
8401
|
-
}).catch((err) => {
|
|
8402
|
-
console.error(`${TAG18} fetch-failed op=events message=${err instanceof Error ? err.message : String(err)}`);
|
|
8403
|
-
return null;
|
|
8404
|
-
});
|
|
8405
|
-
if (!upstream || !upstream.body) return c.json({ error: "manager-unreachable" }, 503);
|
|
8406
|
-
return new Response(upstream.body, {
|
|
8407
|
-
status: upstream.status,
|
|
8408
|
-
headers: {
|
|
8409
|
-
"content-type": "text/event-stream",
|
|
8410
|
-
"cache-control": "no-cache, no-transform",
|
|
8411
|
-
"x-accel-buffering": "no",
|
|
8412
|
-
connection: "keep-alive"
|
|
8413
|
-
}
|
|
8414
|
-
});
|
|
8415
|
-
});
|
|
8416
|
-
app15.get("/", async (c) => {
|
|
8417
|
-
const cacheKey = c.get("cacheKey") ?? "";
|
|
8418
|
-
const senderId = getAccountIdForSession(cacheKey) ?? "";
|
|
8419
|
-
if (!senderId) return c.json({ error: "admin-account-not-resolved" }, 500);
|
|
8420
|
-
const upstream = await fetch(
|
|
8421
|
-
`${managerBase3()}/list?senderId=${encodeURIComponent(senderId)}`
|
|
8422
|
-
).catch((err) => {
|
|
8423
|
-
console.error(`${TAG18} fetch-failed op=list message=${err instanceof Error ? err.message : String(err)}`);
|
|
8424
|
-
return null;
|
|
8425
|
-
});
|
|
8426
|
-
if (!upstream) return c.json({ error: "manager-unreachable" }, 503);
|
|
8427
|
-
return new Response(upstream.body, { status: upstream.status, headers: upstream.headers });
|
|
8428
|
-
});
|
|
8429
|
-
app15.post("/resume", async (c) => {
|
|
8430
|
-
const cacheKey = c.get("cacheKey") ?? "";
|
|
8431
|
-
const senderId = getAccountIdForSession(cacheKey) ?? "";
|
|
8432
|
-
if (!senderId) return c.json({ error: "admin-account-not-resolved" }, 500);
|
|
8433
|
-
const userId = getUserIdForSession(cacheKey);
|
|
8434
|
-
let body = {};
|
|
8435
|
-
try {
|
|
8436
|
-
body = await c.req.json();
|
|
8437
|
-
} catch {
|
|
8438
|
-
return c.json({ error: "body-not-json" }, 400);
|
|
8439
|
-
}
|
|
8440
|
-
if (typeof body.sessionId !== "string" || !body.sessionId) {
|
|
8441
|
-
return c.json({ error: "sessionId-required" }, 400);
|
|
8442
|
-
}
|
|
8443
|
-
const refusal = await refuseIfClaudeAuthDead(c, "resume", body.sessionId);
|
|
8444
|
-
if (refusal) return refusal;
|
|
8445
|
-
const channel = typeof body.channel === "string" ? body.channel : "browser";
|
|
8446
|
-
const idempotencyKey = typeof body.idempotencyKey === "string" ? body.idempotencyKey : void 0;
|
|
8447
|
-
const aboutOwner = await resolveOwnerProfileBlock(senderId, userId);
|
|
8448
|
-
const dormantPlugins = computeDormantPlugins(senderId);
|
|
8449
|
-
const activePlugins = computeActivePlugins(senderId);
|
|
8450
|
-
const specialistDomains = computeSpecialistDomains(senderId);
|
|
8451
|
-
const tunnelUrl = resolveTunnelUrl();
|
|
8452
|
-
const upstream = await fetch(`${managerBase3()}/resume`, {
|
|
8453
|
-
method: "POST",
|
|
8454
|
-
headers: { "content-type": "application/json" },
|
|
8455
|
-
body: JSON.stringify({
|
|
8456
|
-
senderId,
|
|
8457
|
-
// Task 205 — resume parity with /spawn: thread userId so the
|
|
8458
|
-
// respawned pty inherits the same USER_ID env.
|
|
8459
|
-
userId,
|
|
8460
|
-
role: "admin",
|
|
8461
|
-
channel,
|
|
8462
|
-
sessionId: body.sessionId,
|
|
8463
|
-
idempotencyKey,
|
|
8464
|
-
aboutOwner,
|
|
8465
|
-
dormantPlugins,
|
|
8466
|
-
activePlugins,
|
|
8467
|
-
specialistDomains,
|
|
8468
|
-
tunnelUrl,
|
|
8469
|
-
// Task 382 — resume parity with /spawn: thread the active
|
|
8470
|
-
// sessionId so the re-spawned PTY's MCP env carries
|
|
8471
|
-
// SESSION_NODE_ID. Undefined when no active conversation is
|
|
8472
|
-
// bound to this cacheKey (rare for resume — the user is by
|
|
8473
|
-
// definition continuing a known conversation).
|
|
8474
|
-
conversationNodeId: getSessionIdForSession(cacheKey)
|
|
8475
|
-
})
|
|
8476
|
-
}).catch((err) => {
|
|
8477
|
-
console.error(`${TAG18} fetch-failed op=resume message=${err instanceof Error ? err.message : String(err)}`);
|
|
8478
|
-
return null;
|
|
8479
|
-
});
|
|
8480
|
-
if (!upstream) return c.json({ error: "manager-unreachable" }, 503);
|
|
8481
|
-
const bodyText = await upstream.text().catch(() => "");
|
|
8482
|
-
let claudeSessionIdFromResume = null;
|
|
8483
|
-
if (upstream.ok) {
|
|
8484
|
-
try {
|
|
8485
|
-
const parsed = JSON.parse(bodyText);
|
|
8486
|
-
if (typeof parsed.sessionId === "string" && parsed.sessionId.length > 0) {
|
|
8487
|
-
claudeSessionIdFromResume = parsed.sessionId;
|
|
8488
|
-
}
|
|
8489
|
-
} catch {
|
|
8490
|
-
}
|
|
8491
|
-
}
|
|
8492
|
-
mintTranscriptEdge(
|
|
8493
|
-
getSessionIdForSession(cacheKey),
|
|
8494
|
-
claudeSessionIdFromResume,
|
|
8495
|
-
senderId
|
|
8496
|
-
);
|
|
8497
|
-
return new Response(bodyText, { status: upstream.status, headers: upstream.headers });
|
|
8498
|
-
});
|
|
8499
|
-
app15.post("/:sessionId/stop", async (c) => {
|
|
8500
|
-
const sessionId = c.req.param("sessionId");
|
|
8501
|
-
const upstream = await fetch(
|
|
8502
|
-
`${managerBase3()}/${encodeURIComponent(sessionId)}/stop`,
|
|
8503
|
-
{ method: "POST" }
|
|
8504
|
-
).catch((err) => {
|
|
8505
|
-
console.error(`${TAG18} fetch-failed op=stop message=${err instanceof Error ? err.message : String(err)}`);
|
|
8506
|
-
return null;
|
|
8507
|
-
});
|
|
8508
|
-
if (!upstream) return c.json({ error: "manager-unreachable" }, 503);
|
|
8509
|
-
return new Response(upstream.body, { status: upstream.status, headers: upstream.headers });
|
|
8510
|
-
});
|
|
8511
|
-
app15.post("/:sessionId/rename", async (c) => {
|
|
8512
|
-
const sessionId = c.req.param("sessionId");
|
|
8513
|
-
const body = await c.req.text();
|
|
8514
|
-
const upstream = await fetch(
|
|
8515
|
-
`${managerBase3()}/${encodeURIComponent(sessionId)}/rename`,
|
|
8516
|
-
{
|
|
8517
|
-
method: "POST",
|
|
8518
|
-
headers: { "content-type": "application/json" },
|
|
8519
|
-
body
|
|
8520
|
-
}
|
|
8521
|
-
).catch((err) => {
|
|
8522
|
-
console.error(`${TAG18} fetch-failed op=rename message=${err instanceof Error ? err.message : String(err)}`);
|
|
8523
|
-
return null;
|
|
8524
|
-
});
|
|
8525
|
-
if (!upstream) return c.json({ error: "manager-unreachable" }, 503);
|
|
8526
|
-
return new Response(upstream.body, { status: upstream.status, headers: upstream.headers });
|
|
8527
|
-
});
|
|
8528
|
-
app15.delete("/:sessionId", async (c) => {
|
|
8529
|
-
const claudeSessionId = c.req.param("sessionId");
|
|
8530
|
-
const cacheKey = c.get("cacheKey") ?? "";
|
|
8531
|
-
const accountId = getAccountIdForSession(cacheKey) ?? "";
|
|
8532
|
-
if (!accountId) return c.json({ error: "admin-account-not-resolved" }, 500);
|
|
8533
|
-
const sessionId = await getSessionIdByClaudeSessionId(claudeSessionId, accountId);
|
|
8534
|
-
if (!sessionId) {
|
|
8535
|
-
console.log(`[admin-conversation-delete] reason=no-conversation-mapping claudeSessionId=${claudeSessionId.slice(0, 8)}`);
|
|
8536
|
-
const upstream = await fetch(
|
|
8537
|
-
`${managerBase3()}/${encodeURIComponent(claudeSessionId)}`,
|
|
8538
|
-
{ method: "DELETE" }
|
|
8539
|
-
).catch((err) => {
|
|
8540
|
-
console.error(`${TAG18} fetch-failed op=delete message=${err instanceof Error ? err.message : String(err)}`);
|
|
8541
|
-
return null;
|
|
8542
|
-
});
|
|
8543
|
-
if (!upstream) return c.json({ error: "manager-unreachable" }, 503);
|
|
8544
|
-
return new Response(upstream.body, { status: upstream.status, headers: upstream.headers });
|
|
8545
|
-
}
|
|
8546
|
-
let siblings;
|
|
8547
|
-
try {
|
|
8548
|
-
siblings = await getConversationClaudeSessionIds(sessionId, accountId);
|
|
8549
|
-
} catch {
|
|
8550
|
-
siblings = [claudeSessionId];
|
|
8551
|
-
}
|
|
8552
|
-
const all = [claudeSessionId, ...siblings.filter((s) => s !== claudeSessionId)];
|
|
8553
|
-
const outcome = await cascadeAdminConversationDelete({
|
|
8554
|
-
sessionId,
|
|
8555
|
-
accountId,
|
|
8556
|
-
managerBase: managerBase3(),
|
|
8557
|
-
claudeSessionIds: all
|
|
8558
|
-
});
|
|
8559
|
-
if (outcome.ok) return c.json({ ok: true, claudeSessionIds: outcome.claudeSessionIds });
|
|
8560
|
-
if (outcome.reason === "pty-still-alive") {
|
|
8561
|
-
return c.json(
|
|
8562
|
-
{ error: "pty-still-alive", detail: "stop the session before deleting", claudeSessionId: outcome.claudeSessionId },
|
|
8563
|
-
409
|
|
8564
|
-
);
|
|
8565
|
-
}
|
|
8566
|
-
if (outcome.reason === "conversation-not-found") {
|
|
8567
|
-
return c.json({ ok: true, claudeSessionIds: [] });
|
|
8568
|
-
}
|
|
8569
|
-
if (outcome.reason === "jsonl-purge-failed") {
|
|
8570
|
-
return c.json(
|
|
8571
|
-
{
|
|
8572
|
-
error: "jsonl-purge-failed",
|
|
8573
|
-
detail: outcome.message,
|
|
8574
|
-
claudeSessionId: outcome.claudeSessionId,
|
|
8575
|
-
sessionId,
|
|
8576
|
-
claudeSessionIdsPurged: outcome.claudeSessionIdsPurged
|
|
8577
|
-
},
|
|
8578
|
-
outcome.status >= 400 && outcome.status < 600 ? outcome.status : 502
|
|
8579
|
-
);
|
|
8580
|
-
}
|
|
8581
|
-
return c.json(
|
|
8582
|
-
{
|
|
8583
|
-
error: "graph-delete-failed",
|
|
8584
|
-
detail: outcome.message,
|
|
8585
|
-
sessionId,
|
|
8586
|
-
claudeSessionIdsPurged: outcome.claudeSessionIdsPurged
|
|
8587
|
-
},
|
|
8588
|
-
500
|
|
8589
|
-
);
|
|
8590
|
-
});
|
|
8591
|
-
app15.post("/:sessionId/archive", async (c) => {
|
|
8592
|
-
const sessionId = c.req.param("sessionId");
|
|
8593
|
-
const body = await c.req.text();
|
|
8594
|
-
const upstream = await fetch(
|
|
8595
|
-
`${managerBase3()}/${encodeURIComponent(sessionId)}/archive`,
|
|
8596
|
-
{
|
|
8597
|
-
method: "POST",
|
|
8598
|
-
headers: { "content-type": "application/json" },
|
|
8599
|
-
body
|
|
8600
|
-
}
|
|
8601
|
-
).catch((err) => {
|
|
8602
|
-
console.error(`${TAG18} fetch-failed op=archive message=${err instanceof Error ? err.message : String(err)}`);
|
|
8603
|
-
return null;
|
|
8604
|
-
});
|
|
8605
|
-
if (!upstream) return c.json({ error: "manager-unreachable" }, 503);
|
|
8606
|
-
return new Response(upstream.body, { status: upstream.status, headers: upstream.headers });
|
|
8607
|
-
});
|
|
8608
|
-
app15.get("/:sessionId/meta", async (c) => {
|
|
8609
|
-
const sessionId = c.req.param("sessionId");
|
|
8610
|
-
const upstream = await fetch(
|
|
8611
|
-
`${managerBase3()}/${encodeURIComponent(sessionId)}/meta`
|
|
8612
|
-
).catch((err) => {
|
|
8613
|
-
console.error(`${TAG18} fetch-failed op=meta message=${err instanceof Error ? err.message : String(err)}`);
|
|
8614
|
-
return null;
|
|
8615
|
-
});
|
|
8616
|
-
if (!upstream) return c.json({ error: "manager-unreachable" }, 503);
|
|
8617
|
-
return new Response(upstream.body, { status: upstream.status, headers: upstream.headers });
|
|
8618
|
-
});
|
|
8619
|
-
app15.post("/:sessionId/input", async (c) => {
|
|
8620
|
-
const sessionId = c.req.param("sessionId");
|
|
8621
|
-
const rawBody = await c.req.text();
|
|
8622
|
-
const upstream = await fetch(
|
|
8623
|
-
`${managerBase3()}/${encodeURIComponent(sessionId)}/input`,
|
|
8624
|
-
{
|
|
8625
|
-
method: "POST",
|
|
8626
|
-
headers: { "content-type": "application/json" },
|
|
8627
|
-
body: rawBody
|
|
8628
|
-
}
|
|
8629
|
-
).catch((err) => {
|
|
8630
|
-
console.error(`${TAG18} fetch-failed op=input message=${err instanceof Error ? err.message : String(err)}`);
|
|
8631
|
-
return null;
|
|
8632
|
-
});
|
|
8633
|
-
if (!upstream) return c.json({ error: "manager-unreachable" }, 503);
|
|
8634
|
-
return new Response(upstream.body, { status: upstream.status, headers: upstream.headers });
|
|
8635
|
-
});
|
|
8636
|
-
app15.get("/:sessionId/log", async (c) => {
|
|
8637
|
-
const sessionId = c.req.param("sessionId");
|
|
8638
|
-
const search = new URLSearchParams();
|
|
8639
|
-
if (c.req.query("follow") === "1") search.set("follow", "1");
|
|
8640
|
-
if (c.req.query("download") === "1") search.set("download", "1");
|
|
8641
|
-
const qs = search.toString() ? `?${search.toString()}` : "";
|
|
8642
|
-
const upstream = await fetch(
|
|
8643
|
-
`${managerBase3()}/${encodeURIComponent(sessionId)}/log${qs}`
|
|
8644
|
-
).catch((err) => {
|
|
8645
|
-
console.error(`${TAG18} fetch-failed op=log message=${err instanceof Error ? err.message : String(err)}`);
|
|
8646
|
-
return null;
|
|
8647
|
-
});
|
|
8648
|
-
if (!upstream) return c.json({ error: "manager-unreachable" }, 503);
|
|
8649
|
-
return new Response(upstream.body, { status: upstream.status, headers: upstream.headers });
|
|
8650
|
-
});
|
|
8651
|
-
var claude_sessions_default = app15;
|
|
8302
|
+
var claude_sessions_default = app12;
|
|
8652
8303
|
|
|
8653
8304
|
// server/routes/admin/log-ingest.ts
|
|
8654
8305
|
var TAG19 = "[log-ingest]";
|
|
8655
8306
|
var TAG_PATTERN = /^[A-Za-z0-9_:-]{1,32}$/;
|
|
8656
8307
|
var LEVELS = /* @__PURE__ */ new Set(["debug", "info", "warn", "error"]);
|
|
8657
8308
|
var MAX_LINE_BYTES = 4096;
|
|
8658
|
-
var
|
|
8309
|
+
var app13 = new Hono();
|
|
8659
8310
|
function isLoopbackAddr(addr) {
|
|
8660
8311
|
return addr === "127.0.0.1" || addr === "::1" || addr === "::ffff:127.0.0.1";
|
|
8661
8312
|
}
|
|
8662
|
-
|
|
8313
|
+
app13.post("/", async (c) => {
|
|
8663
8314
|
const remoteAddr = c.env?.incoming?.socket?.remoteAddress ?? "";
|
|
8664
8315
|
if (!isLoopbackAddr(remoteAddr)) {
|
|
8665
8316
|
console.error(`${TAG19} reject reason=non-loopback remoteAddr=${remoteAddr}`);
|
|
@@ -8702,7 +8353,7 @@ app16.post("/", async (c) => {
|
|
|
8702
8353
|
else console.log(formatted);
|
|
8703
8354
|
return c.json({ ok: true }, 200);
|
|
8704
8355
|
});
|
|
8705
|
-
var log_ingest_default =
|
|
8356
|
+
var log_ingest_default = app13;
|
|
8706
8357
|
|
|
8707
8358
|
// server/routes/admin/events.ts
|
|
8708
8359
|
var ALLOWED_EVENTS = /* @__PURE__ */ new Set([
|
|
@@ -8711,8 +8362,8 @@ var ALLOWED_EVENTS = /* @__PURE__ */ new Set([
|
|
|
8711
8362
|
"device-url:vnc-surface-shown",
|
|
8712
8363
|
"device-url:malformed"
|
|
8713
8364
|
]);
|
|
8714
|
-
var
|
|
8715
|
-
|
|
8365
|
+
var app14 = new Hono();
|
|
8366
|
+
app14.post("/", async (c) => {
|
|
8716
8367
|
const TAG28 = "[admin:events]";
|
|
8717
8368
|
let body;
|
|
8718
8369
|
try {
|
|
@@ -8743,13 +8394,13 @@ app17.post("/", async (c) => {
|
|
|
8743
8394
|
console.error(`[${event}] ${formatted}`);
|
|
8744
8395
|
return c.json({ ok: true });
|
|
8745
8396
|
});
|
|
8746
|
-
var events_default =
|
|
8397
|
+
var events_default = app14;
|
|
8747
8398
|
|
|
8748
8399
|
// server/routes/admin/files.ts
|
|
8749
8400
|
import { createReadStream as createReadStream2 } from "fs";
|
|
8750
8401
|
import { readdir as readdir2, readFile as readFile4, stat as stat4, mkdir as mkdir3, writeFile as writeFile4, unlink as unlink2 } from "fs/promises";
|
|
8751
8402
|
import { realpathSync as realpathSync4 } from "fs";
|
|
8752
|
-
import { basename as basename4, dirname as
|
|
8403
|
+
import { basename as basename4, dirname as dirname3, join as join11, resolve as resolve13, sep as sep3 } from "path";
|
|
8753
8404
|
import { Readable as Readable2 } from "stream";
|
|
8754
8405
|
|
|
8755
8406
|
// app/lib/data-path.ts
|
|
@@ -9111,7 +8762,7 @@ async function cascadeDeleteDocument(params) {
|
|
|
9111
8762
|
var UUID_RE3 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
9112
8763
|
async function readMeta(absDir, baseName) {
|
|
9113
8764
|
try {
|
|
9114
|
-
const raw = await readFile4(
|
|
8765
|
+
const raw = await readFile4(join11(absDir, `${baseName}.meta.json`), "utf8");
|
|
9115
8766
|
const parsed = JSON.parse(raw);
|
|
9116
8767
|
if (typeof parsed?.filename === "string") {
|
|
9117
8768
|
return { filename: parsed.filename, mimeType: typeof parsed.mimeType === "string" ? parsed.mimeType : void 0 };
|
|
@@ -9149,7 +8800,7 @@ async function readAccountNames() {
|
|
|
9149
8800
|
}
|
|
9150
8801
|
async function enrich(absolute, entry, accountNames) {
|
|
9151
8802
|
if (entry.kind === "directory" && UUID_RE3.test(entry.name)) {
|
|
9152
|
-
const meta = await readMeta(
|
|
8803
|
+
const meta = await readMeta(join11(absolute, entry.name), entry.name);
|
|
9153
8804
|
if (meta?.filename) {
|
|
9154
8805
|
entry.displayName = meta.filename;
|
|
9155
8806
|
entry.mimeType = meta.mimeType;
|
|
@@ -9180,8 +8831,8 @@ function buildDisplayPath(relPath2, accountNames) {
|
|
|
9180
8831
|
return dn ? { name: seg, displayName: dn } : { name: seg };
|
|
9181
8832
|
});
|
|
9182
8833
|
}
|
|
9183
|
-
var
|
|
9184
|
-
|
|
8834
|
+
var app15 = new Hono();
|
|
8835
|
+
app15.get("/", requireAdminSession, async (c) => {
|
|
9185
8836
|
const cacheKey = c.var.cacheKey;
|
|
9186
8837
|
if (!getAccountIdForSession(cacheKey)) {
|
|
9187
8838
|
console.error(`[data] auth-rejected endpoint="/api/admin/files" reason="no account for session"`);
|
|
@@ -9208,7 +8859,7 @@ app18.get("/", requireAdminSession, async (c) => {
|
|
|
9208
8859
|
continue;
|
|
9209
8860
|
}
|
|
9210
8861
|
try {
|
|
9211
|
-
const entryPath =
|
|
8862
|
+
const entryPath = join11(absolute, name);
|
|
9212
8863
|
const s = await stat4(entryPath);
|
|
9213
8864
|
entries.push({
|
|
9214
8865
|
name,
|
|
@@ -9242,7 +8893,7 @@ app18.get("/", requireAdminSession, async (c) => {
|
|
|
9242
8893
|
return c.json({ error: message }, 500);
|
|
9243
8894
|
}
|
|
9244
8895
|
});
|
|
9245
|
-
|
|
8896
|
+
app15.get("/download", requireAdminSession, async (c) => {
|
|
9246
8897
|
const cacheKey = c.var.cacheKey;
|
|
9247
8898
|
if (!getAccountIdForSession(cacheKey)) {
|
|
9248
8899
|
console.error(`[data] auth-rejected endpoint="/api/admin/files/download" reason="no account for session"`);
|
|
@@ -9290,7 +8941,7 @@ app18.get("/download", requireAdminSession, async (c) => {
|
|
|
9290
8941
|
return c.json({ error: message }, 500);
|
|
9291
8942
|
}
|
|
9292
8943
|
});
|
|
9293
|
-
|
|
8944
|
+
app15.post("/upload", requireAdminSession, async (c) => {
|
|
9294
8945
|
const cacheKey = c.var.cacheKey;
|
|
9295
8946
|
const accountId = getAccountIdForSession(cacheKey);
|
|
9296
8947
|
if (!accountId) {
|
|
@@ -9348,7 +8999,7 @@ app18.post("/upload", requireAdminSession, async (c) => {
|
|
|
9348
8999
|
mimeType: file.type
|
|
9349
9000
|
});
|
|
9350
9001
|
});
|
|
9351
|
-
|
|
9002
|
+
app15.delete("/", requireAdminSession, async (c) => {
|
|
9352
9003
|
const cacheKey = c.var.cacheKey;
|
|
9353
9004
|
const accountId = getAccountIdForSession(cacheKey);
|
|
9354
9005
|
if (!accountId) {
|
|
@@ -9381,7 +9032,7 @@ app18.delete("/", requireAdminSession, async (c) => {
|
|
|
9381
9032
|
}
|
|
9382
9033
|
const dot = base.lastIndexOf(".");
|
|
9383
9034
|
const stem = dot === -1 ? base : base.slice(0, dot);
|
|
9384
|
-
const sidecarPath = UUID_RE3.test(stem) && base !== `${stem}.meta.json` ?
|
|
9035
|
+
const sidecarPath = UUID_RE3.test(stem) && base !== `${stem}.meta.json` ? join11(dirname3(absolute), `${stem}.meta.json`) : null;
|
|
9385
9036
|
await unlink2(absolute);
|
|
9386
9037
|
if (sidecarPath) {
|
|
9387
9038
|
try {
|
|
@@ -9415,7 +9066,7 @@ app18.delete("/", requireAdminSession, async (c) => {
|
|
|
9415
9066
|
return c.json({ error: message }, 500);
|
|
9416
9067
|
}
|
|
9417
9068
|
});
|
|
9418
|
-
var files_default =
|
|
9069
|
+
var files_default = app15;
|
|
9419
9070
|
|
|
9420
9071
|
// ../lib/graph-search/src/index.ts
|
|
9421
9072
|
var import_dist = __toESM(require_dist());
|
|
@@ -10180,8 +9831,8 @@ var MAX_LIMIT = 2e3;
|
|
|
10180
9831
|
var DEFAULT_VECTOR_THRESHOLD = 0.82;
|
|
10181
9832
|
var MESSAGE_FAMILY_LABELS = ["Message", "UserMessage", "AssistantMessage", "WhatsAppMessage"];
|
|
10182
9833
|
var CONVERSATION_PARENT_LABELS = /* @__PURE__ */ new Set(["AdminConversation", "PublicConversation"]);
|
|
10183
|
-
var
|
|
10184
|
-
|
|
9834
|
+
var app16 = new Hono();
|
|
9835
|
+
app16.get("/", requireAdminSession, async (c) => {
|
|
10185
9836
|
const cacheKey = c.var.cacheKey;
|
|
10186
9837
|
const q = (c.req.query("q") ?? "").trim();
|
|
10187
9838
|
const rawLimit = c.req.query("limit");
|
|
@@ -10312,7 +9963,7 @@ app19.get("/", requireAdminSession, async (c) => {
|
|
|
10312
9963
|
await session.close();
|
|
10313
9964
|
}
|
|
10314
9965
|
});
|
|
10315
|
-
var graph_search_default =
|
|
9966
|
+
var graph_search_default = app16;
|
|
10316
9967
|
|
|
10317
9968
|
// server/routes/admin/graph-subgraph.ts
|
|
10318
9969
|
import neo4j from "neo4j-driver";
|
|
@@ -10390,8 +10041,8 @@ var STRIPPED_PROPERTIES = /* @__PURE__ */ new Set([
|
|
|
10390
10041
|
"otpCode",
|
|
10391
10042
|
"cacheKey"
|
|
10392
10043
|
]);
|
|
10393
|
-
var
|
|
10394
|
-
|
|
10044
|
+
var app17 = new Hono();
|
|
10045
|
+
app17.get("/", requireAdminSession, async (c) => {
|
|
10395
10046
|
const cacheKey = c.var.cacheKey;
|
|
10396
10047
|
const accountId = getAccountIdForSession(cacheKey);
|
|
10397
10048
|
if (!accountId) {
|
|
@@ -10974,12 +10625,12 @@ function pruneNode(node, warnedClasses, conversationWarnings) {
|
|
|
10974
10625
|
}
|
|
10975
10626
|
return trashed ? { id: node.id, labels, properties, trashed: true } : { id: node.id, labels, properties };
|
|
10976
10627
|
}
|
|
10977
|
-
var graph_subgraph_default =
|
|
10628
|
+
var graph_subgraph_default = app17;
|
|
10978
10629
|
|
|
10979
10630
|
// server/routes/admin/graph-delete.ts
|
|
10980
10631
|
var ALLOWED_BY = ["graph-page", "graph-drag-trash", "graph-side-panel-trash"];
|
|
10981
|
-
var
|
|
10982
|
-
|
|
10632
|
+
var app18 = new Hono();
|
|
10633
|
+
app18.post("/", requireAdminSession, async (c) => {
|
|
10983
10634
|
const cacheKey = c.var.cacheKey;
|
|
10984
10635
|
const accountId = getAccountIdForSession(cacheKey);
|
|
10985
10636
|
if (!accountId) {
|
|
@@ -11142,11 +10793,11 @@ app21.post("/", requireAdminSession, async (c) => {
|
|
|
11142
10793
|
}
|
|
11143
10794
|
}
|
|
11144
10795
|
});
|
|
11145
|
-
var graph_delete_default =
|
|
10796
|
+
var graph_delete_default = app18;
|
|
11146
10797
|
|
|
11147
10798
|
// server/routes/admin/graph-restore.ts
|
|
11148
|
-
var
|
|
11149
|
-
|
|
10799
|
+
var app19 = new Hono();
|
|
10800
|
+
app19.post("/", requireAdminSession, async (c) => {
|
|
11150
10801
|
const cacheKey = c.var.cacheKey;
|
|
11151
10802
|
const accountId = getAccountIdForSession(cacheKey);
|
|
11152
10803
|
if (!accountId) {
|
|
@@ -11210,11 +10861,11 @@ app22.post("/", requireAdminSession, async (c) => {
|
|
|
11210
10861
|
}
|
|
11211
10862
|
}
|
|
11212
10863
|
});
|
|
11213
|
-
var graph_restore_default =
|
|
10864
|
+
var graph_restore_default = app19;
|
|
11214
10865
|
|
|
11215
10866
|
// server/routes/admin/graph-labels-in-graph.ts
|
|
11216
|
-
var
|
|
11217
|
-
|
|
10867
|
+
var app20 = new Hono();
|
|
10868
|
+
app20.get("/", requireAdminSession, async (c) => {
|
|
11218
10869
|
const cacheKey = c.var.cacheKey;
|
|
11219
10870
|
const accountId = getAccountIdForSession(cacheKey);
|
|
11220
10871
|
if (!accountId) {
|
|
@@ -11280,11 +10931,11 @@ var LABELS_IN_GRAPH_CYPHER = `
|
|
|
11280
10931
|
sum(halfEdges) AS relDegree
|
|
11281
10932
|
RETURN label, nodeCount, relDegree
|
|
11282
10933
|
`;
|
|
11283
|
-
var graph_labels_in_graph_default =
|
|
10934
|
+
var graph_labels_in_graph_default = app20;
|
|
11284
10935
|
|
|
11285
10936
|
// server/routes/admin/graph-default-view.ts
|
|
11286
|
-
var
|
|
11287
|
-
|
|
10937
|
+
var app21 = new Hono();
|
|
10938
|
+
app21.get("/", requireAdminSession, async (c) => {
|
|
11288
10939
|
const cacheKey = c.var.cacheKey;
|
|
11289
10940
|
const accountId = getAccountIdForSession(cacheKey);
|
|
11290
10941
|
const userId = getUserIdForSession(cacheKey);
|
|
@@ -11322,7 +10973,7 @@ app24.get("/", requireAdminSession, async (c) => {
|
|
|
11322
10973
|
}
|
|
11323
10974
|
}
|
|
11324
10975
|
});
|
|
11325
|
-
|
|
10976
|
+
app21.put("/", requireAdminSession, async (c) => {
|
|
11326
10977
|
const cacheKey = c.var.cacheKey;
|
|
11327
10978
|
const accountId = getAccountIdForSession(cacheKey);
|
|
11328
10979
|
const userId = getUserIdForSession(cacheKey);
|
|
@@ -11411,139 +11062,11 @@ var WRITE_CYPHER = `
|
|
|
11411
11062
|
p.updatedAt = $updatedAt
|
|
11412
11063
|
RETURN p.labels AS labels
|
|
11413
11064
|
`;
|
|
11414
|
-
var graph_default_view_default =
|
|
11415
|
-
|
|
11416
|
-
// server/routes/admin/session-defaults.ts
|
|
11417
|
-
var app25 = new Hono();
|
|
11418
|
-
var MODE_OPTIONS = ["default", "acceptEdits", "plan", "auto", "bypassPermissions"];
|
|
11419
|
-
var MODEL_OPTIONS = ["claude-opus-4-7", "claude-sonnet-4-6", "claude-haiku-4-5"];
|
|
11420
|
-
app25.get("/", requireAdminSession, async (c) => {
|
|
11421
|
-
const cacheKey = c.var.cacheKey;
|
|
11422
|
-
const accountId = getAccountIdForSession(cacheKey);
|
|
11423
|
-
const userId = getUserIdForSession(cacheKey);
|
|
11424
|
-
if (!accountId || !userId) {
|
|
11425
|
-
console.error('[session-defaults] rejected op=load reason="missing account or user context"');
|
|
11426
|
-
return c.json({ error: "Account and user context required for session defaults" }, 401);
|
|
11427
|
-
}
|
|
11428
|
-
const started = Date.now();
|
|
11429
|
-
const session = getSession();
|
|
11430
|
-
try {
|
|
11431
|
-
const result = await session.executeRead(async (tx) => {
|
|
11432
|
-
return await tx.run(READ_CYPHER2, { accountId, userId });
|
|
11433
|
-
});
|
|
11434
|
-
const record = result.records[0];
|
|
11435
|
-
const rawMode = record?.get("permissionMode");
|
|
11436
|
-
const rawModel = record?.get("model");
|
|
11437
|
-
const permissionMode = MODE_OPTIONS.includes(rawMode ?? "") ? rawMode : "default";
|
|
11438
|
-
const model = MODEL_OPTIONS.includes(rawModel ?? "") ? rawModel : null;
|
|
11439
|
-
const elapsed = Date.now() - started;
|
|
11440
|
-
console.error(
|
|
11441
|
-
`[session-defaults] load account=${accountId} user=${userId} permissionMode=${permissionMode} model=${model ?? "null"} ms=${elapsed}`
|
|
11442
|
-
);
|
|
11443
|
-
return c.json({ permissionMode, model });
|
|
11444
|
-
} catch (err) {
|
|
11445
|
-
const elapsed = Date.now() - started;
|
|
11446
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
11447
|
-
console.error(
|
|
11448
|
-
`[session-defaults] rejected op=load account=${accountId} reason="${message}" ms=${elapsed}`
|
|
11449
|
-
);
|
|
11450
|
-
return c.json({ error: `Session defaults unavailable: ${message}` }, 503);
|
|
11451
|
-
} finally {
|
|
11452
|
-
try {
|
|
11453
|
-
await session.close();
|
|
11454
|
-
} catch {
|
|
11455
|
-
}
|
|
11456
|
-
}
|
|
11457
|
-
});
|
|
11458
|
-
app25.put("/", requireAdminSession, async (c) => {
|
|
11459
|
-
const cacheKey = c.var.cacheKey;
|
|
11460
|
-
const accountId = getAccountIdForSession(cacheKey);
|
|
11461
|
-
const userId = getUserIdForSession(cacheKey);
|
|
11462
|
-
if (!accountId || !userId) {
|
|
11463
|
-
console.error('[session-defaults] rejected op=save reason="missing account or user context"');
|
|
11464
|
-
return c.json({ error: "Account and user context required for session defaults" }, 401);
|
|
11465
|
-
}
|
|
11466
|
-
const body = await safeJson(c);
|
|
11467
|
-
if (!body) {
|
|
11468
|
-
return c.json({ error: "Request body must be JSON" }, 400);
|
|
11469
|
-
}
|
|
11470
|
-
const validation = validateBody2(body);
|
|
11471
|
-
if (!validation.ok) {
|
|
11472
|
-
console.error(
|
|
11473
|
-
`[session-defaults] rejected op=save account=${accountId} reason="${validation.reason}"`
|
|
11474
|
-
);
|
|
11475
|
-
return c.json({ error: validation.reason }, 400);
|
|
11476
|
-
}
|
|
11477
|
-
const { permissionMode, model } = validation;
|
|
11478
|
-
const started = Date.now();
|
|
11479
|
-
const session = getSession();
|
|
11480
|
-
try {
|
|
11481
|
-
await session.executeWrite(async (tx) => {
|
|
11482
|
-
return await tx.run(WRITE_CYPHER2, {
|
|
11483
|
-
accountId,
|
|
11484
|
-
userId,
|
|
11485
|
-
permissionMode,
|
|
11486
|
-
model,
|
|
11487
|
-
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
11488
|
-
});
|
|
11489
|
-
});
|
|
11490
|
-
const elapsed = Date.now() - started;
|
|
11491
|
-
console.error(
|
|
11492
|
-
`[session-defaults] save account=${accountId} user=${userId} permissionMode=${permissionMode} model=${model ?? "null"} ms=${elapsed}`
|
|
11493
|
-
);
|
|
11494
|
-
return c.json({ permissionMode, model });
|
|
11495
|
-
} catch (err) {
|
|
11496
|
-
const elapsed = Date.now() - started;
|
|
11497
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
11498
|
-
console.error(
|
|
11499
|
-
`[session-defaults] rejected op=save account=${accountId} reason="${message}" ms=${elapsed}`
|
|
11500
|
-
);
|
|
11501
|
-
return c.json({ error: `Failed to save session defaults: ${message}` }, 503);
|
|
11502
|
-
} finally {
|
|
11503
|
-
try {
|
|
11504
|
-
await session.close();
|
|
11505
|
-
} catch {
|
|
11506
|
-
}
|
|
11507
|
-
}
|
|
11508
|
-
});
|
|
11509
|
-
function validateBody2(body) {
|
|
11510
|
-
if (typeof body.permissionMode !== "string") {
|
|
11511
|
-
return { ok: false, reason: "permissionMode must be a string" };
|
|
11512
|
-
}
|
|
11513
|
-
if (!MODE_OPTIONS.includes(body.permissionMode)) {
|
|
11514
|
-
return { ok: false, reason: `permissionMode "${body.permissionMode}" is not one of ${MODE_OPTIONS.join(", ")}` };
|
|
11515
|
-
}
|
|
11516
|
-
if (!("model" in body)) {
|
|
11517
|
-
return { ok: false, reason: "model is required (use null for no override)" };
|
|
11518
|
-
}
|
|
11519
|
-
if (body.model !== null && typeof body.model !== "string") {
|
|
11520
|
-
return { ok: false, reason: "model must be a string or null" };
|
|
11521
|
-
}
|
|
11522
|
-
if (body.model !== null && !MODEL_OPTIONS.includes(body.model)) {
|
|
11523
|
-
return { ok: false, reason: `model "${body.model}" is not one of ${MODEL_OPTIONS.join(", ")} (or null)` };
|
|
11524
|
-
}
|
|
11525
|
-
return {
|
|
11526
|
-
ok: true,
|
|
11527
|
-
permissionMode: body.permissionMode,
|
|
11528
|
-
model: body.model
|
|
11529
|
-
};
|
|
11530
|
-
}
|
|
11531
|
-
var READ_CYPHER2 = `
|
|
11532
|
-
OPTIONAL MATCH (p:SpawnPreference {accountId: $accountId, userId: $userId})
|
|
11533
|
-
RETURN p.permissionMode AS permissionMode, p.model AS model
|
|
11534
|
-
`;
|
|
11535
|
-
var WRITE_CYPHER2 = `
|
|
11536
|
-
MERGE (p:SpawnPreference {accountId: $accountId, userId: $userId})
|
|
11537
|
-
SET p.permissionMode = $permissionMode,
|
|
11538
|
-
p.model = $model,
|
|
11539
|
-
p.updatedAt = $updatedAt
|
|
11540
|
-
RETURN p.permissionMode AS permissionMode
|
|
11541
|
-
`;
|
|
11542
|
-
var session_defaults_default = app25;
|
|
11065
|
+
var graph_default_view_default = app21;
|
|
11543
11066
|
|
|
11544
11067
|
// server/routes/admin/file-attach.ts
|
|
11545
|
-
var
|
|
11546
|
-
|
|
11068
|
+
var app22 = new Hono();
|
|
11069
|
+
app22.post("/", async (c) => {
|
|
11547
11070
|
try {
|
|
11548
11071
|
const body = await c.req.json();
|
|
11549
11072
|
const { filePath, accountId } = body;
|
|
@@ -11566,18 +11089,18 @@ app26.post("/", async (c) => {
|
|
|
11566
11089
|
return c.json({ error: message }, 500);
|
|
11567
11090
|
}
|
|
11568
11091
|
});
|
|
11569
|
-
var file_attach_default =
|
|
11092
|
+
var file_attach_default = app22;
|
|
11570
11093
|
|
|
11571
11094
|
// server/routes/admin/sidebar-artefacts.ts
|
|
11572
11095
|
import neo4j2 from "neo4j-driver";
|
|
11573
11096
|
import { readFile as readFile5, readdir as readdir3, stat as stat5 } from "fs/promises";
|
|
11574
11097
|
import { resolve as resolve14, relative as relative2, isAbsolute } from "path";
|
|
11575
|
-
import { existsSync as
|
|
11098
|
+
import { existsSync as existsSync16 } from "fs";
|
|
11576
11099
|
var LIMIT = 50;
|
|
11577
11100
|
var TEXT_MIME_PREFIXES = ["text/", "application/json", "application/markdown"];
|
|
11578
11101
|
var ADMIN_AGENT_FILES = ["IDENTITY.md", "SOUL.md", "KNOWLEDGE.md"];
|
|
11579
|
-
var
|
|
11580
|
-
|
|
11102
|
+
var app23 = new Hono();
|
|
11103
|
+
app23.get("/", requireAdminSession, async (c) => {
|
|
11581
11104
|
const cacheKey = c.var.cacheKey;
|
|
11582
11105
|
const accountId = getAccountIdForSession(cacheKey);
|
|
11583
11106
|
if (!accountId) {
|
|
@@ -11720,7 +11243,7 @@ async function fetchAgentTemplateRows(accountDir) {
|
|
|
11720
11243
|
async function unionSpecialistFilenames(overrideDir, bundledDir) {
|
|
11721
11244
|
const names = /* @__PURE__ */ new Set();
|
|
11722
11245
|
for (const dir of [overrideDir, bundledDir]) {
|
|
11723
|
-
if (!
|
|
11246
|
+
if (!existsSync16(dir)) continue;
|
|
11724
11247
|
try {
|
|
11725
11248
|
const entries = await readdir3(dir);
|
|
11726
11249
|
for (const entry of entries) {
|
|
@@ -11735,7 +11258,7 @@ async function unionSpecialistFilenames(overrideDir, bundledDir) {
|
|
|
11735
11258
|
}
|
|
11736
11259
|
async function readAgentTemplateRow(inp) {
|
|
11737
11260
|
let chosenPath = null;
|
|
11738
|
-
if (
|
|
11261
|
+
if (existsSync16(inp.overridePath)) {
|
|
11739
11262
|
try {
|
|
11740
11263
|
validateFilePathInAccount(inp.overridePath, inp.overrideRoot);
|
|
11741
11264
|
chosenPath = inp.overridePath;
|
|
@@ -11746,7 +11269,7 @@ async function readAgentTemplateRow(inp) {
|
|
|
11746
11269
|
);
|
|
11747
11270
|
return null;
|
|
11748
11271
|
}
|
|
11749
|
-
} else if (
|
|
11272
|
+
} else if (existsSync16(inp.bundledPath)) {
|
|
11750
11273
|
if (!isWithin(inp.bundledPath, inp.bundledRoot)) {
|
|
11751
11274
|
console.error(
|
|
11752
11275
|
`[admin/sidebar-artefacts] agent-template-read-failed agent=${inp.displayName} kind=${inp.logName} error="bundled path outside PLATFORM_ROOT"`
|
|
@@ -11783,16 +11306,16 @@ function isWithin(target, root) {
|
|
|
11783
11306
|
const rel = relative2(root, target);
|
|
11784
11307
|
return !rel.startsWith("..") && !isAbsolute(rel);
|
|
11785
11308
|
}
|
|
11786
|
-
var sidebar_artefacts_default =
|
|
11309
|
+
var sidebar_artefacts_default = app23;
|
|
11787
11310
|
|
|
11788
11311
|
// server/routes/admin/sidebar-artefact-save.ts
|
|
11789
11312
|
import { mkdir as mkdir4, readdir as readdir4, stat as stat6, writeFile as writeFile5 } from "fs/promises";
|
|
11790
11313
|
import { resolve as resolve15 } from "path";
|
|
11791
|
-
import { existsSync as
|
|
11314
|
+
import { existsSync as existsSync17 } from "fs";
|
|
11792
11315
|
var ADMIN_AGENT_FILES2 = /* @__PURE__ */ new Set(["IDENTITY.md", "SOUL.md", "KNOWLEDGE.md"]);
|
|
11793
11316
|
var UUID_RE4 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/;
|
|
11794
|
-
var
|
|
11795
|
-
|
|
11317
|
+
var app24 = new Hono();
|
|
11318
|
+
app24.post("/", requireAdminSession, async (c) => {
|
|
11796
11319
|
const cacheKey = c.var.cacheKey;
|
|
11797
11320
|
const accountId = getAccountIdForSession(cacheKey);
|
|
11798
11321
|
if (!accountId) return c.json({ error: "Account not found for session" }, 401);
|
|
@@ -11856,7 +11379,7 @@ async function resolveSavePath(id, accountId, accountDir) {
|
|
|
11856
11379
|
}
|
|
11857
11380
|
if (UUID_RE4.test(id)) {
|
|
11858
11381
|
const dir = resolve15(ATTACHMENTS_ROOT, accountId, id);
|
|
11859
|
-
if (!
|
|
11382
|
+
if (!existsSync17(dir)) {
|
|
11860
11383
|
const attShort = id.slice(0, 8);
|
|
11861
11384
|
if (isHealPending(accountId, id)) {
|
|
11862
11385
|
console.error(`[admin/sidebar-artefact-save] heal-race attachmentId=${attShort} outcome=503-retry source=heal-pending`);
|
|
@@ -11904,15 +11427,15 @@ async function resolveSavePath(id, accountId, accountDir) {
|
|
|
11904
11427
|
function relPath(absPath, root) {
|
|
11905
11428
|
return absPath.startsWith(root) ? absPath.slice(root.length + 1) : absPath;
|
|
11906
11429
|
}
|
|
11907
|
-
var sidebar_artefact_save_default =
|
|
11430
|
+
var sidebar_artefact_save_default = app24;
|
|
11908
11431
|
|
|
11909
11432
|
// server/routes/admin/sidebar-artefact-content.ts
|
|
11910
11433
|
import { readFile as readFile6, readdir as readdir5 } from "fs/promises";
|
|
11911
|
-
import { existsSync as
|
|
11434
|
+
import { existsSync as existsSync18 } from "fs";
|
|
11912
11435
|
import { resolve as resolve16 } from "path";
|
|
11913
11436
|
var UUID_RE5 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/;
|
|
11914
|
-
var
|
|
11915
|
-
|
|
11437
|
+
var app25 = new Hono();
|
|
11438
|
+
app25.get("/", requireAdminSession, async (c) => {
|
|
11916
11439
|
const cacheKey = c.var.cacheKey;
|
|
11917
11440
|
const accountId = getAccountIdForSession(cacheKey);
|
|
11918
11441
|
if (!accountId) return new Response("Unauthorized", { status: 401 });
|
|
@@ -11922,7 +11445,7 @@ app29.get("/", requireAdminSession, async (c) => {
|
|
|
11922
11445
|
return new Response("Not found", { status: 404 });
|
|
11923
11446
|
}
|
|
11924
11447
|
const dir = resolve16(ATTACHMENTS_ROOT, accountId, id);
|
|
11925
|
-
if (!
|
|
11448
|
+
if (!existsSync18(dir)) {
|
|
11926
11449
|
console.error(`[admin/sidebar-artefact-content] not-found id=${id.slice(0, 8)}`);
|
|
11927
11450
|
return new Response("Not found", { status: 404 });
|
|
11928
11451
|
}
|
|
@@ -11953,7 +11476,7 @@ app29.get("/", requireAdminSession, async (c) => {
|
|
|
11953
11476
|
}
|
|
11954
11477
|
});
|
|
11955
11478
|
});
|
|
11956
|
-
var sidebar_artefact_content_default =
|
|
11479
|
+
var sidebar_artefact_content_default = app25;
|
|
11957
11480
|
|
|
11958
11481
|
// server/routes/admin/system-stats.ts
|
|
11959
11482
|
import { readFile as readFile7 } from "fs/promises";
|
|
@@ -12050,8 +11573,8 @@ async function sample() {
|
|
|
12050
11573
|
if (process.platform === "linux") return sampleLinux();
|
|
12051
11574
|
return sampleOsFallback();
|
|
12052
11575
|
}
|
|
12053
|
-
var
|
|
12054
|
-
|
|
11576
|
+
var app26 = new Hono();
|
|
11577
|
+
app26.get("/", async (c) => {
|
|
12055
11578
|
const started = Date.now();
|
|
12056
11579
|
if (!inflight) {
|
|
12057
11580
|
inflight = sample().finally(() => {
|
|
@@ -12074,17 +11597,17 @@ app30.get("/", async (c) => {
|
|
|
12074
11597
|
return c.json({ degraded: true, reason, sampledAtMs: Date.now() });
|
|
12075
11598
|
}
|
|
12076
11599
|
});
|
|
12077
|
-
var system_stats_default =
|
|
11600
|
+
var system_stats_default = app26;
|
|
12078
11601
|
|
|
12079
11602
|
// server/routes/admin/health.ts
|
|
12080
|
-
import { existsSync as
|
|
12081
|
-
import { resolve as resolve17, join as
|
|
11603
|
+
import { existsSync as existsSync19, readFileSync as readFileSync14 } from "fs";
|
|
11604
|
+
import { resolve as resolve17, join as join12 } from "path";
|
|
12082
11605
|
var PLATFORM_ROOT6 = process.env.MAXY_PLATFORM_ROOT ?? resolve17(process.cwd(), "..");
|
|
12083
11606
|
var brandHostname = "maxy";
|
|
12084
|
-
var brandJsonPath =
|
|
12085
|
-
if (
|
|
11607
|
+
var brandJsonPath = join12(PLATFORM_ROOT6, "config", "brand.json");
|
|
11608
|
+
if (existsSync19(brandJsonPath)) {
|
|
12086
11609
|
try {
|
|
12087
|
-
const brand = JSON.parse(
|
|
11610
|
+
const brand = JSON.parse(readFileSync14(brandJsonPath, "utf-8"));
|
|
12088
11611
|
if (brand.hostname) brandHostname = brand.hostname;
|
|
12089
11612
|
} catch {
|
|
12090
11613
|
}
|
|
@@ -12093,8 +11616,8 @@ var VERSION_FILE = resolve17(PLATFORM_ROOT6, `config/.${brandHostname}-version`)
|
|
|
12093
11616
|
var PROCESS_STARTED_AT = (/* @__PURE__ */ new Date()).toISOString();
|
|
12094
11617
|
var PROBE_TIMEOUT_MS = 1e3;
|
|
12095
11618
|
function readVersion() {
|
|
12096
|
-
if (!
|
|
12097
|
-
return
|
|
11619
|
+
if (!existsSync19(VERSION_FILE)) return "unknown";
|
|
11620
|
+
return readFileSync14(VERSION_FILE, "utf-8").trim() || "unknown";
|
|
12098
11621
|
}
|
|
12099
11622
|
async function probeConversationDb() {
|
|
12100
11623
|
let session;
|
|
@@ -12119,8 +11642,8 @@ async function probeConversationDb() {
|
|
|
12119
11642
|
});
|
|
12120
11643
|
}
|
|
12121
11644
|
}
|
|
12122
|
-
var
|
|
12123
|
-
|
|
11645
|
+
var app27 = new Hono();
|
|
11646
|
+
app27.get("/", async (c) => {
|
|
12124
11647
|
const version = readVersion();
|
|
12125
11648
|
const probe = await probeConversationDb();
|
|
12126
11649
|
const uptimeMs = Date.now() - new Date(PROCESS_STARTED_AT).getTime();
|
|
@@ -12142,7 +11665,7 @@ app31.get("/", async (c) => {
|
|
|
12142
11665
|
uptimeMs
|
|
12143
11666
|
});
|
|
12144
11667
|
});
|
|
12145
|
-
var health_default2 =
|
|
11668
|
+
var health_default2 = app27;
|
|
12146
11669
|
|
|
12147
11670
|
// server/routes/admin/linkedin-ingest.ts
|
|
12148
11671
|
var TAG20 = "[linkedin-ingest-route]";
|
|
@@ -12238,8 +11761,8 @@ function buildInitialMessage(env) {
|
|
|
12238
11761
|
}
|
|
12239
11762
|
return header;
|
|
12240
11763
|
}
|
|
12241
|
-
var
|
|
12242
|
-
|
|
11764
|
+
var app28 = new Hono();
|
|
11765
|
+
app28.post("/", requireAdminSession, async (c) => {
|
|
12243
11766
|
let body;
|
|
12244
11767
|
try {
|
|
12245
11768
|
body = await c.req.json();
|
|
@@ -12293,7 +11816,7 @@ app32.post("/", requireAdminSession, async (c) => {
|
|
|
12293
11816
|
);
|
|
12294
11817
|
return c.json({ ok: true, dispatchId: envelope.dispatchId, taskId: claudeSessionId }, 202);
|
|
12295
11818
|
});
|
|
12296
|
-
var linkedin_ingest_default =
|
|
11819
|
+
var linkedin_ingest_default = app28;
|
|
12297
11820
|
|
|
12298
11821
|
// server/routes/admin/post-turn-context.ts
|
|
12299
11822
|
import neo4j3 from "neo4j-driver";
|
|
@@ -12335,8 +11858,8 @@ function pruneProperties(raw) {
|
|
|
12335
11858
|
}
|
|
12336
11859
|
return out;
|
|
12337
11860
|
}
|
|
12338
|
-
var
|
|
12339
|
-
|
|
11861
|
+
var app29 = new Hono();
|
|
11862
|
+
app29.get("/", async (c) => {
|
|
12340
11863
|
const remoteAddr = c.env?.incoming?.socket?.remoteAddress ?? "";
|
|
12341
11864
|
if (!isLoopbackAddr2(remoteAddr)) {
|
|
12342
11865
|
console.error(`${TAG21} reject reason=non-loopback remoteAddr=${remoteAddr}`);
|
|
@@ -12396,7 +11919,7 @@ app33.get("/", async (c) => {
|
|
|
12396
11919
|
await session.close();
|
|
12397
11920
|
}
|
|
12398
11921
|
});
|
|
12399
|
-
var post_turn_context_default =
|
|
11922
|
+
var post_turn_context_default = app29;
|
|
12400
11923
|
|
|
12401
11924
|
// server/routes/admin/public-session-context.ts
|
|
12402
11925
|
import neo4j4 from "neo4j-driver";
|
|
@@ -12438,8 +11961,8 @@ function pruneProperties2(raw) {
|
|
|
12438
11961
|
}
|
|
12439
11962
|
return out;
|
|
12440
11963
|
}
|
|
12441
|
-
var
|
|
12442
|
-
|
|
11964
|
+
var app30 = new Hono();
|
|
11965
|
+
app30.get("/", async (c) => {
|
|
12443
11966
|
const remoteAddr = c.env?.incoming?.socket?.remoteAddress ?? "";
|
|
12444
11967
|
if (!isLoopbackAddr3(remoteAddr)) {
|
|
12445
11968
|
console.error(`${TAG22} reject reason=non-loopback remoteAddr=${remoteAddr}`);
|
|
@@ -12498,15 +12021,15 @@ app34.get("/", async (c) => {
|
|
|
12498
12021
|
await session.close();
|
|
12499
12022
|
}
|
|
12500
12023
|
});
|
|
12501
|
-
var public_session_context_default =
|
|
12024
|
+
var public_session_context_default = app30;
|
|
12502
12025
|
|
|
12503
12026
|
// server/routes/admin/public-session-exit.ts
|
|
12504
12027
|
var TAG23 = "[public-session-exit-route]";
|
|
12505
12028
|
function isLoopbackAddr4(addr) {
|
|
12506
12029
|
return addr === "127.0.0.1" || addr === "::1" || addr === "::ffff:127.0.0.1";
|
|
12507
12030
|
}
|
|
12508
|
-
var
|
|
12509
|
-
|
|
12031
|
+
var app31 = new Hono();
|
|
12032
|
+
app31.post("/", async (c) => {
|
|
12510
12033
|
const remoteAddr = c.env?.incoming?.socket?.remoteAddress ?? "";
|
|
12511
12034
|
if (!isLoopbackAddr4(remoteAddr)) {
|
|
12512
12035
|
console.error(`${TAG23} reject reason=non-loopback remoteAddr=${remoteAddr}`);
|
|
@@ -12533,15 +12056,15 @@ app35.post("/", async (c) => {
|
|
|
12533
12056
|
handlePublicSessionExit(sessionId);
|
|
12534
12057
|
return c.json({ ok: true });
|
|
12535
12058
|
});
|
|
12536
|
-
var public_session_exit_default =
|
|
12059
|
+
var public_session_exit_default = app31;
|
|
12537
12060
|
|
|
12538
12061
|
// server/routes/admin/access-session-evict.ts
|
|
12539
12062
|
var TAG24 = "[access-session-evict]";
|
|
12540
12063
|
function isLoopbackAddr5(addr) {
|
|
12541
12064
|
return addr === "127.0.0.1" || addr === "::1" || addr === "::ffff:127.0.0.1";
|
|
12542
12065
|
}
|
|
12543
|
-
var
|
|
12544
|
-
|
|
12066
|
+
var app32 = new Hono();
|
|
12067
|
+
app32.post("/", async (c) => {
|
|
12545
12068
|
const remoteAddr = c.env?.incoming?.socket?.remoteAddress ?? "";
|
|
12546
12069
|
if (!isLoopbackAddr5(remoteAddr)) {
|
|
12547
12070
|
console.error(`${TAG24} reject reason=non-loopback remoteAddr=${remoteAddr}`);
|
|
@@ -12569,46 +12092,42 @@ app36.post("/", async (c) => {
|
|
|
12569
12092
|
console.log(`${TAG24} grantId=${grantId} dropped=${dropped}`);
|
|
12570
12093
|
return c.json({ ok: true, dropped });
|
|
12571
12094
|
});
|
|
12572
|
-
var access_session_evict_default =
|
|
12095
|
+
var access_session_evict_default = app32;
|
|
12573
12096
|
|
|
12574
12097
|
// server/routes/admin/index.ts
|
|
12575
|
-
var
|
|
12576
|
-
|
|
12577
|
-
|
|
12578
|
-
|
|
12579
|
-
|
|
12580
|
-
|
|
12581
|
-
|
|
12582
|
-
|
|
12583
|
-
|
|
12584
|
-
|
|
12585
|
-
|
|
12586
|
-
|
|
12587
|
-
|
|
12588
|
-
|
|
12589
|
-
|
|
12590
|
-
|
|
12591
|
-
|
|
12592
|
-
|
|
12593
|
-
|
|
12594
|
-
|
|
12595
|
-
|
|
12596
|
-
|
|
12597
|
-
|
|
12598
|
-
|
|
12599
|
-
|
|
12600
|
-
|
|
12601
|
-
|
|
12602
|
-
|
|
12603
|
-
|
|
12604
|
-
app37.route("/public-session-context", public_session_context_default);
|
|
12605
|
-
app37.route("/public-session-exit", public_session_exit_default);
|
|
12606
|
-
app37.route("/access-session-evict", access_session_evict_default);
|
|
12607
|
-
var admin_default = app37;
|
|
12098
|
+
var app33 = new Hono();
|
|
12099
|
+
app33.route("/session", session_default);
|
|
12100
|
+
app33.route("/logs", logs_default);
|
|
12101
|
+
app33.route("/claude-info", claude_info_default);
|
|
12102
|
+
app33.route("/attachment", attachment_default);
|
|
12103
|
+
app33.route("/agents", agents_default);
|
|
12104
|
+
app33.route("/sessions", sessions_default);
|
|
12105
|
+
app33.route("/claude-sessions", claude_sessions_default);
|
|
12106
|
+
app33.route("/log-ingest", log_ingest_default);
|
|
12107
|
+
app33.route("/events", events_default);
|
|
12108
|
+
app33.route("/files", files_default);
|
|
12109
|
+
app33.route("/graph-search", graph_search_default);
|
|
12110
|
+
app33.route("/graph-subgraph", graph_subgraph_default);
|
|
12111
|
+
app33.route("/graph-delete", graph_delete_default);
|
|
12112
|
+
app33.route("/graph-restore", graph_restore_default);
|
|
12113
|
+
app33.route("/graph-labels-in-graph", graph_labels_in_graph_default);
|
|
12114
|
+
app33.route("/graph-default-view", graph_default_view_default);
|
|
12115
|
+
app33.route("/file-attach", file_attach_default);
|
|
12116
|
+
app33.route("/sidebar-artefacts", sidebar_artefacts_default);
|
|
12117
|
+
app33.route("/sidebar-artefact-save", sidebar_artefact_save_default);
|
|
12118
|
+
app33.route("/sidebar-artefact-content", sidebar_artefact_content_default);
|
|
12119
|
+
app33.route("/system-stats", system_stats_default);
|
|
12120
|
+
app33.route("/health-brand", health_default2);
|
|
12121
|
+
app33.route("/linkedin-ingest", linkedin_ingest_default);
|
|
12122
|
+
app33.route("/post-turn-context", post_turn_context_default);
|
|
12123
|
+
app33.route("/public-session-context", public_session_context_default);
|
|
12124
|
+
app33.route("/public-session-exit", public_session_exit_default);
|
|
12125
|
+
app33.route("/access-session-evict", access_session_evict_default);
|
|
12126
|
+
var admin_default = app33;
|
|
12608
12127
|
|
|
12609
12128
|
// app/lib/access-gate.ts
|
|
12610
12129
|
import neo4j5 from "neo4j-driver";
|
|
12611
|
-
import { readFileSync as
|
|
12130
|
+
import { readFileSync as readFileSync15 } from "fs";
|
|
12612
12131
|
import { resolve as resolve18 } from "path";
|
|
12613
12132
|
import { randomUUID as randomUUID8 } from "crypto";
|
|
12614
12133
|
var PLATFORM_ROOT7 = process.env.MAXY_PLATFORM_ROOT ?? resolve18(process.cwd(), "..");
|
|
@@ -12617,7 +12136,7 @@ function readPassword() {
|
|
|
12617
12136
|
if (process.env.NEO4J_PASSWORD) return process.env.NEO4J_PASSWORD;
|
|
12618
12137
|
const passwordFile = resolve18(PLATFORM_ROOT7, "config/.neo4j-password");
|
|
12619
12138
|
try {
|
|
12620
|
-
return
|
|
12139
|
+
return readFileSync15(passwordFile, "utf-8").trim();
|
|
12621
12140
|
} catch {
|
|
12622
12141
|
throw new Error(
|
|
12623
12142
|
`Neo4j password not found. Expected at ${passwordFile} or in NEO4J_PASSWORD env var.`
|
|
@@ -12818,8 +12337,8 @@ async function generateNewMagicToken(grantId) {
|
|
|
12818
12337
|
var TAG25 = "[access-verify]";
|
|
12819
12338
|
var MINT_TAG = "[access-session-mint]";
|
|
12820
12339
|
var COOKIE_NAME = "__access_session";
|
|
12821
|
-
var
|
|
12822
|
-
|
|
12340
|
+
var app34 = new Hono();
|
|
12341
|
+
app34.post("/", async (c) => {
|
|
12823
12342
|
const ip = c.var.clientIp || "unknown";
|
|
12824
12343
|
let body;
|
|
12825
12344
|
try {
|
|
@@ -12901,7 +12420,7 @@ app38.post("/", async (c) => {
|
|
|
12901
12420
|
displayName: grant.displayName
|
|
12902
12421
|
});
|
|
12903
12422
|
});
|
|
12904
|
-
var verify_token_default =
|
|
12423
|
+
var verify_token_default = app34;
|
|
12905
12424
|
|
|
12906
12425
|
// app/lib/access-email.ts
|
|
12907
12426
|
import { spawn as spawn2 } from "child_process";
|
|
@@ -12964,9 +12483,9 @@ async function sendMagicLinkEmail(payload) {
|
|
|
12964
12483
|
|
|
12965
12484
|
// server/routes/access/request-magic-link.ts
|
|
12966
12485
|
var TAG26 = "[access-request-link]";
|
|
12967
|
-
var
|
|
12486
|
+
var app35 = new Hono();
|
|
12968
12487
|
var VISITOR_MESSAGE = "If that email is on the invite list, a fresh link is on the way.";
|
|
12969
|
-
|
|
12488
|
+
app35.post("/", async (c) => {
|
|
12970
12489
|
let body;
|
|
12971
12490
|
try {
|
|
12972
12491
|
body = await c.req.json();
|
|
@@ -13040,16 +12559,16 @@ app39.post("/", async (c) => {
|
|
|
13040
12559
|
);
|
|
13041
12560
|
return c.json({ message: VISITOR_MESSAGE }, 200);
|
|
13042
12561
|
});
|
|
13043
|
-
var request_magic_link_default =
|
|
12562
|
+
var request_magic_link_default = app35;
|
|
13044
12563
|
|
|
13045
12564
|
// server/routes/access/index.ts
|
|
13046
|
-
var
|
|
13047
|
-
|
|
13048
|
-
|
|
13049
|
-
var access_default =
|
|
12565
|
+
var app36 = new Hono();
|
|
12566
|
+
app36.route("/verify-token", verify_token_default);
|
|
12567
|
+
app36.route("/request-magic-link", request_magic_link_default);
|
|
12568
|
+
var access_default = app36;
|
|
13050
12569
|
|
|
13051
12570
|
// server/routes/sites.ts
|
|
13052
|
-
import { existsSync as
|
|
12571
|
+
import { existsSync as existsSync20, readFileSync as readFileSync16, realpathSync as realpathSync5, statSync as statSync7 } from "fs";
|
|
13053
12572
|
import { resolve as resolve20 } from "path";
|
|
13054
12573
|
var SAFE_SEG_RE = /^[a-z0-9_][a-z0-9_.-]{0,99}$/i;
|
|
13055
12574
|
var MIME = {
|
|
@@ -13081,8 +12600,8 @@ function getExt(p) {
|
|
|
13081
12600
|
if (idx < p.lastIndexOf("/")) return "";
|
|
13082
12601
|
return p.slice(idx).toLowerCase();
|
|
13083
12602
|
}
|
|
13084
|
-
var
|
|
13085
|
-
|
|
12603
|
+
var app37 = new Hono();
|
|
12604
|
+
app37.get("/:rel{.*}", (c) => {
|
|
13086
12605
|
const reqPath = c.req.path;
|
|
13087
12606
|
const rawRel = c.req.param("rel") ?? "";
|
|
13088
12607
|
const trimmed = rawRel.replace(/^\/+/, "").replace(/\/+$/, "");
|
|
@@ -13115,7 +12634,7 @@ app41.get("/:rel{.*}", (c) => {
|
|
|
13115
12634
|
}
|
|
13116
12635
|
let stat7;
|
|
13117
12636
|
try {
|
|
13118
|
-
stat7 =
|
|
12637
|
+
stat7 = existsSync20(filePath) ? statSync7(filePath) : null;
|
|
13119
12638
|
} catch {
|
|
13120
12639
|
stat7 = null;
|
|
13121
12640
|
}
|
|
@@ -13134,7 +12653,7 @@ app41.get("/:rel{.*}", (c) => {
|
|
|
13134
12653
|
console.error(`[sites] path-traversal-rejected path=${reqPath} reason=escape status=403`);
|
|
13135
12654
|
return c.text("Forbidden", 403);
|
|
13136
12655
|
}
|
|
13137
|
-
if (!
|
|
12656
|
+
if (!existsSync20(filePath)) {
|
|
13138
12657
|
console.error(`[sites] not-found path=${reqPath} status=404`);
|
|
13139
12658
|
return c.text("Not found", 404);
|
|
13140
12659
|
}
|
|
@@ -13153,7 +12672,7 @@ app41.get("/:rel{.*}", (c) => {
|
|
|
13153
12672
|
}
|
|
13154
12673
|
let body;
|
|
13155
12674
|
try {
|
|
13156
|
-
body =
|
|
12675
|
+
body = readFileSync16(realPath);
|
|
13157
12676
|
} catch (err) {
|
|
13158
12677
|
const code = err?.code;
|
|
13159
12678
|
if (code === "EISDIR") {
|
|
@@ -13185,12 +12704,12 @@ app41.get("/:rel{.*}", (c) => {
|
|
|
13185
12704
|
"X-Content-Type-Options": "nosniff"
|
|
13186
12705
|
});
|
|
13187
12706
|
});
|
|
13188
|
-
var sites_default =
|
|
12707
|
+
var sites_default = app37;
|
|
13189
12708
|
|
|
13190
12709
|
// app/lib/visitor-token.ts
|
|
13191
12710
|
import { createHmac, randomBytes, timingSafeEqual } from "crypto";
|
|
13192
|
-
import { mkdirSync as mkdirSync4, readFileSync as
|
|
13193
|
-
import { dirname as
|
|
12711
|
+
import { mkdirSync as mkdirSync4, readFileSync as readFileSync17, writeFileSync as writeFileSync6 } from "fs";
|
|
12712
|
+
import { dirname as dirname4 } from "path";
|
|
13194
12713
|
var TOKEN_PREFIX = "v1.";
|
|
13195
12714
|
var SECRET_BYTES = 32;
|
|
13196
12715
|
var DEFAULT_TTL_MS = 30 * 24 * 60 * 60 * 1e3;
|
|
@@ -13198,7 +12717,7 @@ var cachedSecret = null;
|
|
|
13198
12717
|
function getSecret() {
|
|
13199
12718
|
if (cachedSecret) return cachedSecret;
|
|
13200
12719
|
try {
|
|
13201
|
-
const hex2 =
|
|
12720
|
+
const hex2 = readFileSync17(VISITOR_TOKEN_SECRET_FILE, "utf-8").trim();
|
|
13202
12721
|
if (hex2.length === SECRET_BYTES * 2) {
|
|
13203
12722
|
cachedSecret = Buffer.from(hex2, "hex");
|
|
13204
12723
|
return cachedSecret;
|
|
@@ -13207,12 +12726,12 @@ function getSecret() {
|
|
|
13207
12726
|
}
|
|
13208
12727
|
const fresh = randomBytes(SECRET_BYTES).toString("hex");
|
|
13209
12728
|
try {
|
|
13210
|
-
mkdirSync4(
|
|
12729
|
+
mkdirSync4(dirname4(VISITOR_TOKEN_SECRET_FILE), { recursive: true, mode: 448 });
|
|
13211
12730
|
writeFileSync6(VISITOR_TOKEN_SECRET_FILE, fresh, { mode: 384, flag: "wx" });
|
|
13212
12731
|
console.log(`[visitor-token] secret minted path=${VISITOR_TOKEN_SECRET_FILE}`);
|
|
13213
12732
|
} catch {
|
|
13214
12733
|
}
|
|
13215
|
-
const hex =
|
|
12734
|
+
const hex = readFileSync17(VISITOR_TOKEN_SECRET_FILE, "utf-8").trim();
|
|
13216
12735
|
cachedSecret = Buffer.from(hex, "hex");
|
|
13217
12736
|
return cachedSecret;
|
|
13218
12737
|
}
|
|
@@ -13265,8 +12784,8 @@ var VISITOR_COOKIE_NAME = "mxy_v";
|
|
|
13265
12784
|
var VISITOR_COOKIE_MAX_AGE_SECONDS = Math.floor(DEFAULT_TTL_MS / 1e3);
|
|
13266
12785
|
|
|
13267
12786
|
// app/lib/brand-config.ts
|
|
13268
|
-
import { existsSync as
|
|
13269
|
-
import { join as
|
|
12787
|
+
import { existsSync as existsSync21, readFileSync as readFileSync18 } from "fs";
|
|
12788
|
+
import { join as join13 } from "path";
|
|
13270
12789
|
var cached2 = null;
|
|
13271
12790
|
var cachedAttempted = false;
|
|
13272
12791
|
function readBrandConfig() {
|
|
@@ -13274,10 +12793,10 @@ function readBrandConfig() {
|
|
|
13274
12793
|
cachedAttempted = true;
|
|
13275
12794
|
const platformRoot = process.env.MAXY_PLATFORM_ROOT;
|
|
13276
12795
|
if (!platformRoot) return null;
|
|
13277
|
-
const brandPath =
|
|
13278
|
-
if (!
|
|
12796
|
+
const brandPath = join13(platformRoot, "config", "brand.json");
|
|
12797
|
+
if (!existsSync21(brandPath)) return null;
|
|
13279
12798
|
try {
|
|
13280
|
-
cached2 = JSON.parse(
|
|
12799
|
+
cached2 = JSON.parse(readFileSync18(brandPath, "utf-8"));
|
|
13281
12800
|
return cached2;
|
|
13282
12801
|
} catch {
|
|
13283
12802
|
return null;
|
|
@@ -13285,7 +12804,7 @@ function readBrandConfig() {
|
|
|
13285
12804
|
}
|
|
13286
12805
|
|
|
13287
12806
|
// server/routes/visitor-consent.ts
|
|
13288
|
-
var
|
|
12807
|
+
var app38 = new Hono();
|
|
13289
12808
|
var CONSENT_COOKIE_NAME = "mxy_consent";
|
|
13290
12809
|
var CONSENT_COOKIE_MAX_AGE_SECONDS = 60 * 60 * 24 * 365;
|
|
13291
12810
|
var DEFAULT_CONSENT_COPY = {
|
|
@@ -13330,17 +12849,17 @@ function siteSlugFromReferer(referer) {
|
|
|
13330
12849
|
return "";
|
|
13331
12850
|
}
|
|
13332
12851
|
}
|
|
13333
|
-
|
|
12852
|
+
app38.options("/consent", (c) => {
|
|
13334
12853
|
const origin = getOrigin(c);
|
|
13335
12854
|
setCorsHeaders(c, origin);
|
|
13336
12855
|
return c.body(null, 204);
|
|
13337
12856
|
});
|
|
13338
|
-
|
|
12857
|
+
app38.options("/brand-config", (c) => {
|
|
13339
12858
|
const origin = getOrigin(c);
|
|
13340
12859
|
setCorsHeaders(c, origin);
|
|
13341
12860
|
return c.body(null, 204);
|
|
13342
12861
|
});
|
|
13343
|
-
|
|
12862
|
+
app38.post("/consent", async (c) => {
|
|
13344
12863
|
const origin = getOrigin(c);
|
|
13345
12864
|
setCorsHeaders(c, origin);
|
|
13346
12865
|
let raw;
|
|
@@ -13380,7 +12899,7 @@ app42.post("/consent", async (c) => {
|
|
|
13380
12899
|
console.log(`[consent] ${parsed.decision} site=${site} brand=${brandName} tokenBound=${tokenBound}`);
|
|
13381
12900
|
return c.body(null, 204);
|
|
13382
12901
|
});
|
|
13383
|
-
|
|
12902
|
+
app38.get("/brand-config", (c) => {
|
|
13384
12903
|
const origin = getOrigin(c);
|
|
13385
12904
|
setCorsHeaders(c, origin);
|
|
13386
12905
|
const brand = readBrandConfig();
|
|
@@ -13390,7 +12909,7 @@ app42.get("/brand-config", (c) => {
|
|
|
13390
12909
|
c.header("Cache-Control", "public, max-age=300");
|
|
13391
12910
|
return c.json({ consent: { copy, palette } });
|
|
13392
12911
|
});
|
|
13393
|
-
var visitor_consent_default =
|
|
12912
|
+
var visitor_consent_default = app38;
|
|
13394
12913
|
|
|
13395
12914
|
// server/routes/listings.ts
|
|
13396
12915
|
function getCookie(headerValue, name) {
|
|
@@ -13417,8 +12936,8 @@ function appendConsentParams(pageUrl, token) {
|
|
|
13417
12936
|
}
|
|
13418
12937
|
var SAFE_SLUG_RE = /^[a-z0-9](?:[a-z0-9-]{0,118}[a-z0-9])?$/;
|
|
13419
12938
|
var CHAT_SESSION_KEY_RE = /^[A-Za-z0-9][A-Za-z0-9_-]{7,127}$/;
|
|
13420
|
-
var
|
|
13421
|
-
|
|
12939
|
+
var app39 = new Hono();
|
|
12940
|
+
app39.get("/:slug/click", async (c) => {
|
|
13422
12941
|
const slug = c.req.param("slug") ?? "";
|
|
13423
12942
|
const rawSession = c.req.query("session") ?? "";
|
|
13424
12943
|
const sessionKey = CHAT_SESSION_KEY_RE.test(rawSession) ? rawSession : "invalid";
|
|
@@ -13482,10 +13001,10 @@ app43.get("/:slug/click", async (c) => {
|
|
|
13482
13001
|
console.log(`[property-card-click] sessionKey=${sessionKey} listingSlug=${slug} consent=${consentCookie ?? "absent"} ts=${(/* @__PURE__ */ new Date()).toISOString()}`);
|
|
13483
13002
|
return c.redirect(redirectUrl, 302);
|
|
13484
13003
|
});
|
|
13485
|
-
var listings_default =
|
|
13004
|
+
var listings_default = app39;
|
|
13486
13005
|
|
|
13487
13006
|
// server/routes/visitor-event.ts
|
|
13488
|
-
var
|
|
13007
|
+
var app40 = new Hono();
|
|
13489
13008
|
var BOT_UA_RE = /\b(bot|crawl|spider|slurp|headlesschrome|phantomjs|googlebot|bingbot|yandex|baiduspider|ahrefsbot|semrushbot|mj12bot|dotbot|petalbot)\b/i;
|
|
13490
13009
|
var buckets = /* @__PURE__ */ new Map();
|
|
13491
13010
|
var RATE_LIMIT = 60;
|
|
@@ -13552,12 +13071,12 @@ function originAllowed(origin, allowlist) {
|
|
|
13552
13071
|
return false;
|
|
13553
13072
|
}
|
|
13554
13073
|
}
|
|
13555
|
-
|
|
13074
|
+
app40.options("/event", (c) => {
|
|
13556
13075
|
const origin = getOrigin2(c);
|
|
13557
13076
|
setCorsHeaders2(c, origin);
|
|
13558
13077
|
return c.body(null, 204);
|
|
13559
13078
|
});
|
|
13560
|
-
|
|
13079
|
+
app40.post("/event", async (c) => {
|
|
13561
13080
|
const origin = getOrigin2(c);
|
|
13562
13081
|
setCorsHeaders2(c, origin);
|
|
13563
13082
|
const ua = c.req.header("user-agent") ?? "";
|
|
@@ -13762,7 +13281,7 @@ async function writeEvent(opts) {
|
|
|
13762
13281
|
);
|
|
13763
13282
|
}
|
|
13764
13283
|
}
|
|
13765
|
-
var visitor_event_default =
|
|
13284
|
+
var visitor_event_default = app40;
|
|
13766
13285
|
|
|
13767
13286
|
// app/lib/graph-health.ts
|
|
13768
13287
|
var HOUR_MS = 60 * 60 * 1e3;
|
|
@@ -13906,7 +13425,7 @@ function broadcastAdminShutdown(reason) {
|
|
|
13906
13425
|
|
|
13907
13426
|
// ../lib/entitlement/src/index.ts
|
|
13908
13427
|
import { createPublicKey, createHash as createHash4, verify as cryptoVerify } from "crypto";
|
|
13909
|
-
import { existsSync as
|
|
13428
|
+
import { existsSync as existsSync22, readFileSync as readFileSync19, statSync as statSync8 } from "fs";
|
|
13910
13429
|
import { resolve as resolve21 } from "path";
|
|
13911
13430
|
|
|
13912
13431
|
// ../lib/entitlement/src/canonicalize.ts
|
|
@@ -13955,7 +13474,7 @@ function resolveEntitlement(brand, account) {
|
|
|
13955
13474
|
return logResolved(implicitTrust(account), null);
|
|
13956
13475
|
}
|
|
13957
13476
|
const entitlementPath = resolve21(brand.configDir, "entitlement.json");
|
|
13958
|
-
if (!
|
|
13477
|
+
if (!existsSync22(entitlementPath)) {
|
|
13959
13478
|
return logResolved(anonymousFallback("missing"), { reason: "missing" });
|
|
13960
13479
|
}
|
|
13961
13480
|
const stat7 = statSync8(entitlementPath);
|
|
@@ -13970,7 +13489,7 @@ function resolveEntitlement(brand, account) {
|
|
|
13970
13489
|
function verifyAndResolve(brand, entitlementPath, account) {
|
|
13971
13490
|
let pubkeyPem;
|
|
13972
13491
|
try {
|
|
13973
|
-
pubkeyPem =
|
|
13492
|
+
pubkeyPem = readFileSync19(pubkeyPath(brand), "utf-8");
|
|
13974
13493
|
} catch (err) {
|
|
13975
13494
|
return logResolved(anonymousFallback("pubkey-missing"), {
|
|
13976
13495
|
reason: "pubkey-missing"
|
|
@@ -13984,7 +13503,7 @@ function verifyAndResolve(brand, entitlementPath, account) {
|
|
|
13984
13503
|
}
|
|
13985
13504
|
let envelope;
|
|
13986
13505
|
try {
|
|
13987
|
-
envelope = JSON.parse(
|
|
13506
|
+
envelope = JSON.parse(readFileSync19(entitlementPath, "utf-8"));
|
|
13988
13507
|
} catch {
|
|
13989
13508
|
return logResolved(anonymousFallback("malformed"), { reason: "malformed" });
|
|
13990
13509
|
}
|
|
@@ -14145,14 +13664,14 @@ function clientFrom(c) {
|
|
|
14145
13664
|
);
|
|
14146
13665
|
}
|
|
14147
13666
|
var PLATFORM_ROOT9 = process.env.MAXY_PLATFORM_ROOT || "";
|
|
14148
|
-
var BRAND_JSON_PATH = PLATFORM_ROOT9 ?
|
|
13667
|
+
var BRAND_JSON_PATH = PLATFORM_ROOT9 ? join14(PLATFORM_ROOT9, "config", "brand.json") : "";
|
|
14149
13668
|
var BRAND = { productName: "Maxy", hostname: "maxy", configDir: ".maxy", marketingUrl: "https://getmaxy.com" };
|
|
14150
|
-
if (BRAND_JSON_PATH && !
|
|
13669
|
+
if (BRAND_JSON_PATH && !existsSync23(BRAND_JSON_PATH)) {
|
|
14151
13670
|
console.error(`[brand] WARNING: brand.json not found at ${BRAND_JSON_PATH} \u2014 using Maxy defaults`);
|
|
14152
13671
|
}
|
|
14153
|
-
if (BRAND_JSON_PATH &&
|
|
13672
|
+
if (BRAND_JSON_PATH && existsSync23(BRAND_JSON_PATH)) {
|
|
14154
13673
|
try {
|
|
14155
|
-
const parsed = JSON.parse(
|
|
13674
|
+
const parsed = JSON.parse(readFileSync20(BRAND_JSON_PATH, "utf-8"));
|
|
14156
13675
|
BRAND = { ...BRAND, ...parsed };
|
|
14157
13676
|
} catch (err) {
|
|
14158
13677
|
console.error(`[brand] Failed to parse brand.json: ${err.message}`);
|
|
@@ -14171,11 +13690,11 @@ var brandLoginOpts = {
|
|
|
14171
13690
|
bodyFont: BRAND.defaultFonts?.body,
|
|
14172
13691
|
logoContainsName: !!BRAND.logoContainsName
|
|
14173
13692
|
};
|
|
14174
|
-
var ALIAS_DOMAINS_PATH =
|
|
13693
|
+
var ALIAS_DOMAINS_PATH = join14(homedir2(), BRAND.configDir, "alias-domains.json");
|
|
14175
13694
|
function loadAliasDomains() {
|
|
14176
13695
|
try {
|
|
14177
|
-
if (!
|
|
14178
|
-
const parsed = JSON.parse(
|
|
13696
|
+
if (!existsSync23(ALIAS_DOMAINS_PATH)) return null;
|
|
13697
|
+
const parsed = JSON.parse(readFileSync20(ALIAS_DOMAINS_PATH, "utf-8"));
|
|
14179
13698
|
if (!Array.isArray(parsed)) {
|
|
14180
13699
|
console.error("[alias-domains] malformed alias-domains.json \u2014 expected array");
|
|
14181
13700
|
return null;
|
|
@@ -14199,9 +13718,9 @@ watchFile(ALIAS_DOMAINS_PATH, { interval: 2e3 }, () => {
|
|
|
14199
13718
|
function isPublicHost(host) {
|
|
14200
13719
|
return host.startsWith("public.") || aliasDomains.has(host);
|
|
14201
13720
|
}
|
|
14202
|
-
var
|
|
14203
|
-
|
|
14204
|
-
|
|
13721
|
+
var app41 = new Hono();
|
|
13722
|
+
app41.use("*", clientIpMiddleware);
|
|
13723
|
+
app41.use("*", async (c, next) => {
|
|
14205
13724
|
await next();
|
|
14206
13725
|
c.header("X-Content-Type-Options", "nosniff");
|
|
14207
13726
|
c.header("Referrer-Policy", "strict-origin-when-cross-origin");
|
|
@@ -14211,7 +13730,7 @@ app45.use("*", async (c, next) => {
|
|
|
14211
13730
|
);
|
|
14212
13731
|
});
|
|
14213
13732
|
var HTTP_LOG_PATHS = /* @__PURE__ */ new Set(["/vnc-viewer.html", "/vnc-popout.html"]);
|
|
14214
|
-
|
|
13733
|
+
app41.use("*", async (c, next) => {
|
|
14215
13734
|
if (!HTTP_LOG_PATHS.has(c.req.path)) {
|
|
14216
13735
|
await next();
|
|
14217
13736
|
return;
|
|
@@ -14244,7 +13763,7 @@ var PUBLIC_ALLOWED_PREFIXES = [
|
|
|
14244
13763
|
"/sites/"
|
|
14245
13764
|
];
|
|
14246
13765
|
var PUBLIC_ALLOWED_EXACT = ["/favicon.ico"];
|
|
14247
|
-
|
|
13766
|
+
app41.use("*", async (c, next) => {
|
|
14248
13767
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
14249
13768
|
if (!isPublicHost(host)) {
|
|
14250
13769
|
await next();
|
|
@@ -14284,7 +13803,7 @@ function resolveRemoteAuthOpts() {
|
|
|
14284
13803
|
return brandLoginOpts;
|
|
14285
13804
|
}
|
|
14286
13805
|
var MAX_LOGIN_BODY = 8 * 1024;
|
|
14287
|
-
|
|
13806
|
+
app41.post("/__remote-auth/login", async (c) => {
|
|
14288
13807
|
const client = clientFrom(c);
|
|
14289
13808
|
const clientIp = client.ip || "unknown";
|
|
14290
13809
|
if (!requestIsTlsTerminated(c)) {
|
|
@@ -14329,7 +13848,7 @@ app45.post("/__remote-auth/login", async (c) => {
|
|
|
14329
13848
|
}
|
|
14330
13849
|
});
|
|
14331
13850
|
});
|
|
14332
|
-
|
|
13851
|
+
app41.get("/__remote-auth/logout", (c) => {
|
|
14333
13852
|
const client = clientFrom(c);
|
|
14334
13853
|
const clientIp = client.ip || "unknown";
|
|
14335
13854
|
console.error(`[remote-auth] logout ip=${clientIp}`);
|
|
@@ -14342,7 +13861,7 @@ app45.get("/__remote-auth/logout", (c) => {
|
|
|
14342
13861
|
}
|
|
14343
13862
|
});
|
|
14344
13863
|
});
|
|
14345
|
-
|
|
13864
|
+
app41.post("/__remote-auth/change-password", async (c) => {
|
|
14346
13865
|
const client = clientFrom(c);
|
|
14347
13866
|
const clientIp = client.ip || "unknown";
|
|
14348
13867
|
const rateLimited = checkRateLimit(client);
|
|
@@ -14393,13 +13912,13 @@ app45.post("/__remote-auth/change-password", async (c) => {
|
|
|
14393
13912
|
return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(), mode: "change", changeError: "Failed to save password", redirect }), 200);
|
|
14394
13913
|
}
|
|
14395
13914
|
});
|
|
14396
|
-
|
|
13915
|
+
app41.get("/__remote-auth/setup", (c) => {
|
|
14397
13916
|
if (isRemoteAuthConfigured()) {
|
|
14398
13917
|
return c.redirect("/");
|
|
14399
13918
|
}
|
|
14400
13919
|
return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(), mode: "setup" }), 200);
|
|
14401
13920
|
});
|
|
14402
|
-
|
|
13921
|
+
app41.post("/__remote-auth/set-initial-password", async (c) => {
|
|
14403
13922
|
if (isRemoteAuthConfigured()) {
|
|
14404
13923
|
return c.redirect("/");
|
|
14405
13924
|
}
|
|
@@ -14437,10 +13956,10 @@ app45.post("/__remote-auth/set-initial-password", async (c) => {
|
|
|
14437
13956
|
return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(), mode: "setup", setupError: "Failed to save password. Please try again." }), 200);
|
|
14438
13957
|
}
|
|
14439
13958
|
});
|
|
14440
|
-
|
|
13959
|
+
app41.get("/api/remote-auth/status", (c) => {
|
|
14441
13960
|
return c.json({ configured: isRemoteAuthConfigured() });
|
|
14442
13961
|
});
|
|
14443
|
-
|
|
13962
|
+
app41.post("/api/remote-auth/set-password", async (c) => {
|
|
14444
13963
|
let body;
|
|
14445
13964
|
try {
|
|
14446
13965
|
body = await c.req.json();
|
|
@@ -14471,9 +13990,9 @@ app45.post("/api/remote-auth/set-password", async (c) => {
|
|
|
14471
13990
|
return c.json({ error: "Failed to save password" }, 500);
|
|
14472
13991
|
}
|
|
14473
13992
|
});
|
|
14474
|
-
|
|
13993
|
+
app41.route("/api/_client-error", client_error_default);
|
|
14475
13994
|
console.log("[client-error-route] mounted");
|
|
14476
|
-
|
|
13995
|
+
app41.use("*", async (c, next) => {
|
|
14477
13996
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
14478
13997
|
const path2 = c.req.path;
|
|
14479
13998
|
if (path2 === "/favicon.ico" || path2.startsWith("/assets/") || path2.startsWith("/brand/")) {
|
|
@@ -14506,12 +14025,12 @@ app45.use("*", async (c, next) => {
|
|
|
14506
14025
|
console.error(`[remote-auth] login required ip=${clientIp} path=${path2} ${disambig}`);
|
|
14507
14026
|
return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(), redirect: path2 }), 200);
|
|
14508
14027
|
});
|
|
14509
|
-
|
|
14510
|
-
|
|
14511
|
-
|
|
14512
|
-
|
|
14513
|
-
|
|
14514
|
-
|
|
14028
|
+
app41.route("/api/health", health_default);
|
|
14029
|
+
app41.route("/api/chat", chat_default);
|
|
14030
|
+
app41.route("/api/whatsapp", whatsapp_default);
|
|
14031
|
+
app41.route("/api/onboarding", onboarding_default);
|
|
14032
|
+
app41.route("/api/admin", admin_default);
|
|
14033
|
+
app41.route("/api/access", access_default);
|
|
14515
14034
|
var SAFE_SLUG_RE2 = /^[a-z][a-z0-9-]{2,49}$/;
|
|
14516
14035
|
var SAFE_FILENAME_RE = /^[a-z0-9_][a-z0-9_.-]{0,99}$/i;
|
|
14517
14036
|
var IMAGE_MIME = {
|
|
@@ -14523,7 +14042,7 @@ var IMAGE_MIME = {
|
|
|
14523
14042
|
".svg": "image/svg+xml",
|
|
14524
14043
|
".ico": "image/x-icon"
|
|
14525
14044
|
};
|
|
14526
|
-
|
|
14045
|
+
app41.get("/agent-assets/:slug/:filename", (c) => {
|
|
14527
14046
|
const slug = c.req.param("slug");
|
|
14528
14047
|
const filename = c.req.param("filename");
|
|
14529
14048
|
if (!SAFE_SLUG_RE2.test(slug)) {
|
|
@@ -14545,20 +14064,20 @@ app45.get("/agent-assets/:slug/:filename", (c) => {
|
|
|
14545
14064
|
console.error(`[agent-assets] path-traversal-rejected slug=${slug} file=${filename}`);
|
|
14546
14065
|
return c.text("Forbidden", 403);
|
|
14547
14066
|
}
|
|
14548
|
-
if (!
|
|
14067
|
+
if (!existsSync23(filePath)) {
|
|
14549
14068
|
console.error(`[agent-assets] serve slug=${slug} file=${filename} status=404`);
|
|
14550
14069
|
return c.text("Not found", 404);
|
|
14551
14070
|
}
|
|
14552
14071
|
const ext = "." + filename.split(".").pop()?.toLowerCase();
|
|
14553
14072
|
const contentType = IMAGE_MIME[ext] || "application/octet-stream";
|
|
14554
14073
|
console.log(`[agent-assets] serve slug=${slug} file=${filename} status=200`);
|
|
14555
|
-
const body =
|
|
14074
|
+
const body = readFileSync20(filePath);
|
|
14556
14075
|
return c.body(body, 200, {
|
|
14557
14076
|
"Content-Type": contentType,
|
|
14558
14077
|
"Cache-Control": "public, max-age=3600"
|
|
14559
14078
|
});
|
|
14560
14079
|
});
|
|
14561
|
-
|
|
14080
|
+
app41.get("/generated/:filename", (c) => {
|
|
14562
14081
|
const filename = c.req.param("filename");
|
|
14563
14082
|
if (!SAFE_FILENAME_RE.test(filename) || filename.includes("..")) {
|
|
14564
14083
|
console.error(`[generated] serve file=${filename} status=403`);
|
|
@@ -14575,29 +14094,29 @@ app45.get("/generated/:filename", (c) => {
|
|
|
14575
14094
|
console.error(`[generated] serve file=${filename} status=403`);
|
|
14576
14095
|
return c.text("Forbidden", 403);
|
|
14577
14096
|
}
|
|
14578
|
-
if (!
|
|
14097
|
+
if (!existsSync23(filePath)) {
|
|
14579
14098
|
console.error(`[generated] serve file=${filename} status=404`);
|
|
14580
14099
|
return c.text("Not found", 404);
|
|
14581
14100
|
}
|
|
14582
14101
|
const ext = "." + filename.split(".").pop()?.toLowerCase();
|
|
14583
14102
|
const contentType = IMAGE_MIME[ext] || "application/octet-stream";
|
|
14584
14103
|
console.log(`[generated] serve file=${filename} status=200`);
|
|
14585
|
-
const body =
|
|
14104
|
+
const body = readFileSync20(filePath);
|
|
14586
14105
|
return c.body(body, 200, {
|
|
14587
14106
|
"Content-Type": contentType,
|
|
14588
14107
|
"Cache-Control": "public, max-age=86400"
|
|
14589
14108
|
});
|
|
14590
14109
|
});
|
|
14591
|
-
|
|
14592
|
-
|
|
14593
|
-
|
|
14594
|
-
|
|
14110
|
+
app41.route("/sites", sites_default);
|
|
14111
|
+
app41.route("/listings", listings_default);
|
|
14112
|
+
app41.route("/v", visitor_event_default);
|
|
14113
|
+
app41.route("/v", visitor_consent_default);
|
|
14595
14114
|
var htmlCache = /* @__PURE__ */ new Map();
|
|
14596
14115
|
var brandLogoPath = "/brand/maxy-monochrome.png";
|
|
14597
14116
|
var brandIconPath = "/brand/maxy-monochrome.png";
|
|
14598
|
-
if (BRAND_JSON_PATH &&
|
|
14117
|
+
if (BRAND_JSON_PATH && existsSync23(BRAND_JSON_PATH)) {
|
|
14599
14118
|
try {
|
|
14600
|
-
const fullBrand = JSON.parse(
|
|
14119
|
+
const fullBrand = JSON.parse(readFileSync20(BRAND_JSON_PATH, "utf-8"));
|
|
14601
14120
|
if (fullBrand.assets?.logo) brandLogoPath = `/brand/${fullBrand.assets.logo}`;
|
|
14602
14121
|
brandIconPath = fullBrand.assets?.icon ? `/brand/${fullBrand.assets.icon}` : brandLogoPath;
|
|
14603
14122
|
} catch {
|
|
@@ -14614,9 +14133,9 @@ var brandScript = `<script>window.__BRAND__=${JSON.stringify({
|
|
|
14614
14133
|
function readInstalledVersion() {
|
|
14615
14134
|
try {
|
|
14616
14135
|
if (!PLATFORM_ROOT9) return "unknown";
|
|
14617
|
-
const versionFile =
|
|
14618
|
-
if (!
|
|
14619
|
-
const content =
|
|
14136
|
+
const versionFile = join14(PLATFORM_ROOT9, "config", `.${BRAND.hostname}-version`);
|
|
14137
|
+
if (!existsSync23(versionFile)) return "unknown";
|
|
14138
|
+
const content = readFileSync20(versionFile, "utf-8").trim();
|
|
14620
14139
|
return content || "unknown";
|
|
14621
14140
|
} catch {
|
|
14622
14141
|
return "unknown";
|
|
@@ -14657,7 +14176,7 @@ var clientErrorReporterScript = `<script>
|
|
|
14657
14176
|
function cachedHtml(file) {
|
|
14658
14177
|
let html = htmlCache.get(file);
|
|
14659
14178
|
if (!html) {
|
|
14660
|
-
html =
|
|
14179
|
+
html = readFileSync20(resolve22(process.cwd(), "public", file), "utf-8");
|
|
14661
14180
|
const productNameEsc = escapeHtml(BRAND.productName);
|
|
14662
14181
|
html = html.replace(/<title>([^<]*)<\/title>/, (_match, inner) => `<title>${escapeHtml(inner).replace(/Maxy/g, productNameEsc)}</title>`);
|
|
14663
14182
|
html = html.replace('href="/favicon.ico"', `href="${escapeHtml(brandFaviconPath)}"`);
|
|
@@ -14673,26 +14192,26 @@ ${clientErrorReporterScript}
|
|
|
14673
14192
|
}
|
|
14674
14193
|
var brandedHtmlCache = /* @__PURE__ */ new Map();
|
|
14675
14194
|
function loadBrandingCache(agentSlug) {
|
|
14676
|
-
const configDir2 =
|
|
14195
|
+
const configDir2 = join14(homedir2(), BRAND.configDir);
|
|
14677
14196
|
try {
|
|
14678
|
-
const accountJsonPath =
|
|
14679
|
-
if (!
|
|
14680
|
-
const account = JSON.parse(
|
|
14197
|
+
const accountJsonPath = join14(configDir2, "account.json");
|
|
14198
|
+
if (!existsSync23(accountJsonPath)) return null;
|
|
14199
|
+
const account = JSON.parse(readFileSync20(accountJsonPath, "utf-8"));
|
|
14681
14200
|
const accountId = account.accountId;
|
|
14682
14201
|
if (!accountId) return null;
|
|
14683
|
-
const cachePath =
|
|
14684
|
-
if (!
|
|
14685
|
-
return JSON.parse(
|
|
14202
|
+
const cachePath = join14(configDir2, "branding-cache", accountId, `${agentSlug}.json`);
|
|
14203
|
+
if (!existsSync23(cachePath)) return null;
|
|
14204
|
+
return JSON.parse(readFileSync20(cachePath, "utf-8"));
|
|
14686
14205
|
} catch {
|
|
14687
14206
|
return null;
|
|
14688
14207
|
}
|
|
14689
14208
|
}
|
|
14690
14209
|
function resolveDefaultSlug() {
|
|
14691
14210
|
try {
|
|
14692
|
-
const configDir2 =
|
|
14693
|
-
const accountJsonPath =
|
|
14694
|
-
if (!
|
|
14695
|
-
const account = JSON.parse(
|
|
14211
|
+
const configDir2 = join14(homedir2(), BRAND.configDir);
|
|
14212
|
+
const accountJsonPath = join14(configDir2, "account.json");
|
|
14213
|
+
if (!existsSync23(accountJsonPath)) return null;
|
|
14214
|
+
const account = JSON.parse(readFileSync20(accountJsonPath, "utf-8"));
|
|
14696
14215
|
return account.defaultAgent || null;
|
|
14697
14216
|
} catch {
|
|
14698
14217
|
return null;
|
|
@@ -14728,7 +14247,7 @@ function brandedPublicHtml(agentSlug) {
|
|
|
14728
14247
|
function escapeHtml(s) {
|
|
14729
14248
|
return s.replace(/&/g, "&").replace(/"/g, """).replace(/</g, "<").replace(/>/g, ">");
|
|
14730
14249
|
}
|
|
14731
|
-
|
|
14250
|
+
app41.get("/", (c) => {
|
|
14732
14251
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
14733
14252
|
if (isPublicHost(host)) {
|
|
14734
14253
|
const defaultSlug = resolveDefaultSlug();
|
|
@@ -14736,12 +14255,12 @@ app45.get("/", (c) => {
|
|
|
14736
14255
|
}
|
|
14737
14256
|
return c.html(cachedHtml("index.html"));
|
|
14738
14257
|
});
|
|
14739
|
-
|
|
14258
|
+
app41.get("/public", (c) => {
|
|
14740
14259
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
14741
14260
|
if (isPublicHost(host)) return c.text("Not found", 404);
|
|
14742
14261
|
return c.html(cachedHtml("public.html"));
|
|
14743
14262
|
});
|
|
14744
|
-
|
|
14263
|
+
app41.get("/chat", (c) => {
|
|
14745
14264
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
14746
14265
|
if (isPublicHost(host)) return c.text("Not found", 404);
|
|
14747
14266
|
return c.html(cachedHtml("public.html"));
|
|
@@ -14760,12 +14279,12 @@ async function logViewerFetch(c, next) {
|
|
|
14760
14279
|
duration_ms: Date.now() - start
|
|
14761
14280
|
});
|
|
14762
14281
|
}
|
|
14763
|
-
|
|
14764
|
-
|
|
14765
|
-
|
|
14282
|
+
app41.use("/vnc-viewer.html", logViewerFetch);
|
|
14283
|
+
app41.use("/vnc-popout.html", logViewerFetch);
|
|
14284
|
+
app41.get("/vnc-popout.html", (c) => {
|
|
14766
14285
|
let html = htmlCache.get("vnc-popout.html");
|
|
14767
14286
|
if (!html) {
|
|
14768
|
-
html =
|
|
14287
|
+
html = readFileSync20(resolve22(process.cwd(), "public", "vnc-popout.html"), "utf-8");
|
|
14769
14288
|
const name = escapeHtml(BRAND.productName);
|
|
14770
14289
|
html = html.replace("<title>Browser \u2014 Maxy</title>", `<title>${name}</title>`);
|
|
14771
14290
|
html = html.replace("</head>", ` ${brandScript}
|
|
@@ -14775,7 +14294,7 @@ app45.get("/vnc-popout.html", (c) => {
|
|
|
14775
14294
|
}
|
|
14776
14295
|
return c.html(html);
|
|
14777
14296
|
});
|
|
14778
|
-
|
|
14297
|
+
app41.post("/api/vnc/client-event", async (c) => {
|
|
14779
14298
|
let body;
|
|
14780
14299
|
try {
|
|
14781
14300
|
body = await c.req.json();
|
|
@@ -14796,25 +14315,25 @@ app45.post("/api/vnc/client-event", async (c) => {
|
|
|
14796
14315
|
});
|
|
14797
14316
|
return c.json({ ok: true });
|
|
14798
14317
|
});
|
|
14799
|
-
|
|
14318
|
+
app41.get("/g/:slug", (c) => {
|
|
14800
14319
|
return c.html(brandedPublicHtml());
|
|
14801
14320
|
});
|
|
14802
|
-
|
|
14321
|
+
app41.get("/graph", (c) => {
|
|
14803
14322
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
14804
14323
|
if (isPublicHost(host)) return c.text("Not found", 404);
|
|
14805
14324
|
return c.html(cachedHtml("graph.html"));
|
|
14806
14325
|
});
|
|
14807
|
-
|
|
14326
|
+
app41.get("/sessions", (c) => {
|
|
14808
14327
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
14809
14328
|
if (isPublicHost(host)) return c.text("Not found", 404);
|
|
14810
14329
|
return c.html(cachedHtml("sessions.html"));
|
|
14811
14330
|
});
|
|
14812
|
-
|
|
14331
|
+
app41.get("/data", (c) => {
|
|
14813
14332
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
14814
14333
|
if (isPublicHost(host)) return c.text("Not found", 404);
|
|
14815
14334
|
return c.html(cachedHtml("data.html"));
|
|
14816
14335
|
});
|
|
14817
|
-
|
|
14336
|
+
app41.get("/:slug", async (c, next) => {
|
|
14818
14337
|
const slug = c.req.param("slug");
|
|
14819
14338
|
if (AGENT_SLUG_PATTERN.test(`/${slug}`)) {
|
|
14820
14339
|
const branding = loadBrandingCache(slug);
|
|
@@ -14824,15 +14343,15 @@ app45.get("/:slug", async (c, next) => {
|
|
|
14824
14343
|
await next();
|
|
14825
14344
|
});
|
|
14826
14345
|
if (brandFaviconPath !== "/favicon.ico") {
|
|
14827
|
-
|
|
14346
|
+
app41.get("/favicon.ico", (c) => {
|
|
14828
14347
|
c.header("Cache-Control", "public, max-age=300");
|
|
14829
14348
|
return c.redirect(brandFaviconPath, 302);
|
|
14830
14349
|
});
|
|
14831
14350
|
}
|
|
14832
|
-
|
|
14351
|
+
app41.use("/*", serveStatic({ root: "./public" }));
|
|
14833
14352
|
var port = requirePortEnv("MAXY_UI_INTERNAL_PORT", { tag: "ui-server" });
|
|
14834
14353
|
var hostname = process.env.HOSTNAME ?? "127.0.0.1";
|
|
14835
|
-
var httpServer = serve({ fetch:
|
|
14354
|
+
var httpServer = serve({ fetch: app41.fetch, port, hostname });
|
|
14836
14355
|
console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
|
|
14837
14356
|
{
|
|
14838
14357
|
const loopHist = monitorEventLoopDelay({ resolution: 50 });
|
|
@@ -14868,7 +14387,7 @@ for (const m of SUBAPP_MANIFEST) {
|
|
|
14868
14387
|
}
|
|
14869
14388
|
try {
|
|
14870
14389
|
const registered = [];
|
|
14871
|
-
for (const r of
|
|
14390
|
+
for (const r of app41.routes ?? []) {
|
|
14872
14391
|
if (typeof r.path !== "string" || r.path.includes(":") || r.path.includes("*")) continue;
|
|
14873
14392
|
if (AGENT_SLUG_PATTERN.test(r.path)) {
|
|
14874
14393
|
registered.push({ method: (r.method ?? "ALL").toUpperCase(), path: r.path });
|
|
@@ -14890,8 +14409,8 @@ try {
|
|
|
14890
14409
|
}
|
|
14891
14410
|
(async () => {
|
|
14892
14411
|
try {
|
|
14893
|
-
if (!
|
|
14894
|
-
const usersRaw =
|
|
14412
|
+
if (!existsSync23(USERS_FILE)) return;
|
|
14413
|
+
const usersRaw = readFileSync20(USERS_FILE, "utf-8").trim();
|
|
14895
14414
|
if (!usersRaw) return;
|
|
14896
14415
|
const users = JSON.parse(usersRaw);
|
|
14897
14416
|
const userId = users[0]?.userId;
|
|
@@ -14983,7 +14502,7 @@ if (bootAccountConfig?.whatsapp) {
|
|
|
14983
14502
|
}
|
|
14984
14503
|
init({
|
|
14985
14504
|
configDir: configDirForWhatsApp,
|
|
14986
|
-
platformRoot: resolve22(process.env.MAXY_PLATFORM_ROOT ??
|
|
14505
|
+
platformRoot: resolve22(process.env.MAXY_PLATFORM_ROOT ?? join14(__dirname, "..")),
|
|
14987
14506
|
accountConfig: bootAccountConfig,
|
|
14988
14507
|
onMessage: async (msg) => {
|
|
14989
14508
|
if (process.env.WHATSAPP_PTY_BRIDGE_ENABLED === "true" && msg.text && !msg.isOwnerMirror) {
|