@rubytech/create-realagent 1.0.656 → 1.0.657
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/payload/platform/plugins/admin/skills/deck-pages/SKILL.md +418 -0
- package/payload/server/public/assets/{admin-CcPqY5ao.js → admin-C6FCOBJJ.js} +7 -7
- package/payload/server/public/assets/{data-Jicczbp2.js → data-OhPCCGxF.js} +1 -1
- package/payload/server/public/assets/{file-CpoHig3h.js → file-vGZzzcEL.js} +1 -1
- package/payload/server/public/assets/graph-arM1qUve.js +49 -0
- package/payload/server/public/assets/{house-BJnnbtXo.js → house-CStAEh5N.js} +1 -1
- package/payload/server/public/assets/{jsx-runtime-POVQm-te.css → jsx-runtime-CE3bWIbP.css} +1 -1
- package/payload/server/public/assets/{public-CQlgNVSl.js → public-CA8hdxVS.js} +1 -1
- package/payload/server/public/assets/{share-2-Cb1yEAij.js → share-2-BgiUCVf3.js} +1 -1
- package/payload/server/public/assets/{useVoiceRecorder-C_zUudei.js → useVoiceRecorder-B343k-mr.js} +1 -1
- package/payload/server/public/assets/x-CNdlr5ao.js +1 -0
- package/payload/server/public/data.html +6 -6
- package/payload/server/public/graph.html +6 -6
- package/payload/server/public/index.html +7 -7
- package/payload/server/public/public.html +4 -4
- package/payload/server/server.js +234 -74
- package/payload/server/public/assets/graph-DP93PA2D.js +0 -49
- package/payload/server/public/assets/x-CdsUXLpH.js +0 -1
- /package/payload/server/public/assets/{jsx-runtime-BkM8jsiV.js → jsx-runtime-ZaEwDls0.js} +0 -0
|
@@ -5,13 +5,13 @@
|
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
6
|
<title>Data — Maxy</title>
|
|
7
7
|
<link rel="icon" href="/favicon.ico">
|
|
8
|
-
<script type="module" crossorigin src="/assets/data-
|
|
8
|
+
<script type="module" crossorigin src="/assets/data-OhPCCGxF.js"></script>
|
|
9
9
|
<link rel="modulepreload" crossorigin href="/assets/chunk-DD-I1_y5.js">
|
|
10
|
-
<link rel="modulepreload" crossorigin href="/assets/jsx-runtime-
|
|
11
|
-
<link rel="modulepreload" crossorigin href="/assets/share-2-
|
|
12
|
-
<link rel="modulepreload" crossorigin href="/assets/file-
|
|
13
|
-
<link rel="modulepreload" crossorigin href="/assets/house-
|
|
14
|
-
<link rel="stylesheet" crossorigin href="/assets/jsx-runtime-
|
|
10
|
+
<link rel="modulepreload" crossorigin href="/assets/jsx-runtime-ZaEwDls0.js">
|
|
11
|
+
<link rel="modulepreload" crossorigin href="/assets/share-2-BgiUCVf3.js">
|
|
12
|
+
<link rel="modulepreload" crossorigin href="/assets/file-vGZzzcEL.js">
|
|
13
|
+
<link rel="modulepreload" crossorigin href="/assets/house-CStAEh5N.js">
|
|
14
|
+
<link rel="stylesheet" crossorigin href="/assets/jsx-runtime-CE3bWIbP.css">
|
|
15
15
|
</head>
|
|
16
16
|
<body>
|
|
17
17
|
<div id="root"></div>
|
|
@@ -5,13 +5,13 @@
|
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
6
|
<title>Graph — Maxy</title>
|
|
7
7
|
<link rel="icon" href="/favicon.ico">
|
|
8
|
-
<script type="module" crossorigin src="/assets/graph-
|
|
8
|
+
<script type="module" crossorigin src="/assets/graph-arM1qUve.js"></script>
|
|
9
9
|
<link rel="modulepreload" crossorigin href="/assets/chunk-DD-I1_y5.js">
|
|
10
|
-
<link rel="modulepreload" crossorigin href="/assets/jsx-runtime-
|
|
11
|
-
<link rel="modulepreload" crossorigin href="/assets/share-2-
|
|
12
|
-
<link rel="modulepreload" crossorigin href="/assets/house-
|
|
13
|
-
<link rel="modulepreload" crossorigin href="/assets/x-
|
|
14
|
-
<link rel="stylesheet" crossorigin href="/assets/jsx-runtime-
|
|
10
|
+
<link rel="modulepreload" crossorigin href="/assets/jsx-runtime-ZaEwDls0.js">
|
|
11
|
+
<link rel="modulepreload" crossorigin href="/assets/share-2-BgiUCVf3.js">
|
|
12
|
+
<link rel="modulepreload" crossorigin href="/assets/house-CStAEh5N.js">
|
|
13
|
+
<link rel="modulepreload" crossorigin href="/assets/x-CNdlr5ao.js">
|
|
14
|
+
<link rel="stylesheet" crossorigin href="/assets/jsx-runtime-CE3bWIbP.css">
|
|
15
15
|
</head>
|
|
16
16
|
<body>
|
|
17
17
|
<div id="root"></div>
|
|
@@ -5,15 +5,15 @@
|
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
6
|
<title>Real Agent</title>
|
|
7
7
|
<link rel="icon" href="/favicon.ico">
|
|
8
|
-
<script type="module" crossorigin src="/assets/admin-
|
|
8
|
+
<script type="module" crossorigin src="/assets/admin-C6FCOBJJ.js"></script>
|
|
9
9
|
<link rel="modulepreload" crossorigin href="/assets/chunk-DD-I1_y5.js">
|
|
10
|
-
<link rel="modulepreload" crossorigin href="/assets/jsx-runtime-
|
|
10
|
+
<link rel="modulepreload" crossorigin href="/assets/jsx-runtime-ZaEwDls0.js">
|
|
11
11
|
<link rel="modulepreload" crossorigin href="/assets/preload-helper-qlgyTAkD.js">
|
|
12
|
-
<link rel="modulepreload" crossorigin href="/assets/useVoiceRecorder-
|
|
13
|
-
<link rel="modulepreload" crossorigin href="/assets/share-2-
|
|
14
|
-
<link rel="modulepreload" crossorigin href="/assets/file-
|
|
15
|
-
<link rel="modulepreload" crossorigin href="/assets/x-
|
|
16
|
-
<link rel="stylesheet" crossorigin href="/assets/jsx-runtime-
|
|
12
|
+
<link rel="modulepreload" crossorigin href="/assets/useVoiceRecorder-B343k-mr.js">
|
|
13
|
+
<link rel="modulepreload" crossorigin href="/assets/share-2-BgiUCVf3.js">
|
|
14
|
+
<link rel="modulepreload" crossorigin href="/assets/file-vGZzzcEL.js">
|
|
15
|
+
<link rel="modulepreload" crossorigin href="/assets/x-CNdlr5ao.js">
|
|
16
|
+
<link rel="stylesheet" crossorigin href="/assets/jsx-runtime-CE3bWIbP.css">
|
|
17
17
|
<link rel="stylesheet" crossorigin href="/assets/admin-kHJ-D0s7.css">
|
|
18
18
|
<link rel="stylesheet" href="/brand-defaults.css">
|
|
19
19
|
</head>
|
|
@@ -5,12 +5,12 @@
|
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
6
|
<title>Real Agent</title>
|
|
7
7
|
<link rel="icon" href="/favicon.ico">
|
|
8
|
-
<script type="module" crossorigin src="/assets/public-
|
|
8
|
+
<script type="module" crossorigin src="/assets/public-CA8hdxVS.js"></script>
|
|
9
9
|
<link rel="modulepreload" crossorigin href="/assets/chunk-DD-I1_y5.js">
|
|
10
|
-
<link rel="modulepreload" crossorigin href="/assets/jsx-runtime-
|
|
10
|
+
<link rel="modulepreload" crossorigin href="/assets/jsx-runtime-ZaEwDls0.js">
|
|
11
11
|
<link rel="modulepreload" crossorigin href="/assets/preload-helper-qlgyTAkD.js">
|
|
12
|
-
<link rel="modulepreload" crossorigin href="/assets/useVoiceRecorder-
|
|
13
|
-
<link rel="stylesheet" crossorigin href="/assets/jsx-runtime-
|
|
12
|
+
<link rel="modulepreload" crossorigin href="/assets/useVoiceRecorder-B343k-mr.js">
|
|
13
|
+
<link rel="stylesheet" crossorigin href="/assets/jsx-runtime-CE3bWIbP.css">
|
|
14
14
|
<link rel="stylesheet" href="/brand-defaults.css">
|
|
15
15
|
</head>
|
|
16
16
|
<body>
|
package/payload/server/server.js
CHANGED
|
@@ -1201,14 +1201,14 @@ var Hono = class _Hono {
|
|
|
1201
1201
|
* app.route("/api", app2) // GET /api/user
|
|
1202
1202
|
* ```
|
|
1203
1203
|
*/
|
|
1204
|
-
route(path2,
|
|
1204
|
+
route(path2, app33) {
|
|
1205
1205
|
const subApp = this.basePath(path2);
|
|
1206
|
-
|
|
1206
|
+
app33.routes.map((r) => {
|
|
1207
1207
|
let handler;
|
|
1208
|
-
if (
|
|
1208
|
+
if (app33.errorHandler === errorHandler) {
|
|
1209
1209
|
handler = r.handler;
|
|
1210
1210
|
} else {
|
|
1211
|
-
handler = async (c, next) => (await compose([],
|
|
1211
|
+
handler = async (c, next) => (await compose([], app33.errorHandler)(c, () => r.handler(c, next))).res;
|
|
1212
1212
|
handler[COMPOSED_HANDLER] = r.handler;
|
|
1213
1213
|
}
|
|
1214
1214
|
subApp.#addRoute(r.method, r.path, handler);
|
|
@@ -20670,6 +20670,7 @@ app26.get("/", requireAdminSession, async (c) => {
|
|
|
20670
20670
|
async function handleDefault(c, accountId) {
|
|
20671
20671
|
const rawLabels = c.req.query("labels") ?? "";
|
|
20672
20672
|
const labels = rawLabels.split(",").map((s) => s.trim()).filter(Boolean);
|
|
20673
|
+
const includeTrashed = c.req.query("includeTrashed") === "1";
|
|
20673
20674
|
if (labels.length === 0) {
|
|
20674
20675
|
console.error(
|
|
20675
20676
|
`[graph-page] load rejected reason=missing-filter account=${accountId} labels=`
|
|
@@ -20699,14 +20700,16 @@ async function handleDefault(c, accountId) {
|
|
|
20699
20700
|
const started = Date.now();
|
|
20700
20701
|
const session = getSession();
|
|
20701
20702
|
try {
|
|
20703
|
+
const countCypher = includeTrashed ? DEFAULT_COUNT_CYPHER_INCLUDE_TRASHED : DEFAULT_COUNT_CYPHER;
|
|
20704
|
+
const fetchCypher = includeTrashed ? DEFAULT_FETCH_CYPHER_INCLUDE_TRASHED : DEFAULT_FETCH_CYPHER;
|
|
20702
20705
|
const result = await session.executeRead(async (tx) => {
|
|
20703
|
-
const countResult = await tx.run(
|
|
20706
|
+
const countResult = await tx.run(countCypher, { accountId, labels });
|
|
20704
20707
|
const matchedRaw = countResult.records[0]?.get("matched");
|
|
20705
20708
|
const matched = typeof matchedRaw === "bigint" ? Number(matchedRaw) : Number(matchedRaw ?? 0);
|
|
20706
20709
|
if (matched > CEILING) {
|
|
20707
20710
|
return { overLimit: true, matched };
|
|
20708
20711
|
}
|
|
20709
|
-
const fetchResult = await tx.run(
|
|
20712
|
+
const fetchResult = await tx.run(fetchCypher, { accountId, labels });
|
|
20710
20713
|
const record = fetchResult.records[0];
|
|
20711
20714
|
const rawNodes = record?.get("nodes") ?? [];
|
|
20712
20715
|
const rawEdges = record?.get("edges") ?? [];
|
|
@@ -20727,8 +20730,9 @@ async function handleDefault(c, accountId) {
|
|
|
20727
20730
|
}
|
|
20728
20731
|
const nodes = result.rawNodes.map(pruneNode);
|
|
20729
20732
|
const edges = result.rawEdges.filter((e) => e && e.id != null);
|
|
20733
|
+
const trashedSuffix = includeTrashed ? " includeTrashed=1" : "";
|
|
20730
20734
|
console.error(
|
|
20731
|
-
`[graph-page] load mode=default account=${accountId} labels=${labels.join(",")} nodes=${nodes.length} edges=${edges.length} ms=${elapsed}`
|
|
20735
|
+
`[graph-page] load mode=default account=${accountId} labels=${labels.join(",")}${trashedSuffix} nodes=${nodes.length} edges=${edges.length} ms=${elapsed}`
|
|
20732
20736
|
);
|
|
20733
20737
|
return c.json({ nodes, edges });
|
|
20734
20738
|
} catch (err) {
|
|
@@ -20814,6 +20818,33 @@ var DEFAULT_FETCH_CYPHER = `
|
|
|
20814
20818
|
[x IN nodes | {id: elementId(x), labels: labels(x), properties: properties(x)}] AS nodes,
|
|
20815
20819
|
[e IN rawEdges WHERE e IS NOT NULL] AS edges
|
|
20816
20820
|
`;
|
|
20821
|
+
var DEFAULT_COUNT_CYPHER_INCLUDE_TRASHED = `
|
|
20822
|
+
MATCH (n)
|
|
20823
|
+
WHERE n.accountId = $accountId
|
|
20824
|
+
AND any(lbl IN labels(n) WHERE lbl IN $labels)
|
|
20825
|
+
AND n.deletedAt IS NULL
|
|
20826
|
+
RETURN count(n) AS matched
|
|
20827
|
+
`;
|
|
20828
|
+
var DEFAULT_FETCH_CYPHER_INCLUDE_TRASHED = `
|
|
20829
|
+
MATCH (n)
|
|
20830
|
+
WHERE n.accountId = $accountId
|
|
20831
|
+
AND any(lbl IN labels(n) WHERE lbl IN $labels)
|
|
20832
|
+
AND n.deletedAt IS NULL
|
|
20833
|
+
WITH collect(n) AS nodes, collect(elementId(n)) AS nodeIds
|
|
20834
|
+
UNWIND nodes AS n
|
|
20835
|
+
OPTIONAL MATCH (n)-[r]-(m)
|
|
20836
|
+
WHERE elementId(m) IN nodeIds
|
|
20837
|
+
WITH nodes,
|
|
20838
|
+
collect(DISTINCT CASE WHEN r IS NULL THEN null ELSE {
|
|
20839
|
+
id: elementId(r),
|
|
20840
|
+
from: elementId(startNode(r)),
|
|
20841
|
+
to: elementId(endNode(r)),
|
|
20842
|
+
type: type(r)
|
|
20843
|
+
} END) AS rawEdges
|
|
20844
|
+
RETURN
|
|
20845
|
+
[x IN nodes | {id: elementId(x), labels: labels(x), properties: properties(x)}] AS nodes,
|
|
20846
|
+
[e IN rawEdges WHERE e IS NOT NULL] AS edges
|
|
20847
|
+
`;
|
|
20817
20848
|
var NEIGHBOURHOOD_CYPHER = `
|
|
20818
20849
|
MATCH (n)
|
|
20819
20850
|
WHERE elementId(n) = $elementId
|
|
@@ -20847,7 +20878,9 @@ function pruneNode(node) {
|
|
|
20847
20878
|
if (STRIPPED_PROPERTIES.has(key)) continue;
|
|
20848
20879
|
properties[key] = value;
|
|
20849
20880
|
}
|
|
20850
|
-
|
|
20881
|
+
const trashed = (node.labels ?? []).includes("Trashed");
|
|
20882
|
+
const labels = (node.labels ?? []).filter((l) => l !== "Trashed");
|
|
20883
|
+
return trashed ? { id: node.id, labels, properties, trashed: true } : { id: node.id, labels, properties };
|
|
20851
20884
|
}
|
|
20852
20885
|
var graph_subgraph_default = app26;
|
|
20853
20886
|
|
|
@@ -20940,6 +20973,64 @@ async function trashNode(params) {
|
|
|
20940
20973
|
originalKeys
|
|
20941
20974
|
};
|
|
20942
20975
|
}
|
|
20976
|
+
async function restoreNode(params) {
|
|
20977
|
+
const { session, accountId, elementId } = params;
|
|
20978
|
+
const lookup = await session.run(
|
|
20979
|
+
`MATCH (n:Trashed) WHERE elementId(n) = $eid
|
|
20980
|
+
RETURN labels(n) AS labels, n._trashedKeys AS keysJson`,
|
|
20981
|
+
{ eid: elementId }
|
|
20982
|
+
);
|
|
20983
|
+
if (lookup.records.length === 0) {
|
|
20984
|
+
throw new Error(
|
|
20985
|
+
`restoreNode: trashed node not found (elementId=${elementId})`
|
|
20986
|
+
);
|
|
20987
|
+
}
|
|
20988
|
+
const allLabels = lookup.records[0].get("labels");
|
|
20989
|
+
const baseLabels = allLabels.filter((l) => l !== "Trashed");
|
|
20990
|
+
const keysJson = lookup.records[0].get("keysJson");
|
|
20991
|
+
const originalKeys = keysJson ? JSON.parse(keysJson) : {};
|
|
20992
|
+
for (const label of baseLabels) {
|
|
20993
|
+
const uniqueKeys = UNIQUE_KEYS_BY_LABEL[label] ?? [];
|
|
20994
|
+
for (const k of uniqueKeys) {
|
|
20995
|
+
const v = originalKeys[k];
|
|
20996
|
+
if (v === void 0 || v === null) continue;
|
|
20997
|
+
const conflict = await session.run(
|
|
20998
|
+
`MATCH (other:\`${label}\`)
|
|
20999
|
+
WHERE elementId(other) <> $eid
|
|
21000
|
+
AND NOT other:Trashed
|
|
21001
|
+
AND other.\`${k}\` = $val
|
|
21002
|
+
RETURN elementId(other) AS otherId LIMIT 1`,
|
|
21003
|
+
{ eid: elementId, val: v }
|
|
21004
|
+
);
|
|
21005
|
+
if (conflict.records.length > 0) {
|
|
21006
|
+
const otherId = conflict.records[0].get("otherId");
|
|
21007
|
+
throw new Error(
|
|
21008
|
+
`restoreNode: cannot restore ${label} elementId=${elementId} \u2014 active node elementId=${otherId} already holds ${k}=${JSON.stringify(v)}`
|
|
21009
|
+
);
|
|
21010
|
+
}
|
|
21011
|
+
}
|
|
21012
|
+
}
|
|
21013
|
+
const setClauses = Object.keys(originalKeys).map((k) => `n.\`${k}\` = $val_${k}`).join(", ");
|
|
21014
|
+
const setSuffix = setClauses ? `, ${setClauses}` : "";
|
|
21015
|
+
const setParams = { eid: elementId };
|
|
21016
|
+
for (const [k, v] of Object.entries(originalKeys)) setParams[`val_${k}`] = v;
|
|
21017
|
+
await session.run(
|
|
21018
|
+
`MATCH (n:Trashed) WHERE elementId(n) = $eid
|
|
21019
|
+
REMOVE n:Trashed, n.trashedAt, n.trashedBy, n.trashReason, n._trashedKeys
|
|
21020
|
+
SET n.restoredAt = datetime()${setSuffix}`,
|
|
21021
|
+
setParams
|
|
21022
|
+
);
|
|
21023
|
+
process.stderr.write(
|
|
21024
|
+
`[trash:restored] accountId=${accountId} elementId=${elementId} labels=${baseLabels.join(",")}
|
|
21025
|
+
`
|
|
21026
|
+
);
|
|
21027
|
+
return {
|
|
21028
|
+
restored: true,
|
|
21029
|
+
nodeId: elementId,
|
|
21030
|
+
labels: baseLabels,
|
|
21031
|
+
restoredKeys: originalKeys
|
|
21032
|
+
};
|
|
21033
|
+
}
|
|
20943
21034
|
|
|
20944
21035
|
// server/routes/admin/graph-delete.ts
|
|
20945
21036
|
var app27 = new Hono2();
|
|
@@ -21009,9 +21100,77 @@ app27.post("/", requireAdminSession, async (c) => {
|
|
|
21009
21100
|
});
|
|
21010
21101
|
var graph_delete_default = app27;
|
|
21011
21102
|
|
|
21012
|
-
// server/routes/admin/
|
|
21103
|
+
// server/routes/admin/graph-restore.ts
|
|
21013
21104
|
var app28 = new Hono2();
|
|
21014
|
-
app28.post("/", async (c) => {
|
|
21105
|
+
app28.post("/", requireAdminSession, async (c) => {
|
|
21106
|
+
const sessionKey = c.var.sessionKey;
|
|
21107
|
+
const accountId = getAccountIdForSession(sessionKey);
|
|
21108
|
+
if (!accountId) {
|
|
21109
|
+
console.error('[graph-page] restore auth-rejected reason="no account for session"');
|
|
21110
|
+
return c.json({ error: "Account not found for session" }, 401);
|
|
21111
|
+
}
|
|
21112
|
+
const body = await safeJson(c);
|
|
21113
|
+
if (!body) {
|
|
21114
|
+
return c.json({ error: "JSON body required" }, 400);
|
|
21115
|
+
}
|
|
21116
|
+
const elementId = typeof body.elementId === "string" ? body.elementId.trim() : "";
|
|
21117
|
+
if (!elementId) {
|
|
21118
|
+
return c.json({ error: "elementId required" }, 400);
|
|
21119
|
+
}
|
|
21120
|
+
const started = Date.now();
|
|
21121
|
+
const session = getSession();
|
|
21122
|
+
try {
|
|
21123
|
+
const lookup = await session.run(
|
|
21124
|
+
`MATCH (n:Trashed)
|
|
21125
|
+
WHERE elementId(n) = $elementId AND n.accountId = $accountId
|
|
21126
|
+
RETURN labels(n) AS labels LIMIT 1`,
|
|
21127
|
+
{ elementId, accountId }
|
|
21128
|
+
);
|
|
21129
|
+
if (lookup.records.length === 0) {
|
|
21130
|
+
const elapsed2 = Date.now() - started;
|
|
21131
|
+
console.error(
|
|
21132
|
+
`[graph-page] restore account=${accountId} elementId=${elementId} labels= result=not-found ms=${elapsed2}`
|
|
21133
|
+
);
|
|
21134
|
+
return c.json({ error: "Node not found or not trashed" }, 404);
|
|
21135
|
+
}
|
|
21136
|
+
const preflightLabels = (lookup.records[0].get("labels") ?? []).filter((l) => l !== "Trashed");
|
|
21137
|
+
const result = await restoreNode({ session, accountId, elementId });
|
|
21138
|
+
const elapsed = Date.now() - started;
|
|
21139
|
+
const labelSummary = (result.labels.length > 0 ? result.labels : preflightLabels).join(",");
|
|
21140
|
+
console.error(
|
|
21141
|
+
`[graph-page] restore account=${accountId} elementId=${elementId} labels=${labelSummary} result=ok ms=${elapsed}`
|
|
21142
|
+
);
|
|
21143
|
+
const response = {
|
|
21144
|
+
elementId: result.nodeId,
|
|
21145
|
+
labels: result.labels.length > 0 ? result.labels : preflightLabels,
|
|
21146
|
+
restoredKeys: result.restoredKeys
|
|
21147
|
+
};
|
|
21148
|
+
return c.json(response);
|
|
21149
|
+
} catch (err) {
|
|
21150
|
+
const elapsed = Date.now() - started;
|
|
21151
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
21152
|
+
if (message.includes("already holds")) {
|
|
21153
|
+
console.error(
|
|
21154
|
+
`[graph-page] restore account=${accountId} elementId=${elementId} labels= result=conflict ms=${elapsed} err="${message}"`
|
|
21155
|
+
);
|
|
21156
|
+
return c.json({ error: message }, 409);
|
|
21157
|
+
}
|
|
21158
|
+
console.error(
|
|
21159
|
+
`[graph-page] restore account=${accountId} elementId=${elementId} labels= result=error ms=${elapsed} err="${message}"`
|
|
21160
|
+
);
|
|
21161
|
+
return c.json({ error: `Restore failed: ${message}` }, 503);
|
|
21162
|
+
} finally {
|
|
21163
|
+
try {
|
|
21164
|
+
await session.close();
|
|
21165
|
+
} catch {
|
|
21166
|
+
}
|
|
21167
|
+
}
|
|
21168
|
+
});
|
|
21169
|
+
var graph_restore_default = app28;
|
|
21170
|
+
|
|
21171
|
+
// server/routes/admin/file-attach.ts
|
|
21172
|
+
var app29 = new Hono2();
|
|
21173
|
+
app29.post("/", async (c) => {
|
|
21015
21174
|
try {
|
|
21016
21175
|
const body = await c.req.json();
|
|
21017
21176
|
const { filePath, accountId } = body;
|
|
@@ -21034,11 +21193,11 @@ app28.post("/", async (c) => {
|
|
|
21034
21193
|
return c.json({ error: message }, 500);
|
|
21035
21194
|
}
|
|
21036
21195
|
});
|
|
21037
|
-
var file_attach_default =
|
|
21196
|
+
var file_attach_default = app29;
|
|
21038
21197
|
|
|
21039
21198
|
// server/routes/admin/adherence.ts
|
|
21040
|
-
var
|
|
21041
|
-
|
|
21199
|
+
var app30 = new Hono2();
|
|
21200
|
+
app30.get("/", requireAdminSession, async (c) => {
|
|
21042
21201
|
const agent = c.req.query("agent") ?? "admin";
|
|
21043
21202
|
const includeBlock = c.req.query("block") === "1";
|
|
21044
21203
|
const account = resolveAccount();
|
|
@@ -21059,31 +21218,32 @@ app29.get("/", requireAdminSession, async (c) => {
|
|
|
21059
21218
|
return c.json({ error: "Failed to read adherence ledger", agent }, 500);
|
|
21060
21219
|
}
|
|
21061
21220
|
});
|
|
21062
|
-
var adherence_default =
|
|
21221
|
+
var adherence_default = app30;
|
|
21063
21222
|
|
|
21064
21223
|
// server/routes/admin/index.ts
|
|
21065
|
-
var
|
|
21066
|
-
|
|
21067
|
-
|
|
21068
|
-
|
|
21069
|
-
|
|
21070
|
-
|
|
21071
|
-
|
|
21072
|
-
|
|
21073
|
-
|
|
21074
|
-
|
|
21075
|
-
|
|
21076
|
-
|
|
21077
|
-
|
|
21078
|
-
|
|
21079
|
-
|
|
21080
|
-
|
|
21081
|
-
|
|
21082
|
-
|
|
21083
|
-
|
|
21084
|
-
|
|
21085
|
-
|
|
21086
|
-
|
|
21224
|
+
var app31 = new Hono2();
|
|
21225
|
+
app31.route("/session", session_default2);
|
|
21226
|
+
app31.route("/chat", chat_default2);
|
|
21227
|
+
app31.route("/compact", compact_default);
|
|
21228
|
+
app31.route("/logs", logs_default);
|
|
21229
|
+
app31.route("/claude-info", claude_info_default);
|
|
21230
|
+
app31.route("/attachment", attachment_default);
|
|
21231
|
+
app31.route("/account", account_default);
|
|
21232
|
+
app31.route("/agents", agents_default);
|
|
21233
|
+
app31.route("/version", version_default);
|
|
21234
|
+
app31.route("/sessions", sessions_default);
|
|
21235
|
+
app31.route("/browser", browser_default);
|
|
21236
|
+
app31.route("/device-browser", device_browser_default);
|
|
21237
|
+
app31.route("/events", events_default);
|
|
21238
|
+
app31.route("/cloudflare", cloudflare_default);
|
|
21239
|
+
app31.route("/files", files_default);
|
|
21240
|
+
app31.route("/graph-search", graph_search_default);
|
|
21241
|
+
app31.route("/graph-subgraph", graph_subgraph_default);
|
|
21242
|
+
app31.route("/graph-delete", graph_delete_default);
|
|
21243
|
+
app31.route("/graph-restore", graph_restore_default);
|
|
21244
|
+
app31.route("/file-attach", file_attach_default);
|
|
21245
|
+
app31.route("/adherence", adherence_default);
|
|
21246
|
+
var admin_default = app31;
|
|
21087
21247
|
|
|
21088
21248
|
// server/index.ts
|
|
21089
21249
|
var PLATFORM_ROOT11 = process.env.MAXY_PLATFORM_ROOT || "";
|
|
@@ -21141,9 +21301,9 @@ watchFile(ALIAS_DOMAINS_PATH2, { interval: 2e3 }, () => {
|
|
|
21141
21301
|
function isPublicHost(host) {
|
|
21142
21302
|
return host.startsWith("public.") || aliasDomains.has(host);
|
|
21143
21303
|
}
|
|
21144
|
-
var
|
|
21145
|
-
|
|
21146
|
-
|
|
21304
|
+
var app32 = new Hono2();
|
|
21305
|
+
app32.use("*", clientIpMiddleware);
|
|
21306
|
+
app32.use("*", async (c, next) => {
|
|
21147
21307
|
await next();
|
|
21148
21308
|
c.header("X-Content-Type-Options", "nosniff");
|
|
21149
21309
|
c.header("Referrer-Policy", "strict-origin-when-cross-origin");
|
|
@@ -21166,7 +21326,7 @@ var PUBLIC_ALLOWED_PREFIXES = [
|
|
|
21166
21326
|
"/g/"
|
|
21167
21327
|
];
|
|
21168
21328
|
var PUBLIC_ALLOWED_EXACT = ["/favicon.ico"];
|
|
21169
|
-
|
|
21329
|
+
app32.use("*", async (c, next) => {
|
|
21170
21330
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
21171
21331
|
if (!isPublicHost(host)) {
|
|
21172
21332
|
await next();
|
|
@@ -21206,7 +21366,7 @@ function resolveRemoteAuthOpts() {
|
|
|
21206
21366
|
return brandLoginOpts;
|
|
21207
21367
|
}
|
|
21208
21368
|
var MAX_LOGIN_BODY = 8 * 1024;
|
|
21209
|
-
|
|
21369
|
+
app32.post("/__remote-auth/login", async (c) => {
|
|
21210
21370
|
const clientIp = c.var.clientIp || "unknown";
|
|
21211
21371
|
const rateLimited = checkRateLimit(clientIp);
|
|
21212
21372
|
if (rateLimited) {
|
|
@@ -21242,7 +21402,7 @@ app31.post("/__remote-auth/login", async (c) => {
|
|
|
21242
21402
|
}
|
|
21243
21403
|
});
|
|
21244
21404
|
});
|
|
21245
|
-
|
|
21405
|
+
app32.get("/__remote-auth/logout", (c) => {
|
|
21246
21406
|
const cookieHeader = c.req.header("cookie");
|
|
21247
21407
|
const token = parseCookie(cookieHeader, "__remote_session");
|
|
21248
21408
|
if (token) invalidateRemoteSession(token);
|
|
@@ -21255,7 +21415,7 @@ app31.get("/__remote-auth/logout", (c) => {
|
|
|
21255
21415
|
}
|
|
21256
21416
|
});
|
|
21257
21417
|
});
|
|
21258
|
-
|
|
21418
|
+
app32.post("/__remote-auth/change-password", async (c) => {
|
|
21259
21419
|
const clientIp = c.var.clientIp || "unknown";
|
|
21260
21420
|
const rateLimited = checkRateLimit(clientIp);
|
|
21261
21421
|
if (rateLimited) {
|
|
@@ -21304,13 +21464,13 @@ app31.post("/__remote-auth/change-password", async (c) => {
|
|
|
21304
21464
|
return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(), mode: "change", changeError: "Failed to save password", redirect }), 200);
|
|
21305
21465
|
}
|
|
21306
21466
|
});
|
|
21307
|
-
|
|
21467
|
+
app32.get("/__remote-auth/setup", (c) => {
|
|
21308
21468
|
if (isRemoteAuthConfigured()) {
|
|
21309
21469
|
return c.redirect("/");
|
|
21310
21470
|
}
|
|
21311
21471
|
return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(), mode: "setup" }), 200);
|
|
21312
21472
|
});
|
|
21313
|
-
|
|
21473
|
+
app32.post("/__remote-auth/set-initial-password", async (c) => {
|
|
21314
21474
|
if (isRemoteAuthConfigured()) {
|
|
21315
21475
|
return c.redirect("/");
|
|
21316
21476
|
}
|
|
@@ -21346,10 +21506,10 @@ app31.post("/__remote-auth/set-initial-password", async (c) => {
|
|
|
21346
21506
|
return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(), mode: "setup", setupError: "Failed to save password. Please try again." }), 200);
|
|
21347
21507
|
}
|
|
21348
21508
|
});
|
|
21349
|
-
|
|
21509
|
+
app32.get("/api/remote-auth/status", (c) => {
|
|
21350
21510
|
return c.json({ configured: isRemoteAuthConfigured() });
|
|
21351
21511
|
});
|
|
21352
|
-
|
|
21512
|
+
app32.post("/api/remote-auth/set-password", async (c) => {
|
|
21353
21513
|
let body;
|
|
21354
21514
|
try {
|
|
21355
21515
|
body = await c.req.json();
|
|
@@ -21379,9 +21539,9 @@ app31.post("/api/remote-auth/set-password", async (c) => {
|
|
|
21379
21539
|
return c.json({ error: "Failed to save password" }, 500);
|
|
21380
21540
|
}
|
|
21381
21541
|
});
|
|
21382
|
-
|
|
21542
|
+
app32.route("/api/_client-error", client_error_default);
|
|
21383
21543
|
console.log("[client-error-route] mounted");
|
|
21384
|
-
|
|
21544
|
+
app32.use("*", async (c, next) => {
|
|
21385
21545
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
21386
21546
|
const path2 = c.req.path;
|
|
21387
21547
|
if (path2 === "/favicon.ico" || path2.startsWith("/assets/") || path2.startsWith("/brand/")) {
|
|
@@ -21421,15 +21581,15 @@ function parseCookie(cookieHeader, name) {
|
|
|
21421
21581
|
return null;
|
|
21422
21582
|
}
|
|
21423
21583
|
}
|
|
21424
|
-
|
|
21425
|
-
|
|
21426
|
-
|
|
21427
|
-
|
|
21428
|
-
|
|
21429
|
-
|
|
21430
|
-
|
|
21431
|
-
|
|
21432
|
-
|
|
21584
|
+
app32.route("/api/health", health_default);
|
|
21585
|
+
app32.route("/api/session", session_default);
|
|
21586
|
+
app32.route("/api/chat", chat_default);
|
|
21587
|
+
app32.route("/api/group", group_default);
|
|
21588
|
+
app32.route("/api/access", access_default);
|
|
21589
|
+
app32.route("/api/telegram", telegram_default);
|
|
21590
|
+
app32.route("/api/whatsapp", whatsapp_default);
|
|
21591
|
+
app32.route("/api/onboarding", onboarding_default);
|
|
21592
|
+
app32.route("/api/admin", admin_default);
|
|
21433
21593
|
var SAFE_SLUG_RE = /^[a-z][a-z0-9-]{2,49}$/;
|
|
21434
21594
|
var SAFE_FILENAME_RE = /^[a-z0-9_][a-z0-9_.-]{0,99}$/i;
|
|
21435
21595
|
var IMAGE_MIME = {
|
|
@@ -21441,7 +21601,7 @@ var IMAGE_MIME = {
|
|
|
21441
21601
|
".svg": "image/svg+xml",
|
|
21442
21602
|
".ico": "image/x-icon"
|
|
21443
21603
|
};
|
|
21444
|
-
|
|
21604
|
+
app32.get("/agent-assets/:slug/:filename", (c) => {
|
|
21445
21605
|
const slug = c.req.param("slug");
|
|
21446
21606
|
const filename = c.req.param("filename");
|
|
21447
21607
|
if (!SAFE_SLUG_RE.test(slug)) {
|
|
@@ -21476,7 +21636,7 @@ app31.get("/agent-assets/:slug/:filename", (c) => {
|
|
|
21476
21636
|
"Cache-Control": "public, max-age=3600"
|
|
21477
21637
|
});
|
|
21478
21638
|
});
|
|
21479
|
-
|
|
21639
|
+
app32.get("/generated/:filename", (c) => {
|
|
21480
21640
|
const filename = c.req.param("filename");
|
|
21481
21641
|
if (!SAFE_FILENAME_RE.test(filename) || filename.includes("..")) {
|
|
21482
21642
|
console.error(`[generated] serve file=${filename} status=403`);
|
|
@@ -21641,7 +21801,7 @@ function brandedPublicHtml(agentSlug) {
|
|
|
21641
21801
|
function escapeHtml2(s) {
|
|
21642
21802
|
return s.replace(/&/g, "&").replace(/"/g, """).replace(/</g, "<").replace(/>/g, ">");
|
|
21643
21803
|
}
|
|
21644
|
-
|
|
21804
|
+
app32.get("/", (c) => {
|
|
21645
21805
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
21646
21806
|
if (isPublicHost(host)) {
|
|
21647
21807
|
const defaultSlug = resolveDefaultSlug();
|
|
@@ -21649,12 +21809,12 @@ app31.get("/", (c) => {
|
|
|
21649
21809
|
}
|
|
21650
21810
|
return c.html(cachedHtml("index.html"));
|
|
21651
21811
|
});
|
|
21652
|
-
|
|
21812
|
+
app32.get("/public", (c) => {
|
|
21653
21813
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
21654
21814
|
if (isPublicHost(host)) return c.text("Not found", 404);
|
|
21655
21815
|
return c.html(cachedHtml("public.html"));
|
|
21656
21816
|
});
|
|
21657
|
-
|
|
21817
|
+
app32.get("/chat", (c) => {
|
|
21658
21818
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
21659
21819
|
if (isPublicHost(host)) return c.text("Not found", 404);
|
|
21660
21820
|
return c.html(cachedHtml("public.html"));
|
|
@@ -21673,9 +21833,9 @@ async function logViewerFetch(c, next) {
|
|
|
21673
21833
|
duration_ms: Date.now() - start
|
|
21674
21834
|
});
|
|
21675
21835
|
}
|
|
21676
|
-
|
|
21677
|
-
|
|
21678
|
-
|
|
21836
|
+
app32.use("/vnc-viewer.html", logViewerFetch);
|
|
21837
|
+
app32.use("/vnc-popout.html", logViewerFetch);
|
|
21838
|
+
app32.get("/vnc-popout.html", (c) => {
|
|
21679
21839
|
let html = htmlCache.get("vnc-popout.html");
|
|
21680
21840
|
if (!html) {
|
|
21681
21841
|
html = readFileSync26(resolve30(process.cwd(), "public", "vnc-popout.html"), "utf-8");
|
|
@@ -21688,7 +21848,7 @@ app31.get("/vnc-popout.html", (c) => {
|
|
|
21688
21848
|
}
|
|
21689
21849
|
return c.html(html);
|
|
21690
21850
|
});
|
|
21691
|
-
|
|
21851
|
+
app32.post("/api/vnc/client-event", async (c) => {
|
|
21692
21852
|
let body;
|
|
21693
21853
|
try {
|
|
21694
21854
|
body = await c.req.json();
|
|
@@ -21709,20 +21869,20 @@ app31.post("/api/vnc/client-event", async (c) => {
|
|
|
21709
21869
|
});
|
|
21710
21870
|
return c.json({ ok: true });
|
|
21711
21871
|
});
|
|
21712
|
-
|
|
21872
|
+
app32.get("/g/:slug", (c) => {
|
|
21713
21873
|
return c.html(brandedPublicHtml());
|
|
21714
21874
|
});
|
|
21715
|
-
|
|
21875
|
+
app32.get("/graph", (c) => {
|
|
21716
21876
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
21717
21877
|
if (isPublicHost(host)) return c.text("Not found", 404);
|
|
21718
21878
|
return c.html(cachedHtml("graph.html"));
|
|
21719
21879
|
});
|
|
21720
|
-
|
|
21880
|
+
app32.get("/data", (c) => {
|
|
21721
21881
|
const host = (c.req.header("host") ?? "").split(":")[0];
|
|
21722
21882
|
if (isPublicHost(host)) return c.text("Not found", 404);
|
|
21723
21883
|
return c.html(cachedHtml("data.html"));
|
|
21724
21884
|
});
|
|
21725
|
-
|
|
21885
|
+
app32.get("/:slug", async (c, next) => {
|
|
21726
21886
|
const slug = c.req.param("slug");
|
|
21727
21887
|
if (AGENT_SLUG_PATTERN.test(`/${slug}`)) {
|
|
21728
21888
|
const branding = loadBrandingCache(slug);
|
|
@@ -21731,10 +21891,10 @@ app31.get("/:slug", async (c, next) => {
|
|
|
21731
21891
|
}
|
|
21732
21892
|
await next();
|
|
21733
21893
|
});
|
|
21734
|
-
|
|
21894
|
+
app32.use("/*", serveStatic({ root: "./public" }));
|
|
21735
21895
|
var port = parseInt(process.env.PORT ?? "19200", 10);
|
|
21736
21896
|
var hostname = process.env.HOSTNAME ?? "0.0.0.0";
|
|
21737
|
-
var httpServer = serve({ fetch:
|
|
21897
|
+
var httpServer = serve({ fetch: app32.fetch, port, hostname });
|
|
21738
21898
|
attachVncWsProxy(httpServer, {
|
|
21739
21899
|
isPublicHost,
|
|
21740
21900
|
upstreamHost: "127.0.0.1",
|
|
@@ -21780,7 +21940,7 @@ for (const m of SUBAPP_MANIFEST) {
|
|
|
21780
21940
|
}
|
|
21781
21941
|
try {
|
|
21782
21942
|
const registered = [];
|
|
21783
|
-
for (const r of
|
|
21943
|
+
for (const r of app32.routes ?? []) {
|
|
21784
21944
|
if (typeof r.path !== "string" || r.path.includes(":") || r.path.includes("*")) continue;
|
|
21785
21945
|
if (AGENT_SLUG_PATTERN.test(r.path)) {
|
|
21786
21946
|
registered.push({ method: (r.method ?? "ALL").toUpperCase(), path: r.path });
|