@rubytech/create-maxy-code 0.1.454 → 0.1.456

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 (94) hide show
  1. package/package.json +1 -1
  2. package/payload/platform/plugins/admin/.claude-plugin/plugin.json +1 -1
  3. package/payload/platform/plugins/admin/PLUGIN.md +1 -1
  4. package/payload/platform/plugins/admin/mcp/dist/index.js +24 -6
  5. package/payload/platform/plugins/admin/mcp/dist/index.js.map +1 -1
  6. package/payload/platform/plugins/admin/mcp/dist/tools/account-lifecycle.d.ts +10 -0
  7. package/payload/platform/plugins/admin/mcp/dist/tools/account-lifecycle.d.ts.map +1 -1
  8. package/payload/platform/plugins/admin/mcp/dist/tools/account-lifecycle.js +44 -4
  9. package/payload/platform/plugins/admin/mcp/dist/tools/account-lifecycle.js.map +1 -1
  10. package/payload/platform/plugins/admin/skills/platform-architecture/SKILL.md +3 -2
  11. package/payload/platform/plugins/docs/references/outlook-guide.md +2 -1
  12. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/profile-update-bootstrap.test.js +52 -0
  13. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/profile-update-bootstrap.test.js.map +1 -1
  14. package/payload/platform/plugins/memory/mcp/dist/tools/profile-update.js +11 -0
  15. package/payload/platform/plugins/memory/mcp/dist/tools/profile-update.js.map +1 -1
  16. package/payload/platform/plugins/outlook/.claude-plugin/plugin.json +1 -1
  17. package/payload/platform/plugins/outlook/PLUGIN.md +6 -2
  18. package/payload/platform/plugins/outlook/mcp/dist/__tests__/has-attachments.test.d.ts +2 -0
  19. package/payload/platform/plugins/outlook/mcp/dist/__tests__/has-attachments.test.d.ts.map +1 -0
  20. package/payload/platform/plugins/outlook/mcp/dist/__tests__/has-attachments.test.js +66 -0
  21. package/payload/platform/plugins/outlook/mcp/dist/__tests__/has-attachments.test.js.map +1 -0
  22. package/payload/platform/plugins/outlook/mcp/dist/__tests__/mail-attachment.test.d.ts +2 -0
  23. package/payload/platform/plugins/outlook/mcp/dist/__tests__/mail-attachment.test.d.ts.map +1 -0
  24. package/payload/platform/plugins/outlook/mcp/dist/__tests__/mail-attachment.test.js +195 -0
  25. package/payload/platform/plugins/outlook/mcp/dist/__tests__/mail-attachment.test.js.map +1 -0
  26. package/payload/platform/plugins/outlook/mcp/dist/index.js +19 -0
  27. package/payload/platform/plugins/outlook/mcp/dist/index.js.map +1 -1
  28. package/payload/platform/plugins/outlook/mcp/dist/tools/mail-attachment.d.ts +55 -0
  29. package/payload/platform/plugins/outlook/mcp/dist/tools/mail-attachment.d.ts.map +1 -0
  30. package/payload/platform/plugins/outlook/mcp/dist/tools/mail-attachment.js +130 -0
  31. package/payload/platform/plugins/outlook/mcp/dist/tools/mail-attachment.js.map +1 -0
  32. package/payload/platform/plugins/outlook/mcp/dist/tools/mail-fetch-body.d.ts +1 -0
  33. package/payload/platform/plugins/outlook/mcp/dist/tools/mail-fetch-body.d.ts.map +1 -1
  34. package/payload/platform/plugins/outlook/mcp/dist/tools/mail-fetch-body.js +2 -1
  35. package/payload/platform/plugins/outlook/mcp/dist/tools/mail-fetch-body.js.map +1 -1
  36. package/payload/platform/plugins/outlook/mcp/dist/tools/mail-list.d.ts +4 -0
  37. package/payload/platform/plugins/outlook/mcp/dist/tools/mail-list.d.ts.map +1 -1
  38. package/payload/platform/plugins/outlook/mcp/dist/tools/mail-list.js +2 -1
  39. package/payload/platform/plugins/outlook/mcp/dist/tools/mail-list.js.map +1 -1
  40. package/payload/platform/plugins/outlook/mcp/dist/tools/mail-search.d.ts.map +1 -1
  41. package/payload/platform/plugins/outlook/mcp/dist/tools/mail-search.js +2 -1
  42. package/payload/platform/plugins/outlook/mcp/dist/tools/mail-search.js.map +1 -1
  43. package/payload/platform/plugins/outlook/references/graph-surfaces.md +18 -3
  44. package/payload/platform/plugins/outlook/skills/outlook/SKILL.md +2 -0
  45. package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/getUserTimezone.test.js +87 -67
  46. package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/getUserTimezone.test.js.map +1 -1
  47. package/payload/platform/plugins/scheduling/mcp/dist/lib/neo4j.d.ts +37 -11
  48. package/payload/platform/plugins/scheduling/mcp/dist/lib/neo4j.d.ts.map +1 -1
  49. package/payload/platform/plugins/scheduling/mcp/dist/lib/neo4j.js +56 -14
  50. package/payload/platform/plugins/scheduling/mcp/dist/lib/neo4j.js.map +1 -1
  51. package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.d.ts.map +1 -1
  52. package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.js +1 -0
  53. package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.js.map +1 -1
  54. package/payload/platform/templates/specialists/agents/personal-assistant.md +1 -1
  55. package/payload/server/{chunk-WC4WJR6X.js → chunk-F4D35LKL.js} +7 -3
  56. package/payload/server/maxy-edge.js +1 -1
  57. package/payload/server/public/assets/{AdminLoginScreens-5R0A40Is.js → AdminLoginScreens-Cl7VBbPS.js} +1 -1
  58. package/payload/server/public/assets/{AdminShell-B2HeKInP.js → AdminShell-lBaQG3aT.js} +1 -1
  59. package/payload/server/public/assets/{Checkbox-yjCERU3B.js → Checkbox-P8PNtn8n.js} +1 -1
  60. package/payload/server/public/assets/{admin-BDio0OER.js → admin-CB6VgLUJ.js} +1 -1
  61. package/payload/server/public/assets/{browser-bSeWXhod.js → browser-CKH8YoIg.js} +1 -1
  62. package/payload/server/public/assets/{calendar-MNAmsxL3.js → calendar-xQ-OEVti.js} +1 -1
  63. package/payload/server/public/assets/chat-DH8K5TeZ.js +1 -0
  64. package/payload/server/public/assets/chevron-left-Ceky-ebO.js +1 -0
  65. package/payload/server/public/assets/data-Cvv8Kg9J.js +1 -0
  66. package/payload/server/public/assets/{graph-DRWRwsUZ.js → graph-CrEmAyVE.js} +2 -2
  67. package/payload/server/public/assets/{graph-labels-Cy7GyGln.js → graph-labels-DbL7Cxod.js} +1 -1
  68. package/payload/server/public/assets/{maximize-2-BRHW5pKh.js → maximize-2-Up8UP3Iu.js} +1 -1
  69. package/payload/server/public/assets/{operator-Dv2k2JaW.js → operator-BE366HH-.js} +1 -1
  70. package/payload/server/public/assets/{page-BZRZZcqM.js → page-CQjjQz0V.js} +1 -1
  71. package/payload/server/public/assets/{page-CoBzMOIg.js → page-Wvb1S03b.js} +1 -1
  72. package/payload/server/public/assets/{public-CirpatD6.js → public-ZkXB-CHy.js} +1 -1
  73. package/payload/server/public/assets/{rotate-ccw-tv1JxnBS.js → rotate-ccw-TTz_MVO0.js} +1 -1
  74. package/payload/server/public/assets/{tasks-B8iXIZ3w.js → tasks-DNCoSRkP.js} +1 -1
  75. package/payload/server/public/assets/{time-entry-format-MGC9wMbZ.js → time-entry-format-BooKdDRT.js} +1 -1
  76. package/payload/server/public/assets/{useCopyFeedback-DdwMdpa-.js → useCopyFeedback-C23_n92I.js} +1 -1
  77. package/payload/server/public/assets/{useSelectionMode-DyoyGg7d.js → useSelectionMode-c4oZYAW0.js} +1 -1
  78. package/payload/server/public/assets/{useSubAccountSwitcher-CMi8n_8S.css → useSubAccountSwitcher-CHJo5leK.css} +1 -1
  79. package/payload/server/public/assets/{useVoiceRecorder-BDtJhfh_.js → useVoiceRecorder-BkxW-GL1.js} +1 -1
  80. package/payload/server/public/browser.html +5 -5
  81. package/payload/server/public/calendar.html +6 -6
  82. package/payload/server/public/chat.html +12 -12
  83. package/payload/server/public/data.html +10 -10
  84. package/payload/server/public/graph.html +11 -11
  85. package/payload/server/public/index.html +13 -13
  86. package/payload/server/public/operator.html +14 -14
  87. package/payload/server/public/public.html +12 -12
  88. package/payload/server/public/tasks.html +5 -5
  89. package/payload/server/server.js +1 -1
  90. package/payload/server/{userprofile-reconcile-GLGKDVQQ.js → userprofile-reconcile-QHVLY2AH.js} +12 -2
  91. package/payload/server/public/assets/chat-Bq4Uq3Ht.js +0 -1
  92. package/payload/server/public/assets/chevron-left-D5XwUM2x.js +0 -1
  93. package/payload/server/public/assets/data-DY10qHOy.js +0 -1
  94. /package/payload/server/public/assets/{useSubAccountSwitcher-B_zj_dY-.js → useSubAccountSwitcher-6UoTftbJ.js} +0 -0
@@ -43,7 +43,7 @@ const WELL_KNOWN_ALIASES = {
43
43
  archive: "archive",
44
44
  outbox: "outbox",
45
45
  };
46
- const FIELDS = "id,subject,from,receivedDateTime,bodyPreview,isRead";
46
+ const FIELDS = "id,subject,from,receivedDateTime,bodyPreview,isRead,hasAttachments";
47
47
  function toGraphDate(input, field) {
48
48
  const d = new Date(input);
49
49
  if (!Number.isFinite(d.getTime())) {
@@ -127,6 +127,7 @@ function shapeMessage(msg) {
127
127
  receivedDateTime: msg.receivedDateTime,
128
128
  bodyPreview: (msg.bodyPreview ?? "").slice(0, 1024),
129
129
  isRead: msg.isRead ?? false,
130
+ hasAttachments: msg.hasAttachments ?? false,
130
131
  };
131
132
  }
132
133
  function clampTop(input, fallback) {
@@ -1 +1 @@
1
- {"version":3,"file":"mail-list.js","sourceRoot":"","sources":["../../src/tools/mail-list.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"mail-list.js","sourceRoot":"","sources":["../../src/tools/mail-list.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"mail-search.d.ts","sourceRoot":"","sources":["../../src/tools/mail-search.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAGhE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAEnD,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;;;;OAIG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAWD,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,YAAY,EAAE,CAAC;IACtB,4DAA4D;IAC5D,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAID,wBAAsB,aAAa,CACjC,MAAM,EAAE,iBAAiB,EACzB,IAAI,EAAE,cAAc,GACnB,OAAO,CAAC,gBAAgB,CAAC,CA8C3B"}
1
+ {"version":3,"file":"mail-search.d.ts","sourceRoot":"","sources":["../../src/tools/mail-search.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAGhE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAEnD,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;;;;OAIG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAYD,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,YAAY,EAAE,CAAC;IACtB,4DAA4D;IAC5D,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAID,wBAAsB,aAAa,CACjC,MAAM,EAAE,iBAAiB,EACzB,IAAI,EAAE,cAAc,GACnB,OAAO,CAAC,gBAAgB,CAAC,CA+C3B"}
@@ -1,6 +1,6 @@
1
1
  import { callGraphPaged } from "../lib/graph-client.js";
2
2
  import { log, trunc } from "../lib/log.js";
3
- const FIELDS = "id,subject,from,receivedDateTime,bodyPreview,isRead";
3
+ const FIELDS = "id,subject,from,receivedDateTime,bodyPreview,isRead,hasAttachments";
4
4
  export async function runMailSearch(config, args) {
5
5
  const top = clampTop(args.top, 25);
6
6
  const query = args.query.trim();
@@ -30,6 +30,7 @@ export async function runMailSearch(config, args) {
30
30
  receivedDateTime: msg.receivedDateTime,
31
31
  bodyPreview: (msg.bodyPreview ?? "").slice(0, 1024),
32
32
  isRead: msg.isRead ?? false,
33
+ hasAttachments: msg.hasAttachments ?? false,
33
34
  }));
34
35
  log({
35
36
  event: "mail-search",
@@ -1 +1 @@
1
- {"version":3,"file":"mail-search.js","sourceRoot":"","sources":["../../src/tools/mail-search.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"mail-search.js","sourceRoot":"","sources":["../../src/tools/mail-search.ts"],"names":[],"mappings":"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"}
@@ -4,7 +4,7 @@ Microsoft Graph endpoints used by each tool, with the response shape and the fie
4
4
 
5
5
  ## outlook-mail-list
6
6
 
7
- **Endpoint (Inbox):** `GET /me/mailFolders/Inbox/messages?$top={N}&$orderby=receivedDateTime DESC&$select=id,subject,from,receivedDateTime,bodyPreview,isRead`
7
+ **Endpoint (Inbox):** `GET /me/mailFolders/Inbox/messages?$top={N}&$orderby=receivedDateTime DESC&$select=id,subject,from,receivedDateTime,bodyPreview,isRead,hasAttachments`
8
8
 
9
9
  **Endpoint (other folder):** `GET /me/mailFolders/{well-known-token-or-folderId}/messages?...`
10
10
 
@@ -43,7 +43,7 @@ Any value not in this table is treated as a raw folder id and passed through unc
43
43
 
44
44
  ## outlook-mail-search
45
45
 
46
- **Endpoint:** `GET /me/messages?$search="{query}"&$top={N}&$select=id,subject,from,receivedDateTime,bodyPreview,isRead`
46
+ **Endpoint:** `GET /me/messages?$search="{query}"&$top={N}&$select=id,subject,from,receivedDateTime,bodyPreview,isRead,hasAttachments`
47
47
 
48
48
  **Required header:** `ConsistencyLevel: eventual` (Graph requirement for `$search`).
49
49
 
@@ -55,7 +55,7 @@ Any value not in this table is treated as a raw folder id and passed through unc
55
55
 
56
56
  ## outlook-mail-fetch-body
57
57
 
58
- **Endpoint:** `GET /me/messages/{id}?$select=id,subject,from,toRecipients,ccRecipients,receivedDateTime,conversationId,isRead,body`
58
+ **Endpoint:** `GET /me/messages/{id}?$select=id,subject,from,toRecipients,ccRecipients,receivedDateTime,conversationId,isRead,hasAttachments,body`
59
59
 
60
60
  Reads the COMPLETE body (not `bodyPreview`). `body.contentType` is `html` or `text`; HTML is decoded to plain text (`lib/html-to-text.ts`). No preview cap — this is the full-read path that `outlook-mail-list`/`-search` (preview only) do not provide. Never falls back to `bodyPreview`; the logged `bytes` surfaces a shortfall.
61
61
 
@@ -70,11 +70,26 @@ Reads the COMPLETE body (not `bodyPreview`). `body.contentType` is `html` or `te
70
70
  receivedDateTime: string;
71
71
  conversationId: string | null;
72
72
  isRead: boolean;
73
+ hasAttachments: boolean; // Graph flag; true when the message carries enclosures
73
74
  contentType: "html" | "text";
74
75
  body: string; // full, decoded
75
76
  }
76
77
  ```
77
78
 
79
+ `hasAttachments` is also on `outlook-mail-list` / `outlook-mail-search` items (each `$select` now carries it), so the preview tools flag an enclosure before the agent fetches the body or the attachment.
80
+
81
+ ## outlook-mail-attachment
82
+
83
+ **List endpoint:** `GET /me/messages/{id}/attachments?$select=id,name,contentType,size,isInline` — metadata only; `$select` omits `contentBytes`, so no bytes are downloaded. Each item's `@odata.type` maps to a `kind`: `#microsoft.graph.fileAttachment` → `file`, `#microsoft.graph.itemAttachment` → `item`, `#microsoft.graph.referenceAttachment` → `reference` (anything else → `unknown`).
84
+
85
+ **Download endpoint:** `GET /me/messages/{id}/attachments/{attachmentId}` — the full attachment object, including base64 `contentBytes` for a `fileAttachment`. The bytes are decoded and written to `{accountDir}/uploads/outlook/<sha256(messageId)[:16]>/<sha256(bytes)[:16]>-<safeName>` at mode `0o600`; the write is re-stat-verified before the path is returned. `resolveAccountDir` (shared with `outlook-mail-reply`) locates the account directory; the 25 MB cap is `OUTLOOK_ATTACHMENT_MAX_BYTES`.
86
+
87
+ **Refusals (nothing written):** a non-`file` kind (`Cannot download <kind> attachment …`), an empty/absent `contentBytes` (`… returned no bytes`), a declared or decoded size over the 25 MB cap (`… too large …`), and no resolvable account directory. Each refusal logs `[mail-attachment] op=refuse … reason=<reason>`.
88
+
89
+ **Returned shapes:** list → `{ items: [{ id, name, contentType, size, isInline, kind }] }`; download → `{ path, name, contentType, bytes }`.
90
+
91
+ **Scope:** `Mail.Read` (read-only; the same scope the read tools use).
92
+
78
93
  ## outlook-mail-reply
79
94
 
80
95
  **Endpoints (in order):**
@@ -52,6 +52,8 @@ The revoke path below is scoped to one specific, visible failure. It is not a ge
52
52
  - `outlook-mail-list` — mail newest-first, default top=25, folder=Inbox. Returns Microsoft's short `bodyPreview` (~255 chars) for cheap triage. Add `since`/`before` (ISO date-times) for a date window. To reach mail older than the newest page, pass the response's `nextCursor` back as `cursor` — repeat until `nextCursor` is null. Filter by sender or subject via `outlook-mail-search`.
53
53
  - `outlook-mail-search query=<keyword>` — Microsoft Graph `$search` (KQL) over the mailbox; same preview-only shape as the list. Put filters in the query: `from:addr`, `to:addr`, `subject:text`, `received>=2024-01-01`, or free text. Page with `nextCursor` → `cursor` like the list. (Graph forbids `$search`+date-`$filter`, so a strict date window is on `outlook-mail-list`.)
54
54
  - `outlook-mail-fetch-body messageId=<id>` — the COMPLETE body of one message (HTML decoded to text, no preview cap). This is the full-read path: `outlook-mail-list` / `outlook-mail-search` return previews only, so when you must read or act on a message's actual content, fetch the body by its id. Also returns the envelope (from, to, cc, subject, date, conversationId).
55
+ - `outlook-mail-attachment messageId=<id>` — LIST a message's attachments (`id`, `name`, `contentType`, `size`, `isInline`, `kind`). `outlook-mail-list` / `outlook-mail-search` / `outlook-mail-fetch-body` all report `hasAttachments`; when it is true, call this to see what is attached.
56
+ - `outlook-mail-attachment messageId=<id> attachmentId=<id>` — DOWNLOAD one file attachment. The bytes are saved under the account's `uploads/outlook` folder and the absolute path is returned, ready for the Read tool, `SendUserFile`, or an `outlook-mail-reply` attachment. Only file attachments download: `item` and `reference` kinds are refused, as are empty payloads and anything over 25 MB. Needs `Mail.Read`.
55
57
 
56
58
  ## Replying and deleting
57
59
 
@@ -1,17 +1,24 @@
1
1
  /**
2
- * UserProfile reads keyed by (accountId, userId).
2
+ * UserProfile timezone reads resolve the account's seeded OWNER, not the
3
+ * acting session user (Task 1684).
3
4
  *
4
- * These tests pin the read doctrine on the scheduling lib's getUserTimezone:
5
- * - Missing userId is a caller bug, surfaced as MissingUserIdError, not as
6
- * a silent widening to an account-wide read.
7
- * - The cypher predicates BOTH accountId AND userId the discriminating
8
- * anti-regression check that prevents reversion to bare-accountId reads.
9
- * - The "no timezone" error message names the exact UserProfile target so
10
- * the operator can update the same row that was read.
5
+ * A house operator acting inside a client sub-account has no UserProfile
6
+ * scoped to that account; the account owner's profile is authoritative
7
+ * (mirrors the 1557/1564 owner-resolution). These tests pin:
8
+ * - Missing acting userId is still a caller bug (MissingUserIdError),
9
+ * surfaced before any query the read never widens account-wide.
10
+ * - When the account has a seeded owner, the profile read is keyed on the
11
+ * OWNER's userId, not the acting user's the discriminating check that
12
+ * prevents reversion to acting-user reads.
13
+ * - When the account has NO seeded owner (legacy), it falls back to the
14
+ * acting user's profile.
15
+ * - The profile read still predicates BOTH accountId AND userId.
16
+ * - The "no profile" / "no timezone" errors name the RESOLVED owner row so
17
+ * a profile-update writes and reads the same row.
11
18
  *
12
- * The Neo4j driver is mocked through vi.mock so these tests never need a
13
- * live database. Tests are colocated under src/lib/__tests__/ to match the
14
- * codebase convention (memory plugin).
19
+ * The Neo4j driver is mocked through vi.mock so these tests never need a live
20
+ * database. The single mocked session.run serves both queries in order:
21
+ * run #1 is the owner-resolution query, run #2 is the profile read.
15
22
  */
16
23
  import { describe, it, expect, beforeEach, vi } from "vitest";
17
24
  const mockRun = vi.fn();
@@ -34,23 +41,27 @@ vi.mock("neo4j-driver", () => {
34
41
  process.env.NEO4J_URI = "bolt://localhost:7687";
35
42
  process.env.NEO4J_PASSWORD = "test";
36
43
  const { getUserTimezone, MissingUserIdError } = await import("../neo4j.js");
37
- function makeRecord(timezone) {
44
+ function tzRecord(timezone) {
38
45
  return { get: (key) => (key === "timezone" ? timezone : null) };
39
46
  }
40
- describe("getUserTimezone read doctrine", () => {
47
+ function ownerRecord(userId) {
48
+ return { get: (key) => (key === "userId" ? userId : null) };
49
+ }
50
+ /** Queue the two run() results for one getUserTimezone call: owner, then profile. */
51
+ function queue(owner, tz) {
52
+ mockRun.mockResolvedValueOnce({ records: owner ? [ownerRecord(owner)] : [] });
53
+ mockRun.mockResolvedValueOnce({ records: tz === "no-row" ? [] : [tzRecord(tz)] });
54
+ }
55
+ describe("getUserTimezone owner-resolution (Task 1684)", () => {
41
56
  beforeEach(() => {
42
57
  mockRun.mockReset();
43
58
  mockClose.mockClear();
44
59
  });
45
- it("throws MissingUserIdError when userId is empty string", async () => {
60
+ it("throws MissingUserIdError when acting userId is empty string — no query runs", async () => {
46
61
  await expect(getUserTimezone("acct-abc12345", "")).rejects.toBeInstanceOf(MissingUserIdError);
47
- // Read-side guard fires before any session.run, so no query is made.
48
62
  expect(mockRun).not.toHaveBeenCalled();
49
63
  });
50
- it("throws MissingUserIdError when userId is null/undefined", async () => {
51
- // The signature is (accountId, userId: string), but at runtime callers can
52
- // still pass undefined/null when their own wiring is broken — the lib is
53
- // the last line of defence.
64
+ it("throws MissingUserIdError when acting userId is null/undefined — no query runs", async () => {
54
65
  await expect(
55
66
  // @ts-expect-error — exercising runtime-undefined case
56
67
  getUserTimezone("acct-abc12345", undefined)).rejects.toBeInstanceOf(MissingUserIdError);
@@ -59,61 +70,70 @@ describe("getUserTimezone read doctrine", () => {
59
70
  getUserTimezone("acct-abc12345", null)).rejects.toBeInstanceOf(MissingUserIdError);
60
71
  expect(mockRun).not.toHaveBeenCalled();
61
72
  });
62
- it("returns the timezone for the matched (accountId, userId)", async () => {
63
- mockRun.mockResolvedValueOnce({ records: [makeRecord("Europe/London")] });
64
- const tz = await getUserTimezone("acct-abc12345", "user-xyz98765");
73
+ it("reads the OWNER's profile, not the acting user's, when the account has a seeded owner", async () => {
74
+ // Acting user = house operator with no profile in this account; owner has
75
+ // the Europe/London card. The scheduler must return the owner's tz.
76
+ queue("owner-3f81e7c2", "Europe/London");
77
+ const tz = await getUserTimezone("acct-2078cb54", "operator-436fdf2d");
65
78
  expect(tz).toBe("Europe/London");
79
+ // Two queries: owner-resolution, then the profile read.
80
+ expect(mockRun).toHaveBeenCalledTimes(2);
81
+ // The owner-resolution query keys on role:'owner'.
82
+ expect(mockRun.mock.calls[0][0]).toMatch(/role:\s*'owner'/);
83
+ expect(mockRun.mock.calls[0][1]).toEqual({ accountId: "acct-2078cb54" });
84
+ // The profile read is keyed on the OWNER userId — NOT the acting operator.
85
+ expect(mockRun.mock.calls[1][1]).toEqual({
86
+ accountId: "acct-2078cb54",
87
+ userId: "owner-3f81e7c2",
88
+ });
89
+ });
90
+ it("falls back to the acting user's profile when the account has NO seeded owner (legacy)", async () => {
91
+ queue(null, "America/Toronto");
92
+ const tz = await getUserTimezone("acct-legacy999", "acting-user-777");
93
+ expect(tz).toBe("America/Toronto");
94
+ // Profile read falls back to the acting user id.
95
+ expect(mockRun).toHaveBeenCalledTimes(2);
96
+ expect(mockRun.mock.calls[1][1]).toEqual({
97
+ accountId: "acct-legacy999",
98
+ userId: "acting-user-777",
99
+ });
100
+ });
101
+ it("operator acting in their own single-identity account resolves the same profile (no regression)", async () => {
102
+ // Owner-resolution returns the acting user itself; behaviour matches the
103
+ // pre-1684 single-identity read.
104
+ queue("acting-user-777", "Europe/Berlin");
105
+ const tz = await getUserTimezone("acct-solo", "acting-user-777");
106
+ expect(tz).toBe("Europe/Berlin");
107
+ expect(mockRun.mock.calls[1][1]).toEqual({
108
+ accountId: "acct-solo",
109
+ userId: "acting-user-777",
110
+ });
66
111
  });
67
- it("query keys on BOTH accountId AND userId — discriminating anti-regression check", async () => {
68
- mockRun.mockResolvedValueOnce({ records: [makeRecord("America/Toronto")] });
69
- await getUserTimezone("acct-abc12345", "user-xyz98765");
70
- expect(mockRun).toHaveBeenCalledTimes(1);
71
- const [query, params] = mockRun.mock.calls[0];
112
+ it("profile read predicates BOTH accountId AND userId — anti-regression against a bare-accountId read", async () => {
113
+ queue("owner-3f81e7c2", "Europe/London");
114
+ await getUserTimezone("acct-2078cb54", "operator-436fdf2d");
115
+ const [query] = mockRun.mock.calls[1];
72
116
  expect(query).toMatch(/accountId:\s*\$accountId/);
73
117
  expect(query).toMatch(/userId:\s*\$userId/);
74
- expect(params).toEqual({ accountId: "acct-abc12345", userId: "user-xyz98765" });
75
118
  });
76
- it("throws with the new error-message text when matched UserProfile has timezone=NULL", async () => {
77
- // userId.slice(0, 8) of "user-xyz98765" = "user-xyz" — pin the slice
78
- // shape so a future change to slice length surfaces here, not silently.
79
- mockRun.mockResolvedValueOnce({ records: [makeRecord(null)] });
80
- await expect(getUserTimezone("acct-abc12345", "user-xyz98765")).rejects.toThrow(/No timezone on UserProfile for userId user-xyz/);
81
- mockRun.mockResolvedValueOnce({ records: [makeRecord(null)] });
82
- await expect(getUserTimezone("acct-abc12345", "user-xyz98765")).rejects.toThrow(/set via profile-update with profileFields: \{ timezone: 'IANA_TZ' \}/);
119
+ it("names the resolved OWNER row when the owner profile has timezone=NULL", async () => {
120
+ // slice(0, 8) of "owner-3f81e7c2" = "owner-3f"
121
+ queue("owner-3f81e7c2", null);
122
+ await expect(getUserTimezone("acct-2078cb54", "operator-436fdf2d")).rejects.toThrow(/No timezone on UserProfile for userId owner-3f/);
123
+ queue("owner-3f81e7c2", null);
124
+ await expect(getUserTimezone("acct-2078cb54", "operator-436fdf2d")).rejects.toThrow(/set via profile-update with profileFields: \{ timezone: 'IANA_TZ' \}/);
83
125
  });
84
- it("throws when no UserProfile matches the (accountId, userId) pair (post-Task-792 0-or-1-row state)", async () => {
85
- mockRun.mockResolvedValueOnce({ records: [] });
86
- // slice(0, 8) of "user-nope0000" = "user-nop"
87
- await expect(getUserTimezone("acct-abc12345", "user-nope0000")).rejects.toThrow(/No UserProfile for userId user-nop/);
126
+ it("names the resolved OWNER row when the owner has no UserProfile at all", async () => {
127
+ // Owner AdminUser exists but has no HAS_PROFILE UserProfile (provisioning
128
+ // gap, Task 1150). The error names the owner, and does NOT fall back to
129
+ // the acting user. slice(0, 8) of "owner-3f81e7c2" = "owner-3f"
130
+ queue("owner-3f81e7c2", "no-row");
131
+ await expect(getUserTimezone("acct-2078cb54", "operator-436fdf2d")).rejects.toThrow(/No UserProfile for userId owner-3f/);
88
132
  });
89
- it("never returns a timezone from a non-matching UserProfile when multiple UserProfiles exist for one accountId", async () => {
90
- // Simulate the ghost-rows world from before the constraint: 3
91
- // UserProfiles share an accountId but only the targeted userId has the
92
- // timezone field set. The cypher predicate must include userId so Neo4j
93
- // returns ONLY the targeted row — the mock asserts this by inspecting
94
- // the actual query parameters and returning the appropriate result set.
95
- const multiRowUniverse = {
96
- "user-target-001": "Europe/Berlin",
97
- "user-ghost-aaa": null,
98
- "user-ghost-bbb": null,
99
- };
100
- mockRun.mockImplementation(async (_query, params) => {
101
- // The lib's query filters on userId, so a correctly-implemented call
102
- // returns at most one row. If a future regression drops the userId
103
- // predicate, this mock still returns only the matching row — but the
104
- // anti-regression check above (query string assertion) would have
105
- // already caught it.
106
- const tz = multiRowUniverse[params.userId];
107
- if (tz === undefined)
108
- return { records: [] };
109
- return { records: [makeRecord(tz)] };
110
- });
111
- // Targeted user: returns the targeted timezone.
112
- expect(await getUserTimezone("acct-shared", "user-target-001")).toBe("Europe/Berlin");
113
- // Ghost user with NULL timezone: throws the "No timezone" branch — does
114
- // NOT silently leak the targeted user's timezone.
115
- // slice(0, 8) of "user-ghost-aaa" = "user-gho"
116
- await expect(getUserTimezone("acct-shared", "user-ghost-aaa")).rejects.toThrow(/No timezone on UserProfile for userId user-gho/);
133
+ it("names the acting-user row in the no-owner fallback when that profile is missing", async () => {
134
+ // slice(0, 8) of "acting-user-777" = "acting-u"
135
+ queue(null, "no-row");
136
+ await expect(getUserTimezone("acct-legacy999", "acting-user-777")).rejects.toThrow(/No UserProfile for userId acting-u/);
117
137
  });
118
138
  });
119
139
  //# sourceMappingURL=getUserTimezone.test.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"getUserTimezone.test.js","sourceRoot":"","sources":["../../../src/lib/__tests__/getUserTimezone.test.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"getUserTimezone.test.js","sourceRoot":"","sources":["../../../src/lib/__tests__/getUserTimezone.test.ts"],"names":[],"mappings":"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"}
@@ -11,20 +11,46 @@ export declare class MissingUserIdError extends Error {
11
11
  constructor(message: string);
12
12
  }
13
13
  /**
14
- * Fetches the user's IANA timezone from their UserProfile node.
14
+ * Task 1684 — resolve the account's seeded owner `AdminUser` userId.
15
+ *
16
+ * A sub-account is seeded (Task 1359 `seedAccountGraphRoot`) with exactly one
17
+ * `AdminUser {role:'owner'}`. When a house operator acts inside that
18
+ * sub-account, the operator's boot userId has no node in the sub-account
19
+ * subgraph, so keying a UserProfile read on it reads empty. The owner is the
20
+ * single, unambiguous locale identity for the account. Returns null when the
21
+ * account has no owner `AdminUser` (a legacy, pre-1359 account) — the caller
22
+ * then falls back to the acting user via an explicit, logged path.
23
+ *
24
+ * Mirrors the memory plugin's `resolve-owner-userid.ts` and
25
+ * `@maxy/active-rules`' `resolveOwnerUserId` — the query literal is duplicated
26
+ * per package deliberately (each keeps its own neo4j coupling) rather than
27
+ * introducing a cross-package import.
28
+ */
29
+ export declare function resolveOwnerUserId(session: Session, accountId: string): Promise<string | null>;
30
+ /**
31
+ * Fetches the account's IANA timezone from its owner's UserProfile node.
15
32
  *
16
33
  * UserProfile read doctrine: single-row consumers key reads on
17
- * (accountId, userId). AccountId-only reads are forbidden here because
18
- * enforces (accountId, userId) uniqueness a bare-accountId read
19
- * would target a non-deterministic row and (in multi-row state) point the
20
- * caller at a remediation that writes to a different row than the read.
34
+ * (accountId, userId). AccountId-only reads are forbidden the constraint
35
+ * enforces (accountId, userId) uniqueness, so a bare-accountId read would
36
+ * target a non-deterministic row and (in multi-row state) point the caller at
37
+ * a remediation that writes to a different row than the read.
38
+ *
39
+ * Task 1684: the read is keyed on the account's seeded OWNER, not the acting
40
+ * session user. A house operator acting inside a client sub-account has no
41
+ * UserProfile scoped to that account; the owner's profile is authoritative
42
+ * (the same owner-resolution 1557/1564 applied to profile writes and standing
43
+ * rules). The acting user is used only as an explicit fallback when the
44
+ * account has no seeded owner (legacy), which also preserves the pre-1684
45
+ * behaviour for single-identity accounts where the acting user IS the owner.
21
46
  *
22
- * Throws MissingUserIdError when userId is empty — caller forgot to thread
23
- * the live userId from the MCP session.
24
- * Throws Error when no UserProfile exists for the (accountId, userId) pair.
25
- * Throws Error when the row exists but timezone is unset — message names
26
- * the exact UserProfile so the operator can target the same row with
27
- * profile-update.
47
+ * Throws MissingUserIdError when the acting userId is empty — caller forgot to
48
+ * thread the live userId from the MCP session (still required for the fallback
49
+ * path and for attribution).
50
+ * Throws Error when no UserProfile exists for the resolved (accountId, userId)
51
+ * pair — the message names the resolved row (owner, or acting user in the
52
+ * fallback) so profile-update targets the same row that was read.
53
+ * Throws Error when the row exists but timezone is unset — same naming.
28
54
  */
29
55
  export declare function getUserTimezone(accountId: string, userId: string): Promise<string>;
30
56
  //# sourceMappingURL=neo4j.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"neo4j.d.ts","sourceRoot":"","sources":["../../src/lib/neo4j.ts"],"names":[],"mappings":"AAAA,OAAc,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAuBtD,wBAAgB,SAAS,IAAI,MAAM,CAgBlC;AAED,wBAAgB,UAAU,IAAI,OAAO,CAEpC;AAED,wBAAsB,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC,CAKjD;AAED;;;;GAIG;AACH,qBAAa,kBAAmB,SAAQ,KAAK;gBAC/B,OAAO,EAAE,MAAM;CAI5B;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,eAAe,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAmCxF"}
1
+ {"version":3,"file":"neo4j.d.ts","sourceRoot":"","sources":["../../src/lib/neo4j.ts"],"names":[],"mappings":"AAAA,OAAc,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAuBtD,wBAAgB,SAAS,IAAI,MAAM,CAgBlC;AAED,wBAAgB,UAAU,IAAI,OAAO,CAEpC;AAED,wBAAsB,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC,CAKjD;AAED;;;;GAIG;AACH,qBAAa,kBAAmB,SAAQ,KAAK;gBAC/B,OAAO,EAAE,MAAM;CAI5B;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,kBAAkB,CACtC,OAAO,EAAE,OAAO,EAChB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAUxB;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAsB,eAAe,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CA8CxF"}
@@ -49,20 +49,53 @@ export class MissingUserIdError extends Error {
49
49
  }
50
50
  }
51
51
  /**
52
- * Fetches the user's IANA timezone from their UserProfile node.
52
+ * Task 1684 — resolve the account's seeded owner `AdminUser` userId.
53
+ *
54
+ * A sub-account is seeded (Task 1359 `seedAccountGraphRoot`) with exactly one
55
+ * `AdminUser {role:'owner'}`. When a house operator acts inside that
56
+ * sub-account, the operator's boot userId has no node in the sub-account
57
+ * subgraph, so keying a UserProfile read on it reads empty. The owner is the
58
+ * single, unambiguous locale identity for the account. Returns null when the
59
+ * account has no owner `AdminUser` (a legacy, pre-1359 account) — the caller
60
+ * then falls back to the acting user via an explicit, logged path.
61
+ *
62
+ * Mirrors the memory plugin's `resolve-owner-userid.ts` and
63
+ * `@maxy/active-rules`' `resolveOwnerUserId` — the query literal is duplicated
64
+ * per package deliberately (each keeps its own neo4j coupling) rather than
65
+ * introducing a cross-package import.
66
+ */
67
+ export async function resolveOwnerUserId(session, accountId) {
68
+ const res = await session.run(`MATCH (au:AdminUser {accountId: $accountId, role: 'owner'})
69
+ RETURN au.userId AS userId
70
+ ORDER BY au.createdAt ASC
71
+ LIMIT 1`, { accountId });
72
+ const userId = res.records[0]?.get("userId");
73
+ return typeof userId === "string" && userId.length > 0 ? userId : null;
74
+ }
75
+ /**
76
+ * Fetches the account's IANA timezone from its owner's UserProfile node.
53
77
  *
54
78
  * UserProfile read doctrine: single-row consumers key reads on
55
- * (accountId, userId). AccountId-only reads are forbidden here because
56
- * enforces (accountId, userId) uniqueness a bare-accountId read
57
- * would target a non-deterministic row and (in multi-row state) point the
58
- * caller at a remediation that writes to a different row than the read.
79
+ * (accountId, userId). AccountId-only reads are forbidden the constraint
80
+ * enforces (accountId, userId) uniqueness, so a bare-accountId read would
81
+ * target a non-deterministic row and (in multi-row state) point the caller at
82
+ * a remediation that writes to a different row than the read.
83
+ *
84
+ * Task 1684: the read is keyed on the account's seeded OWNER, not the acting
85
+ * session user. A house operator acting inside a client sub-account has no
86
+ * UserProfile scoped to that account; the owner's profile is authoritative
87
+ * (the same owner-resolution 1557/1564 applied to profile writes and standing
88
+ * rules). The acting user is used only as an explicit fallback when the
89
+ * account has no seeded owner (legacy), which also preserves the pre-1684
90
+ * behaviour for single-identity accounts where the acting user IS the owner.
59
91
  *
60
- * Throws MissingUserIdError when userId is empty — caller forgot to thread
61
- * the live userId from the MCP session.
62
- * Throws Error when no UserProfile exists for the (accountId, userId) pair.
63
- * Throws Error when the row exists but timezone is unset — message names
64
- * the exact UserProfile so the operator can target the same row with
65
- * profile-update.
92
+ * Throws MissingUserIdError when the acting userId is empty — caller forgot to
93
+ * thread the live userId from the MCP session (still required for the fallback
94
+ * path and for attribution).
95
+ * Throws Error when no UserProfile exists for the resolved (accountId, userId)
96
+ * pair — the message names the resolved row (owner, or acting user in the
97
+ * fallback) so profile-update targets the same row that was read.
98
+ * Throws Error when the row exists but timezone is unset — same naming.
66
99
  */
67
100
  export async function getUserTimezone(accountId, userId) {
68
101
  if (!userId || userId.trim().length === 0) {
@@ -71,15 +104,24 @@ export async function getUserTimezone(accountId, userId) {
71
104
  }
72
105
  const session = getSession();
73
106
  try {
107
+ const ownerUserId = await resolveOwnerUserId(session, accountId);
108
+ const effectiveUserId = ownerUserId ?? userId;
109
+ const source = ownerUserId ? "owner" : "acting-fallback";
110
+ const ownerTag = ownerUserId ? ownerUserId.slice(0, 8) : "none";
111
+ const traceHead = `[scheduling] tz-resolve accountId=${accountId.slice(0, 8)} ` +
112
+ `actingUserId=${userId.slice(0, 8)} resolved=${source} ownerUserId=${ownerTag}`;
74
113
  const result = await session.run(`MATCH (up:UserProfile {accountId: $accountId, userId: $userId})
75
- RETURN up.timezone AS timezone`, { accountId, userId });
114
+ RETURN up.timezone AS timezone`, { accountId, userId: effectiveUserId });
76
115
  if (result.records.length === 0) {
77
- throw new Error(`No UserProfile for userId ${userId.slice(0, 8)}… (account ${accountId.slice(0, 8)}…) — cannot format locale times`);
116
+ console.error(`${traceHead} tz=absent`);
117
+ throw new Error(`No UserProfile for userId ${effectiveUserId.slice(0, 8)}… (account ${accountId.slice(0, 8)}…) — cannot format locale times`);
78
118
  }
79
119
  const timezone = result.records[0].get("timezone");
80
120
  if (!timezone || timezone.trim().length === 0) {
81
- throw new Error(`No timezone on UserProfile for userId ${userId.slice(0, 8)}… (account ${accountId.slice(0, 8)}…) — set via profile-update with profileFields: { timezone: 'IANA_TZ' }`);
121
+ console.error(`${traceHead} tz=unset`);
122
+ throw new Error(`No timezone on UserProfile for userId ${effectiveUserId.slice(0, 8)}… (account ${accountId.slice(0, 8)}…) — set via profile-update with profileFields: { timezone: 'IANA_TZ' }`);
82
123
  }
124
+ console.error(`${traceHead} tz=${timezone}`);
83
125
  return timezone;
84
126
  }
85
127
  finally {
@@ -1 +1 @@
1
- {"version":3,"file":"neo4j.js","sourceRoot":"","sources":["../../src/lib/neo4j.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"neo4j.js","sourceRoot":"","sources":["../../src/lib/neo4j.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"canonical-tool-names.generated.d.ts","sourceRoot":"","sources":["../src/canonical-tool-names.generated.ts"],"names":[],"mappings":"AAQA,+EAA+E;AAC/E,eAAO,MAAM,gBAAgB,EAAE,SAAS,MAAM,EAuB7C,CAAA;AAED,gEAAgE;AAChE,eAAO,MAAM,yBAAyB,EAAE,SAAS,MAAM,EA+RtD,CAAA"}
1
+ {"version":3,"file":"canonical-tool-names.generated.d.ts","sourceRoot":"","sources":["../src/canonical-tool-names.generated.ts"],"names":[],"mappings":"AAQA,+EAA+E;AAC/E,eAAO,MAAM,gBAAgB,EAAE,SAAS,MAAM,EAuB7C,CAAA;AAED,gEAAgE;AAChE,eAAO,MAAM,yBAAyB,EAAE,SAAS,MAAM,EAgStD,CAAA"}
@@ -233,6 +233,7 @@ export const CANONICAL_MAXY_TOOL_NAMES = [
233
233
  "mcp__plugin_outlook_outlook__outlook-draft",
234
234
  "mcp__plugin_outlook_outlook__outlook-draft-edit",
235
235
  "mcp__plugin_outlook_outlook__outlook-draft-send",
236
+ "mcp__plugin_outlook_outlook__outlook-mail-attachment",
236
237
  "mcp__plugin_outlook_outlook__outlook-mail-delete",
237
238
  "mcp__plugin_outlook_outlook__outlook-mail-fetch-body",
238
239
  "mcp__plugin_outlook_outlook__outlook-mail-list",
@@ -1 +1 @@
1
- {"version":3,"file":"canonical-tool-names.generated.js","sourceRoot":"","sources":["../src/canonical-tool-names.generated.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"canonical-tool-names.generated.js","sourceRoot":"","sources":["../src/canonical-tool-names.generated.ts"],"names":[],"mappings":"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"}