@rubytech/create-maxy 1.0.763 → 1.0.765

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 (88) hide show
  1. package/package.json +1 -1
  2. package/payload/platform/package-lock.json +56 -1
  3. package/payload/platform/package.json +1 -0
  4. package/payload/platform/plugins/docs/references/outlook-guide.md +69 -0
  5. package/payload/platform/plugins/docs/references/platform.md +1 -1
  6. package/payload/platform/plugins/outlook/PLUGIN.md +48 -0
  7. package/payload/platform/plugins/outlook/mcp/dist/__tests__/graph-client.test.d.ts +2 -0
  8. package/payload/platform/plugins/outlook/mcp/dist/__tests__/graph-client.test.d.ts.map +1 -0
  9. package/payload/platform/plugins/outlook/mcp/dist/__tests__/graph-client.test.js +94 -0
  10. package/payload/platform/plugins/outlook/mcp/dist/__tests__/graph-client.test.js.map +1 -0
  11. package/payload/platform/plugins/outlook/mcp/dist/__tests__/log.test.d.ts +2 -0
  12. package/payload/platform/plugins/outlook/mcp/dist/__tests__/log.test.d.ts.map +1 -0
  13. package/payload/platform/plugins/outlook/mcp/dist/__tests__/log.test.js +31 -0
  14. package/payload/platform/plugins/outlook/mcp/dist/__tests__/log.test.js.map +1 -0
  15. package/payload/platform/plugins/outlook/mcp/dist/__tests__/pkce-flow.test.d.ts +2 -0
  16. package/payload/platform/plugins/outlook/mcp/dist/__tests__/pkce-flow.test.d.ts.map +1 -0
  17. package/payload/platform/plugins/outlook/mcp/dist/__tests__/pkce-flow.test.js +213 -0
  18. package/payload/platform/plugins/outlook/mcp/dist/__tests__/pkce-flow.test.js.map +1 -0
  19. package/payload/platform/plugins/outlook/mcp/dist/__tests__/token-store.test.d.ts +2 -0
  20. package/payload/platform/plugins/outlook/mcp/dist/__tests__/token-store.test.d.ts.map +1 -0
  21. package/payload/platform/plugins/outlook/mcp/dist/__tests__/token-store.test.js +130 -0
  22. package/payload/platform/plugins/outlook/mcp/dist/__tests__/token-store.test.js.map +1 -0
  23. package/payload/platform/plugins/outlook/mcp/dist/auth/pkce-flow.d.ts +65 -0
  24. package/payload/platform/plugins/outlook/mcp/dist/auth/pkce-flow.d.ts.map +1 -0
  25. package/payload/platform/plugins/outlook/mcp/dist/auth/pkce-flow.js +261 -0
  26. package/payload/platform/plugins/outlook/mcp/dist/auth/pkce-flow.js.map +1 -0
  27. package/payload/platform/plugins/outlook/mcp/dist/auth/token-store.d.ts +61 -0
  28. package/payload/platform/plugins/outlook/mcp/dist/auth/token-store.d.ts.map +1 -0
  29. package/payload/platform/plugins/outlook/mcp/dist/auth/token-store.js +170 -0
  30. package/payload/platform/plugins/outlook/mcp/dist/auth/token-store.js.map +1 -0
  31. package/payload/platform/plugins/outlook/mcp/dist/index.d.ts +18 -0
  32. package/payload/platform/plugins/outlook/mcp/dist/index.d.ts.map +1 -0
  33. package/payload/platform/plugins/outlook/mcp/dist/index.js +152 -0
  34. package/payload/platform/plugins/outlook/mcp/dist/index.js.map +1 -0
  35. package/payload/platform/plugins/outlook/mcp/dist/lib/graph-client.d.ts +60 -0
  36. package/payload/platform/plugins/outlook/mcp/dist/lib/graph-client.d.ts.map +1 -0
  37. package/payload/platform/plugins/outlook/mcp/dist/lib/graph-client.js +189 -0
  38. package/payload/platform/plugins/outlook/mcp/dist/lib/graph-client.js.map +1 -0
  39. package/payload/platform/plugins/outlook/mcp/dist/lib/log.d.ts +23 -0
  40. package/payload/platform/plugins/outlook/mcp/dist/lib/log.d.ts.map +1 -0
  41. package/payload/platform/plugins/outlook/mcp/dist/lib/log.js +53 -0
  42. package/payload/platform/plugins/outlook/mcp/dist/lib/log.js.map +1 -0
  43. package/payload/platform/plugins/outlook/mcp/dist/tools/account-register.d.ts +26 -0
  44. package/payload/platform/plugins/outlook/mcp/dist/tools/account-register.d.ts.map +1 -0
  45. package/payload/platform/plugins/outlook/mcp/dist/tools/account-register.js +50 -0
  46. package/payload/platform/plugins/outlook/mcp/dist/tools/account-register.js.map +1 -0
  47. package/payload/platform/plugins/outlook/mcp/dist/tools/calendar-event.d.ts +12 -0
  48. package/payload/platform/plugins/outlook/mcp/dist/tools/calendar-event.d.ts.map +1 -0
  49. package/payload/platform/plugins/outlook/mcp/dist/tools/calendar-event.js +32 -0
  50. package/payload/platform/plugins/outlook/mcp/dist/tools/calendar-event.js.map +1 -0
  51. package/payload/platform/plugins/outlook/mcp/dist/tools/calendar-list.d.ts +59 -0
  52. package/payload/platform/plugins/outlook/mcp/dist/tools/calendar-list.d.ts.map +1 -0
  53. package/payload/platform/plugins/outlook/mcp/dist/tools/calendar-list.js +54 -0
  54. package/payload/platform/plugins/outlook/mcp/dist/tools/calendar-list.js.map +1 -0
  55. package/payload/platform/plugins/outlook/mcp/dist/tools/contacts-list.d.ts +14 -0
  56. package/payload/platform/plugins/outlook/mcp/dist/tools/contacts-list.d.ts.map +1 -0
  57. package/payload/platform/plugins/outlook/mcp/dist/tools/contacts-list.js +45 -0
  58. package/payload/platform/plugins/outlook/mcp/dist/tools/contacts-list.js.map +1 -0
  59. package/payload/platform/plugins/outlook/mcp/dist/tools/mail-list.d.ts +15 -0
  60. package/payload/platform/plugins/outlook/mcp/dist/tools/mail-list.d.ts.map +1 -0
  61. package/payload/platform/plugins/outlook/mcp/dist/tools/mail-list.js +48 -0
  62. package/payload/platform/plugins/outlook/mcp/dist/tools/mail-list.js.map +1 -0
  63. package/payload/platform/plugins/outlook/mcp/dist/tools/mail-search.d.ts +8 -0
  64. package/payload/platform/plugins/outlook/mcp/dist/tools/mail-search.d.ts.map +1 -0
  65. package/payload/platform/plugins/outlook/mcp/dist/tools/mail-search.js +49 -0
  66. package/payload/platform/plugins/outlook/mcp/dist/tools/mail-search.js.map +1 -0
  67. package/payload/platform/plugins/outlook/mcp/dist/tools/mailbox-info.d.ts +19 -0
  68. package/payload/platform/plugins/outlook/mcp/dist/tools/mailbox-info.d.ts.map +1 -0
  69. package/payload/platform/plugins/outlook/mcp/dist/tools/mailbox-info.js +58 -0
  70. package/payload/platform/plugins/outlook/mcp/dist/tools/mailbox-info.js.map +1 -0
  71. package/payload/platform/plugins/outlook/mcp/package.json +20 -0
  72. package/payload/platform/plugins/outlook/mcp/scripts/verify-doc-impl.sh +109 -0
  73. package/payload/platform/plugins/outlook/references/auth.md +118 -0
  74. package/payload/platform/plugins/outlook/references/graph-surfaces.md +114 -0
  75. package/payload/platform/plugins/outlook/skills/outlook/SKILL.md +65 -0
  76. package/payload/platform/templates/specialists/agents/personal-assistant.md +1 -1
  77. package/payload/server/chunk-EIQT6QDH.js +9562 -0
  78. package/payload/server/chunk-IO2WQEY4.js +9562 -0
  79. package/payload/server/chunk-TKYZ7AEB.js +3142 -0
  80. package/payload/server/client-pool-CX2MFW75.js +28 -0
  81. package/payload/server/maxy-edge.js +2 -2
  82. package/payload/server/public/assets/{admin-V6NDkEoR.js → admin-g-Fjko8R.js} +5 -5
  83. package/payload/server/public/assets/{graph-BHcUKzXh.js → graph-DHBGJFDX.js} +1 -1
  84. package/payload/server/public/assets/page-BscgOyqp.js +50 -0
  85. package/payload/server/public/graph.html +2 -2
  86. package/payload/server/public/index.html +2 -2
  87. package/payload/server/server.js +146 -39
  88. package/payload/server/public/assets/page-DxH_Opxt.js +0 -50
@@ -5,12 +5,12 @@
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
6
  <title>Graph — Maxy</title>
7
7
  <link rel="icon" href="/favicon.ico">
8
- <script type="module" crossorigin src="/assets/graph-BHcUKzXh.js"></script>
8
+ <script type="module" crossorigin src="/assets/graph-DHBGJFDX.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-B4QFltsm.js">
11
11
  <link rel="modulepreload" crossorigin href="/assets/Checkbox-BRLBdX7n.js">
12
12
  <link rel="modulepreload" crossorigin href="/assets/share-2-Cc99o2of.js">
13
- <link rel="modulepreload" crossorigin href="/assets/page-DxH_Opxt.js">
13
+ <link rel="modulepreload" crossorigin href="/assets/page-BscgOyqp.js">
14
14
  <link rel="stylesheet" crossorigin href="/assets/jsx-runtime-BRkYVd7p.css">
15
15
  </head>
16
16
  <body>
@@ -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-V6NDkEoR.js"></script>
8
+ <script type="module" crossorigin src="/assets/admin-g-Fjko8R.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-B4QFltsm.js">
11
11
  <link rel="modulepreload" crossorigin href="/assets/preload-helper-qlgyTAkD.js">
@@ -13,7 +13,7 @@
13
13
  <link rel="modulepreload" crossorigin href="/assets/useVoiceRecorder-C2CyyNiy.js">
14
14
  <link rel="modulepreload" crossorigin href="/assets/share-2-Cc99o2of.js">
15
15
  <link rel="modulepreload" crossorigin href="/assets/page-v5z5MBB6.js">
16
- <link rel="modulepreload" crossorigin href="/assets/page-DxH_Opxt.js">
16
+ <link rel="modulepreload" crossorigin href="/assets/page-BscgOyqp.js">
17
17
  <link rel="stylesheet" crossorigin href="/assets/jsx-runtime-BRkYVd7p.css">
18
18
  <link rel="stylesheet" crossorigin href="/assets/admin-CWMpccrR.css">
19
19
  <link rel="stylesheet" href="/brand-defaults.css">
@@ -47,7 +47,7 @@ import {
47
47
  vncLog,
48
48
  waitForExit,
49
49
  writeChromiumWrapper
50
- } from "./chunk-SGBNY4NP.js";
50
+ } from "./chunk-IO2WQEY4.js";
51
51
  import {
52
52
  ACCOUNTS_DIR,
53
53
  GREETING_DIRECTIVE,
@@ -107,7 +107,7 @@ import {
107
107
  validateSession,
108
108
  verifyAndGetConversationUpdatedAt,
109
109
  verifyConversationOwnership
110
- } from "./chunk-S3M2NZMA.js";
110
+ } from "./chunk-TKYZ7AEB.js";
111
111
 
112
112
  // ../lib/graph-trash/dist/index.js
113
113
  var require_dist = __commonJS({
@@ -606,7 +606,7 @@ var serveStatic = (options = { root: "" }) => {
606
606
  };
607
607
 
608
608
  // server/index.ts
609
- import { readFileSync as readFileSync16, existsSync as existsSync19, watchFile } from "fs";
609
+ import { readFileSync as readFileSync16, existsSync as existsSync20, watchFile } from "fs";
610
610
  import { resolve as resolve21, join as join10, basename as basename7 } from "path";
611
611
  import { homedir as homedir2 } from "os";
612
612
 
@@ -1351,9 +1351,9 @@ function discoverAllSources(configDir2, accountLogDir2) {
1351
1351
  }
1352
1352
  function readNewLines(filepath, prev) {
1353
1353
  if (!existsSync3(filepath)) return null;
1354
- const stat5 = statSync3(filepath);
1355
- const size = stat5.size;
1356
- const inode = stat5.ino;
1354
+ const stat6 = statSync3(filepath);
1355
+ const size = stat6.size;
1356
+ const inode = stat6.ino;
1357
1357
  let startOffset = 0;
1358
1358
  let rotated = false;
1359
1359
  let truncated = false;
@@ -8132,7 +8132,7 @@ var app11 = new Hono();
8132
8132
  app11.post("/cancel", requireAdminSession, async (c) => {
8133
8133
  const session_key = c.var.sessionKey;
8134
8134
  try {
8135
- const { interruptClient: interruptClient2 } = await import("./client-pool-5V5GX3UT.js");
8135
+ const { interruptClient: interruptClient2 } = await import("./client-pool-CX2MFW75.js");
8136
8136
  await interruptClient2(session_key);
8137
8137
  return c.json({ ok: true });
8138
8138
  } catch (err) {
@@ -8843,12 +8843,6 @@ var agents_default = app16;
8843
8843
  import crypto2 from "crypto";
8844
8844
  import { resolve as resolvePath } from "path";
8845
8845
  import { appendFileSync as appendFileSync5 } from "fs";
8846
- var PERSISTENT_COMPONENT_NAMES = /* @__PURE__ */ new Set([
8847
- "action-list",
8848
- "document-editor",
8849
- "rich-content-editor",
8850
- "grid-editor"
8851
- ]);
8852
8846
  function reconstructAssistantEvents(content, components, conversationId, messageId, streamLogPath) {
8853
8847
  if (components.length === 0) {
8854
8848
  return {
@@ -8904,7 +8898,7 @@ function reconstructAssistantEvents(content, components, conversationId, message
8904
8898
  valid += 1;
8905
8899
  const eventIndex = events.length;
8906
8900
  events.push({ type: "component", name: c.name, data: parsedData });
8907
- if (c.submitted === true && !PERSISTENT_COMPONENT_NAMES.has(c.name)) {
8901
+ if (c.submitted === true) {
8908
8902
  submittedEventIndices.push(eventIndex);
8909
8903
  }
8910
8904
  }
@@ -9049,8 +9043,7 @@ app17.post("/:id/resume", requireAdminSession, async (c) => {
9049
9043
  events,
9050
9044
  createdAt: m.createdAt,
9051
9045
  // Submitted-event indices for client `submittedComponents` seed —
9052
- // empty array when no PERSISTENT_COMPONENT was approved live, omitted
9053
- // from the wire payload to keep the response slim.
9046
+ // omitted from the wire payload when empty to keep the response slim.
9054
9047
  ...submittedEventIndices.length > 0 ? { submittedEventIndices } : {}
9055
9048
  };
9056
9049
  });
@@ -11691,13 +11684,14 @@ app31.get("/", requireAdminSession, async (c) => {
11691
11684
  const result = await session.run(
11692
11685
  `MATCH (p:Project { accountId: $accountId })
11693
11686
  WHERE NOT p:Trashed
11694
- RETURN p.taskId AS id, p.name AS name, p.updatedAt AS updatedAt
11687
+ RETURN p.taskId AS id, elementId(p) AS elementId, p.name AS name, p.updatedAt AS updatedAt
11695
11688
  ORDER BY p.updatedAt DESC
11696
11689
  LIMIT $limit`,
11697
11690
  { accountId, limit: neo4j3.int(LIMIT) }
11698
11691
  );
11699
11692
  const projects = result.records.map((r) => ({
11700
11693
  id: r.get("id"),
11694
+ elementId: r.get("elementId"),
11701
11695
  name: r.get("name") ?? "",
11702
11696
  updatedAt: r.get("updatedAt") ?? ""
11703
11697
  }));
@@ -11717,10 +11711,12 @@ var sidebar_projects_default = app31;
11717
11711
 
11718
11712
  // server/routes/admin/sidebar-artefacts.ts
11719
11713
  import neo4j4 from "neo4j-driver";
11720
- import { readFile as readFile5, readdir as readdir3 } from "fs/promises";
11721
- import { resolve as resolve20 } from "path";
11714
+ import { readFile as readFile5, readdir as readdir3, stat as stat5 } from "fs/promises";
11715
+ import { resolve as resolve20, relative as relative2, isAbsolute } from "path";
11716
+ import { existsSync as existsSync19 } from "fs";
11722
11717
  var LIMIT2 = 50;
11723
11718
  var TEXT_MIME_PREFIXES = ["text/", "application/json", "application/markdown"];
11719
+ var ADMIN_AGENT_FILES = ["IDENTITY.md", "SOUL.md", "KNOWLEDGE.md"];
11724
11720
  var app32 = new Hono();
11725
11721
  app32.get("/", requireAdminSession, async (c) => {
11726
11722
  const sessionKey = c.var.sessionKey;
@@ -11729,6 +11725,22 @@ app32.get("/", requireAdminSession, async (c) => {
11729
11725
  return c.json({ error: "Account not found for session" }, 401);
11730
11726
  }
11731
11727
  const start = Date.now();
11728
+ const docs = await fetchKnowledgeDocs(accountId);
11729
+ if (docs === null) {
11730
+ return c.json({ error: "Failed to load artefacts" }, 500);
11731
+ }
11732
+ const accountDir = resolve20(ACCOUNTS_DIR, accountId);
11733
+ const agents = await fetchAgentTemplateRows(accountDir);
11734
+ const artefacts = [...docs, ...agents].sort(
11735
+ (a, b) => (b.updatedAt ?? "").localeCompare(a.updatedAt ?? "")
11736
+ ).slice(0, LIMIT2);
11737
+ const ms = Date.now() - start;
11738
+ console.log(
11739
+ `[admin/sidebar-artefacts] account=${accountId} count=${artefacts.length} docs=${docs.length} agents=${agents.length} ms=${ms}`
11740
+ );
11741
+ return c.json({ artefacts });
11742
+ });
11743
+ async function fetchKnowledgeDocs(accountId) {
11732
11744
  const session = getSession();
11733
11745
  let metas = [];
11734
11746
  try {
@@ -11749,22 +11761,18 @@ app32.get("/", requireAdminSession, async (c) => {
11749
11761
  mimeType: r.get("mimeType") ?? ""
11750
11762
  }));
11751
11763
  } catch (err) {
11752
- const ms2 = Date.now() - start;
11753
11764
  const message = err instanceof Error ? err.message : String(err);
11754
- console.error(`[admin/sidebar-artefacts] account=${accountId} error="${message}" ms=${ms2}`);
11765
+ console.error(`[admin/sidebar-artefacts] account=${accountId} error="${message}"`);
11755
11766
  await session.close();
11756
- return c.json({ error: "Failed to load artefacts" }, 500);
11767
+ return null;
11757
11768
  } finally {
11758
11769
  await session.close();
11759
11770
  }
11760
- const artefacts = await Promise.all(metas.map(async (m) => {
11771
+ return Promise.all(metas.map(async (m) => {
11761
11772
  const content = await readArtefactContent(accountId, m.attachmentId, m.mimeType);
11762
- return { id: m.id, name: m.name, updatedAt: m.updatedAt, content };
11773
+ return { id: m.id, name: m.name, kind: "knowledge-doc", updatedAt: m.updatedAt, content };
11763
11774
  }));
11764
- const ms = Date.now() - start;
11765
- console.log(`[admin/sidebar-artefacts] account=${accountId} count=${artefacts.length} ms=${ms}`);
11766
- return c.json({ artefacts });
11767
- });
11775
+ }
11768
11776
  async function readArtefactContent(accountId, attachmentId, mimeType) {
11769
11777
  if (!attachmentId) return "";
11770
11778
  const isText = TEXT_MIME_PREFIXES.some((p) => mimeType.startsWith(p));
@@ -11787,6 +11795,105 @@ async function readArtefactContent(accountId, attachmentId, mimeType) {
11787
11795
  return "";
11788
11796
  }
11789
11797
  }
11798
+ async function fetchAgentTemplateRows(accountDir) {
11799
+ const rows = [];
11800
+ for (const filename of ADMIN_AGENT_FILES) {
11801
+ const overridePath = resolve20(accountDir, "agents", "admin", filename);
11802
+ const bundledPath = resolve20(PLATFORM_ROOT, "templates", "agents", "admin", filename);
11803
+ const labelStem = filename.replace(/\.md$/, "");
11804
+ const row = await readAgentTemplateRow({
11805
+ id: `agent-template:admin:${filename}`,
11806
+ displayName: `Admin \xB7 ${labelStem}`,
11807
+ logName: `admin/${filename}`,
11808
+ overridePath,
11809
+ overrideRoot: accountDir,
11810
+ bundledPath,
11811
+ bundledRoot: PLATFORM_ROOT
11812
+ });
11813
+ if (row) rows.push(row);
11814
+ }
11815
+ const overrideDir = resolve20(accountDir, "specialists", "agents");
11816
+ const bundledDir = resolve20(PLATFORM_ROOT, "templates", "specialists", "agents");
11817
+ const specialistNames = await unionSpecialistFilenames(overrideDir, bundledDir);
11818
+ for (const filename of specialistNames) {
11819
+ const overridePath = resolve20(overrideDir, filename);
11820
+ const bundledPath = resolve20(bundledDir, filename);
11821
+ const row = await readAgentTemplateRow({
11822
+ id: `agent-template:specialist:${filename}`,
11823
+ displayName: filename.replace(/\.md$/, ""),
11824
+ logName: `specialist/${filename}`,
11825
+ overridePath,
11826
+ overrideRoot: accountDir,
11827
+ bundledPath,
11828
+ bundledRoot: PLATFORM_ROOT
11829
+ });
11830
+ if (row) rows.push(row);
11831
+ }
11832
+ return rows;
11833
+ }
11834
+ async function unionSpecialistFilenames(overrideDir, bundledDir) {
11835
+ const names = /* @__PURE__ */ new Set();
11836
+ for (const dir of [overrideDir, bundledDir]) {
11837
+ if (!existsSync19(dir)) continue;
11838
+ try {
11839
+ const entries = await readdir3(dir);
11840
+ for (const entry of entries) {
11841
+ if (entry.endsWith(".md")) names.add(entry);
11842
+ }
11843
+ } catch (err) {
11844
+ const message = err instanceof Error ? err.message : String(err);
11845
+ console.error(`[admin/sidebar-artefacts] specialists-read-failed dir=${dir} error="${message}"`);
11846
+ }
11847
+ }
11848
+ return [...names].sort();
11849
+ }
11850
+ async function readAgentTemplateRow(inp) {
11851
+ let chosenPath = null;
11852
+ if (existsSync19(inp.overridePath)) {
11853
+ try {
11854
+ validateFilePathInAccount(inp.overridePath, inp.overrideRoot);
11855
+ chosenPath = inp.overridePath;
11856
+ } catch (err) {
11857
+ const message = err instanceof Error ? err.message : String(err);
11858
+ console.error(
11859
+ `[admin/sidebar-artefacts] agent-template-read-failed agent=${inp.displayName} kind=${inp.logName} error="${message}"`
11860
+ );
11861
+ return null;
11862
+ }
11863
+ } else if (existsSync19(inp.bundledPath)) {
11864
+ if (!isWithin(inp.bundledPath, inp.bundledRoot)) {
11865
+ console.error(
11866
+ `[admin/sidebar-artefacts] agent-template-read-failed agent=${inp.displayName} kind=${inp.logName} error="bundled path outside PLATFORM_ROOT"`
11867
+ );
11868
+ return null;
11869
+ }
11870
+ chosenPath = inp.bundledPath;
11871
+ }
11872
+ if (!chosenPath) return null;
11873
+ try {
11874
+ const [content, st] = await Promise.all([
11875
+ readFile5(chosenPath, "utf-8"),
11876
+ stat5(chosenPath)
11877
+ ]);
11878
+ return {
11879
+ id: inp.id,
11880
+ name: inp.displayName,
11881
+ kind: "agent-template",
11882
+ updatedAt: st.mtime.toISOString(),
11883
+ content
11884
+ };
11885
+ } catch (err) {
11886
+ const message = err instanceof Error ? err.message : String(err);
11887
+ console.error(
11888
+ `[admin/sidebar-artefacts] agent-template-read-failed agent=${inp.displayName} kind=${inp.logName} error="${message}"`
11889
+ );
11890
+ return null;
11891
+ }
11892
+ }
11893
+ function isWithin(target, root) {
11894
+ const rel = relative2(root, target);
11895
+ return !rel.startsWith("..") && !isAbsolute(rel);
11896
+ }
11790
11897
  var sidebar_artefacts_default = app32;
11791
11898
 
11792
11899
  // server/routes/admin/index.ts
@@ -11916,10 +12023,10 @@ function clientFrom(c) {
11916
12023
  var PLATFORM_ROOT7 = process.env.MAXY_PLATFORM_ROOT || "";
11917
12024
  var BRAND_JSON_PATH = PLATFORM_ROOT7 ? join10(PLATFORM_ROOT7, "config", "brand.json") : "";
11918
12025
  var BRAND = { productName: "Maxy", hostname: "maxy", configDir: ".maxy", domain: "getmaxy.com" };
11919
- if (BRAND_JSON_PATH && !existsSync19(BRAND_JSON_PATH)) {
12026
+ if (BRAND_JSON_PATH && !existsSync20(BRAND_JSON_PATH)) {
11920
12027
  console.error(`[brand] WARNING: brand.json not found at ${BRAND_JSON_PATH} \u2014 using Maxy defaults`);
11921
12028
  }
11922
- if (BRAND_JSON_PATH && existsSync19(BRAND_JSON_PATH)) {
12029
+ if (BRAND_JSON_PATH && existsSync20(BRAND_JSON_PATH)) {
11923
12030
  try {
11924
12031
  const parsed = JSON.parse(readFileSync16(BRAND_JSON_PATH, "utf-8"));
11925
12032
  BRAND = { ...BRAND, ...parsed };
@@ -11943,7 +12050,7 @@ var brandLoginOpts = {
11943
12050
  var ALIAS_DOMAINS_PATH2 = join10(homedir2(), BRAND.configDir, "alias-domains.json");
11944
12051
  function loadAliasDomains() {
11945
12052
  try {
11946
- if (!existsSync19(ALIAS_DOMAINS_PATH2)) return null;
12053
+ if (!existsSync20(ALIAS_DOMAINS_PATH2)) return null;
11947
12054
  const parsed = JSON.parse(readFileSync16(ALIAS_DOMAINS_PATH2, "utf-8"));
11948
12055
  if (!Array.isArray(parsed)) {
11949
12056
  console.error("[alias-domains] malformed alias-domains.json \u2014 expected array");
@@ -12289,7 +12396,7 @@ app34.get("/agent-assets/:slug/:filename", (c) => {
12289
12396
  console.error(`[agent-assets] path-traversal-rejected slug=${slug} file=${filename}`);
12290
12397
  return c.text("Forbidden", 403);
12291
12398
  }
12292
- if (!existsSync19(filePath)) {
12399
+ if (!existsSync20(filePath)) {
12293
12400
  console.error(`[agent-assets] serve slug=${slug} file=${filename} status=404`);
12294
12401
  return c.text("Not found", 404);
12295
12402
  }
@@ -12319,7 +12426,7 @@ app34.get("/generated/:filename", (c) => {
12319
12426
  console.error(`[generated] serve file=${filename} status=403`);
12320
12427
  return c.text("Forbidden", 403);
12321
12428
  }
12322
- if (!existsSync19(filePath)) {
12429
+ if (!existsSync20(filePath)) {
12323
12430
  console.error(`[generated] serve file=${filename} status=404`);
12324
12431
  return c.text("Not found", 404);
12325
12432
  }
@@ -12335,7 +12442,7 @@ app34.get("/generated/:filename", (c) => {
12335
12442
  var htmlCache = /* @__PURE__ */ new Map();
12336
12443
  var brandLogoPath = "/brand/maxy-monochrome.png";
12337
12444
  var brandIconPath = "/brand/maxy-monochrome.png";
12338
- if (BRAND_JSON_PATH && existsSync19(BRAND_JSON_PATH)) {
12445
+ if (BRAND_JSON_PATH && existsSync20(BRAND_JSON_PATH)) {
12339
12446
  try {
12340
12447
  const fullBrand = JSON.parse(readFileSync16(BRAND_JSON_PATH, "utf-8"));
12341
12448
  if (fullBrand.assets?.logo) brandLogoPath = `/brand/${fullBrand.assets.logo}`;
@@ -12355,7 +12462,7 @@ function readInstalledVersion() {
12355
12462
  try {
12356
12463
  if (!PLATFORM_ROOT7) return "unknown";
12357
12464
  const versionFile = join10(PLATFORM_ROOT7, "config", `.${BRAND.hostname}-version`);
12358
- if (!existsSync19(versionFile)) return "unknown";
12465
+ if (!existsSync20(versionFile)) return "unknown";
12359
12466
  const content = readFileSync16(versionFile, "utf-8").trim();
12360
12467
  return content || "unknown";
12361
12468
  } catch {
@@ -12416,12 +12523,12 @@ function loadBrandingCache(agentSlug) {
12416
12523
  const configDir2 = join10(homedir2(), BRAND.configDir);
12417
12524
  try {
12418
12525
  const accountJsonPath = join10(configDir2, "account.json");
12419
- if (!existsSync19(accountJsonPath)) return null;
12526
+ if (!existsSync20(accountJsonPath)) return null;
12420
12527
  const account = JSON.parse(readFileSync16(accountJsonPath, "utf-8"));
12421
12528
  const accountId = account.accountId;
12422
12529
  if (!accountId) return null;
12423
12530
  const cachePath = join10(configDir2, "branding-cache", accountId, `${agentSlug}.json`);
12424
- if (!existsSync19(cachePath)) return null;
12531
+ if (!existsSync20(cachePath)) return null;
12425
12532
  return JSON.parse(readFileSync16(cachePath, "utf-8"));
12426
12533
  } catch {
12427
12534
  return null;
@@ -12431,7 +12538,7 @@ function resolveDefaultSlug() {
12431
12538
  try {
12432
12539
  const configDir2 = join10(homedir2(), BRAND.configDir);
12433
12540
  const accountJsonPath = join10(configDir2, "account.json");
12434
- if (!existsSync19(accountJsonPath)) return null;
12541
+ if (!existsSync20(accountJsonPath)) return null;
12435
12542
  const account = JSON.parse(readFileSync16(accountJsonPath, "utf-8"));
12436
12543
  return account.defaultAgent || null;
12437
12544
  } catch {
@@ -12595,7 +12702,7 @@ try {
12595
12702
  (async () => {
12596
12703
  try {
12597
12704
  let userId = "";
12598
- if (existsSync19(USERS_FILE)) {
12705
+ if (existsSync20(USERS_FILE)) {
12599
12706
  const users = JSON.parse(readFileSync16(USERS_FILE, "utf-8").trim() || "[]");
12600
12707
  userId = users[0]?.userId ?? "";
12601
12708
  }