@rubytech/create-maxy 1.0.798 → 1.0.800

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,7 +5,7 @@
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
6
  <title>Maxy</title>
7
7
  <link rel="icon" href="/favicon.ico">
8
- <script type="module" crossorigin src="/assets/admin-Cz8hUAqx.js"></script>
8
+ <script type="module" crossorigin src="/assets/admin-Sa301b8q.js"></script>
9
9
  <link rel="modulepreload" crossorigin href="/assets/chunk-DD-I1_y5.js">
10
10
  <link rel="modulepreload" crossorigin href="/assets/jsx-runtime-DJER3a7U.js">
11
11
  <link rel="modulepreload" crossorigin href="/assets/preload-helper-qlgyTAkD.js">
@@ -42,6 +42,7 @@ import {
42
42
  setRemotePassword,
43
43
  sleep,
44
44
  streamLogPathFor,
45
+ stripAttachmentMetaSuffix,
45
46
  validateKey,
46
47
  validatePasswordStrength,
47
48
  verifyPassword,
@@ -49,7 +50,7 @@ import {
49
50
  vncLog,
50
51
  waitForExit,
51
52
  writeChromiumWrapper
52
- } from "./chunk-KM23Y7SY.js";
53
+ } from "./chunk-SBHI2NMF.js";
53
54
  import {
54
55
  ACCOUNTS_DIR,
55
56
  GREETING_DIRECTIVE,
@@ -112,7 +113,7 @@ import {
112
113
  verifyAndGetConversationUpdatedAt,
113
114
  verifyConversationOwnership,
114
115
  writeAdminUserAndPerson
115
- } from "./chunk-BURNRCKP.js";
116
+ } from "./chunk-WHF6YXJ5.js";
116
117
  import {
117
118
  __commonJS,
118
119
  __toESM
@@ -615,7 +616,7 @@ var serveStatic = (options = { root: "" }) => {
615
616
  };
616
617
 
617
618
  // server/index.ts
618
- import { readFileSync as readFileSync17, existsSync as existsSync23, watchFile } from "fs";
619
+ import { readFileSync as readFileSync17, existsSync as existsSync24, watchFile } from "fs";
619
620
  import { resolve as resolve24, join as join10, basename as basename7 } from "path";
620
621
  import { homedir as homedir2 } from "os";
621
622
 
@@ -8324,7 +8325,7 @@ var app11 = new Hono();
8324
8325
  app11.post("/cancel", requireAdminSession, async (c) => {
8325
8326
  const session_key = c.var.sessionKey;
8326
8327
  try {
8327
- const { interruptClient: interruptClient2 } = await import("./client-pool-PV45NUTN.js");
8328
+ const { interruptClient: interruptClient2 } = await import("./client-pool-4YDRTKAT.js");
8328
8329
  await interruptClient2(session_key);
8329
8330
  return c.json({ ok: true });
8330
8331
  } catch (err) {
@@ -9078,7 +9079,35 @@ var agents_default = app16;
9078
9079
  // server/routes/admin/sessions.ts
9079
9080
  import crypto2 from "crypto";
9080
9081
  import { resolve as resolvePath } from "path";
9081
- import { appendFileSync as appendFileSync5 } from "fs";
9082
+ import { appendFileSync as appendFileSync5, existsSync as existsSync18 } from "fs";
9083
+ function validateAndShapeAttachments(raws, conversationAccountId, conversationId, messageId, streamLogPath) {
9084
+ const chips = [];
9085
+ let valid = 0;
9086
+ let invalid = 0;
9087
+ for (const a of raws) {
9088
+ let reason = null;
9089
+ if (!a.attachmentId || !a.filename || !a.mimeType || !a.storagePath) reason = "schema-fail";
9090
+ else if (a.accountId !== conversationAccountId) reason = "account-mismatch";
9091
+ else if (!existsSync18(a.storagePath)) reason = "missing-file";
9092
+ if (reason) {
9093
+ invalid++;
9094
+ try {
9095
+ appendFileSync5(streamLogPath, `[${(/* @__PURE__ */ new Date()).toISOString()}] [attachment-rehydrate-invalid] conversationId=${conversationId.slice(0, 8)} messageId=${messageId.slice(0, 8)} attachmentId=${(a.attachmentId || "").slice(0, 8)} reason=${reason}
9096
+ `);
9097
+ } catch {
9098
+ }
9099
+ continue;
9100
+ }
9101
+ valid++;
9102
+ chips.push({
9103
+ attachmentId: a.attachmentId,
9104
+ filename: a.filename,
9105
+ mimeType: a.mimeType,
9106
+ sizeBytes: a.sizeBytes
9107
+ });
9108
+ }
9109
+ return { chips, valid, invalid };
9110
+ }
9082
9111
  function reconstructAssistantEvents(content, components, conversationId, messageId, streamLogPath) {
9083
9112
  if (components.length === 0) {
9084
9113
  return {
@@ -9231,7 +9260,17 @@ app17.get("/:id/messages", requireAdminSession, async (c) => {
9231
9260
  if (!owned) return c.json({ error: "Conversation not found" }, 404);
9232
9261
  try {
9233
9262
  const messages = await getRecentMessages(conversationId, 50);
9234
- return c.json({ messages });
9263
+ const sanitised = messages.map((m) => ({
9264
+ ...m,
9265
+ attachments: m.attachments.map((a) => ({
9266
+ attachmentId: a.attachmentId,
9267
+ filename: a.filename,
9268
+ mimeType: a.mimeType,
9269
+ sizeBytes: a.sizeBytes,
9270
+ ordinal: a.ordinal
9271
+ }))
9272
+ }));
9273
+ return c.json({ messages: sanitised });
9235
9274
  } catch (err) {
9236
9275
  console.error(`[sessions-messages] Failed: ${err instanceof Error ? err.message : String(err)}`);
9237
9276
  return c.json({ error: "Failed to fetch messages" }, 500);
@@ -9264,10 +9303,23 @@ app17.post("/:id/resume", requireAdminSession, async (c) => {
9264
9303
  let totalValid = 0;
9265
9304
  let totalInvalid = 0;
9266
9305
  let totalComponents = 0;
9306
+ let totalAttachments = 0;
9307
+ let totalAttachmentInvalid = 0;
9267
9308
  const rehydrated = messages.map((m) => {
9268
9309
  const components = m.components ?? [];
9310
+ const rawAttachments = m.attachments ?? [];
9269
9311
  if (m.role !== "assistant") {
9270
- return { messageId: m.messageId, role: m.role, content: m.content, createdAt: m.createdAt };
9312
+ const { chips, valid: valid2, invalid: invalid2 } = validateAndShapeAttachments(rawAttachments, accountId, conversationId, m.messageId, streamLogPath);
9313
+ totalAttachments += valid2;
9314
+ totalAttachmentInvalid += invalid2;
9315
+ const cleanedContent = chips.length > 0 ? stripAttachmentMetaSuffix(m.content) : m.content;
9316
+ return {
9317
+ messageId: m.messageId,
9318
+ role: m.role,
9319
+ content: cleanedContent,
9320
+ createdAt: m.createdAt,
9321
+ ...chips.length > 0 ? { attachments: chips } : {}
9322
+ };
9271
9323
  }
9272
9324
  const { events, valid, invalid, submittedEventIndices } = reconstructAssistantEvents(m.content, components, conversationId, m.messageId, streamLogPath);
9273
9325
  totalValid += valid;
@@ -9284,17 +9336,22 @@ app17.post("/:id/resume", requireAdminSession, async (c) => {
9284
9336
  };
9285
9337
  });
9286
9338
  const textRuns = rehydrated.reduce((n, m) => n + (m.events?.filter((e) => e.type === "text").length ?? 0), 0);
9339
+ const userMessageCount = rehydrated.filter((m) => m.role !== "assistant").length;
9287
9340
  try {
9288
- appendFileSync5(streamLogPath, `[${(/* @__PURE__ */ new Date()).toISOString()}] [admin-resume] sessionKey=${sessionKey.slice(0, 8)} conversationId=${conversationId.slice(0, 8)} ${tag} loadedMessages=${messages.length} componentCount=${totalComponents}
9341
+ 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}
9289
9342
  `);
9290
9343
  if (totalComponents > 0) {
9291
9344
  appendFileSync5(streamLogPath, `[${(/* @__PURE__ */ new Date()).toISOString()}] [component-rehydrate] conversationId=${conversationId.slice(0, 8)} count=${totalComponents} valid=${totalValid} invalid=${totalInvalid} textRuns=${textRuns}
9345
+ `);
9346
+ }
9347
+ if (totalAttachments > 0 || totalAttachmentInvalid > 0) {
9348
+ appendFileSync5(streamLogPath, `[${(/* @__PURE__ */ new Date()).toISOString()}] [attachment-rehydrate] conversationId=${conversationId.slice(0, 8)} userMessages=${userMessageCount} attachments=${totalAttachments} invalid=${totalAttachmentInvalid}
9292
9349
  `);
9293
9350
  }
9294
9351
  } catch {
9295
9352
  }
9296
9353
  const age = formatAge(updatedAt);
9297
- console.log(`[admin-resume] ${(/* @__PURE__ */ new Date()).toISOString()} conversationId=${conversationId.slice(0, 8)}\u2026 age=${age} loaded=${messages.length} messages ${tag} components=${totalComponents} sessionKey=${sessionKey.slice(0, 8)}\u2026`);
9354
+ 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`);
9298
9355
  return c.json({ conversationId, messages: rehydrated });
9299
9356
  });
9300
9357
  app17.post("/:id/label", requireAdminSession, async (c) => {
@@ -9569,12 +9626,12 @@ function isValidDomain(value) {
9569
9626
  }
9570
9627
 
9571
9628
  // app/lib/alias-domains.ts
9572
- import { existsSync as existsSync18, mkdirSync as mkdirSync8, readFileSync as readFileSync14, writeFileSync as writeFileSync9 } from "fs";
9629
+ import { existsSync as existsSync19, mkdirSync as mkdirSync8, readFileSync as readFileSync14, writeFileSync as writeFileSync9 } from "fs";
9573
9630
  import { dirname as dirname7 } from "path";
9574
9631
  import { resolve as resolve16 } from "path";
9575
9632
  var ALIAS_DOMAINS_PATH = resolve16(MAXY_DIR, "alias-domains.json");
9576
9633
  function readExisting() {
9577
- if (!existsSync18(ALIAS_DOMAINS_PATH)) return /* @__PURE__ */ new Set();
9634
+ if (!existsSync19(ALIAS_DOMAINS_PATH)) return /* @__PURE__ */ new Set();
9578
9635
  try {
9579
9636
  const parsed = JSON.parse(readFileSync14(ALIAS_DOMAINS_PATH, "utf-8"));
9580
9637
  if (!Array.isArray(parsed)) return /* @__PURE__ */ new Set();
@@ -11911,7 +11968,7 @@ var adherence_default = app30;
11911
11968
  import neo4j3 from "neo4j-driver";
11912
11969
  import { readFile as readFile5, readdir as readdir3, stat as stat5 } from "fs/promises";
11913
11970
  import { resolve as resolve20, relative as relative2, isAbsolute } from "path";
11914
- import { existsSync as existsSync19 } from "fs";
11971
+ import { existsSync as existsSync20 } from "fs";
11915
11972
  var LIMIT = 50;
11916
11973
  var TEXT_MIME_PREFIXES = ["text/", "application/json", "application/markdown"];
11917
11974
  var ADMIN_AGENT_FILES = ["IDENTITY.md", "SOUL.md", "KNOWLEDGE.md"];
@@ -12059,7 +12116,7 @@ async function fetchAgentTemplateRows(accountDir) {
12059
12116
  async function unionSpecialistFilenames(overrideDir, bundledDir) {
12060
12117
  const names = /* @__PURE__ */ new Set();
12061
12118
  for (const dir of [overrideDir, bundledDir]) {
12062
- if (!existsSync19(dir)) continue;
12119
+ if (!existsSync20(dir)) continue;
12063
12120
  try {
12064
12121
  const entries = await readdir3(dir);
12065
12122
  for (const entry of entries) {
@@ -12074,7 +12131,7 @@ async function unionSpecialistFilenames(overrideDir, bundledDir) {
12074
12131
  }
12075
12132
  async function readAgentTemplateRow(inp) {
12076
12133
  let chosenPath = null;
12077
- if (existsSync19(inp.overridePath)) {
12134
+ if (existsSync20(inp.overridePath)) {
12078
12135
  try {
12079
12136
  validateFilePathInAccount(inp.overridePath, inp.overrideRoot);
12080
12137
  chosenPath = inp.overridePath;
@@ -12085,7 +12142,7 @@ async function readAgentTemplateRow(inp) {
12085
12142
  );
12086
12143
  return null;
12087
12144
  }
12088
- } else if (existsSync19(inp.bundledPath)) {
12145
+ } else if (existsSync20(inp.bundledPath)) {
12089
12146
  if (!isWithin(inp.bundledPath, inp.bundledRoot)) {
12090
12147
  console.error(
12091
12148
  `[admin/sidebar-artefacts] agent-template-read-failed agent=${inp.displayName} kind=${inp.logName} error="bundled path outside PLATFORM_ROOT"`
@@ -12127,7 +12184,7 @@ var sidebar_artefacts_default = app31;
12127
12184
  // server/routes/admin/sidebar-artefact-save.ts
12128
12185
  import { mkdir as mkdir4, readdir as readdir4, stat as stat6, writeFile as writeFile5 } from "fs/promises";
12129
12186
  import { resolve as resolve21 } from "path";
12130
- import { existsSync as existsSync20 } from "fs";
12187
+ import { existsSync as existsSync21 } from "fs";
12131
12188
  var ADMIN_AGENT_FILES2 = /* @__PURE__ */ new Set(["IDENTITY.md", "SOUL.md", "KNOWLEDGE.md"]);
12132
12189
  var UUID_RE4 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/;
12133
12190
  var app32 = new Hono();
@@ -12191,7 +12248,7 @@ async function resolveSavePath(id, accountId, accountDir) {
12191
12248
  }
12192
12249
  if (UUID_RE4.test(id)) {
12193
12250
  const dir = resolve21(ATTACHMENTS_ROOT, accountId, id);
12194
- if (!existsSync20(dir)) {
12251
+ if (!existsSync21(dir)) {
12195
12252
  return { kind: "reject", status: 400, reason: "not-found" };
12196
12253
  }
12197
12254
  try {
@@ -12215,7 +12272,7 @@ var sidebar_artefact_save_default = app32;
12215
12272
 
12216
12273
  // server/routes/admin/sidebar-artefact-content.ts
12217
12274
  import { readFile as readFile6, readdir as readdir5 } from "fs/promises";
12218
- import { existsSync as existsSync21 } from "fs";
12275
+ import { existsSync as existsSync22 } from "fs";
12219
12276
  import { resolve as resolve22 } from "path";
12220
12277
  var UUID_RE5 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/;
12221
12278
  var app33 = new Hono();
@@ -12229,7 +12286,7 @@ app33.get("/", requireAdminSession, async (c) => {
12229
12286
  return new Response("Not found", { status: 404 });
12230
12287
  }
12231
12288
  const dir = resolve22(ATTACHMENTS_ROOT, accountId, id);
12232
- if (!existsSync21(dir)) {
12289
+ if (!existsSync22(dir)) {
12233
12290
  console.error(`[admin/sidebar-artefact-content] not-found id=${id.slice(0, 8)}`);
12234
12291
  return new Response("Not found", { status: 404 });
12235
12292
  }
@@ -12291,7 +12348,7 @@ app34.route("/sidebar-artefact-content", sidebar_artefact_content_default);
12291
12348
  var admin_default = app34;
12292
12349
 
12293
12350
  // server/routes/sites.ts
12294
- import { existsSync as existsSync22, readFileSync as readFileSync16, realpathSync as realpathSync5, statSync as statSync8 } from "fs";
12351
+ import { existsSync as existsSync23, readFileSync as readFileSync16, realpathSync as realpathSync5, statSync as statSync8 } from "fs";
12295
12352
  import { resolve as resolve23 } from "path";
12296
12353
  var SAFE_SEG_RE = /^[a-z0-9_][a-z0-9_.-]{0,99}$/i;
12297
12354
  var MIME = {
@@ -12358,7 +12415,7 @@ app35.get("/:rel{.*}", (c) => {
12358
12415
  }
12359
12416
  let stat7;
12360
12417
  try {
12361
- stat7 = existsSync22(filePath) ? statSync8(filePath) : null;
12418
+ stat7 = existsSync23(filePath) ? statSync8(filePath) : null;
12362
12419
  } catch {
12363
12420
  stat7 = null;
12364
12421
  }
@@ -12371,7 +12428,7 @@ app35.get("/:rel{.*}", (c) => {
12371
12428
  console.error(`[sites] path-traversal-rejected path=${reqPath} reason=escape status=403`);
12372
12429
  return c.text("Forbidden", 403);
12373
12430
  }
12374
- if (!existsSync22(filePath)) {
12431
+ if (!existsSync23(filePath)) {
12375
12432
  console.error(`[sites] not-found path=${reqPath} status=404`);
12376
12433
  return c.text("Not found", 404);
12377
12434
  }
@@ -12524,10 +12581,10 @@ function clientFrom(c) {
12524
12581
  var PLATFORM_ROOT7 = process.env.MAXY_PLATFORM_ROOT || "";
12525
12582
  var BRAND_JSON_PATH = PLATFORM_ROOT7 ? join10(PLATFORM_ROOT7, "config", "brand.json") : "";
12526
12583
  var BRAND = { productName: "Maxy", hostname: "maxy", configDir: ".maxy", domain: "getmaxy.com" };
12527
- if (BRAND_JSON_PATH && !existsSync23(BRAND_JSON_PATH)) {
12584
+ if (BRAND_JSON_PATH && !existsSync24(BRAND_JSON_PATH)) {
12528
12585
  console.error(`[brand] WARNING: brand.json not found at ${BRAND_JSON_PATH} \u2014 using Maxy defaults`);
12529
12586
  }
12530
- if (BRAND_JSON_PATH && existsSync23(BRAND_JSON_PATH)) {
12587
+ if (BRAND_JSON_PATH && existsSync24(BRAND_JSON_PATH)) {
12531
12588
  try {
12532
12589
  const parsed = JSON.parse(readFileSync17(BRAND_JSON_PATH, "utf-8"));
12533
12590
  BRAND = { ...BRAND, ...parsed };
@@ -12551,7 +12608,7 @@ var brandLoginOpts = {
12551
12608
  var ALIAS_DOMAINS_PATH2 = join10(homedir2(), BRAND.configDir, "alias-domains.json");
12552
12609
  function loadAliasDomains() {
12553
12610
  try {
12554
- if (!existsSync23(ALIAS_DOMAINS_PATH2)) return null;
12611
+ if (!existsSync24(ALIAS_DOMAINS_PATH2)) return null;
12555
12612
  const parsed = JSON.parse(readFileSync17(ALIAS_DOMAINS_PATH2, "utf-8"));
12556
12613
  if (!Array.isArray(parsed)) {
12557
12614
  console.error("[alias-domains] malformed alias-domains.json \u2014 expected array");
@@ -12898,7 +12955,7 @@ app36.get("/agent-assets/:slug/:filename", (c) => {
12898
12955
  console.error(`[agent-assets] path-traversal-rejected slug=${slug} file=${filename}`);
12899
12956
  return c.text("Forbidden", 403);
12900
12957
  }
12901
- if (!existsSync23(filePath)) {
12958
+ if (!existsSync24(filePath)) {
12902
12959
  console.error(`[agent-assets] serve slug=${slug} file=${filename} status=404`);
12903
12960
  return c.text("Not found", 404);
12904
12961
  }
@@ -12928,7 +12985,7 @@ app36.get("/generated/:filename", (c) => {
12928
12985
  console.error(`[generated] serve file=${filename} status=403`);
12929
12986
  return c.text("Forbidden", 403);
12930
12987
  }
12931
- if (!existsSync23(filePath)) {
12988
+ if (!existsSync24(filePath)) {
12932
12989
  console.error(`[generated] serve file=${filename} status=404`);
12933
12990
  return c.text("Not found", 404);
12934
12991
  }
@@ -12945,7 +13002,7 @@ app36.route("/sites", sites_default);
12945
13002
  var htmlCache = /* @__PURE__ */ new Map();
12946
13003
  var brandLogoPath = "/brand/maxy-monochrome.png";
12947
13004
  var brandIconPath = "/brand/maxy-monochrome.png";
12948
- if (BRAND_JSON_PATH && existsSync23(BRAND_JSON_PATH)) {
13005
+ if (BRAND_JSON_PATH && existsSync24(BRAND_JSON_PATH)) {
12949
13006
  try {
12950
13007
  const fullBrand = JSON.parse(readFileSync17(BRAND_JSON_PATH, "utf-8"));
12951
13008
  if (fullBrand.assets?.logo) brandLogoPath = `/brand/${fullBrand.assets.logo}`;
@@ -12965,7 +13022,7 @@ function readInstalledVersion() {
12965
13022
  try {
12966
13023
  if (!PLATFORM_ROOT7) return "unknown";
12967
13024
  const versionFile = join10(PLATFORM_ROOT7, "config", `.${BRAND.hostname}-version`);
12968
- if (!existsSync23(versionFile)) return "unknown";
13025
+ if (!existsSync24(versionFile)) return "unknown";
12969
13026
  const content = readFileSync17(versionFile, "utf-8").trim();
12970
13027
  return content || "unknown";
12971
13028
  } catch {
@@ -13026,12 +13083,12 @@ function loadBrandingCache(agentSlug) {
13026
13083
  const configDir2 = join10(homedir2(), BRAND.configDir);
13027
13084
  try {
13028
13085
  const accountJsonPath = join10(configDir2, "account.json");
13029
- if (!existsSync23(accountJsonPath)) return null;
13086
+ if (!existsSync24(accountJsonPath)) return null;
13030
13087
  const account = JSON.parse(readFileSync17(accountJsonPath, "utf-8"));
13031
13088
  const accountId = account.accountId;
13032
13089
  if (!accountId) return null;
13033
13090
  const cachePath = join10(configDir2, "branding-cache", accountId, `${agentSlug}.json`);
13034
- if (!existsSync23(cachePath)) return null;
13091
+ if (!existsSync24(cachePath)) return null;
13035
13092
  return JSON.parse(readFileSync17(cachePath, "utf-8"));
13036
13093
  } catch {
13037
13094
  return null;
@@ -13041,7 +13098,7 @@ function resolveDefaultSlug() {
13041
13098
  try {
13042
13099
  const configDir2 = join10(homedir2(), BRAND.configDir);
13043
13100
  const accountJsonPath = join10(configDir2, "account.json");
13044
- if (!existsSync23(accountJsonPath)) return null;
13101
+ if (!existsSync24(accountJsonPath)) return null;
13045
13102
  const account = JSON.parse(readFileSync17(accountJsonPath, "utf-8"));
13046
13103
  return account.defaultAgent || null;
13047
13104
  } catch {
@@ -13205,7 +13262,7 @@ try {
13205
13262
  (async () => {
13206
13263
  try {
13207
13264
  let userId = "";
13208
- if (existsSync23(USERS_FILE)) {
13265
+ if (existsSync24(USERS_FILE)) {
13209
13266
  const users = JSON.parse(readFileSync17(USERS_FILE, "utf-8").trim() || "[]");
13210
13267
  userId = users[0]?.userId ?? "";
13211
13268
  }