@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.
@@ -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-Jicczbp2.js"></script>
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-BkM8jsiV.js">
11
- <link rel="modulepreload" crossorigin href="/assets/share-2-Cb1yEAij.js">
12
- <link rel="modulepreload" crossorigin href="/assets/file-CpoHig3h.js">
13
- <link rel="modulepreload" crossorigin href="/assets/house-BJnnbtXo.js">
14
- <link rel="stylesheet" crossorigin href="/assets/jsx-runtime-POVQm-te.css">
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-DP93PA2D.js"></script>
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-BkM8jsiV.js">
11
- <link rel="modulepreload" crossorigin href="/assets/share-2-Cb1yEAij.js">
12
- <link rel="modulepreload" crossorigin href="/assets/house-BJnnbtXo.js">
13
- <link rel="modulepreload" crossorigin href="/assets/x-CdsUXLpH.js">
14
- <link rel="stylesheet" crossorigin href="/assets/jsx-runtime-POVQm-te.css">
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-CcPqY5ao.js"></script>
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-BkM8jsiV.js">
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-C_zUudei.js">
13
- <link rel="modulepreload" crossorigin href="/assets/share-2-Cb1yEAij.js">
14
- <link rel="modulepreload" crossorigin href="/assets/file-CpoHig3h.js">
15
- <link rel="modulepreload" crossorigin href="/assets/x-CdsUXLpH.js">
16
- <link rel="stylesheet" crossorigin href="/assets/jsx-runtime-POVQm-te.css">
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-CQlgNVSl.js"></script>
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-BkM8jsiV.js">
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-C_zUudei.js">
13
- <link rel="stylesheet" crossorigin href="/assets/jsx-runtime-POVQm-te.css">
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>
@@ -1201,14 +1201,14 @@ var Hono = class _Hono {
1201
1201
  * app.route("/api", app2) // GET /api/user
1202
1202
  * ```
1203
1203
  */
1204
- route(path2, app32) {
1204
+ route(path2, app33) {
1205
1205
  const subApp = this.basePath(path2);
1206
- app32.routes.map((r) => {
1206
+ app33.routes.map((r) => {
1207
1207
  let handler;
1208
- if (app32.errorHandler === errorHandler) {
1208
+ if (app33.errorHandler === errorHandler) {
1209
1209
  handler = r.handler;
1210
1210
  } else {
1211
- handler = async (c, next) => (await compose([], app32.errorHandler)(c, () => r.handler(c, next))).res;
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(DEFAULT_COUNT_CYPHER, { accountId, labels });
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(DEFAULT_FETCH_CYPHER, { accountId, labels });
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
- return { id: node.id, labels: node.labels, properties };
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/file-attach.ts
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 = app28;
21196
+ var file_attach_default = app29;
21038
21197
 
21039
21198
  // server/routes/admin/adherence.ts
21040
- var app29 = new Hono2();
21041
- app29.get("/", requireAdminSession, async (c) => {
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 = app29;
21221
+ var adherence_default = app30;
21063
21222
 
21064
21223
  // server/routes/admin/index.ts
21065
- var app30 = new Hono2();
21066
- app30.route("/session", session_default2);
21067
- app30.route("/chat", chat_default2);
21068
- app30.route("/compact", compact_default);
21069
- app30.route("/logs", logs_default);
21070
- app30.route("/claude-info", claude_info_default);
21071
- app30.route("/attachment", attachment_default);
21072
- app30.route("/account", account_default);
21073
- app30.route("/agents", agents_default);
21074
- app30.route("/version", version_default);
21075
- app30.route("/sessions", sessions_default);
21076
- app30.route("/browser", browser_default);
21077
- app30.route("/device-browser", device_browser_default);
21078
- app30.route("/events", events_default);
21079
- app30.route("/cloudflare", cloudflare_default);
21080
- app30.route("/files", files_default);
21081
- app30.route("/graph-search", graph_search_default);
21082
- app30.route("/graph-subgraph", graph_subgraph_default);
21083
- app30.route("/graph-delete", graph_delete_default);
21084
- app30.route("/file-attach", file_attach_default);
21085
- app30.route("/adherence", adherence_default);
21086
- var admin_default = app30;
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 app31 = new Hono2();
21145
- app31.use("*", clientIpMiddleware);
21146
- app31.use("*", async (c, next) => {
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
- app31.use("*", async (c, next) => {
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
- app31.post("/__remote-auth/login", async (c) => {
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
- app31.get("/__remote-auth/logout", (c) => {
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
- app31.post("/__remote-auth/change-password", async (c) => {
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
- app31.get("/__remote-auth/setup", (c) => {
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
- app31.post("/__remote-auth/set-initial-password", async (c) => {
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
- app31.get("/api/remote-auth/status", (c) => {
21509
+ app32.get("/api/remote-auth/status", (c) => {
21350
21510
  return c.json({ configured: isRemoteAuthConfigured() });
21351
21511
  });
21352
- app31.post("/api/remote-auth/set-password", async (c) => {
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
- app31.route("/api/_client-error", client_error_default);
21542
+ app32.route("/api/_client-error", client_error_default);
21383
21543
  console.log("[client-error-route] mounted");
21384
- app31.use("*", async (c, next) => {
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
- app31.route("/api/health", health_default);
21425
- app31.route("/api/session", session_default);
21426
- app31.route("/api/chat", chat_default);
21427
- app31.route("/api/group", group_default);
21428
- app31.route("/api/access", access_default);
21429
- app31.route("/api/telegram", telegram_default);
21430
- app31.route("/api/whatsapp", whatsapp_default);
21431
- app31.route("/api/onboarding", onboarding_default);
21432
- app31.route("/api/admin", admin_default);
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
- app31.get("/agent-assets/:slug/:filename", (c) => {
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
- app31.get("/generated/:filename", (c) => {
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, "&amp;").replace(/"/g, "&quot;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
21643
21803
  }
21644
- app31.get("/", (c) => {
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
- app31.get("/public", (c) => {
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
- app31.get("/chat", (c) => {
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
- app31.use("/vnc-viewer.html", logViewerFetch);
21677
- app31.use("/vnc-popout.html", logViewerFetch);
21678
- app31.get("/vnc-popout.html", (c) => {
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
- app31.post("/api/vnc/client-event", async (c) => {
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
- app31.get("/g/:slug", (c) => {
21872
+ app32.get("/g/:slug", (c) => {
21713
21873
  return c.html(brandedPublicHtml());
21714
21874
  });
21715
- app31.get("/graph", (c) => {
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
- app31.get("/data", (c) => {
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
- app31.get("/:slug", async (c, next) => {
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
- app31.use("/*", serveStatic({ root: "./public" }));
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: app31.fetch, port, hostname });
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 app31.routes ?? []) {
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 });