@rubytech/create-realagent 1.0.664 → 1.0.665

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.
Files changed (52) hide show
  1. package/dist/index.js +5 -1
  2. package/package.json +1 -1
  3. package/payload/platform/plugins/docs/references/memory-guide.md +1 -1
  4. package/payload/platform/plugins/docs/references/platform.md +1 -1
  5. package/payload/platform/plugins/docs/references/troubleshooting.md +24 -6
  6. package/payload/platform/scripts/vnc.sh +174 -2
  7. package/payload/server/public/assets/{admin-Bo3NKS_u.js → admin-Brug36E-.js} +5 -5
  8. package/payload/server/public/assets/{data-DQcIUUZW.js → data-woLf2Tmp.js} +1 -1
  9. package/payload/server/public/assets/{file-BhFSdU7V.js → file-rN5uuyaV.js} +1 -1
  10. package/payload/server/public/assets/{graph-DSUSNmfO.js → graph-BYaOEZUg.js} +17 -17
  11. package/payload/server/public/assets/{house-CA7LcTyb.js → house-DnFgpCt2.js} +1 -1
  12. package/payload/server/public/assets/jsx-runtime-CSCPZpLN.css +1 -0
  13. package/payload/server/public/assets/{public-C7sPrAvE.js → public-BRrqpeVH.js} +1 -1
  14. package/payload/server/public/assets/{share-2-CVCJTVW7.js → share-2-DLjRUEiG.js} +1 -1
  15. package/payload/server/public/assets/{useVoiceRecorder-DwMKR9su.js → useVoiceRecorder-D_efR3Nx.js} +1 -1
  16. package/payload/server/public/assets/{x-Dnw-ie9I.js → x-L6KPMfIN.js} +1 -1
  17. package/payload/server/public/brand/claude.png +0 -0
  18. package/payload/server/public/data.html +6 -6
  19. package/payload/server/public/graph.html +6 -6
  20. package/payload/server/public/index.html +7 -7
  21. package/payload/server/public/public.html +4 -4
  22. package/payload/server/server.js +252 -114
  23. package/payload/platform/plugins/admin/mcp/dist/lib/onboarding.test.d.ts +0 -2
  24. package/payload/platform/plugins/admin/mcp/dist/lib/onboarding.test.d.ts.map +0 -1
  25. package/payload/platform/plugins/admin/mcp/dist/lib/onboarding.test.js +0 -224
  26. package/payload/platform/plugins/admin/mcp/dist/lib/onboarding.test.js.map +0 -1
  27. package/payload/platform/plugins/documents/mcp/dist/index.d.ts +0 -2
  28. package/payload/platform/plugins/documents/mcp/dist/index.d.ts.map +0 -1
  29. package/payload/platform/plugins/documents/mcp/dist/index.js +0 -98
  30. package/payload/platform/plugins/documents/mcp/dist/index.js.map +0 -1
  31. package/payload/platform/plugins/memory/mcp/dist/lib/semantic-chunker.test.d.ts +0 -2
  32. package/payload/platform/plugins/memory/mcp/dist/lib/semantic-chunker.test.d.ts.map +0 -1
  33. package/payload/platform/plugins/memory/mcp/dist/lib/semantic-chunker.test.js +0 -233
  34. package/payload/platform/plugins/memory/mcp/dist/lib/semantic-chunker.test.js.map +0 -1
  35. package/payload/platform/plugins/memory/mcp/dist/scripts/graph-prune.d.ts +0 -18
  36. package/payload/platform/plugins/memory/mcp/dist/scripts/graph-prune.d.ts.map +0 -1
  37. package/payload/platform/plugins/memory/mcp/dist/scripts/graph-prune.js +0 -80
  38. package/payload/platform/plugins/memory/mcp/dist/scripts/graph-prune.js.map +0 -1
  39. package/payload/platform/plugins/memory/mcp/dist/tools/graph-prune-run.d.ts +0 -7
  40. package/payload/platform/plugins/memory/mcp/dist/tools/graph-prune-run.d.ts.map +0 -1
  41. package/payload/platform/plugins/memory/mcp/dist/tools/graph-prune-run.js +0 -10
  42. package/payload/platform/plugins/memory/mcp/dist/tools/graph-prune-run.js.map +0 -1
  43. package/payload/platform/plugins/waitlist/mcp/dist/lib/anthropic.d.ts +0 -23
  44. package/payload/platform/plugins/waitlist/mcp/dist/lib/anthropic.d.ts.map +0 -1
  45. package/payload/platform/plugins/waitlist/mcp/dist/lib/anthropic.js +0 -115
  46. package/payload/platform/plugins/waitlist/mcp/dist/lib/anthropic.js.map +0 -1
  47. package/payload/platform/plugins/waitlist/mcp/dist/tools/waitlist-extract.d.ts +0 -12
  48. package/payload/platform/plugins/waitlist/mcp/dist/tools/waitlist-extract.d.ts.map +0 -1
  49. package/payload/platform/plugins/waitlist/mcp/dist/tools/waitlist-extract.js +0 -197
  50. package/payload/platform/plugins/waitlist/mcp/dist/tools/waitlist-extract.js.map +0 -1
  51. package/payload/server/public/assets/jsx-runtime-CH3XaSdT.css +0 -1
  52. /package/payload/server/public/assets/{jsx-runtime-BZgdWJ0Y.js → jsx-runtime-XWiDQoTG.js} +0 -0
@@ -1201,14 +1201,14 @@ var Hono = class _Hono {
1201
1201
  * app.route("/api", app2) // GET /api/user
1202
1202
  * ```
1203
1203
  */
1204
- route(path2, app35) {
1204
+ route(path2, app36) {
1205
1205
  const subApp = this.basePath(path2);
1206
- app35.routes.map((r) => {
1206
+ app36.routes.map((r) => {
1207
1207
  let handler;
1208
- if (app35.errorHandler === errorHandler) {
1208
+ if (app36.errorHandler === errorHandler) {
1209
1209
  handler = r.handler;
1210
1210
  } else {
1211
- handler = async (c, next) => (await compose([], app35.errorHandler)(c, () => r.handler(c, next))).res;
1211
+ handler = async (c, next) => (await compose([], app36.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);
@@ -4501,6 +4501,7 @@ function resolveBrowserTransport(req, remoteAddress) {
4501
4501
  return transport;
4502
4502
  }
4503
4503
  var currentCdpDisplay = null;
4504
+ var currentTerminalDisplay = null;
4504
4505
  function discoverNativeDisplay() {
4505
4506
  const fallback = { sessionType: "x11", display: ":0", waylandDisplay: "" };
4506
4507
  try {
@@ -4671,6 +4672,73 @@ async function ensureCdp(transport = "vnc") {
4671
4672
  function killChromium() {
4672
4673
  spawnSync("pkill", ["-f", "chromium"], { stdio: "pipe" });
4673
4674
  }
4675
+ function terminalAlive() {
4676
+ const result = spawnSync("bash", [VNC_SCRIPT, "status-terminal"], {
4677
+ stdio: "pipe",
4678
+ timeout: 2e3
4679
+ });
4680
+ return result.status === 0;
4681
+ }
4682
+ async function ensureTerminal(transport = "vnc") {
4683
+ const targetSentinel = transport === "native" ? "native" : ":99";
4684
+ if (terminalAlive()) {
4685
+ if (currentTerminalDisplay !== null && currentTerminalDisplay !== targetSentinel) {
4686
+ console.error(`[ensureTerminal] Display switch: ${currentTerminalDisplay} \u2192 ${targetSentinel}`);
4687
+ vncLog("ensure-terminal", {
4688
+ action: "display-switch",
4689
+ transport,
4690
+ from_display: currentTerminalDisplay,
4691
+ to_display: targetSentinel
4692
+ });
4693
+ killTerminal();
4694
+ await sleep(500);
4695
+ } else {
4696
+ if (currentTerminalDisplay === null) {
4697
+ currentTerminalDisplay = targetSentinel;
4698
+ }
4699
+ vncLog("ensure-terminal", { action: "already-running", transport });
4700
+ return true;
4701
+ }
4702
+ }
4703
+ const vncCommand = transport === "native" ? "start-terminal-native" : "start-terminal";
4704
+ if (transport === "vnc") {
4705
+ const xAlive = await waitForPort(5900, 1e3);
4706
+ if (!xAlive) {
4707
+ console.error("[ensureTerminal] X server down on :5900 \u2014 escalating to full VNC restart");
4708
+ vncLog("ensure-terminal", { action: "escalate-vnc-restart", reason: "x-down", transport });
4709
+ const vncOk = await ensureVnc();
4710
+ if (!vncOk) {
4711
+ console.error("[ensureTerminal] Full VNC restart failed \u2014 terminal degraded");
4712
+ vncLog("ensure-terminal", { action: "degraded", reason: "vnc-restart-failed", transport });
4713
+ return false;
4714
+ }
4715
+ }
4716
+ }
4717
+ if (transport === "native") {
4718
+ const nativeInfo = discoverNativeDisplay();
4719
+ vncLog("ensure-terminal", {
4720
+ action: "native-display-resolved",
4721
+ transport,
4722
+ session_type: nativeInfo.sessionType,
4723
+ display: nativeInfo.display
4724
+ });
4725
+ }
4726
+ console.error(`[ensureTerminal] Launching terminal (${vncCommand}) for transport=${transport}`);
4727
+ vncLog("ensure-terminal", { action: `launch-${vncCommand}`, transport });
4728
+ try {
4729
+ execFileSync("bash", [VNC_SCRIPT, vncCommand], { timeout: 1e4 });
4730
+ } catch (err) {
4731
+ vncLog("ensure-terminal", { action: "launch-failed", transport, err: err.message });
4732
+ return false;
4733
+ }
4734
+ currentTerminalDisplay = targetSentinel;
4735
+ vncLog("ensure-terminal", { action: "launch-complete", transport, sentinel: targetSentinel });
4736
+ return true;
4737
+ }
4738
+ function killTerminal() {
4739
+ spawnSync("bash", [VNC_SCRIPT, "kill-terminal"], { stdio: "pipe", timeout: 5e3 });
4740
+ currentTerminalDisplay = null;
4741
+ }
4674
4742
  function writeChromiumWrapper() {
4675
4743
  mkdirSync4(BIN_DIR, { recursive: true });
4676
4744
  const wrapperPath = resolve5(BIN_DIR, "chromium");
@@ -19797,6 +19865,44 @@ app20.post("/launch", async (c) => {
19797
19865
  });
19798
19866
  var browser_default = app20;
19799
19867
 
19868
+ // server/routes/admin/terminal.ts
19869
+ var app21 = new Hono2();
19870
+ app21.post("/launch", async (c) => {
19871
+ try {
19872
+ const transport = resolveBrowserTransport(c.req.raw, c.env?.incoming?.socket?.remoteAddress);
19873
+ if (transport === "vnc") {
19874
+ const vncOk = await ensureVnc();
19875
+ if (!vncOk) {
19876
+ return c.json({ ok: false, error: "VNC failed to start" }, 502);
19877
+ }
19878
+ }
19879
+ const terminalOk = await ensureTerminal(transport);
19880
+ if (!terminalOk) {
19881
+ return c.json({ ok: false, error: "Terminal failed to start" }, 502);
19882
+ }
19883
+ return c.json({ ok: true, transport });
19884
+ } catch (err) {
19885
+ console.error("[admin/terminal/launch] Failed to start terminal:", err);
19886
+ return c.json(
19887
+ { ok: false, error: err instanceof Error ? err.message : "Unknown error" },
19888
+ 500
19889
+ );
19890
+ }
19891
+ });
19892
+ app21.post("/close", (c) => {
19893
+ try {
19894
+ killTerminal();
19895
+ return c.json({ ok: true });
19896
+ } catch (err) {
19897
+ console.error("[admin/terminal/close] kill failed:", err);
19898
+ return c.json(
19899
+ { ok: false, error: err instanceof Error ? err.message : "Unknown error" },
19900
+ 500
19901
+ );
19902
+ }
19903
+ });
19904
+ var terminal_default = app21;
19905
+
19800
19906
  // app/lib/cdp-client.ts
19801
19907
  var CDP_HOST = "127.0.0.1";
19802
19908
  var CDP_PORT = 9222;
@@ -19838,8 +19944,8 @@ async function cdpNavigateNewTab(url, opts = {}) {
19838
19944
  }
19839
19945
 
19840
19946
  // server/routes/admin/device-browser.ts
19841
- var app21 = new Hono2();
19842
- app21.post("/navigate", async (c) => {
19947
+ var app22 = new Hono2();
19948
+ app22.post("/navigate", async (c) => {
19843
19949
  const TAG19 = "[device-url:click]";
19844
19950
  let body;
19845
19951
  try {
@@ -19926,7 +20032,7 @@ app21.post("/navigate", async (c) => {
19926
20032
  targetId: outcome.targetId
19927
20033
  });
19928
20034
  });
19929
- var device_browser_default = app21;
20035
+ var device_browser_default = app22;
19930
20036
 
19931
20037
  // server/routes/admin/events.ts
19932
20038
  var ALLOWED_EVENTS = /* @__PURE__ */ new Set([
@@ -19935,8 +20041,8 @@ var ALLOWED_EVENTS = /* @__PURE__ */ new Set([
19935
20041
  "device-url:vnc-surface-shown",
19936
20042
  "device-url:malformed"
19937
20043
  ]);
19938
- var app22 = new Hono2();
19939
- app22.post("/", async (c) => {
20044
+ var app23 = new Hono2();
20045
+ app23.post("/", async (c) => {
19940
20046
  const TAG19 = "[admin:events]";
19941
20047
  let body;
19942
20048
  try {
@@ -19967,7 +20073,7 @@ app22.post("/", async (c) => {
19967
20073
  console.error(`[${event}] ${formatted}`);
19968
20074
  return c.json({ ok: true });
19969
20075
  });
19970
- var events_default = app22;
20076
+ var events_default = app23;
19971
20077
 
19972
20078
  // server/routes/admin/cloudflare.ts
19973
20079
  import { homedir as homedir4 } from "os";
@@ -20060,7 +20166,7 @@ function validateBody(body) {
20060
20166
  }
20061
20167
  return null;
20062
20168
  }
20063
- var app23 = new Hono2();
20169
+ var app24 = new Hono2();
20064
20170
  function fieldFromReason(reason) {
20065
20171
  switch (reason) {
20066
20172
  case "not-signed-in":
@@ -20077,7 +20183,7 @@ function fieldFromReason(reason) {
20077
20183
  return "script";
20078
20184
  }
20079
20185
  }
20080
- app23.get("/domains", requireAdminSession, async (c) => {
20186
+ app24.get("/domains", requireAdminSession, async (c) => {
20081
20187
  const started = Date.now();
20082
20188
  const sessionKey = c.var.sessionKey;
20083
20189
  let correlationId;
@@ -20170,7 +20276,7 @@ ${result.stderr}` : ""}`;
20170
20276
  );
20171
20277
  return c.json(success, 200);
20172
20278
  });
20173
- app23.post("/setup", requireAdminSession, async (c) => {
20279
+ app24.post("/setup", requireAdminSession, async (c) => {
20174
20280
  const started = Date.now();
20175
20281
  const sessionKey = c.var.sessionKey;
20176
20282
  let correlationId;
@@ -20308,7 +20414,7 @@ ${result.stderr}` : ""}`;
20308
20414
  log2(`phase=response-sent`);
20309
20415
  return resp;
20310
20416
  });
20311
- var cloudflare_default = app23;
20417
+ var cloudflare_default = app24;
20312
20418
 
20313
20419
  // server/routes/admin/files.ts
20314
20420
  import { createReadStream as createReadStream3 } from "fs";
@@ -20660,8 +20766,8 @@ function buildDisplayPath(relPath, accountNames) {
20660
20766
  return dn ? { name: seg, displayName: dn } : { name: seg };
20661
20767
  });
20662
20768
  }
20663
- var app24 = new Hono2();
20664
- app24.get("/", requireAdminSession, async (c) => {
20769
+ var app25 = new Hono2();
20770
+ app25.get("/", requireAdminSession, async (c) => {
20665
20771
  const sessionKey = c.var.sessionKey;
20666
20772
  if (!getAccountIdForSession(sessionKey)) {
20667
20773
  console.error(`[data] auth-rejected endpoint="/api/admin/files" reason="no account for session"`);
@@ -20722,7 +20828,7 @@ app24.get("/", requireAdminSession, async (c) => {
20722
20828
  return c.json({ error: message }, 500);
20723
20829
  }
20724
20830
  });
20725
- app24.get("/download", requireAdminSession, async (c) => {
20831
+ app25.get("/download", requireAdminSession, async (c) => {
20726
20832
  const sessionKey = c.var.sessionKey;
20727
20833
  if (!getAccountIdForSession(sessionKey)) {
20728
20834
  console.error(`[data] auth-rejected endpoint="/api/admin/files/download" reason="no account for session"`);
@@ -20770,7 +20876,7 @@ app24.get("/download", requireAdminSession, async (c) => {
20770
20876
  return c.json({ error: message }, 500);
20771
20877
  }
20772
20878
  });
20773
- app24.post("/upload", requireAdminSession, async (c) => {
20879
+ app25.post("/upload", requireAdminSession, async (c) => {
20774
20880
  const sessionKey = c.var.sessionKey;
20775
20881
  const accountId = getAccountIdForSession(sessionKey);
20776
20882
  if (!accountId) {
@@ -20828,7 +20934,7 @@ app24.post("/upload", requireAdminSession, async (c) => {
20828
20934
  mimeType: file.type
20829
20935
  });
20830
20936
  });
20831
- app24.delete("/", requireAdminSession, async (c) => {
20937
+ app25.delete("/", requireAdminSession, async (c) => {
20832
20938
  const sessionKey = c.var.sessionKey;
20833
20939
  const accountId = getAccountIdForSession(sessionKey);
20834
20940
  if (!accountId) {
@@ -20895,13 +21001,13 @@ app24.delete("/", requireAdminSession, async (c) => {
20895
21001
  return c.json({ error: message }, 500);
20896
21002
  }
20897
21003
  });
20898
- var files_default = app24;
21004
+ var files_default = app25;
20899
21005
 
20900
21006
  // server/routes/admin/graph-search.ts
20901
21007
  var DEFAULT_LIMIT = 20;
20902
21008
  var MAX_LIMIT = 100;
20903
- var app25 = new Hono2();
20904
- app25.get("/", requireAdminSession, async (c) => {
21009
+ var app26 = new Hono2();
21010
+ app26.get("/", requireAdminSession, async (c) => {
20905
21011
  const sessionKey = c.var.sessionKey;
20906
21012
  const q = (c.req.query("q") ?? "").trim();
20907
21013
  const rawLimit = c.req.query("limit");
@@ -20926,7 +21032,10 @@ app25.get("/", requireAdminSession, async (c) => {
20926
21032
  return c.json({ error: `Graph search unavailable: ${message}` }, 503);
20927
21033
  }
20928
21034
  });
20929
- var graph_search_default = app25;
21035
+ var graph_search_default = app26;
21036
+
21037
+ // server/routes/admin/graph-subgraph.ts
21038
+ import neo4j3 from "neo4j-driver";
20930
21039
 
20931
21040
  // app/lib/graph-labels.ts
20932
21041
  var GRAPH_LABEL_COLOURS = {
@@ -21002,8 +21111,8 @@ var STRIPPED_PROPERTIES = /* @__PURE__ */ new Set([
21002
21111
  "otpCode",
21003
21112
  "sessionKey"
21004
21113
  ]);
21005
- var app26 = new Hono2();
21006
- app26.get("/", requireAdminSession, async (c) => {
21114
+ var app27 = new Hono2();
21115
+ app27.get("/", requireAdminSession, async (c) => {
21007
21116
  const sessionKey = c.var.sessionKey;
21008
21117
  const accountId = getAccountIdForSession(sessionKey);
21009
21118
  if (!accountId) {
@@ -21228,22 +21337,31 @@ var NEIGHBOURHOOD_CYPHER = `
21228
21337
  [x IN windowNodes | {id: elementId(x), labels: labels(x), properties: properties(x)}] AS nodes,
21229
21338
  [e IN rawEdges WHERE e IS NOT NULL] AS edges
21230
21339
  `;
21340
+ function convertNeo4jValue(value) {
21341
+ if (neo4j3.isDateTime(value) || neo4j3.isDate(value) || neo4j3.isLocalDateTime(value) || neo4j3.isLocalTime(value) || neo4j3.isTime(value) || neo4j3.isDuration(value)) {
21342
+ return value.toString();
21343
+ }
21344
+ if (neo4j3.isInt(value)) {
21345
+ return value.inSafeRange() ? value.toNumber() : value.toString();
21346
+ }
21347
+ return value;
21348
+ }
21231
21349
  function pruneNode(node) {
21232
21350
  const properties = {};
21233
21351
  for (const [key, value] of Object.entries(node.properties ?? {})) {
21234
21352
  if (STRIPPED_PROPERTIES.has(key)) continue;
21235
- properties[key] = value;
21353
+ properties[key] = convertNeo4jValue(value);
21236
21354
  }
21237
21355
  const trashed = (node.labels ?? []).includes("Trashed");
21238
21356
  const labels = (node.labels ?? []).filter((l) => l !== "Trashed");
21239
21357
  return trashed ? { id: node.id, labels, properties, trashed: true } : { id: node.id, labels, properties };
21240
21358
  }
21241
- var graph_subgraph_default = app26;
21359
+ var graph_subgraph_default = app27;
21242
21360
 
21243
21361
  // server/routes/admin/graph-delete.ts
21244
21362
  var ALLOWED_BY = ["graph-page", "graph-drag-trash"];
21245
- var app27 = new Hono2();
21246
- app27.post("/", requireAdminSession, async (c) => {
21363
+ var app28 = new Hono2();
21364
+ app28.post("/", requireAdminSession, async (c) => {
21247
21365
  const sessionKey = c.var.sessionKey;
21248
21366
  const accountId = getAccountIdForSession(sessionKey);
21249
21367
  if (!accountId) {
@@ -21314,11 +21432,11 @@ app27.post("/", requireAdminSession, async (c) => {
21314
21432
  }
21315
21433
  }
21316
21434
  });
21317
- var graph_delete_default = app27;
21435
+ var graph_delete_default = app28;
21318
21436
 
21319
21437
  // server/routes/admin/graph-restore.ts
21320
- var app28 = new Hono2();
21321
- app28.post("/", requireAdminSession, async (c) => {
21438
+ var app29 = new Hono2();
21439
+ app29.post("/", requireAdminSession, async (c) => {
21322
21440
  const sessionKey = c.var.sessionKey;
21323
21441
  const accountId = getAccountIdForSession(sessionKey);
21324
21442
  if (!accountId) {
@@ -21382,11 +21500,11 @@ app28.post("/", requireAdminSession, async (c) => {
21382
21500
  }
21383
21501
  }
21384
21502
  });
21385
- var graph_restore_default = app28;
21503
+ var graph_restore_default = app29;
21386
21504
 
21387
21505
  // server/routes/admin/graph-labels-in-graph.ts
21388
- var app29 = new Hono2();
21389
- app29.get("/", requireAdminSession, async (c) => {
21506
+ var app30 = new Hono2();
21507
+ app30.get("/", requireAdminSession, async (c) => {
21390
21508
  const sessionKey = c.var.sessionKey;
21391
21509
  const accountId = getAccountIdForSession(sessionKey);
21392
21510
  if (!accountId) {
@@ -21403,13 +21521,14 @@ app29.get("/", requireAdminSession, async (c) => {
21403
21521
  const labels = result.records.map((r) => ({
21404
21522
  label: String(r.get("label")),
21405
21523
  nodeCount: toNumber(r.get("nodeCount")),
21406
- relDegree: toNumber(r.get("relDegree"))
21524
+ relDegree: toNumber(r.get("relDegree")),
21525
+ childOnly: toBool(r.get("childOnly"))
21407
21526
  })).filter((row) => row.nodeCount > 0).sort((a, b) => {
21408
21527
  if (b.relDegree !== a.relDegree) return b.relDegree - a.relDegree;
21409
21528
  return a.label.localeCompare(b.label);
21410
21529
  });
21411
21530
  const elapsed = Date.now() - started;
21412
- const summary = labels.map((l) => `${l.label}:${l.nodeCount}:${l.relDegree}`).join(",");
21531
+ const summary = labels.map((l) => `${l.label}:${l.nodeCount}:${l.relDegree}:${l.childOnly ? 1 : 0}`).join(",");
21413
21532
  console.error(
21414
21533
  `[graph-page] labels-in-graph account=${accountId} labels=${summary} ms=${elapsed}`
21415
21534
  );
@@ -21433,21 +21552,39 @@ function toNumber(v) {
21433
21552
  if (typeof v === "number") return v;
21434
21553
  return Number(v ?? 0);
21435
21554
  }
21555
+ function toBool(v) {
21556
+ return v === true;
21557
+ }
21436
21558
  var LABELS_IN_GRAPH_CYPHER = `
21437
21559
  MATCH (n)
21438
21560
  WHERE n.accountId = $accountId
21439
21561
  AND NOT n:Trashed
21440
21562
  AND n.deletedAt IS NULL
21441
- WITH n, [l IN labels(n) WHERE NOT l IN $excluded] AS keptLabels
21563
+ WITH n,
21564
+ [l IN labels(n) WHERE NOT l IN $excluded] AS keptLabels,
21565
+ size([(n)--() | 1]) AS halfEdges
21442
21566
  UNWIND keptLabels AS label
21443
- WITH label, count(DISTINCT n) AS nodeCount, sum(size([(n)--() | 1])) AS relDegree
21444
- RETURN label, nodeCount, relDegree
21567
+ WITH label, n, halfEdges,
21568
+ EXISTS {
21569
+ MATCH (other)-[]->(n)
21570
+ WHERE NOT other:Trashed
21571
+ AND other.deletedAt IS NULL
21572
+ AND NONE(ol IN labels(other) WHERE ol = label)
21573
+ } AS hasNonSelfInbound
21574
+ WITH label,
21575
+ count(DISTINCT n) AS nodeCount,
21576
+ sum(halfEdges) AS relDegree,
21577
+ count(DISTINCT CASE WHEN hasNonSelfInbound THEN n END) AS qualifyingCount
21578
+ RETURN label,
21579
+ nodeCount,
21580
+ relDegree,
21581
+ (nodeCount > 0 AND qualifyingCount = nodeCount) AS childOnly
21445
21582
  `;
21446
- var graph_labels_in_graph_default = app29;
21583
+ var graph_labels_in_graph_default = app30;
21447
21584
 
21448
21585
  // server/routes/admin/graph-default-view.ts
21449
- var app30 = new Hono2();
21450
- app30.get("/", requireAdminSession, async (c) => {
21586
+ var app31 = new Hono2();
21587
+ app31.get("/", requireAdminSession, async (c) => {
21451
21588
  const sessionKey = c.var.sessionKey;
21452
21589
  const accountId = getAccountIdForSession(sessionKey);
21453
21590
  const userId = getUserIdForSession(sessionKey);
@@ -21485,7 +21622,7 @@ app30.get("/", requireAdminSession, async (c) => {
21485
21622
  }
21486
21623
  }
21487
21624
  });
21488
- app30.put("/", requireAdminSession, async (c) => {
21625
+ app31.put("/", requireAdminSession, async (c) => {
21489
21626
  const sessionKey = c.var.sessionKey;
21490
21627
  const accountId = getAccountIdForSession(sessionKey);
21491
21628
  const userId = getUserIdForSession(sessionKey);
@@ -21567,11 +21704,11 @@ var WRITE_CYPHER = `
21567
21704
  p.updatedAt = $updatedAt
21568
21705
  RETURN p.labels AS labels
21569
21706
  `;
21570
- var graph_default_view_default = app30;
21707
+ var graph_default_view_default = app31;
21571
21708
 
21572
21709
  // server/routes/admin/file-attach.ts
21573
- var app31 = new Hono2();
21574
- app31.post("/", async (c) => {
21710
+ var app32 = new Hono2();
21711
+ app32.post("/", async (c) => {
21575
21712
  try {
21576
21713
  const body = await c.req.json();
21577
21714
  const { filePath, accountId } = body;
@@ -21594,11 +21731,11 @@ app31.post("/", async (c) => {
21594
21731
  return c.json({ error: message }, 500);
21595
21732
  }
21596
21733
  });
21597
- var file_attach_default = app31;
21734
+ var file_attach_default = app32;
21598
21735
 
21599
21736
  // server/routes/admin/adherence.ts
21600
- var app32 = new Hono2();
21601
- app32.get("/", requireAdminSession, async (c) => {
21737
+ var app33 = new Hono2();
21738
+ app33.get("/", requireAdminSession, async (c) => {
21602
21739
  const agent = c.req.query("agent") ?? "admin";
21603
21740
  const includeBlock = c.req.query("block") === "1";
21604
21741
  const account = resolveAccount();
@@ -21619,34 +21756,35 @@ app32.get("/", requireAdminSession, async (c) => {
21619
21756
  return c.json({ error: "Failed to read adherence ledger", agent }, 500);
21620
21757
  }
21621
21758
  });
21622
- var adherence_default = app32;
21759
+ var adherence_default = app33;
21623
21760
 
21624
21761
  // server/routes/admin/index.ts
21625
- var app33 = new Hono2();
21626
- app33.route("/session", session_default2);
21627
- app33.route("/chat", chat_default2);
21628
- app33.route("/compact", compact_default);
21629
- app33.route("/logs", logs_default);
21630
- app33.route("/claude-info", claude_info_default);
21631
- app33.route("/attachment", attachment_default);
21632
- app33.route("/account", account_default);
21633
- app33.route("/agents", agents_default);
21634
- app33.route("/version", version_default);
21635
- app33.route("/sessions", sessions_default);
21636
- app33.route("/browser", browser_default);
21637
- app33.route("/device-browser", device_browser_default);
21638
- app33.route("/events", events_default);
21639
- app33.route("/cloudflare", cloudflare_default);
21640
- app33.route("/files", files_default);
21641
- app33.route("/graph-search", graph_search_default);
21642
- app33.route("/graph-subgraph", graph_subgraph_default);
21643
- app33.route("/graph-delete", graph_delete_default);
21644
- app33.route("/graph-restore", graph_restore_default);
21645
- app33.route("/graph-labels-in-graph", graph_labels_in_graph_default);
21646
- app33.route("/graph-default-view", graph_default_view_default);
21647
- app33.route("/file-attach", file_attach_default);
21648
- app33.route("/adherence", adherence_default);
21649
- var admin_default = app33;
21762
+ var app34 = new Hono2();
21763
+ app34.route("/session", session_default2);
21764
+ app34.route("/chat", chat_default2);
21765
+ app34.route("/compact", compact_default);
21766
+ app34.route("/logs", logs_default);
21767
+ app34.route("/claude-info", claude_info_default);
21768
+ app34.route("/attachment", attachment_default);
21769
+ app34.route("/account", account_default);
21770
+ app34.route("/agents", agents_default);
21771
+ app34.route("/version", version_default);
21772
+ app34.route("/sessions", sessions_default);
21773
+ app34.route("/browser", browser_default);
21774
+ app34.route("/terminal", terminal_default);
21775
+ app34.route("/device-browser", device_browser_default);
21776
+ app34.route("/events", events_default);
21777
+ app34.route("/cloudflare", cloudflare_default);
21778
+ app34.route("/files", files_default);
21779
+ app34.route("/graph-search", graph_search_default);
21780
+ app34.route("/graph-subgraph", graph_subgraph_default);
21781
+ app34.route("/graph-delete", graph_delete_default);
21782
+ app34.route("/graph-restore", graph_restore_default);
21783
+ app34.route("/graph-labels-in-graph", graph_labels_in_graph_default);
21784
+ app34.route("/graph-default-view", graph_default_view_default);
21785
+ app34.route("/file-attach", file_attach_default);
21786
+ app34.route("/adherence", adherence_default);
21787
+ var admin_default = app34;
21650
21788
 
21651
21789
  // server/index.ts
21652
21790
  var PLATFORM_ROOT11 = process.env.MAXY_PLATFORM_ROOT || "";
@@ -21704,9 +21842,9 @@ watchFile(ALIAS_DOMAINS_PATH2, { interval: 2e3 }, () => {
21704
21842
  function isPublicHost(host) {
21705
21843
  return host.startsWith("public.") || aliasDomains.has(host);
21706
21844
  }
21707
- var app34 = new Hono2();
21708
- app34.use("*", clientIpMiddleware);
21709
- app34.use("*", async (c, next) => {
21845
+ var app35 = new Hono2();
21846
+ app35.use("*", clientIpMiddleware);
21847
+ app35.use("*", async (c, next) => {
21710
21848
  await next();
21711
21849
  c.header("X-Content-Type-Options", "nosniff");
21712
21850
  c.header("Referrer-Policy", "strict-origin-when-cross-origin");
@@ -21729,7 +21867,7 @@ var PUBLIC_ALLOWED_PREFIXES = [
21729
21867
  "/g/"
21730
21868
  ];
21731
21869
  var PUBLIC_ALLOWED_EXACT = ["/favicon.ico"];
21732
- app34.use("*", async (c, next) => {
21870
+ app35.use("*", async (c, next) => {
21733
21871
  const host = (c.req.header("host") ?? "").split(":")[0];
21734
21872
  if (!isPublicHost(host)) {
21735
21873
  await next();
@@ -21769,7 +21907,7 @@ function resolveRemoteAuthOpts() {
21769
21907
  return brandLoginOpts;
21770
21908
  }
21771
21909
  var MAX_LOGIN_BODY = 8 * 1024;
21772
- app34.post("/__remote-auth/login", async (c) => {
21910
+ app35.post("/__remote-auth/login", async (c) => {
21773
21911
  const clientIp = c.var.clientIp || "unknown";
21774
21912
  const rateLimited = checkRateLimit(clientIp);
21775
21913
  if (rateLimited) {
@@ -21805,7 +21943,7 @@ app34.post("/__remote-auth/login", async (c) => {
21805
21943
  }
21806
21944
  });
21807
21945
  });
21808
- app34.get("/__remote-auth/logout", (c) => {
21946
+ app35.get("/__remote-auth/logout", (c) => {
21809
21947
  const cookieHeader = c.req.header("cookie");
21810
21948
  const token = parseCookie(cookieHeader, "__remote_session");
21811
21949
  if (token) invalidateRemoteSession(token);
@@ -21818,7 +21956,7 @@ app34.get("/__remote-auth/logout", (c) => {
21818
21956
  }
21819
21957
  });
21820
21958
  });
21821
- app34.post("/__remote-auth/change-password", async (c) => {
21959
+ app35.post("/__remote-auth/change-password", async (c) => {
21822
21960
  const clientIp = c.var.clientIp || "unknown";
21823
21961
  const rateLimited = checkRateLimit(clientIp);
21824
21962
  if (rateLimited) {
@@ -21867,13 +22005,13 @@ app34.post("/__remote-auth/change-password", async (c) => {
21867
22005
  return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(), mode: "change", changeError: "Failed to save password", redirect }), 200);
21868
22006
  }
21869
22007
  });
21870
- app34.get("/__remote-auth/setup", (c) => {
22008
+ app35.get("/__remote-auth/setup", (c) => {
21871
22009
  if (isRemoteAuthConfigured()) {
21872
22010
  return c.redirect("/");
21873
22011
  }
21874
22012
  return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(), mode: "setup" }), 200);
21875
22013
  });
21876
- app34.post("/__remote-auth/set-initial-password", async (c) => {
22014
+ app35.post("/__remote-auth/set-initial-password", async (c) => {
21877
22015
  if (isRemoteAuthConfigured()) {
21878
22016
  return c.redirect("/");
21879
22017
  }
@@ -21909,10 +22047,10 @@ app34.post("/__remote-auth/set-initial-password", async (c) => {
21909
22047
  return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(), mode: "setup", setupError: "Failed to save password. Please try again." }), 200);
21910
22048
  }
21911
22049
  });
21912
- app34.get("/api/remote-auth/status", (c) => {
22050
+ app35.get("/api/remote-auth/status", (c) => {
21913
22051
  return c.json({ configured: isRemoteAuthConfigured() });
21914
22052
  });
21915
- app34.post("/api/remote-auth/set-password", async (c) => {
22053
+ app35.post("/api/remote-auth/set-password", async (c) => {
21916
22054
  let body;
21917
22055
  try {
21918
22056
  body = await c.req.json();
@@ -21942,9 +22080,9 @@ app34.post("/api/remote-auth/set-password", async (c) => {
21942
22080
  return c.json({ error: "Failed to save password" }, 500);
21943
22081
  }
21944
22082
  });
21945
- app34.route("/api/_client-error", client_error_default);
22083
+ app35.route("/api/_client-error", client_error_default);
21946
22084
  console.log("[client-error-route] mounted");
21947
- app34.use("*", async (c, next) => {
22085
+ app35.use("*", async (c, next) => {
21948
22086
  const host = (c.req.header("host") ?? "").split(":")[0];
21949
22087
  const path2 = c.req.path;
21950
22088
  if (path2 === "/favicon.ico" || path2.startsWith("/assets/") || path2.startsWith("/brand/")) {
@@ -21984,15 +22122,15 @@ function parseCookie(cookieHeader, name) {
21984
22122
  return null;
21985
22123
  }
21986
22124
  }
21987
- app34.route("/api/health", health_default);
21988
- app34.route("/api/session", session_default);
21989
- app34.route("/api/chat", chat_default);
21990
- app34.route("/api/group", group_default);
21991
- app34.route("/api/access", access_default);
21992
- app34.route("/api/telegram", telegram_default);
21993
- app34.route("/api/whatsapp", whatsapp_default);
21994
- app34.route("/api/onboarding", onboarding_default);
21995
- app34.route("/api/admin", admin_default);
22125
+ app35.route("/api/health", health_default);
22126
+ app35.route("/api/session", session_default);
22127
+ app35.route("/api/chat", chat_default);
22128
+ app35.route("/api/group", group_default);
22129
+ app35.route("/api/access", access_default);
22130
+ app35.route("/api/telegram", telegram_default);
22131
+ app35.route("/api/whatsapp", whatsapp_default);
22132
+ app35.route("/api/onboarding", onboarding_default);
22133
+ app35.route("/api/admin", admin_default);
21996
22134
  var SAFE_SLUG_RE = /^[a-z][a-z0-9-]{2,49}$/;
21997
22135
  var SAFE_FILENAME_RE = /^[a-z0-9_][a-z0-9_.-]{0,99}$/i;
21998
22136
  var IMAGE_MIME = {
@@ -22004,7 +22142,7 @@ var IMAGE_MIME = {
22004
22142
  ".svg": "image/svg+xml",
22005
22143
  ".ico": "image/x-icon"
22006
22144
  };
22007
- app34.get("/agent-assets/:slug/:filename", (c) => {
22145
+ app35.get("/agent-assets/:slug/:filename", (c) => {
22008
22146
  const slug = c.req.param("slug");
22009
22147
  const filename = c.req.param("filename");
22010
22148
  if (!SAFE_SLUG_RE.test(slug)) {
@@ -22039,7 +22177,7 @@ app34.get("/agent-assets/:slug/:filename", (c) => {
22039
22177
  "Cache-Control": "public, max-age=3600"
22040
22178
  });
22041
22179
  });
22042
- app34.get("/generated/:filename", (c) => {
22180
+ app35.get("/generated/:filename", (c) => {
22043
22181
  const filename = c.req.param("filename");
22044
22182
  if (!SAFE_FILENAME_RE.test(filename) || filename.includes("..")) {
22045
22183
  console.error(`[generated] serve file=${filename} status=403`);
@@ -22204,7 +22342,7 @@ function brandedPublicHtml(agentSlug) {
22204
22342
  function escapeHtml2(s) {
22205
22343
  return s.replace(/&/g, "&amp;").replace(/"/g, "&quot;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
22206
22344
  }
22207
- app34.get("/", (c) => {
22345
+ app35.get("/", (c) => {
22208
22346
  const host = (c.req.header("host") ?? "").split(":")[0];
22209
22347
  if (isPublicHost(host)) {
22210
22348
  const defaultSlug = resolveDefaultSlug();
@@ -22212,12 +22350,12 @@ app34.get("/", (c) => {
22212
22350
  }
22213
22351
  return c.html(cachedHtml("index.html"));
22214
22352
  });
22215
- app34.get("/public", (c) => {
22353
+ app35.get("/public", (c) => {
22216
22354
  const host = (c.req.header("host") ?? "").split(":")[0];
22217
22355
  if (isPublicHost(host)) return c.text("Not found", 404);
22218
22356
  return c.html(cachedHtml("public.html"));
22219
22357
  });
22220
- app34.get("/chat", (c) => {
22358
+ app35.get("/chat", (c) => {
22221
22359
  const host = (c.req.header("host") ?? "").split(":")[0];
22222
22360
  if (isPublicHost(host)) return c.text("Not found", 404);
22223
22361
  return c.html(cachedHtml("public.html"));
@@ -22236,9 +22374,9 @@ async function logViewerFetch(c, next) {
22236
22374
  duration_ms: Date.now() - start
22237
22375
  });
22238
22376
  }
22239
- app34.use("/vnc-viewer.html", logViewerFetch);
22240
- app34.use("/vnc-popout.html", logViewerFetch);
22241
- app34.get("/vnc-popout.html", (c) => {
22377
+ app35.use("/vnc-viewer.html", logViewerFetch);
22378
+ app35.use("/vnc-popout.html", logViewerFetch);
22379
+ app35.get("/vnc-popout.html", (c) => {
22242
22380
  let html = htmlCache.get("vnc-popout.html");
22243
22381
  if (!html) {
22244
22382
  html = readFileSync26(resolve30(process.cwd(), "public", "vnc-popout.html"), "utf-8");
@@ -22251,7 +22389,7 @@ app34.get("/vnc-popout.html", (c) => {
22251
22389
  }
22252
22390
  return c.html(html);
22253
22391
  });
22254
- app34.post("/api/vnc/client-event", async (c) => {
22392
+ app35.post("/api/vnc/client-event", async (c) => {
22255
22393
  let body;
22256
22394
  try {
22257
22395
  body = await c.req.json();
@@ -22272,20 +22410,20 @@ app34.post("/api/vnc/client-event", async (c) => {
22272
22410
  });
22273
22411
  return c.json({ ok: true });
22274
22412
  });
22275
- app34.get("/g/:slug", (c) => {
22413
+ app35.get("/g/:slug", (c) => {
22276
22414
  return c.html(brandedPublicHtml());
22277
22415
  });
22278
- app34.get("/graph", (c) => {
22416
+ app35.get("/graph", (c) => {
22279
22417
  const host = (c.req.header("host") ?? "").split(":")[0];
22280
22418
  if (isPublicHost(host)) return c.text("Not found", 404);
22281
22419
  return c.html(cachedHtml("graph.html"));
22282
22420
  });
22283
- app34.get("/data", (c) => {
22421
+ app35.get("/data", (c) => {
22284
22422
  const host = (c.req.header("host") ?? "").split(":")[0];
22285
22423
  if (isPublicHost(host)) return c.text("Not found", 404);
22286
22424
  return c.html(cachedHtml("data.html"));
22287
22425
  });
22288
- app34.get("/:slug", async (c, next) => {
22426
+ app35.get("/:slug", async (c, next) => {
22289
22427
  const slug = c.req.param("slug");
22290
22428
  if (AGENT_SLUG_PATTERN.test(`/${slug}`)) {
22291
22429
  const branding = loadBrandingCache(slug);
@@ -22294,10 +22432,10 @@ app34.get("/:slug", async (c, next) => {
22294
22432
  }
22295
22433
  await next();
22296
22434
  });
22297
- app34.use("/*", serveStatic({ root: "./public" }));
22435
+ app35.use("/*", serveStatic({ root: "./public" }));
22298
22436
  var port = parseInt(process.env.PORT ?? "19200", 10);
22299
22437
  var hostname = process.env.HOSTNAME ?? "0.0.0.0";
22300
- var httpServer = serve({ fetch: app34.fetch, port, hostname });
22438
+ var httpServer = serve({ fetch: app35.fetch, port, hostname });
22301
22439
  attachVncWsProxy(httpServer, {
22302
22440
  isPublicHost,
22303
22441
  upstreamHost: "127.0.0.1",
@@ -22343,7 +22481,7 @@ for (const m of SUBAPP_MANIFEST) {
22343
22481
  }
22344
22482
  try {
22345
22483
  const registered = [];
22346
- for (const r of app34.routes ?? []) {
22484
+ for (const r of app35.routes ?? []) {
22347
22485
  if (typeof r.path !== "string" || r.path.includes(":") || r.path.includes("*")) continue;
22348
22486
  if (AGENT_SLUG_PATTERN.test(r.path)) {
22349
22487
  registered.push({ method: (r.method ?? "ALL").toUpperCase(), path: r.path });