@rubytech/create-realagent 1.0.816 → 1.0.817

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.
@@ -6,7 +6,6 @@ import {
6
6
  TELEGRAM_ADMIN_WEBHOOK_SECRET_FILE,
7
7
  TELEGRAM_WEBHOOK_SECRET_FILE,
8
8
  USERS_FILE,
9
- actionLogPath,
10
9
  autoDeliverPremiumPlugins,
11
10
  buildX11Env,
12
11
  callOauthLlm,
@@ -30,7 +29,6 @@ import {
30
29
  launchAction,
31
30
  load,
32
31
  logPath,
33
- reconcileCloudflareSetupFromLog,
34
32
  recordFailedAttempt,
35
33
  render,
36
34
  renderLoginPage,
@@ -53,7 +51,7 @@ import {
53
51
  vncLog,
54
52
  waitForExit,
55
53
  writeChromiumWrapper
56
- } from "./chunk-Y3UQFQM7.js";
54
+ } from "./chunk-P3HTEK33.js";
57
55
  import {
58
56
  agentLogStream,
59
57
  clearSessionHistory,
@@ -620,8 +618,8 @@ var serveStatic = (options = { root: "" }) => {
620
618
  };
621
619
 
622
620
  // server/index.ts
623
- import { readFileSync as readFileSync19, existsSync as existsSync25, watchFile } from "fs";
624
- import { resolve as resolve25, join as join11, basename as basename7 } from "path";
621
+ import { readFileSync as readFileSync18, existsSync as existsSync24, watchFile } from "fs";
622
+ import { resolve as resolve25, join as join10, basename as basename7 } from "path";
625
623
  import { homedir as homedir2 } from "os";
626
624
 
627
625
  // app/lib/agent-slug-pattern.ts
@@ -807,52 +805,6 @@ function defaultRules() {
807
805
  scope: "session",
808
806
  suggestedAction: "The WebFetch SPA preflight has fired more than once in this conversation. Either the agent is ignoring the loud-failure directive (retrying WebFetch after seeing WEBFETCH_CANNOT_READ_JS_SPA), or multiple SPA URLs are being asked about. Read the conversation's stream log for the [tool-use] / [tool-result] sequence around each occurrence \u2014 if the agent dispatched WebFetch on the same URL or substituted Playwright silently, revisit the IDENTITY.md `Tool Failure Discipline` paragraph that names structured-error handling."
809
807
  },
810
- {
811
- // Task 867 — fires when setup-tunnel.sh emits step=done but no
812
- // `[persist] role=user … Cloudflare setup completed (actionId: <id>)`
813
- // line appears within 60s. Covers the three failure modes of the
814
- // action-relay-queue plumbing: queue-write failed, boot-drain consumer
815
- // skipped the record, or the agent's hoisted persist threw. The
816
- // followup pattern is intentionally narrow to the cloudflare-setup
817
- // relay shape (not a general "any user persist") so a benign user
818
- // typing in chat does not satisfy the followup. logSource=any so
819
- // the rule sees both the script tee (in stream logs / server.log)
820
- // and the [persist] line (server.log).
821
- id: "cloudflare-setup-relay-not-acknowledged",
822
- name: "Cloudflare-setup completed but the chat relay never acknowledged",
823
- type: "absent-followup",
824
- logSource: "any",
825
- pattern: "\\[script:setup-tunnel\\] step=done",
826
- followupPattern: "\\[persist\\] .*role=user.* Cloudflare setup completed \\(actionId:",
827
- followupWindowMs: 6e4,
828
- thresholdCount: 0,
829
- thresholdWindowMinutes: 0,
830
- suggestedAction: "[Task 867] cloudflare-setup completed but the post-action relay never reached the chat history. Check `[action-relay-queue] phase=enqueued` (queue write), `[action-completion-relay] phase=consumed` (boot-drain ran), and `[persist] role=user \u2026 Cloudflare setup completed` (graph write). One of those is missing; the matching grep recipe is in the Task 867 brief Observability section."
831
- },
832
- {
833
- // Task 879 §C — onboarding turn-completion contract: any assistant
834
- // turn that narrates a step transition with a non-question-terminated
835
- // phrase ("Moving to step 9 — operator persona...", "Step 8 done.")
836
- // must be followed within 30s by either a `render-component` call
837
- // (the next step's UI surfaces) or `onboarding-complete-step`
838
- // (deterministic step advance). The trigger pattern matches the
839
- // `[onboarding-step-narration]` line written by stream-parser at the
840
- // assistant text block emit site (only for non-question phrases).
841
- // Operator's symptom in Task 879's evidence: "Moving to step 9..."
842
- // followed by 4 minutes of silence until the operator nudged with
843
- // "yeah, so?" — exact failure shape this rule catches.
844
- id: "assistant-step-advance-deadend",
845
- name: "Onboarding step-advance narration without follow-up tool call",
846
- type: "absent-followup",
847
- logSource: "session",
848
- pattern: "\\[onboarding-step-narration\\]",
849
- followupPattern: "\\[render-component\\]|\\[tool-use\\][^\\n]*name=mcp__admin__onboarding-complete-step",
850
- followupWindowMs: 3e4,
851
- thresholdCount: 0,
852
- thresholdWindowMinutes: 0,
853
- scope: "session",
854
- suggestedAction: '[Task 879 \xA7C] An onboarding turn narrated a step transition (e.g. "Moving to step N", "Step N done.") but did not render a component or call `onboarding-complete-step` within 30s. The operator is left with a dead-end paragraph and no actionable surface. Check the `platform/plugins/admin/skills/onboarding/SKILL.md` Turn-completion contract section \u2014 the agent must end any step-advance turn with `render-component` or a `?`-terminated question, never bare prose.'
855
- },
856
808
  {
857
809
  // Task 538: fires when a [spawn] line appears in a conversation's stream
858
810
  // log but no subprocess-lifecycle marker follows within 10s. The three
@@ -8375,7 +8327,7 @@ app9.post("/", async (c) => {
8375
8327
  const safe = typeof v === "string" ? truncate(v, 200) : typeof v === "number" || typeof v === "boolean" ? String(v) : JSON.stringify(v).slice(0, 200);
8376
8328
  return `${k}=${safe}`;
8377
8329
  }).join(" ");
8378
- const TAGGED_PREFIX_SOURCES = /* @__PURE__ */ new Set(["admin-chat-relay-poll"]);
8330
+ const TAGGED_PREFIX_SOURCES = /* @__PURE__ */ new Set([]);
8379
8331
  if (TAGGED_PREFIX_SOURCES.has(source)) {
8380
8332
  console.log(
8381
8333
  `[${source}] ts=${ts} ip=${ip} version=${version || "unknown"}${extra ? " " + extra : ""}`
@@ -8597,39 +8549,6 @@ app10.post("/", async (c) => {
8597
8549
  const payload = await createAdminSession(selected.accountId, selected.config.thinkingView, userId, userName, selected.role, avatar);
8598
8550
  return c.json(payload);
8599
8551
  });
8600
- app10.post("/rebind", async (c) => {
8601
- let body;
8602
- try {
8603
- body = await c.req.json();
8604
- } catch {
8605
- return c.json({ ok: false, error: "invalid_json" }, 400);
8606
- }
8607
- const sessionKey = typeof body.session_key === "string" ? body.session_key : "";
8608
- const conversationId = typeof body.lastKnownConversationId === "string" ? body.lastKnownConversationId : "";
8609
- if (!sessionKey || !conversationId) {
8610
- return c.json({ ok: false, error: "session_key and lastKnownConversationId required" }, 400);
8611
- }
8612
- const sk8 = sessionKey.slice(0, 8);
8613
- const cid8 = conversationId.slice(0, 8);
8614
- const bridge = await tryCookieBridgeForConversation(c, sessionKey, conversationId);
8615
- if (!bridge.ok) {
8616
- console.log(`[admin/session/rebind] sessionKey=${sk8}\u2026 result=bridge-rejected reason=${bridge.reason} conversationId=${cid8}\u2026`);
8617
- const status = bridge.reason === "conversation-not-found" ? 404 : bridge.reason === "account-mismatch" ? 403 : 401;
8618
- return c.json({ ok: false, error: bridge.reason }, status);
8619
- }
8620
- const existing = getConversationIdForSession(sessionKey);
8621
- if (existing && existing !== conversationId) {
8622
- console.log(`[admin/session/rebind] sessionKey=${sk8}\u2026 result=conflict conversationId=${existing.slice(0, 8)}\u2026 requested=${cid8}\u2026`);
8623
- return c.json({ ok: false, error: "conflict", conversationId: existing }, 409);
8624
- }
8625
- const bound = setConversationIdForSession(sessionKey, conversationId);
8626
- if (!bound) {
8627
- console.error(`[admin/session/rebind] sessionKey=${sk8}\u2026 result=bind-failed conversationId=${cid8}\u2026 (post-bridge session-store missing \u2014 programmer error)`);
8628
- return c.json({ ok: false, error: "bind_failed" }, 500);
8629
- }
8630
- console.log(`[admin/session/rebind] sessionKey=${sk8}\u2026 result=ok conversationId=${cid8}\u2026`);
8631
- return c.json({ ok: true, conversationId });
8632
- });
8633
8552
  var session_default2 = app10;
8634
8553
 
8635
8554
  // server/routes/admin/chat.ts
@@ -9860,13 +9779,14 @@ app17.delete("/:id", requireAdminSession, async (c) => {
9860
9779
  return c.json({ error: "Failed to delete session" }, 500);
9861
9780
  }
9862
9781
  });
9863
- app17.get("/:id/messages", async (c) => {
9782
+ app17.post("/:id/resume", async (c) => {
9864
9783
  const conversationId = c.req.param("id");
9865
9784
  const sessionKey = c.req.query("session_key") ?? "";
9866
9785
  if (!sessionKey) {
9867
9786
  console.error(`[session] middleware-reject status=400 code=session-missing reason="session_key required" path=${c.req.path}`);
9868
9787
  return c.json({ error: "session_key required", code: "session-missing" }, 400);
9869
9788
  }
9789
+ let bridged = false;
9870
9790
  let result = validateSession(sessionKey, "admin");
9871
9791
  if (!result.ok) {
9872
9792
  if (result.reason === "session-not-registered") {
@@ -9879,6 +9799,7 @@ app17.get("/:id/messages", async (c) => {
9879
9799
  console.error(`[session] middleware-reject status=401 code=session-not-registered reason="cookie-bridge-rejected:${bridge.reason}" path=${c.req.path} sessionKey=${tail}\u2026`);
9880
9800
  return c.json({ error: "Invalid or expired admin session", code: "session-not-registered" }, 401);
9881
9801
  }
9802
+ bridged = true;
9882
9803
  result = validateSession(sessionKey, "admin");
9883
9804
  if (!result.ok) {
9884
9805
  const tail = sessionKey.slice(0, 8);
@@ -9893,34 +9814,12 @@ app17.get("/:id/messages", async (c) => {
9893
9814
  }
9894
9815
  }
9895
9816
  const accountId = getAccountIdForSession(sessionKey);
9896
- if (!accountId) return c.json({ error: "Account not found for session" }, 401);
9897
- const owned = await verifyConversationOwnership(conversationId, accountId);
9898
- if (!owned) return c.json({ error: "Conversation not found" }, 404);
9899
- try {
9900
- const messages = await getRecentMessages(conversationId, 50);
9901
- const sanitised = messages.map((m) => ({
9902
- ...m,
9903
- attachments: m.attachments.map((a) => ({
9904
- attachmentId: a.attachmentId,
9905
- filename: a.filename,
9906
- mimeType: a.mimeType,
9907
- sizeBytes: a.sizeBytes,
9908
- ordinal: a.ordinal
9909
- }))
9910
- }));
9911
- return c.json({ messages: sanitised });
9912
- } catch (err) {
9913
- console.error(`[sessions-messages] Failed: ${err instanceof Error ? err.message : String(err)}`);
9914
- return c.json({ error: "Failed to fetch messages" }, 500);
9915
- }
9916
- });
9917
- app17.post("/:id/resume", requireAdminSession, async (c) => {
9918
- const conversationId = c.req.param("id");
9919
- const sessionKey = c.var.sessionKey;
9920
- const accountId = getAccountIdForSession(sessionKey);
9921
9817
  const userId = getUserIdForSession(sessionKey);
9922
- if (!accountId || !userId) {
9923
- return c.json({ error: "Session missing account or user context" }, 400);
9818
+ if (!accountId) {
9819
+ return c.json({ error: "Session missing account context" }, 400);
9820
+ }
9821
+ if (!userId && !bridged) {
9822
+ return c.json({ error: "Session missing user context" }, 400);
9924
9823
  }
9925
9824
  const updatedAt = await verifyAndGetConversationUpdatedAt(conversationId, accountId);
9926
9825
  if (updatedAt === null) return c.json({ error: "Conversation not found" }, 404);
@@ -9975,8 +9874,9 @@ app17.post("/:id/resume", requireAdminSession, async (c) => {
9975
9874
  });
9976
9875
  const textRuns = rehydrated.reduce((n, m) => n + (m.events?.filter((e) => e.type === "text").length ?? 0), 0);
9977
9876
  const userMessageCount = rehydrated.filter((m) => m.role !== "assistant").length;
9877
+ const reason = bridged ? "post-restart" : "page-refresh";
9978
9878
  try {
9979
- appendFileSync5(streamLogPath, `[${(/* @__PURE__ */ new Date()).toISOString()}] [admin-resume] sessionKey=${sessionKey.slice(0, 8)} conversationId=${conversationId.slice(0, 8)} ${tag} loadedMessages=${messages.length} componentCount=${totalComponents} userAttachmentCount=${totalAttachments}
9879
+ appendFileSync5(streamLogPath, `[${(/* @__PURE__ */ new Date()).toISOString()}] [admin-resume] reason=${reason} sessionKey=${sessionKey.slice(0, 8)} conversationId=${conversationId.slice(0, 8)} ${tag} loadedMessages=${messages.length} componentCount=${totalComponents} userAttachmentCount=${totalAttachments}
9980
9880
  `);
9981
9881
  if (totalComponents > 0) {
9982
9882
  appendFileSync5(streamLogPath, `[${(/* @__PURE__ */ new Date()).toISOString()}] [component-rehydrate] conversationId=${conversationId.slice(0, 8)} count=${totalComponents} valid=${totalValid} invalid=${totalInvalid} textRuns=${textRuns}
@@ -9989,7 +9889,7 @@ app17.post("/:id/resume", requireAdminSession, async (c) => {
9989
9889
  } catch {
9990
9890
  }
9991
9891
  const age = formatAge(updatedAt);
9992
- console.log(`[admin-resume] ${(/* @__PURE__ */ new Date()).toISOString()} conversationId=${conversationId.slice(0, 8)}\u2026 age=${age} loaded=${messages.length} messages ${tag} components=${totalComponents} attachments=${totalAttachments} sessionKey=${sessionKey.slice(0, 8)}\u2026`);
9892
+ console.log(`[admin-resume] ${(/* @__PURE__ */ new Date()).toISOString()} reason=${reason} conversationId=${conversationId.slice(0, 8)}\u2026 age=${age} loaded=${messages.length} messages ${tag} components=${totalComponents} attachments=${totalAttachments} sessionKey=${sessionKey.slice(0, 8)}\u2026`);
9993
9893
  return c.json({ conversationId, messages: rehydrated });
9994
9894
  });
9995
9895
  app17.post("/:id/label", requireAdminSession, async (c) => {
@@ -10116,13 +10016,13 @@ async function cdpNavigateNewTab(url, opts = {}) {
10116
10016
  // server/routes/admin/device-browser.ts
10117
10017
  var app19 = new Hono();
10118
10018
  app19.post("/navigate", async (c) => {
10119
- const TAG20 = "[device-url:click]";
10019
+ const TAG19 = "[device-url:click]";
10120
10020
  let body;
10121
10021
  try {
10122
10022
  body = await c.req.json();
10123
10023
  } catch (err) {
10124
10024
  const detail = err instanceof Error ? err.message : String(err);
10125
- console.error(`${TAG20} reject reason=body-not-json detail=${detail} browser=fallback navigateResult=error`);
10025
+ console.error(`${TAG19} reject reason=body-not-json detail=${detail} browser=fallback navigateResult=error`);
10126
10026
  return c.json(
10127
10027
  { ok: false, navigateResult: "error", browser: "fallback", detail: "Request body was not valid JSON" },
10128
10028
  400
@@ -10132,7 +10032,7 @@ app19.post("/navigate", async (c) => {
10132
10032
  const intent = typeof body.intent === "string" ? body.intent : "";
10133
10033
  const hostname2 = typeof body.hostname === "string" ? body.hostname : "";
10134
10034
  if (!url) {
10135
- console.error(`${TAG20} reject reason=missing-url intent=${JSON.stringify(intent)} browser=fallback navigateResult=error`);
10035
+ console.error(`${TAG19} reject reason=missing-url intent=${JSON.stringify(intent)} browser=fallback navigateResult=error`);
10136
10036
  return c.json(
10137
10037
  { ok: false, navigateResult: "error", browser: "fallback", detail: "url field is required" },
10138
10038
  400
@@ -10142,7 +10042,7 @@ app19.post("/navigate", async (c) => {
10142
10042
  try {
10143
10043
  parsed = new URL(url);
10144
10044
  } catch {
10145
- console.error(`${TAG20} reject reason=url-malformed intent=${JSON.stringify(intent)} url=${url} browser=fallback navigateResult=error`);
10045
+ console.error(`${TAG19} reject reason=url-malformed intent=${JSON.stringify(intent)} url=${url} browser=fallback navigateResult=error`);
10146
10046
  return c.json(
10147
10047
  { ok: false, navigateResult: "error", browser: "fallback", detail: "url is not a valid URL" },
10148
10048
  400
@@ -10150,7 +10050,7 @@ app19.post("/navigate", async (c) => {
10150
10050
  }
10151
10051
  if (parsed.protocol !== "http:" && parsed.protocol !== "https:") {
10152
10052
  console.error(
10153
- `${TAG20} reject reason=scheme-not-allowed scheme=${parsed.protocol} intent=${JSON.stringify(intent)} browser=fallback navigateResult=error`
10053
+ `${TAG19} reject reason=scheme-not-allowed scheme=${parsed.protocol} intent=${JSON.stringify(intent)} browser=fallback navigateResult=error`
10154
10054
  );
10155
10055
  return c.json(
10156
10056
  {
@@ -10166,7 +10066,7 @@ app19.post("/navigate", async (c) => {
10166
10066
  const cdpOk = await ensureCdp(transport);
10167
10067
  if (!cdpOk) {
10168
10068
  console.error(
10169
- `${TAG20} intent=${JSON.stringify(intent)} browser=fallback navigateResult=cdp-unreachable hostname=${JSON.stringify(hostname2)}`
10069
+ `${TAG19} intent=${JSON.stringify(intent)} browser=fallback navigateResult=cdp-unreachable hostname=${JSON.stringify(hostname2)}`
10170
10070
  );
10171
10071
  return c.json(
10172
10072
  {
@@ -10182,7 +10082,7 @@ app19.post("/navigate", async (c) => {
10182
10082
  const browser = outcome.result === "ok" ? "vnc" : "fallback";
10183
10083
  const detailStr = outcome.detail ? ` detail=${JSON.stringify(outcome.detail.length > 230 ? outcome.detail.slice(0, 227) + "..." : outcome.detail)}` : "";
10184
10084
  console.error(
10185
- `${TAG20} intent=${JSON.stringify(intent)} browser=${browser} navigateResult=${outcome.result} hostname=${JSON.stringify(hostname2)} targetId=${outcome.targetId ?? "none"}${detailStr}`
10085
+ `${TAG19} intent=${JSON.stringify(intent)} browser=${browser} navigateResult=${outcome.result} hostname=${JSON.stringify(hostname2)} targetId=${outcome.targetId ?? "none"}${detailStr}`
10186
10086
  );
10187
10087
  if (outcome.result !== "ok") {
10188
10088
  return c.json(
@@ -10213,18 +10113,18 @@ var ALLOWED_EVENTS = /* @__PURE__ */ new Set([
10213
10113
  ]);
10214
10114
  var app20 = new Hono();
10215
10115
  app20.post("/", async (c) => {
10216
- const TAG20 = "[admin:events]";
10116
+ const TAG19 = "[admin:events]";
10217
10117
  let body;
10218
10118
  try {
10219
10119
  body = await c.req.json();
10220
10120
  } catch (err) {
10221
10121
  const detail = err instanceof Error ? err.message : String(err);
10222
- console.error(`${TAG20} reject reason=body-not-json detail=${detail}`);
10122
+ console.error(`${TAG19} reject reason=body-not-json detail=${detail}`);
10223
10123
  return c.json({ ok: false, detail: "Request body was not valid JSON" }, 400);
10224
10124
  }
10225
10125
  const event = typeof body.event === "string" ? body.event : "";
10226
10126
  if (!ALLOWED_EVENTS.has(event)) {
10227
- console.error(`${TAG20} reject reason=event-not-allowed event=${JSON.stringify(event)}`);
10127
+ console.error(`${TAG19} reject reason=event-not-allowed event=${JSON.stringify(event)}`);
10228
10128
  return c.json({ ok: false, detail: `Event "${event}" is not allowed` }, 400);
10229
10129
  }
10230
10130
  const rawFields = body.fields && typeof body.fields === "object" ? body.fields : {};
@@ -10248,7 +10148,7 @@ var events_default = app20;
10248
10148
  // server/routes/admin/cloudflare.ts
10249
10149
  import { homedir } from "os";
10250
10150
  import { resolve as resolve18 } from "path";
10251
- import { readFileSync as readFileSync17 } from "fs";
10151
+ import { readFileSync as readFileSync16 } from "fs";
10252
10152
 
10253
10153
  // app/lib/dns-label.ts
10254
10154
  var VALID_LABEL = /^[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?$/;
@@ -10286,131 +10186,14 @@ function addAliasDomain(hostname2) {
10286
10186
  writeFileSync9(ALIAS_DOMAINS_PATH, JSON.stringify([...existing], null, 2) + "\n", "utf-8");
10287
10187
  }
10288
10188
 
10289
- // app/lib/action-relay-queue.ts
10290
- import {
10291
- existsSync as existsSync20,
10292
- mkdirSync as mkdirSync9,
10293
- readdirSync as readdirSync6,
10294
- readFileSync as readFileSync16,
10295
- unlinkSync as unlinkSync2,
10296
- writeFileSync as writeFileSync10
10297
- } from "fs";
10298
- import { join as join9 } from "path";
10299
- var TAG19 = "[action-relay-queue]";
10300
- var FILE_PREFIX = "action-completion-relay-";
10301
- var FILE_SUFFIX = ".json";
10302
- function queueDir(accountDir) {
10303
- return join9(accountDir, "queue");
10304
- }
10305
- function relayFilePath(accountDir, actionId) {
10306
- return join9(queueDir(accountDir), `${FILE_PREFIX}${actionId}${FILE_SUFFIX}`);
10307
- }
10308
- function enqueueActionCompletionRelay(opts) {
10309
- const dir = queueDir(opts.accountDir);
10310
- mkdirSync9(dir, { recursive: true });
10311
- const filePath = relayFilePath(opts.accountDir, opts.actionId);
10312
- const record = {
10313
- actionId: opts.actionId,
10314
- conversationId: opts.conversationId,
10315
- message: opts.message,
10316
- queuedAt: (/* @__PURE__ */ new Date()).toISOString()
10317
- };
10318
- const body = JSON.stringify(record);
10319
- try {
10320
- writeFileSync10(filePath, body, { flag: "wx", encoding: "utf-8" });
10321
- console.log(
10322
- `${TAG19} phase=enqueued actionId=${opts.actionId} conversationId=${opts.conversationId} path=${filePath} bytes=${Buffer.byteLength(body, "utf-8")}`
10323
- );
10324
- return { enqueued: true, path: filePath };
10325
- } catch (e) {
10326
- if (e.code === "EEXIST") {
10327
- console.log(
10328
- `${TAG19} phase=enqueue-skipped actionId=${opts.actionId} reason=already-queued`
10329
- );
10330
- return { enqueued: false, reason: "already-queued", path: filePath };
10331
- }
10332
- throw e;
10333
- }
10334
- }
10335
- function consumeActionCompletionRelays(accountDir) {
10336
- const dir = queueDir(accountDir);
10337
- if (!existsSync20(dir)) return [];
10338
- let entries;
10339
- try {
10340
- entries = readdirSync6(dir);
10341
- } catch (e) {
10342
- console.error(
10343
- `${TAG19} phase=readdir-failed dir=${dir} error=${e instanceof Error ? e.message : String(e)}`
10344
- );
10345
- return [];
10346
- }
10347
- const records = [];
10348
- for (const name of entries) {
10349
- if (!name.startsWith(FILE_PREFIX) || !name.endsWith(FILE_SUFFIX)) continue;
10350
- const filePath = join9(dir, name);
10351
- let raw;
10352
- try {
10353
- raw = readFileSync16(filePath, "utf-8");
10354
- } catch (e) {
10355
- console.error(
10356
- `${TAG19} phase=read-failed file=${name} error=${e instanceof Error ? e.message : String(e)}`
10357
- );
10358
- continue;
10359
- }
10360
- let parsed;
10361
- try {
10362
- parsed = JSON.parse(raw);
10363
- } catch (e) {
10364
- console.error(
10365
- `${TAG19} phase=parse-failed file=${name} error=${e instanceof Error ? e.message : String(e)}`
10366
- );
10367
- continue;
10368
- }
10369
- if (!isActionCompletionRelay(parsed)) {
10370
- console.error(
10371
- `${TAG19} phase=shape-invalid file=${name} keys=${parsed && typeof parsed === "object" ? Object.keys(parsed).join(",") : "non-object"}`
10372
- );
10373
- continue;
10374
- }
10375
- records.push({ rec: parsed, filePath });
10376
- }
10377
- records.sort((a, b) => a.rec.queuedAt.localeCompare(b.rec.queuedAt));
10378
- const out = [];
10379
- const now = Date.now();
10380
- for (const { rec, filePath } of records) {
10381
- const queuedAtMs = Date.parse(rec.queuedAt);
10382
- const ageMs = Number.isFinite(queuedAtMs) ? now - queuedAtMs : 0;
10383
- out.push({ ...rec, ageMs, filePath });
10384
- }
10385
- return out;
10386
- }
10387
- function deleteConsumedRelay(filePath) {
10388
- try {
10389
- unlinkSync2(filePath);
10390
- } catch (e) {
10391
- const code = e.code;
10392
- if (code !== "ENOENT") {
10393
- console.error(
10394
- `${TAG19} phase=unlink-failed file=${filePath} error=${e instanceof Error ? e.message : String(e)}`
10395
- );
10396
- }
10397
- }
10398
- }
10399
- function isActionCompletionRelay(value) {
10400
- if (!value || typeof value !== "object") return false;
10401
- const v = value;
10402
- return typeof v.actionId === "string" && typeof v.conversationId === "string" && typeof v.message === "string" && typeof v.queuedAt === "string";
10403
- }
10404
-
10405
10189
  // server/routes/admin/cloudflare.ts
10406
- import { existsSync as existsSyncFs, readFileSync as readFileSyncFs } from "fs";
10407
10190
  var SETUP_TIMEOUT_MS = 10 * 60 * 1e3;
10408
10191
  var DOMAINS_TIMEOUT_MS = 40 * 1e3;
10409
10192
  function loadBrandInfo() {
10410
10193
  const platformRoot2 = process.env.MAXY_PLATFORM_ROOT ?? resolve18(process.cwd(), "..");
10411
10194
  const brandPath = resolve18(platformRoot2, "config", "brand.json");
10412
10195
  try {
10413
- const parsed = JSON.parse(readFileSync17(brandPath, "utf-8"));
10196
+ const parsed = JSON.parse(readFileSync16(brandPath, "utf-8"));
10414
10197
  const hostname2 = typeof parsed.hostname === "string" && parsed.hostname ? parsed.hostname : "maxy";
10415
10198
  const configDir2 = typeof parsed.configDir === "string" && parsed.configDir ? parsed.configDir : ".maxy";
10416
10199
  return { hostname: hostname2, configDir: configDir2 };
@@ -10706,79 +10489,13 @@ actionId: ${actionId}`,
10706
10489
  };
10707
10490
  return ok(success);
10708
10491
  });
10709
- var RELAY_MAX_BODY = 8 * 1024;
10710
- var RELAY_MAX_MESSAGE = 2048;
10711
- var ACTION_ID_RE = /^[a-z0-9-]+$/;
10712
- app21.post("/relay-completion", requireAdminSession, async (c) => {
10713
- const sessionKey = c.var.sessionKey;
10714
- let raw;
10715
- try {
10716
- raw = await c.req.text();
10717
- } catch {
10718
- return c.json({ ok: false, reason: "invalid-body" }, 400);
10719
- }
10720
- if (Buffer.byteLength(raw, "utf-8") > RELAY_MAX_BODY) {
10721
- return c.json({ ok: false, reason: "body-too-large" }, 413);
10722
- }
10723
- let body;
10724
- try {
10725
- body = JSON.parse(raw);
10726
- } catch {
10727
- return c.json({ ok: false, reason: "invalid-json" }, 400);
10728
- }
10729
- if (!body || typeof body !== "object") {
10730
- return c.json({ ok: false, reason: "invalid-body" }, 400);
10731
- }
10732
- const { actionId, message } = body;
10733
- if (typeof actionId !== "string" || !ACTION_ID_RE.test(actionId) || actionId.length > 200) {
10734
- console.error(`[cloudflare-relay-completion] phase=enqueue-skipped reason=invalid-actionid sessionKey=${sessionKey.slice(-8)}`);
10735
- return c.json({ ok: false, reason: "invalid-actionid" }, 400);
10736
- }
10737
- if (typeof message !== "string" || message.length === 0 || message.length > RELAY_MAX_MESSAGE) {
10738
- return c.json({ ok: false, reason: "invalid-message" }, 400);
10739
- }
10740
- const conversationId = getConversationIdForSession(sessionKey);
10741
- if (!conversationId) {
10742
- console.error(`[cloudflare-relay-completion] phase=enqueue-skipped reason=missing-conversation-id sessionKey=${sessionKey.slice(-8)}`);
10743
- return c.json({ ok: false, reason: "missing-conversation-id" }, 400);
10744
- }
10745
- const account = resolveAccount();
10746
- if (!account) {
10747
- console.error(`[cloudflare-relay-completion] phase=enqueue-skipped reason=missing-account-dir actionId=${actionId}`);
10748
- return c.json({ ok: false, reason: "missing-account-dir" }, 500);
10749
- }
10750
- const logPath2 = actionLogPath(actionId);
10751
- let auditOutcome = "log-absent";
10752
- if (existsSyncFs(logPath2)) {
10753
- try {
10754
- const lines = readFileSyncFs(logPath2, "utf-8").split("\n");
10755
- const reconciled = reconcileCloudflareSetupFromLog(lines);
10756
- auditOutcome = reconciled ? reconciled.kind : "log-incomplete";
10757
- } catch (e) {
10758
- auditOutcome = `read-failed:${e instanceof Error ? e.message : String(e)}`;
10759
- }
10760
- }
10761
- console.log(`[cloudflare-relay-completion] phase=enqueue-attempt actionId=${actionId} auditOutcome=${auditOutcome} conversationId=${conversationId}`);
10762
- try {
10763
- enqueueActionCompletionRelay({
10764
- accountDir: account.accountDir,
10765
- actionId,
10766
- conversationId,
10767
- message
10768
- });
10769
- } catch (e) {
10770
- console.error(`[cloudflare-relay-completion] phase=enqueue-failed actionId=${actionId} error=${e instanceof Error ? e.message : String(e)}`);
10771
- return c.json({ ok: false, reason: "enqueue-failed" }, 500);
10772
- }
10773
- return c.body(null, 204);
10774
- });
10775
10492
  var cloudflare_default = app21;
10776
10493
 
10777
10494
  // server/routes/admin/files.ts
10778
10495
  import { createReadStream as createReadStream3 } from "fs";
10779
10496
  import { readdir as readdir2, readFile as readFile4, stat as stat4, mkdir as mkdir3, writeFile as writeFile4, unlink as unlink2 } from "fs/promises";
10780
10497
  import { realpathSync as realpathSync4 } from "fs";
10781
- import { basename as basename6, dirname as dirname8, join as join10, resolve as resolve20, sep as sep2 } from "path";
10498
+ import { basename as basename6, dirname as dirname8, join as join9, resolve as resolve20, sep as sep2 } from "path";
10782
10499
  import { Readable as Readable2 } from "stream";
10783
10500
 
10784
10501
  // app/lib/data-path.ts
@@ -11136,7 +10853,7 @@ async function cascadeDeleteDocument(params) {
11136
10853
  var UUID_RE4 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
11137
10854
  async function readMeta(absDir, baseName) {
11138
10855
  try {
11139
- const raw = await readFile4(join10(absDir, `${baseName}.meta.json`), "utf8");
10856
+ const raw = await readFile4(join9(absDir, `${baseName}.meta.json`), "utf8");
11140
10857
  const parsed = JSON.parse(raw);
11141
10858
  if (typeof parsed?.filename === "string") {
11142
10859
  return { filename: parsed.filename, mimeType: typeof parsed.mimeType === "string" ? parsed.mimeType : void 0 };
@@ -11174,7 +10891,7 @@ async function readAccountNames() {
11174
10891
  }
11175
10892
  async function enrich(absolute, entry, accountNames) {
11176
10893
  if (entry.kind === "directory" && UUID_RE4.test(entry.name)) {
11177
- const meta = await readMeta(join10(absolute, entry.name), entry.name);
10894
+ const meta = await readMeta(join9(absolute, entry.name), entry.name);
11178
10895
  if (meta?.filename) {
11179
10896
  entry.displayName = meta.filename;
11180
10897
  entry.mimeType = meta.mimeType;
@@ -11233,7 +10950,7 @@ app22.get("/", requireAdminSession, async (c) => {
11233
10950
  continue;
11234
10951
  }
11235
10952
  try {
11236
- const entryPath = join10(absolute, name);
10953
+ const entryPath = join9(absolute, name);
11237
10954
  const s = await stat4(entryPath);
11238
10955
  entries.push({
11239
10956
  name,
@@ -11406,7 +11123,7 @@ app22.delete("/", requireAdminSession, async (c) => {
11406
11123
  }
11407
11124
  const dot = base.lastIndexOf(".");
11408
11125
  const stem = dot === -1 ? base : base.slice(0, dot);
11409
- const sidecarPath = UUID_RE4.test(stem) && base !== `${stem}.meta.json` ? join10(dirname8(absolute), `${stem}.meta.json`) : null;
11126
+ const sidecarPath = UUID_RE4.test(stem) && base !== `${stem}.meta.json` ? join9(dirname8(absolute), `${stem}.meta.json`) : null;
11410
11127
  await unlink2(absolute);
11411
11128
  if (sidecarPath) {
11412
11129
  try {
@@ -12887,7 +12604,7 @@ var adherence_default = app30;
12887
12604
  import neo4j3 from "neo4j-driver";
12888
12605
  import { readFile as readFile5, readdir as readdir3, stat as stat5 } from "fs/promises";
12889
12606
  import { resolve as resolve21, relative as relative2, isAbsolute } from "path";
12890
- import { existsSync as existsSync21 } from "fs";
12607
+ import { existsSync as existsSync20 } from "fs";
12891
12608
  var LIMIT = 50;
12892
12609
  var TEXT_MIME_PREFIXES = ["text/", "application/json", "application/markdown"];
12893
12610
  var ADMIN_AGENT_FILES = ["IDENTITY.md", "SOUL.md", "KNOWLEDGE.md"];
@@ -13035,7 +12752,7 @@ async function fetchAgentTemplateRows(accountDir) {
13035
12752
  async function unionSpecialistFilenames(overrideDir, bundledDir) {
13036
12753
  const names = /* @__PURE__ */ new Set();
13037
12754
  for (const dir of [overrideDir, bundledDir]) {
13038
- if (!existsSync21(dir)) continue;
12755
+ if (!existsSync20(dir)) continue;
13039
12756
  try {
13040
12757
  const entries = await readdir3(dir);
13041
12758
  for (const entry of entries) {
@@ -13050,7 +12767,7 @@ async function unionSpecialistFilenames(overrideDir, bundledDir) {
13050
12767
  }
13051
12768
  async function readAgentTemplateRow(inp) {
13052
12769
  let chosenPath = null;
13053
- if (existsSync21(inp.overridePath)) {
12770
+ if (existsSync20(inp.overridePath)) {
13054
12771
  try {
13055
12772
  validateFilePathInAccount(inp.overridePath, inp.overrideRoot);
13056
12773
  chosenPath = inp.overridePath;
@@ -13061,7 +12778,7 @@ async function readAgentTemplateRow(inp) {
13061
12778
  );
13062
12779
  return null;
13063
12780
  }
13064
- } else if (existsSync21(inp.bundledPath)) {
12781
+ } else if (existsSync20(inp.bundledPath)) {
13065
12782
  if (!isWithin(inp.bundledPath, inp.bundledRoot)) {
13066
12783
  console.error(
13067
12784
  `[admin/sidebar-artefacts] agent-template-read-failed agent=${inp.displayName} kind=${inp.logName} error="bundled path outside PLATFORM_ROOT"`
@@ -13103,7 +12820,7 @@ var sidebar_artefacts_default = app31;
13103
12820
  // server/routes/admin/sidebar-artefact-save.ts
13104
12821
  import { mkdir as mkdir4, readdir as readdir4, stat as stat6, writeFile as writeFile5 } from "fs/promises";
13105
12822
  import { resolve as resolve22 } from "path";
13106
- import { existsSync as existsSync22 } from "fs";
12823
+ import { existsSync as existsSync21 } from "fs";
13107
12824
  var ADMIN_AGENT_FILES2 = /* @__PURE__ */ new Set(["IDENTITY.md", "SOUL.md", "KNOWLEDGE.md"]);
13108
12825
  var UUID_RE5 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/;
13109
12826
  var app32 = new Hono();
@@ -13167,7 +12884,7 @@ async function resolveSavePath(id, accountId, accountDir) {
13167
12884
  }
13168
12885
  if (UUID_RE5.test(id)) {
13169
12886
  const dir = resolve22(ATTACHMENTS_ROOT, accountId, id);
13170
- if (!existsSync22(dir)) {
12887
+ if (!existsSync21(dir)) {
13171
12888
  return { kind: "reject", status: 400, reason: "not-found" };
13172
12889
  }
13173
12890
  try {
@@ -13191,7 +12908,7 @@ var sidebar_artefact_save_default = app32;
13191
12908
 
13192
12909
  // server/routes/admin/sidebar-artefact-content.ts
13193
12910
  import { readFile as readFile6, readdir as readdir5 } from "fs/promises";
13194
- import { existsSync as existsSync23 } from "fs";
12911
+ import { existsSync as existsSync22 } from "fs";
13195
12912
  import { resolve as resolve23 } from "path";
13196
12913
  var UUID_RE6 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/;
13197
12914
  var app33 = new Hono();
@@ -13205,7 +12922,7 @@ app33.get("/", requireAdminSession, async (c) => {
13205
12922
  return new Response("Not found", { status: 404 });
13206
12923
  }
13207
12924
  const dir = resolve23(ATTACHMENTS_ROOT, accountId, id);
13208
- if (!existsSync23(dir)) {
12925
+ if (!existsSync22(dir)) {
13209
12926
  console.error(`[admin/sidebar-artefact-content] not-found id=${id.slice(0, 8)}`);
13210
12927
  return new Response("Not found", { status: 404 });
13211
12928
  }
@@ -13267,7 +12984,7 @@ app34.route("/sidebar-artefact-content", sidebar_artefact_content_default);
13267
12984
  var admin_default = app34;
13268
12985
 
13269
12986
  // server/routes/sites.ts
13270
- import { existsSync as existsSync24, readFileSync as readFileSync18, realpathSync as realpathSync5, statSync as statSync8 } from "fs";
12987
+ import { existsSync as existsSync23, readFileSync as readFileSync17, realpathSync as realpathSync5, statSync as statSync8 } from "fs";
13271
12988
  import { resolve as resolve24 } from "path";
13272
12989
  var SAFE_SEG_RE = /^[a-z0-9_][a-z0-9_.-]{0,99}$/i;
13273
12990
  var MIME = {
@@ -13334,7 +13051,7 @@ app35.get("/:rel{.*}", (c) => {
13334
13051
  }
13335
13052
  let stat7;
13336
13053
  try {
13337
- stat7 = existsSync24(filePath) ? statSync8(filePath) : null;
13054
+ stat7 = existsSync23(filePath) ? statSync8(filePath) : null;
13338
13055
  } catch {
13339
13056
  stat7 = null;
13340
13057
  }
@@ -13347,7 +13064,7 @@ app35.get("/:rel{.*}", (c) => {
13347
13064
  console.error(`[sites] path-traversal-rejected path=${reqPath} reason=escape status=403`);
13348
13065
  return c.text("Forbidden", 403);
13349
13066
  }
13350
- if (!existsSync24(filePath)) {
13067
+ if (!existsSync23(filePath)) {
13351
13068
  console.error(`[sites] not-found path=${reqPath} status=404`);
13352
13069
  return c.text("Not found", 404);
13353
13070
  }
@@ -13366,7 +13083,7 @@ app35.get("/:rel{.*}", (c) => {
13366
13083
  }
13367
13084
  let body;
13368
13085
  try {
13369
- body = readFileSync18(realPath);
13086
+ body = readFileSync17(realPath);
13370
13087
  } catch (err) {
13371
13088
  const code = err?.code;
13372
13089
  if (code === "EISDIR") {
@@ -13498,14 +13215,14 @@ function clientFrom(c) {
13498
13215
  );
13499
13216
  }
13500
13217
  var PLATFORM_ROOT7 = process.env.MAXY_PLATFORM_ROOT || "";
13501
- var BRAND_JSON_PATH = PLATFORM_ROOT7 ? join11(PLATFORM_ROOT7, "config", "brand.json") : "";
13218
+ var BRAND_JSON_PATH = PLATFORM_ROOT7 ? join10(PLATFORM_ROOT7, "config", "brand.json") : "";
13502
13219
  var BRAND = { productName: "Maxy", hostname: "maxy", configDir: ".maxy", domain: "getmaxy.com" };
13503
- if (BRAND_JSON_PATH && !existsSync25(BRAND_JSON_PATH)) {
13220
+ if (BRAND_JSON_PATH && !existsSync24(BRAND_JSON_PATH)) {
13504
13221
  console.error(`[brand] WARNING: brand.json not found at ${BRAND_JSON_PATH} \u2014 using Maxy defaults`);
13505
13222
  }
13506
- if (BRAND_JSON_PATH && existsSync25(BRAND_JSON_PATH)) {
13223
+ if (BRAND_JSON_PATH && existsSync24(BRAND_JSON_PATH)) {
13507
13224
  try {
13508
- const parsed = JSON.parse(readFileSync19(BRAND_JSON_PATH, "utf-8"));
13225
+ const parsed = JSON.parse(readFileSync18(BRAND_JSON_PATH, "utf-8"));
13509
13226
  BRAND = { ...BRAND, ...parsed };
13510
13227
  } catch (err) {
13511
13228
  console.error(`[brand] Failed to parse brand.json: ${err.message}`);
@@ -13524,11 +13241,11 @@ var brandLoginOpts = {
13524
13241
  bodyFont: BRAND.defaultFonts?.body,
13525
13242
  logoContainsName: !!BRAND.logoContainsName
13526
13243
  };
13527
- var ALIAS_DOMAINS_PATH2 = join11(homedir2(), BRAND.configDir, "alias-domains.json");
13244
+ var ALIAS_DOMAINS_PATH2 = join10(homedir2(), BRAND.configDir, "alias-domains.json");
13528
13245
  function loadAliasDomains() {
13529
13246
  try {
13530
- if (!existsSync25(ALIAS_DOMAINS_PATH2)) return null;
13531
- const parsed = JSON.parse(readFileSync19(ALIAS_DOMAINS_PATH2, "utf-8"));
13247
+ if (!existsSync24(ALIAS_DOMAINS_PATH2)) return null;
13248
+ const parsed = JSON.parse(readFileSync18(ALIAS_DOMAINS_PATH2, "utf-8"));
13532
13249
  if (!Array.isArray(parsed)) {
13533
13250
  console.error("[alias-domains] malformed alias-domains.json \u2014 expected array");
13534
13251
  return null;
@@ -13874,14 +13591,14 @@ app36.get("/agent-assets/:slug/:filename", (c) => {
13874
13591
  console.error(`[agent-assets] path-traversal-rejected slug=${slug} file=${filename}`);
13875
13592
  return c.text("Forbidden", 403);
13876
13593
  }
13877
- if (!existsSync25(filePath)) {
13594
+ if (!existsSync24(filePath)) {
13878
13595
  console.error(`[agent-assets] serve slug=${slug} file=${filename} status=404`);
13879
13596
  return c.text("Not found", 404);
13880
13597
  }
13881
13598
  const ext = "." + filename.split(".").pop()?.toLowerCase();
13882
13599
  const contentType = IMAGE_MIME[ext] || "application/octet-stream";
13883
13600
  console.log(`[agent-assets] serve slug=${slug} file=${filename} status=200`);
13884
- const body = readFileSync19(filePath);
13601
+ const body = readFileSync18(filePath);
13885
13602
  return c.body(body, 200, {
13886
13603
  "Content-Type": contentType,
13887
13604
  "Cache-Control": "public, max-age=3600"
@@ -13904,14 +13621,14 @@ app36.get("/generated/:filename", (c) => {
13904
13621
  console.error(`[generated] serve file=${filename} status=403`);
13905
13622
  return c.text("Forbidden", 403);
13906
13623
  }
13907
- if (!existsSync25(filePath)) {
13624
+ if (!existsSync24(filePath)) {
13908
13625
  console.error(`[generated] serve file=${filename} status=404`);
13909
13626
  return c.text("Not found", 404);
13910
13627
  }
13911
13628
  const ext = "." + filename.split(".").pop()?.toLowerCase();
13912
13629
  const contentType = IMAGE_MIME[ext] || "application/octet-stream";
13913
13630
  console.log(`[generated] serve file=${filename} status=200`);
13914
- const body = readFileSync19(filePath);
13631
+ const body = readFileSync18(filePath);
13915
13632
  return c.body(body, 200, {
13916
13633
  "Content-Type": contentType,
13917
13634
  "Cache-Control": "public, max-age=86400"
@@ -13921,9 +13638,9 @@ app36.route("/sites", sites_default);
13921
13638
  var htmlCache = /* @__PURE__ */ new Map();
13922
13639
  var brandLogoPath = "/brand/maxy-monochrome.png";
13923
13640
  var brandIconPath = "/brand/maxy-monochrome.png";
13924
- if (BRAND_JSON_PATH && existsSync25(BRAND_JSON_PATH)) {
13641
+ if (BRAND_JSON_PATH && existsSync24(BRAND_JSON_PATH)) {
13925
13642
  try {
13926
- const fullBrand = JSON.parse(readFileSync19(BRAND_JSON_PATH, "utf-8"));
13643
+ const fullBrand = JSON.parse(readFileSync18(BRAND_JSON_PATH, "utf-8"));
13927
13644
  if (fullBrand.assets?.logo) brandLogoPath = `/brand/${fullBrand.assets.logo}`;
13928
13645
  brandIconPath = fullBrand.assets?.icon ? `/brand/${fullBrand.assets.icon}` : brandLogoPath;
13929
13646
  } catch {
@@ -13940,9 +13657,9 @@ var brandScript = `<script>window.__BRAND__=${JSON.stringify({
13940
13657
  function readInstalledVersion() {
13941
13658
  try {
13942
13659
  if (!PLATFORM_ROOT7) return "unknown";
13943
- const versionFile = join11(PLATFORM_ROOT7, "config", `.${BRAND.hostname}-version`);
13944
- if (!existsSync25(versionFile)) return "unknown";
13945
- const content = readFileSync19(versionFile, "utf-8").trim();
13660
+ const versionFile = join10(PLATFORM_ROOT7, "config", `.${BRAND.hostname}-version`);
13661
+ if (!existsSync24(versionFile)) return "unknown";
13662
+ const content = readFileSync18(versionFile, "utf-8").trim();
13946
13663
  return content || "unknown";
13947
13664
  } catch {
13948
13665
  return "unknown";
@@ -13983,7 +13700,7 @@ var clientErrorReporterScript = `<script>
13983
13700
  function cachedHtml(file) {
13984
13701
  let html = htmlCache.get(file);
13985
13702
  if (!html) {
13986
- html = readFileSync19(resolve25(process.cwd(), "public", file), "utf-8");
13703
+ html = readFileSync18(resolve25(process.cwd(), "public", file), "utf-8");
13987
13704
  const productNameEsc = escapeHtml(BRAND.productName);
13988
13705
  html = html.replace(/<title>([^<]*)<\/title>/, (_match, inner) => `<title>${escapeHtml(inner).replace(/Maxy/g, productNameEsc)}</title>`);
13989
13706
  html = html.replace('href="/favicon.ico"', `href="${escapeHtml(brandFaviconPath)}"`);
@@ -13999,26 +13716,26 @@ ${clientErrorReporterScript}
13999
13716
  }
14000
13717
  var brandedHtmlCache = /* @__PURE__ */ new Map();
14001
13718
  function loadBrandingCache(agentSlug) {
14002
- const configDir2 = join11(homedir2(), BRAND.configDir);
13719
+ const configDir2 = join10(homedir2(), BRAND.configDir);
14003
13720
  try {
14004
- const accountJsonPath = join11(configDir2, "account.json");
14005
- if (!existsSync25(accountJsonPath)) return null;
14006
- const account = JSON.parse(readFileSync19(accountJsonPath, "utf-8"));
13721
+ const accountJsonPath = join10(configDir2, "account.json");
13722
+ if (!existsSync24(accountJsonPath)) return null;
13723
+ const account = JSON.parse(readFileSync18(accountJsonPath, "utf-8"));
14007
13724
  const accountId = account.accountId;
14008
13725
  if (!accountId) return null;
14009
- const cachePath = join11(configDir2, "branding-cache", accountId, `${agentSlug}.json`);
14010
- if (!existsSync25(cachePath)) return null;
14011
- return JSON.parse(readFileSync19(cachePath, "utf-8"));
13726
+ const cachePath = join10(configDir2, "branding-cache", accountId, `${agentSlug}.json`);
13727
+ if (!existsSync24(cachePath)) return null;
13728
+ return JSON.parse(readFileSync18(cachePath, "utf-8"));
14012
13729
  } catch {
14013
13730
  return null;
14014
13731
  }
14015
13732
  }
14016
13733
  function resolveDefaultSlug() {
14017
13734
  try {
14018
- const configDir2 = join11(homedir2(), BRAND.configDir);
14019
- const accountJsonPath = join11(configDir2, "account.json");
14020
- if (!existsSync25(accountJsonPath)) return null;
14021
- const account = JSON.parse(readFileSync19(accountJsonPath, "utf-8"));
13735
+ const configDir2 = join10(homedir2(), BRAND.configDir);
13736
+ const accountJsonPath = join10(configDir2, "account.json");
13737
+ if (!existsSync24(accountJsonPath)) return null;
13738
+ const account = JSON.parse(readFileSync18(accountJsonPath, "utf-8"));
14022
13739
  return account.defaultAgent || null;
14023
13740
  } catch {
14024
13741
  return null;
@@ -14091,7 +13808,7 @@ app36.use("/vnc-popout.html", logViewerFetch);
14091
13808
  app36.get("/vnc-popout.html", (c) => {
14092
13809
  let html = htmlCache.get("vnc-popout.html");
14093
13810
  if (!html) {
14094
- html = readFileSync19(resolve25(process.cwd(), "public", "vnc-popout.html"), "utf-8");
13811
+ html = readFileSync18(resolve25(process.cwd(), "public", "vnc-popout.html"), "utf-8");
14095
13812
  const name = escapeHtml(BRAND.productName);
14096
13813
  html = html.replace("<title>Browser \u2014 Maxy</title>", `<title>${name}</title>`);
14097
13814
  html = html.replace("</head>", ` ${brandScript}
@@ -14181,8 +13898,8 @@ try {
14181
13898
  (async () => {
14182
13899
  try {
14183
13900
  let userId = "";
14184
- if (existsSync25(USERS_FILE)) {
14185
- const users = JSON.parse(readFileSync19(USERS_FILE, "utf-8").trim() || "[]");
13901
+ if (existsSync24(USERS_FILE)) {
13902
+ const users = JSON.parse(readFileSync18(USERS_FILE, "utf-8").trim() || "[]");
14186
13903
  userId = users[0]?.userId ?? "";
14187
13904
  }
14188
13905
  await backfillNullUserIdConversations(userId);
@@ -14242,48 +13959,6 @@ for (const dir of bootEnabled) {
14242
13959
  bootDelivered.push(dir);
14243
13960
  }
14244
13961
  console.error(`[plugins] readiness enabled=${bootEnabled.length} delivered=${bootDelivered.length} dist-missing=[${bootDistMissing.join(",")}] missing=[${bootMissing.join(",")}]`);
14245
- (async () => {
14246
- if (!bootAccount) {
14247
- console.log("[action-completion-relay] phase=consumed-skip reason=no-account");
14248
- return;
14249
- }
14250
- let records;
14251
- try {
14252
- records = consumeActionCompletionRelays(bootAccount.accountDir);
14253
- } catch (err) {
14254
- console.error(`[action-completion-relay] phase=consume-failed error=${err instanceof Error ? err.message : String(err)}`);
14255
- return;
14256
- }
14257
- if (records.length === 0) {
14258
- console.log(`[action-completion-relay] phase=consumed-empty accountId=${bootAccount.accountId.slice(0, 8)}\u2026`);
14259
- return;
14260
- }
14261
- console.log(`[action-completion-relay] phase=consume-batch count=${records.length} accountId=${bootAccount.accountId.slice(0, 8)}\u2026`);
14262
- for (const rec of records) {
14263
- const sessionKey = `cloudflare-relay-boot:${rec.actionId}`;
14264
- let outcome = "injected";
14265
- let dispatchError;
14266
- try {
14267
- registerSession(sessionKey, "admin", bootAccount.accountId);
14268
- setConversationIdForSession(sessionKey, rec.conversationId);
14269
- for await (const _ev of invokeAgent({ type: "admin" }, rec.message, sessionKey)) {
14270
- }
14271
- } catch (err) {
14272
- outcome = "dispatch-failed";
14273
- dispatchError = err instanceof Error ? err.message : String(err);
14274
- } finally {
14275
- unregisterSession(sessionKey);
14276
- }
14277
- if (outcome === "injected") {
14278
- deleteConsumedRelay(rec.filePath);
14279
- console.log(`[action-completion-relay] phase=consumed actionId=${rec.actionId} conversationId=${rec.conversationId} ageMs=${rec.ageMs} outcome=injected`);
14280
- } else {
14281
- console.error(`[action-completion-relay] phase=consumed actionId=${rec.actionId} conversationId=${rec.conversationId} ageMs=${rec.ageMs} outcome=${outcome} reason=${JSON.stringify(dispatchError ?? "")} fileRetained=${JSON.stringify(rec.filePath)}`);
14282
- }
14283
- }
14284
- })().catch((err) => {
14285
- console.error(`[action-completion-relay] boot-drain rejected: ${err instanceof Error ? err.message : String(err)}`);
14286
- });
14287
13962
  if (bootAccountConfig?.whatsapp) {
14288
13963
  console.error(`[whatsapp:boot] loading whatsapp config from account.json publicAgent=${bootPublicAgent ?? "none"}`);
14289
13964
  } else {
@@ -14291,7 +13966,7 @@ if (bootAccountConfig?.whatsapp) {
14291
13966
  }
14292
13967
  init({
14293
13968
  configDir: configDirForWhatsApp,
14294
- platformRoot: resolve25(process.env.MAXY_PLATFORM_ROOT ?? join11(__dirname, "..")),
13969
+ platformRoot: resolve25(process.env.MAXY_PLATFORM_ROOT ?? join10(__dirname, "..")),
14295
13970
  accountConfig: bootAccountConfig,
14296
13971
  onMessage: async (msg) => {
14297
13972
  try {