@rubytech/create-maxy-code 0.1.451 → 0.1.453

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 (140) hide show
  1. package/dist/__tests__/preserve-house-cloudflare.test.js +81 -2
  2. package/dist/index.js +10 -1
  3. package/dist/preserve-house-cloudflare.js +49 -2
  4. package/package.json +1 -1
  5. package/payload/platform/lib/storage-broker/dist/__tests__/cf-exec.test.js +24 -0
  6. package/payload/platform/lib/storage-broker/dist/__tests__/cf-exec.test.js.map +1 -1
  7. package/payload/platform/lib/storage-broker/dist/__tests__/house-scoped-token.test.d.ts +2 -0
  8. package/payload/platform/lib/storage-broker/dist/__tests__/house-scoped-token.test.d.ts.map +1 -0
  9. package/payload/platform/lib/storage-broker/dist/__tests__/house-scoped-token.test.js +48 -0
  10. package/payload/platform/lib/storage-broker/dist/__tests__/house-scoped-token.test.js.map +1 -0
  11. package/payload/platform/lib/storage-broker/dist/__tests__/remediate.test.js +6 -0
  12. package/payload/platform/lib/storage-broker/dist/__tests__/remediate.test.js.map +1 -1
  13. package/payload/platform/lib/storage-broker/dist/bin/remediate-run.d.ts.map +1 -1
  14. package/payload/platform/lib/storage-broker/dist/bin/remediate-run.js +14 -4
  15. package/payload/platform/lib/storage-broker/dist/bin/remediate-run.js.map +1 -1
  16. package/payload/platform/lib/storage-broker/dist/cf-exec.d.ts +1 -0
  17. package/payload/platform/lib/storage-broker/dist/cf-exec.d.ts.map +1 -1
  18. package/payload/platform/lib/storage-broker/dist/cf-exec.js +18 -0
  19. package/payload/platform/lib/storage-broker/dist/cf-exec.js.map +1 -1
  20. package/payload/platform/lib/storage-broker/dist/house-scoped-token.d.ts +9 -0
  21. package/payload/platform/lib/storage-broker/dist/house-scoped-token.d.ts.map +1 -0
  22. package/payload/platform/lib/storage-broker/dist/house-scoped-token.js +60 -0
  23. package/payload/platform/lib/storage-broker/dist/house-scoped-token.js.map +1 -0
  24. package/payload/platform/lib/storage-broker/dist/index.d.ts +1 -0
  25. package/payload/platform/lib/storage-broker/dist/index.d.ts.map +1 -1
  26. package/payload/platform/lib/storage-broker/dist/index.js +1 -0
  27. package/payload/platform/lib/storage-broker/dist/index.js.map +1 -1
  28. package/payload/platform/lib/storage-broker/dist/remediate.d.ts.map +1 -1
  29. package/payload/platform/lib/storage-broker/dist/remediate.js +14 -1
  30. package/payload/platform/lib/storage-broker/dist/remediate.js.map +1 -1
  31. package/payload/platform/lib/storage-broker/src/__tests__/cf-exec.test.ts +28 -1
  32. package/payload/platform/lib/storage-broker/src/__tests__/house-scoped-token.test.ts +48 -0
  33. package/payload/platform/lib/storage-broker/src/__tests__/remediate.test.ts +8 -0
  34. package/payload/platform/lib/storage-broker/src/bin/remediate-run.ts +17 -5
  35. package/payload/platform/lib/storage-broker/src/cf-exec.ts +22 -0
  36. package/payload/platform/lib/storage-broker/src/house-scoped-token.ts +72 -0
  37. package/payload/platform/lib/storage-broker/src/index.ts +1 -0
  38. package/payload/platform/lib/storage-broker/src/remediate.ts +14 -1
  39. package/payload/platform/plugins/admin/PLUGIN.md +1 -0
  40. package/payload/platform/plugins/admin/hooks/__tests__/quote-render-gate.test.sh +107 -0
  41. package/payload/platform/plugins/admin/hooks/quote-render-gate.sh +74 -0
  42. package/payload/platform/plugins/admin/skills/platform-architecture/SKILL.md +4 -4
  43. package/payload/platform/plugins/cloudflare/bin/__tests__/cf-token.test.sh +25 -1
  44. package/payload/platform/plugins/cloudflare/bin/cf-token.sh +9 -1
  45. package/payload/platform/plugins/cloudflare/references/api.md +3 -1
  46. package/payload/platform/plugins/cloudflare/skills/cloudflare/SKILL.md +1 -1
  47. package/payload/platform/plugins/docs/references/outlook-guide.md +3 -3
  48. package/payload/platform/plugins/outlook/.claude-plugin/plugin.json +1 -1
  49. package/payload/platform/plugins/outlook/PLUGIN.md +3 -3
  50. package/payload/platform/plugins/outlook/mcp/dist/__tests__/complete-registration.test.d.ts +2 -0
  51. package/payload/platform/plugins/outlook/mcp/dist/__tests__/complete-registration.test.d.ts.map +1 -0
  52. package/payload/platform/plugins/outlook/mcp/dist/__tests__/complete-registration.test.js +131 -0
  53. package/payload/platform/plugins/outlook/mcp/dist/__tests__/complete-registration.test.js.map +1 -0
  54. package/payload/platform/plugins/outlook/mcp/dist/__tests__/graph-client-paged.test.d.ts +2 -0
  55. package/payload/platform/plugins/outlook/mcp/dist/__tests__/graph-client-paged.test.d.ts.map +1 -0
  56. package/payload/platform/plugins/outlook/mcp/dist/__tests__/graph-client-paged.test.js +55 -0
  57. package/payload/platform/plugins/outlook/mcp/dist/__tests__/graph-client-paged.test.js.map +1 -0
  58. package/payload/platform/plugins/outlook/mcp/dist/__tests__/mail-list-paging.test.d.ts +2 -0
  59. package/payload/platform/plugins/outlook/mcp/dist/__tests__/mail-list-paging.test.d.ts.map +1 -0
  60. package/payload/platform/plugins/outlook/mcp/dist/__tests__/mail-list-paging.test.js +120 -0
  61. package/payload/platform/plugins/outlook/mcp/dist/__tests__/mail-list-paging.test.js.map +1 -0
  62. package/payload/platform/plugins/outlook/mcp/dist/__tests__/mail-search-paging.test.d.ts +2 -0
  63. package/payload/platform/plugins/outlook/mcp/dist/__tests__/mail-search-paging.test.d.ts.map +1 -0
  64. package/payload/platform/plugins/outlook/mcp/dist/__tests__/mail-search-paging.test.js +66 -0
  65. package/payload/platform/plugins/outlook/mcp/dist/__tests__/mail-search-paging.test.js.map +1 -0
  66. package/payload/platform/plugins/outlook/mcp/dist/__tests__/pending-scan.test.d.ts +2 -0
  67. package/payload/platform/plugins/outlook/mcp/dist/__tests__/pending-scan.test.d.ts.map +1 -0
  68. package/payload/platform/plugins/outlook/mcp/dist/__tests__/pending-scan.test.js +48 -0
  69. package/payload/platform/plugins/outlook/mcp/dist/__tests__/pending-scan.test.js.map +1 -0
  70. package/payload/platform/plugins/outlook/mcp/dist/auth/complete-registration.d.ts +31 -0
  71. package/payload/platform/plugins/outlook/mcp/dist/auth/complete-registration.d.ts.map +1 -0
  72. package/payload/platform/plugins/outlook/mcp/dist/auth/complete-registration.js +47 -0
  73. package/payload/platform/plugins/outlook/mcp/dist/auth/complete-registration.js.map +1 -0
  74. package/payload/platform/plugins/outlook/mcp/dist/auth/pending-scan.d.ts +11 -0
  75. package/payload/platform/plugins/outlook/mcp/dist/auth/pending-scan.d.ts.map +1 -0
  76. package/payload/platform/plugins/outlook/mcp/dist/auth/pending-scan.js +31 -0
  77. package/payload/platform/plugins/outlook/mcp/dist/auth/pending-scan.js.map +1 -0
  78. package/payload/platform/plugins/outlook/mcp/dist/index.js +13 -9
  79. package/payload/platform/plugins/outlook/mcp/dist/index.js.map +1 -1
  80. package/payload/platform/plugins/outlook/mcp/dist/lib/graph-client.d.ts +19 -0
  81. package/payload/platform/plugins/outlook/mcp/dist/lib/graph-client.d.ts.map +1 -1
  82. package/payload/platform/plugins/outlook/mcp/dist/lib/graph-client.js +14 -0
  83. package/payload/platform/plugins/outlook/mcp/dist/lib/graph-client.js.map +1 -1
  84. package/payload/platform/plugins/outlook/mcp/dist/scripts/complete-registration.d.ts +2 -0
  85. package/payload/platform/plugins/outlook/mcp/dist/scripts/complete-registration.d.ts.map +1 -0
  86. package/payload/platform/plugins/outlook/mcp/dist/scripts/complete-registration.js +111 -0
  87. package/payload/platform/plugins/outlook/mcp/dist/scripts/complete-registration.js.map +1 -0
  88. package/payload/platform/plugins/outlook/mcp/dist/tools/mail-list.d.ts +16 -1
  89. package/payload/platform/plugins/outlook/mcp/dist/tools/mail-list.d.ts.map +1 -1
  90. package/payload/platform/plugins/outlook/mcp/dist/tools/mail-list.js +37 -7
  91. package/payload/platform/plugins/outlook/mcp/dist/tools/mail-list.js.map +1 -1
  92. package/payload/platform/plugins/outlook/mcp/dist/tools/mail-search.d.ts +12 -1
  93. package/payload/platform/plugins/outlook/mcp/dist/tools/mail-search.d.ts.map +1 -1
  94. package/payload/platform/plugins/outlook/mcp/dist/tools/mail-search.js +16 -12
  95. package/payload/platform/plugins/outlook/mcp/dist/tools/mail-search.js.map +1 -1
  96. package/payload/platform/plugins/outlook/references/auth.md +2 -0
  97. package/payload/platform/plugins/outlook/references/graph-surfaces.md +20 -9
  98. package/payload/platform/plugins/outlook/skills/outlook/SKILL.md +7 -7
  99. package/payload/platform/plugins/scheduling/PLUGIN.md +1 -1
  100. package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/house-scoped-token.test.d.ts +2 -0
  101. package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/house-scoped-token.test.d.ts.map +1 -0
  102. package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/house-scoped-token.test.js +36 -0
  103. package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/house-scoped-token.test.js.map +1 -0
  104. package/payload/platform/plugins/scheduling/mcp/dist/lib/house-scoped-token.d.ts +9 -0
  105. package/payload/platform/plugins/scheduling/mcp/dist/lib/house-scoped-token.d.ts.map +1 -0
  106. package/payload/platform/plugins/scheduling/mcp/dist/lib/house-scoped-token.js +51 -0
  107. package/payload/platform/plugins/scheduling/mcp/dist/lib/house-scoped-token.js.map +1 -0
  108. package/payload/platform/plugins/scheduling/mcp/dist/scripts/publish-availability.js +16 -2
  109. package/payload/platform/plugins/scheduling/mcp/dist/scripts/publish-availability.js.map +1 -1
  110. package/payload/platform/plugins/scheduling/mcp/dist/scripts/reconcile-bookings.js +16 -2
  111. package/payload/platform/plugins/scheduling/mcp/dist/scripts/reconcile-bookings.js.map +1 -1
  112. package/payload/platform/scripts/lib/provision-account-dir.sh +6 -0
  113. package/payload/platform/scripts/smoke-boot-services.sh +1 -0
  114. package/payload/platform/scripts/voice-mirror-audit.sh +70 -0
  115. package/payload/platform/services/claude-session-manager/dist/config.d.ts +5 -0
  116. package/payload/platform/services/claude-session-manager/dist/config.d.ts.map +1 -1
  117. package/payload/platform/services/claude-session-manager/dist/config.js +7 -1
  118. package/payload/platform/services/claude-session-manager/dist/config.js.map +1 -1
  119. package/payload/platform/services/claude-session-manager/dist/fs-watcher.d.ts +15 -0
  120. package/payload/platform/services/claude-session-manager/dist/fs-watcher.d.ts.map +1 -1
  121. package/payload/platform/services/claude-session-manager/dist/fs-watcher.js +38 -3
  122. package/payload/platform/services/claude-session-manager/dist/fs-watcher.js.map +1 -1
  123. package/payload/platform/services/claude-session-manager/dist/http-server.d.ts.map +1 -1
  124. package/payload/platform/services/claude-session-manager/dist/http-server.js +21 -10
  125. package/payload/platform/services/claude-session-manager/dist/http-server.js.map +1 -1
  126. package/payload/platform/services/claude-session-manager/dist/index.js +20 -0
  127. package/payload/platform/services/claude-session-manager/dist/index.js.map +1 -1
  128. package/payload/platform/services/claude-session-manager/dist/plugin-enum.d.ts +34 -0
  129. package/payload/platform/services/claude-session-manager/dist/plugin-enum.d.ts.map +1 -0
  130. package/payload/platform/services/claude-session-manager/dist/plugin-enum.js +66 -0
  131. package/payload/platform/services/claude-session-manager/dist/plugin-enum.js.map +1 -0
  132. package/payload/platform/services/claude-session-manager/dist/pty-spawner.d.ts.map +1 -1
  133. package/payload/platform/services/claude-session-manager/dist/pty-spawner.js +8 -1
  134. package/payload/platform/services/claude-session-manager/dist/pty-spawner.js.map +1 -1
  135. package/payload/platform/services/claude-session-manager/dist/rc-daemon.d.ts.map +1 -1
  136. package/payload/platform/services/claude-session-manager/dist/rc-daemon.js +7 -0
  137. package/payload/platform/services/claude-session-manager/dist/rc-daemon.js.map +1 -1
  138. package/payload/server/{chunk-TTKYHVA7.js → chunk-SDYRKIYY.js} +70 -3
  139. package/payload/server/server.js +59 -10
  140. package/payload/server/{src-FBUXV2FV.js → src-554BYJMN.js} +5 -1
@@ -1,4 +1,4 @@
1
- import { callGraph } from "../lib/graph-client.js";
1
+ import { callGraphPaged } from "../lib/graph-client.js";
2
2
  import { log } from "../lib/log.js";
3
3
  /**
4
4
  * Map a caller-supplied `folder` value to the Graph `/me/mailFolders/{id}`
@@ -44,22 +44,47 @@ const WELL_KNOWN_ALIASES = {
44
44
  outbox: "outbox",
45
45
  };
46
46
  const FIELDS = "id,subject,from,receivedDateTime,bodyPreview,isRead";
47
+ function toGraphDate(input, field) {
48
+ const d = new Date(input);
49
+ if (!Number.isFinite(d.getTime())) {
50
+ throw new Error(`mail-list: ${field} is not a valid date: ${input}`);
51
+ }
52
+ return d.toISOString();
53
+ }
54
+ function buildDateFilter(since, before) {
55
+ const clauses = [];
56
+ if (since)
57
+ clauses.push(`receivedDateTime ge ${toGraphDate(since, "since")}`);
58
+ if (before)
59
+ clauses.push(`receivedDateTime le ${toGraphDate(before, "before")}`);
60
+ return clauses.length > 0 ? clauses.join(" and ") : undefined;
61
+ }
47
62
  export async function runMailList(config, args) {
48
63
  const top = clampTop(args.top, 25);
49
64
  const folderIn = args.folder ?? "Inbox";
50
65
  const { token: folderResolved, asRawId } = resolveFolder(folderIn);
66
+ // With a cursor the nextLink already bakes in the window, so since/before are
67
+ // ignored entirely — including their validation. Without a cursor, an
68
+ // unparseable date throws here before any Graph call is made.
69
+ const filter = args.cursor ? undefined : buildDateFilter(args.since, args.before);
51
70
  const startMs = Date.now();
52
71
  try {
53
- const result = await callGraph(config, async (client) => {
72
+ const page = await callGraphPaged(config, (client) => {
73
+ // A cursor is a full nextLink URL that already encodes
74
+ // folder/filter/order/top/skiptoken — delegate straight to it.
75
+ if (args.cursor)
76
+ return client.api(args.cursor);
54
77
  const path = `/me/mailFolders/${encodeURIComponent(folderResolved)}/messages`;
55
- return (await client
78
+ const base = client
56
79
  .api(path)
57
80
  .top(top)
58
81
  .orderby("receivedDateTime DESC")
59
- .select(FIELDS)
60
- .get());
82
+ .select(FIELDS);
83
+ // Date-only filter orders by the same property, so filter+orderby is
84
+ // accepted by Graph (unlike a from/toRecipients filter).
85
+ return filter ? base.filter(filter) : base;
61
86
  }, { tool: "mail-list" });
62
- const items = result.value.map(shapeMessage);
87
+ const items = page.value.map(shapeMessage);
63
88
  log({
64
89
  event: "mail-list",
65
90
  op: "resolve",
@@ -67,10 +92,13 @@ export async function runMailList(config, args) {
67
92
  folderIn,
68
93
  folderResolved,
69
94
  asRawId,
95
+ since: args.since ?? null,
96
+ before: args.before ?? null,
70
97
  count: items.length,
98
+ nextCursor: page.nextLink ? "present" : "none",
71
99
  elapsedMs: Date.now() - startMs,
72
100
  });
73
- return items;
101
+ return { items, nextCursor: page.nextLink };
74
102
  }
75
103
  catch (err) {
76
104
  // callGraph already logged the graph-error line (status/code, e.g. the 400
@@ -83,6 +111,8 @@ export async function runMailList(config, args) {
83
111
  folderIn,
84
112
  folderResolved,
85
113
  asRawId,
114
+ since: args.since ?? null,
115
+ before: args.before ?? null,
86
116
  error: err.message,
87
117
  elapsedMs: Date.now() - startMs,
88
118
  });
@@ -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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"}
@@ -3,6 +3,17 @@ import type { MailListItem } from "./mail-list.js";
3
3
  export interface MailSearchArgs {
4
4
  query: string;
5
5
  top?: number;
6
+ /**
7
+ * Opaque continuation from a prior call's `nextCursor` (an `@odata.nextLink`
8
+ * URL). When set, `query` is ignored — the nextLink re-issues the original
9
+ * search with its `$skiptoken`.
10
+ */
11
+ cursor?: string;
6
12
  }
7
- export declare function runMailSearch(config: GraphClientConfig, args: MailSearchArgs): Promise<MailListItem[]>;
13
+ export interface MailSearchResult {
14
+ items: MailListItem[];
15
+ /** Opaque cursor for the next page; null when exhausted. */
16
+ nextCursor: string | null;
17
+ }
18
+ export declare function runMailSearch(config: GraphClientConfig, args: MailSearchArgs): Promise<MailSearchResult>;
8
19
  //# sourceMappingURL=mail-search.d.ts.map
@@ -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;CACd;AAiBD,wBAAsB,aAAa,CACjC,MAAM,EAAE,iBAAiB,EACzB,IAAI,EAAE,cAAc,GACnB,OAAO,CAAC,YAAY,EAAE,CAAC,CA0CzB"}
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,26 +1,29 @@
1
- import { callGraph } from "../lib/graph-client.js";
1
+ import { callGraphPaged } from "../lib/graph-client.js";
2
2
  import { log, trunc } from "../lib/log.js";
3
3
  const FIELDS = "id,subject,from,receivedDateTime,bodyPreview,isRead";
4
4
  export async function runMailSearch(config, args) {
5
5
  const top = clampTop(args.top, 25);
6
6
  const query = args.query.trim();
7
- if (!query) {
7
+ if (!args.cursor && !query) {
8
8
  throw new Error("mail-search: query is required and must be non-empty.");
9
9
  }
10
10
  const startMs = Date.now();
11
- const result = await callGraph(config, async (client) => {
12
- // Graph requires the $search value to be enclosed in quotes.
13
- return (await client
11
+ const page = await callGraphPaged(config, (client) => {
12
+ if (args.cursor) {
13
+ // The nextLink already carries $search + $skiptoken; ConsistencyLevel is
14
+ // a header (not in the URL) and must be re-applied for $search continuation.
15
+ return client.api(args.cursor).header("ConsistencyLevel", "eventual");
16
+ }
17
+ // Graph requires the $search value to be enclosed in quotes, and the
18
+ // ConsistencyLevel header for $search.
19
+ return client
14
20
  .api("/me/messages")
15
21
  .search(`"${query.replace(/"/g, '\\"')}"`)
16
22
  .top(top)
17
23
  .select(FIELDS)
18
- // ConsistencyLevel header is required for $search. Older SDK shapes
19
- // accept .header; newer shapes expose it via .request().
20
- .header("ConsistencyLevel", "eventual")
21
- .get());
24
+ .header("ConsistencyLevel", "eventual");
22
25
  }, { tool: "mail-search" });
23
- const items = result.value.map((msg) => ({
26
+ const items = page.value.map((msg) => ({
24
27
  id: msg.id,
25
28
  subject: msg.subject ?? null,
26
29
  from: msg.from?.emailAddress?.address ?? null,
@@ -31,11 +34,12 @@ export async function runMailSearch(config, args) {
31
34
  log({
32
35
  event: "mail-search",
33
36
  account: config.accountId,
34
- query: trunc(query, 32),
37
+ query: args.cursor ? "(cursor)" : trunc(query, 32),
35
38
  count: items.length,
39
+ nextCursor: page.nextLink ? "present" : "none",
36
40
  elapsedMs: Date.now() - startMs,
37
41
  });
38
- return items;
42
+ return { items, nextCursor: page.nextLink };
39
43
  }
40
44
  function clampTop(input, fallback) {
41
45
  if (typeof input !== "number" || !Number.isFinite(input))
@@ -1 +1 @@
1
- {"version":3,"file":"mail-search.js","sourceRoot":"","sources":["../../src/tools/mail-search.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACnD,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AAqB3C,MAAM,MAAM,GAAG,qDAAqD,CAAC;AAErE,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,MAAyB,EACzB,IAAoB;IAEpB,MAAM,GAAG,GAAG,QAAQ,CAAC,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;IACnC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;IAChC,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,IAAI,KAAK,CAAC,uDAAuD,CAAC,CAAC;IAC3E,CAAC;IACD,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAE3B,MAAM,MAAM,GAAG,MAAM,SAAS,CAC5B,MAAM,EACN,KAAK,EAAE,MAAM,EAAE,EAAE;QACf,6DAA6D;QAC7D,OAAO,CAAC,MAAM,MAAM;aACjB,GAAG,CAAC,cAAc,CAAC;aACnB,MAAM,CAAC,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,GAAG,CAAC;aACzC,GAAG,CAAC,GAAG,CAAC;aACR,MAAM,CAAC,MAAM,CAAC;YACf,oEAAoE;YACpE,yDAAyD;aACxD,MAAM,CAAC,kBAAkB,EAAE,UAAU,CAAC;aACtC,GAAG,EAAE,CAA8B,CAAC;IACzC,CAAC,EACD,EAAE,IAAI,EAAE,aAAa,EAAE,CACxB,CAAC;IAEF,MAAM,KAAK,GAAmB,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;QACvD,EAAE,EAAE,GAAG,CAAC,EAAE;QACV,OAAO,EAAE,GAAG,CAAC,OAAO,IAAI,IAAI;QAC5B,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,YAAY,EAAE,OAAO,IAAI,IAAI;QAC7C,gBAAgB,EAAE,GAAG,CAAC,gBAAgB;QACtC,WAAW,EAAE,CAAC,GAAG,CAAC,WAAW,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC;QACnD,MAAM,EAAE,GAAG,CAAC,MAAM,IAAI,KAAK;KAC5B,CAAC,CAAC,CAAC;IAEJ,GAAG,CAAC;QACF,KAAK,EAAE,aAAa;QACpB,OAAO,EAAE,MAAM,CAAC,SAAS;QACzB,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,EAAE,CAAC;QACvB,KAAK,EAAE,KAAK,CAAC,MAAM;QACnB,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,OAAO;KAChC,CAAC,CAAC;IACH,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,QAAQ,CAAC,KAAyB,EAAE,QAAgB;IAC3D,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC;QAAE,OAAO,QAAQ,CAAC;IAC1E,IAAI,KAAK,GAAG,CAAC;QAAE,OAAO,CAAC,CAAC;IACxB,IAAI,KAAK,GAAG,GAAG;QAAE,OAAO,GAAG,CAAC;IAC5B,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;AAC3B,CAAC"}
1
+ {"version":3,"file":"mail-search.js","sourceRoot":"","sources":["../../src/tools/mail-search.ts"],"names":[],"mappings":"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"}
@@ -81,6 +81,8 @@ operator plugin
81
81
 
82
82
  `poll` maps Microsoft's polling errors: `authorization_pending` → `pending` (wait `intervalSec`, poll again), `slow_down` → `pending` with a bumped interval, `expired_token` → `expired`, `access_denied` → `denied`.
83
83
 
84
+ **Server-driven completion.** The poll does not depend on an agent calling it. The always-running `platform/ui` server spawns a self-contained completion dispatcher (`mcp/dist/scripts/complete-registration.js`) on a 30 s interval; it enumerates every account holding a live pending device code and loops `runAccountRegisterPoll` to a terminal outcome, so a mailbox connects on its own once the operator consents. The dispatcher is PID-locked against overlap, inherits `OUTLOOK_CLIENT_ID` / `OUTLOOK_TENANT_ID` from the session-manager env, and is a no-op when the client id is unconfigured. `outlook-account-register-poll` remains the manual path and the fallback if the dispatcher is down. Observability: one `devicecode-autopoll account=<id> status=<status>` line per poll cycle, plus an independent server-side `devicecode-stranded account=<id> ageSec=<N>` audit that flags any `pending-devicecode.enc` older than the maximum code lifetime (the standing signal that the dispatcher is not running).
85
+
84
86
  ### Re-registering an account that already consented
85
87
 
86
88
  First-time registration completes cleanly. Re-registering a mailbox whose Microsoft account has **already granted this app access** on a prior registration does not: after the operator enters the user code, Microsoft's consent step redirects the browser to `http://localhost/?error=invalid_request&error_description=...response_type...`, a "site can't be reached" dead-end, and consent never finishes. Observed for personal accounts (outlook.com, hotmail.com, live.com), whose completion runs through the consumer stack (`login.live.com` `msaidpvalidate` → `post.srf`).
@@ -8,6 +8,10 @@ Microsoft Graph endpoints used by each tool, with the response shape and the fie
8
8
 
9
9
  **Endpoint (other folder):** `GET /me/mailFolders/{well-known-token-or-folderId}/messages?...`
10
10
 
11
+ **Date window:** `since`/`before` (ISO date-times) add `$filter=receivedDateTime ge {since} and receivedDateTime le {before}`. The filter orders by the same `receivedDateTime` property, so `$filter`+`$orderby` is accepted here — a `$filter` on `from`/`toRecipients` combined with this `$orderby` is *not* (Graph: "the restriction or sort order is too complex"), which is why sender/subject filtering lives on `outlook-mail-search` (KQL), not here.
12
+
13
+ **Pagination:** the response's `@odata.nextLink` (a URL carrying a `$skiptoken`) is returned to the caller as `nextCursor`. Passing it back as `cursor` re-issues that exact URL (`client.api(cursor)`), so folder/filter/order/top/skiptoken are preserved and every other arg is ignored. `nextCursor` is `null` when the page is the last. The 250 `$top` is a per-page size, not a reach ceiling — page with the cursor or narrow with the date window to reach older mail.
14
+
11
15
  The `folder` arg is normalized before the path is built. Graph's `{id}` segment accepts only a well-known token (single word, no spaces) or a real folder id — a display name like "Sent Items" is rejected with "Id is malformed". The tool maps the full well-known set plus common aliases, case- and space-insensitively, to the Graph token:
12
16
 
13
17
  | Input (any case/spacing) | Graph token |
@@ -24,14 +28,17 @@ Any value not in this table is treated as a raw folder id and passed through unc
24
28
 
25
29
  **Returned shape:**
26
30
  ```typescript
27
- Array<{
28
- id: string;
29
- subject: string | null;
30
- from: string | null; // emailAddress.address
31
- receivedDateTime: string; // ISO 8601
32
- bodyPreview: string; // Microsoft's short preview (~255 chars); the code's .slice(0,1024) never bites. Full body: outlook-mail-fetch-body
33
- isRead: boolean;
34
- }>
31
+ {
32
+ items: Array<{
33
+ id: string;
34
+ subject: string | null;
35
+ from: string | null; // emailAddress.address
36
+ receivedDateTime: string; // ISO 8601
37
+ bodyPreview: string; // Microsoft's short preview (~255 chars); the code's .slice(0,1024) never bites. Full body: outlook-mail-fetch-body
38
+ isRead: boolean;
39
+ }>;
40
+ nextCursor: string | null; // @odata.nextLink for the next older page; null when exhausted
41
+ }
35
42
  ```
36
43
 
37
44
  ## outlook-mail-search
@@ -40,7 +47,11 @@ Array<{
40
47
 
41
48
  **Required header:** `ConsistencyLevel: eventual` (Graph requirement for `$search`).
42
49
 
43
- **Returned shape:** identical to `outlook-mail-list`.
50
+ **Query filters (KQL):** put sender/subject/recipient/date in the `query` — `from:addr`, `to:addr`, `subject:text`, `received>=2024-01-01`, or free text. Graph forbids combining `$search` with a `$filter`/`$orderby`, so a strict `receivedDateTime` window is on `outlook-mail-list`; date-narrowing here uses the `received:` KQL term.
51
+
52
+ **Pagination:** same as `outlook-mail-list` — the `@odata.nextLink` is returned as `nextCursor`; pass it back as `cursor` and it re-issues via `client.api(cursor)` with the `ConsistencyLevel: eventual` header re-applied (the header is not part of the URL). `cursor` supersedes `query`.
53
+
54
+ **Returned shape:** identical to `outlook-mail-list` (`{ items, nextCursor }`).
44
55
 
45
56
  ## outlook-mail-fetch-body
46
57
 
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: outlook
3
- description: "Microsoft 365 / Outlook.com via Microsoft Graph. Mail is read (list, search, full-body), reply, delete, and compose (draft, draft-edit, send); contacts are read-only; the calendar is read plus control. Use when the user asks about their Outlook mail, calendar, or contacts, wants to read a full message, reply, delete, send or draft a message, or asks to book, move, cancel, or accept a calendar event. First-time use requires outlook-account-register plus outlook-account-register-poll; subsequent use is transparent. Tools: outlook-mail-list / outlook-mail-search (inbox triage, ~255-char preview), outlook-mail-fetch-body (full body of one message), outlook-mail-reply (in-thread reply with attachments), outlook-mail-delete (move to Deleted Items), outlook-mail-otp-extract (poll for a one-time code), outlook-mail-send / outlook-draft / outlook-draft-edit / outlook-draft-send (compose, edit, send), outlook-calendar-list / outlook-calendar-event (read calendar), outlook-calendar-create / outlook-calendar-update / outlook-calendar-cancel / outlook-calendar-respond / outlook-calendar-freebusy (control calendar), outlook-contacts-list (contacts), outlook-mailbox-info (health), outlook-account-register / outlook-account-register-poll (device-code register)."
3
+ description: "Microsoft 365 / Outlook.com via Microsoft Graph. Mail is read (list, search, full-body), reply, delete, and compose (draft, draft-edit, send); contacts are read-only; the calendar is read plus control. Use when the user asks about their Outlook mail, calendar, or contacts, wants to read a full message, reply, delete, send or draft a message, or asks to book, move, cancel, or accept a calendar event. First-time use requires outlook-account-register plus outlook-account-register-poll; subsequent use is transparent. Tools: outlook-mail-list / outlook-mail-search (inbox triage, ~255-char preview, date window + nextCursor paging), outlook-mail-fetch-body (full body of one message), outlook-mail-reply (in-thread reply with attachments), outlook-mail-delete (move to Deleted Items), outlook-mail-otp-extract (poll for a one-time code), outlook-mail-send / outlook-draft / outlook-draft-edit / outlook-draft-send (compose, edit, send), outlook-calendar-list / outlook-calendar-event (read calendar), outlook-calendar-create / outlook-calendar-update / outlook-calendar-cancel / outlook-calendar-respond / outlook-calendar-freebusy (control calendar), outlook-contacts-list (contacts), outlook-mailbox-info (health), outlook-account-register / outlook-account-register-poll (device-code register)."
4
4
  ---
5
5
 
6
6
  # Outlook (Microsoft Graph)
@@ -31,11 +31,11 @@ Connect a mailbox via the device-code flow. The operator never needs the box's b
31
31
 
32
32
  1. Call **`outlook-account-register`**. It returns immediately with `{ status: "pending", userCode, verificationUri, verificationUriComplete, expiresInSec, intervalSec }`. Relay the `userCode` and `verificationUri` to the operator in your reply so the sign-in can begin.
33
33
  2. The operator opens `verificationUri` (`microsoft.com/devicelogin`) on any device (their phone or laptop), enters the `userCode`, signs in with the Microsoft account they want to connect, and consents to the requested scopes (`offline_access`, `User.Read`, `Mail.ReadWrite`, `Mail.Send`, `Calendars.ReadWrite`, `Contacts.Read`). `Mail.Send` enables sending and `Calendars.ReadWrite` enables calendar control; a mailbox last consented on an older read-only scope set must re-register before send or any calendar write succeeds.
34
- 3. **Poll immediately, and keep polling to a terminal outcome.** As soon as the code is issued in step 1, start calling **`outlook-account-register-poll`** on the returned `intervalSec` cadence, and keep calling it until it returns a terminal status. Do not wait for the operator to say the sign-in is finished. The flow is poll-driven: Microsoft's confirmation page authenticates the code at Microsoft and pushes nothing back to this plugin, so only this poll harvests the token. `{ status: "pending" }` means keep polling. `{ status: "registered", graphUserId, scopes, tokenExpSec }` is the sole completion signal (consent finished, tokens persisted); after it, confirm the mailbox is addressable with `outlook-mailbox-list` (a `status:ok` entry) or `outlook-mailbox-info`. `{ status: "expired" }` means the code lapsed unharvested, so restart at step 1. `{ status: "denied" }` means the operator declined.
34
+ 3. **The server completes the sign-in automatically. You do not need to poll.** As soon as the code is issued in step 1, a background dispatcher on the server begins polling Microsoft on the code's own cadence and harvests the token the moment the operator finishes consenting, usually within about half a minute. The flow is poll-driven (Microsoft's confirmation page authenticates the code at Microsoft and pushes nothing back to this plugin), and the server is what polls it, so a mailbox connects on its own with no further action from you. Once the operator says they have entered the code and consented, confirm the mailbox is addressable with `outlook-mailbox-info` or `outlook-mailbox-list` (a `status:ok` entry). `outlook-account-register-poll` stays available to force an immediate check, and is the fallback if the server dispatcher is not running: `{ status: "pending" }` means still waiting, `{ status: "registered", graphUserId, scopes, tokenExpSec }` is the completion signal, `{ status: "expired" }` means the code lapsed so restart at step 1, `{ status: "denied" }` means the operator declined.
35
35
 
36
- **An operator "done" means poll, not verify.** A message like "done", "he confirmed", or "she signed in" maps to *poll now, and keep polling* on the `intervalSec` cadence. It never maps to a read-only `outlook-mailbox-info` check. A read-only check is a valid way to confirm a mailbox that is *already* `registered`; it never completes an in-flight sign-in, and running it in place of the poll lets the live code lapse unharvested.
36
+ **An operator "done" means confirm, not poll.** A message like "done", "he confirmed", or "she signed in" means the server has harvested the token or will within its cadence. Confirm with a read-only `outlook-mailbox-info` or `outlook-mailbox-list` check. You only need `outlook-account-register-poll` if that confirmation shows the mailbox still unregistered and you want to force the harvest immediately rather than wait for the next dispatcher tick.
37
37
 
38
- **Never end the flow with a live pending code.** Once `outlook-account-register` has issued a code, drive it to a terminal status (`registered`, `expired`, or `denied`) before the flow ends. A pending code left hanging is not only an unfinished sign-in: the leftover pending entry makes the next `outlook-account-register` return `register-in-progress` instead of starting a fresh code.
38
+ **The server drives every issued code to a terminal outcome.** Once `outlook-account-register` has issued a code, the completion dispatcher polls it to `registered`, `expired`, or `denied` on its own, so a code is never left hanging and the leftover-pending state that made the next `outlook-account-register` return `register-in-progress` no longer occurs after a normal sign-in.
39
39
 
40
40
  Subsequent tool calls use the persisted refresh token to mint access tokens transparently. Re-register is only needed if the refresh token expires (90 days) or the user revokes consent.
41
41
 
@@ -49,8 +49,8 @@ The revoke path below is scoped to one specific, visible failure. It is not a ge
49
49
 
50
50
  ## Reading mail
51
51
 
52
- - `outlook-mail-list` — recent mail, default top=25, folder=Inbox. Returns Microsoft's short `bodyPreview` (~255 chars) for cheap triage.
53
- - `outlook-mail-search query=<keyword>` — Microsoft Graph `$search` over the mailbox. Same preview-only shape as the list.
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
+ - `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
55
 
56
56
  ## Replying and deleting
@@ -98,7 +98,7 @@ All calendar writes need the `Calendars.ReadWrite` consent (see setup above). Ti
98
98
 
99
99
  | Error | Meaning | Operator action |
100
100
  |---|---|---|
101
- | `auth-required` | Account not registered, or refresh token expired | Run `outlook-account-register`, then `outlook-account-register-poll` |
101
+ | `auth-required` | Account not registered, or refresh token expired | Run `outlook-account-register`; the server completes the sign-in once the operator consents |
102
102
  | `Calendars.ReadWrite scope not granted` | Mailbox last consented on the old read-only calendar scope | Re-run `outlook-account-register` + `outlook-account-register-poll` to re-consent with calendar write |
103
103
  | `Outlook token refresh failed` | Network down or refresh token invalidated | Verify connectivity; re-run register if persistent |
104
104
  | `Microsoft Graph does not support on-premises Exchange` | Mailbox is on hybrid Exchange | Use the `email` plugin (IMAP) |
@@ -154,7 +154,7 @@ Dispatch results are recorded on the Event node (`lastDispatchResult`, `lastDisp
154
154
 
155
155
  It is **armed by the always-running `platform/ui` server on an interval**, because the Pi has no other periodic surface (the same gap `check-due-events` has). A PID lock at `<configDir>/reconcile-bookings.lock` prevents overlapping runs. It registers **no agent tool** — there is nothing for the agent to call — so the tool-surface registries are untouched.
156
156
 
157
- Env: `PLATFORM_ROOT`, `NEO4J_URI` (and `NEO4J_PASSWORD` or `config/.neo4j-password`). Per account it reads `data/accounts/<id>/calendar-availability.json` (for `bookingDbName`) and `data/accounts/<id>/secrets/cloudflare.env` (for the Pages-and-D1 token), and shells `wrangler` for the D1 reads/writes.
157
+ Env: `PLATFORM_ROOT`, `NEO4J_URI` (and `NEO4J_PASSWORD` or `config/.neo4j-password`). Per account it reads `data/accounts/<id>/calendar-availability.json` (for `bookingDbName`). The Cloudflare credential is read house-only from `config/cloudflare-house.env`; that credential is a minter, so the calendar mints a `calendar-d1` (D1-only) token from it via `cf-token.sh` and shells `wrangler` for the D1 reads/writes on that scoped token, never the minter directly.
158
158
 
159
159
  Observability: one `[calendar-booking]` line per step keyed by `bookingId` (`reconcile-claim`, `meeting-write`, `notify`, `booked`), and one `[calendar-reconcile] account=… pendingUnreconciled=… orphanMeetings=…` audit line per account per run. A `pendingUnreconciled` that persists across runs means reconcile is stalled; `orphanMeetings` means a booking meeting has no backing D1 row.
160
160
 
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=house-scoped-token.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"house-scoped-token.test.d.ts","sourceRoot":"","sources":["../../../src/lib/__tests__/house-scoped-token.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,36 @@
1
+ // Task 1670 — the calendar mints (then reuses) a D1-only scoped token from the
2
+ // house minter via cf-token.sh. This guards the readback wrapper: it shells
3
+ // cf-token.sh and returns the value of the persisted key, never the minter.
4
+ import { describe, it, expect } from "vitest";
5
+ import { mkdtempSync, writeFileSync, appendFileSync } from "node:fs";
6
+ import { tmpdir } from "node:os";
7
+ import { join } from "node:path";
8
+ import { resolveHouseScopedToken } from "../house-scoped-token.js";
9
+ function houseFile(contents) {
10
+ const dir = mkdtempSync(join(tmpdir(), "cal-hst-"));
11
+ const p = join(dir, "cloudflare-house.env");
12
+ writeFileSync(p, contents);
13
+ return p;
14
+ }
15
+ describe("resolveHouseScopedToken (calendar)", () => {
16
+ it("mints and reads back the calendar-d1 token", () => {
17
+ const p = houseFile("CLOUDFLARE_API_TOKEN=cfat_minter\nCLOUDFLARE_ACCOUNT_ID=acc\n");
18
+ const run = (_cmd, args) => {
19
+ expect(args[1]).toBe("calendar-d1");
20
+ appendFileSync(p, "CF_CALENDAR_D1_TOKEN=cal_tok\n");
21
+ return "CF_CALENDAR_D1_TOKEN\n";
22
+ };
23
+ expect(resolveHouseScopedToken("calendar-d1", p, "/x/cf-token.sh", run)).toBe("cal_tok");
24
+ });
25
+ it("reuses a pre-existing key", () => {
26
+ const p = houseFile("CLOUDFLARE_API_TOKEN=cfat_minter\nCLOUDFLARE_ACCOUNT_ID=acc\nCF_CALENDAR_D1_TOKEN=already\n");
27
+ const run = () => "CF_CALENDAR_D1_TOKEN\n";
28
+ expect(resolveHouseScopedToken("calendar-d1", p, "/x/cf-token.sh", run)).toBe("already");
29
+ });
30
+ it("throws when the persisted key is absent after the run", () => {
31
+ const p = houseFile("CLOUDFLARE_API_TOKEN=cfat_minter\nCLOUDFLARE_ACCOUNT_ID=acc\n");
32
+ const run = () => "CF_CALENDAR_D1_TOKEN\n"; // writes nothing
33
+ expect(() => resolveHouseScopedToken("calendar-d1", p, "/x/cf-token.sh", run)).toThrow();
34
+ });
35
+ });
36
+ //# sourceMappingURL=house-scoped-token.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"house-scoped-token.test.js","sourceRoot":"","sources":["../../../src/lib/__tests__/house-scoped-token.test.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,4EAA4E;AAC5E,4EAA4E;AAC5E,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AACrE,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,uBAAuB,EAAE,MAAM,0BAA0B,CAAC;AAEnE,SAAS,SAAS,CAAC,QAAgB;IACjC,MAAM,GAAG,GAAG,WAAW,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,UAAU,CAAC,CAAC,CAAC;IACpD,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,EAAE,sBAAsB,CAAC,CAAC;IAC5C,aAAa,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC;IAC3B,OAAO,CAAC,CAAC;AACX,CAAC;AAED,QAAQ,CAAC,oCAAoC,EAAE,GAAG,EAAE;IAClD,EAAE,CAAC,4CAA4C,EAAE,GAAG,EAAE;QACpD,MAAM,CAAC,GAAG,SAAS,CAAC,+DAA+D,CAAC,CAAC;QACrF,MAAM,GAAG,GAAG,CAAC,IAAY,EAAE,IAAc,EAAE,EAAE;YAC3C,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;YACpC,cAAc,CAAC,CAAC,EAAE,gCAAgC,CAAC,CAAC;YACpD,OAAO,wBAAwB,CAAC;QAClC,CAAC,CAAC;QACF,MAAM,CAAC,uBAAuB,CAAC,aAAa,EAAE,CAAC,EAAE,gBAAgB,EAAE,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAC3F,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,2BAA2B,EAAE,GAAG,EAAE;QACnC,MAAM,CAAC,GAAG,SAAS,CAAC,6FAA6F,CAAC,CAAC;QACnH,MAAM,GAAG,GAAG,GAAG,EAAE,CAAC,wBAAwB,CAAC;QAC3C,MAAM,CAAC,uBAAuB,CAAC,aAAa,EAAE,CAAC,EAAE,gBAAgB,EAAE,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAC3F,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uDAAuD,EAAE,GAAG,EAAE;QAC/D,MAAM,CAAC,GAAG,SAAS,CAAC,+DAA+D,CAAC,CAAC;QACrF,MAAM,GAAG,GAAG,GAAG,EAAE,CAAC,wBAAwB,CAAC,CAAC,iBAAiB;QAC7D,MAAM,CAAC,GAAG,EAAE,CAAC,uBAAuB,CAAC,aAAa,EAAE,CAAC,EAAE,gBAAgB,EAAE,GAAG,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC;IAC3F,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,9 @@
1
+ export type RunSync = (cmd: string, args: string[]) => string;
2
+ /**
3
+ * Resolve a scoped data token (e.g. "calendar-d1" = D1 only) from the house
4
+ * minter. Shells cf-token.sh, which mints or reuses the scope and persists the
5
+ * key into the house env file, echoing the key name; reads that key back and
6
+ * returns its value. Throws if the key is absent after the run.
7
+ */
8
+ export declare function resolveHouseScopedToken(scope: string, houseEnvPath: string, cfTokenShPath: string, run?: RunSync): string;
9
+ //# sourceMappingURL=house-scoped-token.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"house-scoped-token.d.ts","sourceRoot":"","sources":["../../src/lib/house-scoped-token.ts"],"names":[],"mappings":"AAQA,MAAM,MAAM,OAAO,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,MAAM,CAAC;AAkB9D;;;;;GAKG;AACH,wBAAgB,uBAAuB,CACrC,KAAK,EAAE,MAAM,EACb,YAAY,EAAE,MAAM,EACpB,aAAa,EAAE,MAAM,EACrB,GAAG,GAAE,OAAoB,GACxB,MAAM,CAWR"}
@@ -0,0 +1,51 @@
1
+ // Task 1670 — the house Cloudflare credential is a minter. The booking calendar
2
+ // mints (then reuses) a D1-only scoped token from it via cf-token.sh, the single
3
+ // mint/reuse state machine. Kept local to the scheduling plugin because it
4
+ // cannot import the storage-broker lib; only the ~10-line shell-and-readback
5
+ // wrapper is mirrored — the mint logic itself lives only in cf-token.sh.
6
+ import { readFileSync } from "node:fs";
7
+ import { spawnSync } from "node:child_process";
8
+ const defaultRun = (cmd, args) => {
9
+ const r = spawnSync(cmd, args, { encoding: "utf-8", timeout: 60_000 });
10
+ if (r.status !== 0) {
11
+ throw new Error(`${cmd} ${args.join(" ")} failed (status ${r.status ?? "null"}): ${r.stderr ?? ""}`);
12
+ }
13
+ return r.stdout;
14
+ };
15
+ function readKey(path, key) {
16
+ for (const line of readFileSync(path, "utf8").split("\n")) {
17
+ const m = line.match(/^([A-Z0-9_]+)=(.*)$/);
18
+ if (m && m[1] === key)
19
+ return m[2].trim();
20
+ }
21
+ return undefined;
22
+ }
23
+ /**
24
+ * Resolve a scoped data token (e.g. "calendar-d1" = D1 only) from the house
25
+ * minter. Shells cf-token.sh, which mints or reuses the scope and persists the
26
+ * key into the house env file, echoing the key name; reads that key back and
27
+ * returns its value. Throws if the key is absent after the run.
28
+ */
29
+ export function resolveHouseScopedToken(scope, houseEnvPath, cfTokenShPath, run = defaultRun) {
30
+ const preexisting = readKey(houseEnvPath, keyForScope(scope)) !== undefined;
31
+ const out = run("bash", [cfTokenShPath, scope, houseEnvPath]);
32
+ const keyName = out.trim().split("\n").pop()?.trim() ?? "";
33
+ if (!keyName)
34
+ throw new Error(`scheduling: cf-token.sh ${scope} returned no key name`);
35
+ const value = readKey(houseEnvPath, keyName);
36
+ if (!value)
37
+ throw new Error(`scheduling: scoped token ${keyName} absent in ${houseEnvPath} after mint`);
38
+ console.error(`[calendar] op=house-scoped-token src=house scope=${scope} action=${preexisting ? "reuse" : "mint"} result=active`);
39
+ return value;
40
+ }
41
+ function keyForScope(scope) {
42
+ switch (scope) {
43
+ case "calendar-d1":
44
+ return "CF_CALENDAR_D1_TOKEN";
45
+ case "storage":
46
+ return "CF_STORAGE_TOKEN";
47
+ default:
48
+ return "";
49
+ }
50
+ }
51
+ //# sourceMappingURL=house-scoped-token.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"house-scoped-token.js","sourceRoot":"","sources":["../../src/lib/house-scoped-token.ts"],"names":[],"mappings":"AAAA,gFAAgF;AAChF,iFAAiF;AACjF,2EAA2E;AAC3E,6EAA6E;AAC7E,yEAAyE;AACzE,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAI/C,MAAM,UAAU,GAAY,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE;IACxC,MAAM,CAAC,GAAG,SAAS,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC;IACvE,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACnB,MAAM,IAAI,KAAK,CAAC,GAAG,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC,MAAM,IAAI,MAAM,MAAM,CAAC,CAAC,MAAM,IAAI,EAAE,EAAE,CAAC,CAAC;IACvG,CAAC;IACD,OAAO,CAAC,CAAC,MAAM,CAAC;AAClB,CAAC,CAAC;AAEF,SAAS,OAAO,CAAC,IAAY,EAAE,GAAW;IACxC,KAAK,MAAM,IAAI,IAAI,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;QAC1D,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,qBAAqB,CAAC,CAAC;QAC5C,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,GAAG;YAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IAC5C,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,uBAAuB,CACrC,KAAa,EACb,YAAoB,EACpB,aAAqB,EACrB,MAAe,UAAU;IAEzB,MAAM,WAAW,GAAG,OAAO,CAAC,YAAY,EAAE,WAAW,CAAC,KAAK,CAAC,CAAC,KAAK,SAAS,CAAC;IAC5E,MAAM,GAAG,GAAG,GAAG,CAAC,MAAM,EAAE,CAAC,aAAa,EAAE,KAAK,EAAE,YAAY,CAAC,CAAC,CAAC;IAC9D,MAAM,OAAO,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;IAC3D,IAAI,CAAC,OAAO;QAAE,MAAM,IAAI,KAAK,CAAC,2BAA2B,KAAK,uBAAuB,CAAC,CAAC;IACvF,MAAM,KAAK,GAAG,OAAO,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;IAC7C,IAAI,CAAC,KAAK;QAAE,MAAM,IAAI,KAAK,CAAC,4BAA4B,OAAO,cAAc,YAAY,aAAa,CAAC,CAAC;IACxG,OAAO,CAAC,KAAK,CACX,oDAAoD,KAAK,WAAW,WAAW,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,gBAAgB,CACnH,CAAC;IACF,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,WAAW,CAAC,KAAa;IAChC,QAAQ,KAAK,EAAE,CAAC;QACd,KAAK,aAAa;YAChB,OAAO,sBAAsB,CAAC;QAChC,KAAK,SAAS;YACZ,OAAO,kBAAkB,CAAC;QAC5B;YACE,OAAO,EAAE,CAAC;IACd,CAAC;AACH,CAAC"}
@@ -27,6 +27,7 @@ import { spawnSync } from "node:child_process";
27
27
  import { readFileSync, writeFileSync, existsSync, unlinkSync, mkdirSync, mkdtempSync, rmSync } from "node:fs";
28
28
  import { resolve, join, basename } from "node:path";
29
29
  import { homedir, tmpdir } from "node:os";
30
+ import { resolveHouseScopedToken } from "../lib/house-scoped-token.js";
30
31
  function resolveConfigDir() {
31
32
  const platformRoot = process.env.PLATFORM_ROOT;
32
33
  if (!platformRoot)
@@ -148,12 +149,25 @@ async function main() {
148
149
  console.error(`[calendar-availability] op=publish accountId=${accountId} result=skipped reason=no-platform-root`);
149
150
  return;
150
151
  }
151
- const houseCred = readEnvFile(join(platformRoot, "config", "cloudflare-house.env"));
152
+ const houseEnvPath = join(platformRoot, "config", "cloudflare-house.env");
153
+ const houseCred = readEnvFile(houseEnvPath);
152
154
  const token = houseCred.CLOUDFLARE_API_TOKEN;
153
155
  if (!token) {
154
156
  console.error(`[calendar-availability] op=publish accountId=${accountId} result=skipped reason=no-house-cloudflare-credential`);
155
157
  return;
156
158
  }
159
+ // Task 1670 — the house credential is a minter; mint (then reuse) a D1-only
160
+ // scoped token from it via cf-token.sh and run wrangler on THAT, never the
161
+ // minter directly (a minter returns 10000 on wrangler d1).
162
+ const cfTokenSh = join(platformRoot, "plugins/cloudflare/bin/cf-token.sh");
163
+ let scopedToken;
164
+ try {
165
+ scopedToken = resolveHouseScopedToken("calendar-d1", houseEnvPath, cfTokenSh);
166
+ }
167
+ catch (err) {
168
+ console.error(`[calendar-availability] op=publish accountId=${accountId} result=skipped reason=scoped-token-mint-failed err="${err.message}"`);
169
+ return;
170
+ }
157
171
  const port = process.env.MAXY_UI_INTERNAL_PORT;
158
172
  if (!port) {
159
173
  console.error(`[calendar-availability] op=publish accountId=${accountId} result=error reason=no-internal-port`);
@@ -215,7 +229,7 @@ ON CONFLICT(id) DO UPDATE SET payload=excluded.payload, updatedAt=excluded.updat
215
229
  try {
216
230
  writeFileSync(sqlFile, sql);
217
231
  const wranglerEnv = {
218
- CLOUDFLARE_API_TOKEN: token,
232
+ CLOUDFLARE_API_TOKEN: scopedToken,
219
233
  ...(houseCred.CLOUDFLARE_ACCOUNT_ID ? { CLOUDFLARE_ACCOUNT_ID: houseCred.CLOUDFLARE_ACCOUNT_ID } : {}),
220
234
  };
221
235
  const proc = spawnSync("npx", ["wrangler", "d1", "execute", dbName, "--remote", "--file", sqlFile], {
@@ -1 +1 @@
1
- {"version":3,"file":"publish-availability.js","sourceRoot":"","sources":["../../src/scripts/publish-availability.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"publish-availability.js","sourceRoot":"","sources":["../../src/scripts/publish-availability.ts"],"names":[],"mappings":"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"}
@@ -29,6 +29,7 @@ import { homedir } from "node:os";
29
29
  import { reconcileOne, auditCounts, ensureConnectorSyncEvent, countPublishedConflicts } from "../lib/booking-reconcile.js";
30
30
  import { notifyBooking } from "../lib/booking-notify.js";
31
31
  import { buildD1Command } from "../lib/d1-command.js";
32
+ import { resolveHouseScopedToken } from "../lib/house-scoped-token.js";
32
33
  function resolveConfigDir() {
33
34
  const platformRoot = process.env.PLATFORM_ROOT;
34
35
  if (!platformRoot)
@@ -323,17 +324,30 @@ async function main() {
323
324
  if (accountIds.length === 0)
324
325
  return;
325
326
  // Task 1631 — the account-wide Cloudflare credential lives house-only.
326
- const houseCred = readEnvFile(join(platformRoot, "config", "cloudflare-house.env"));
327
+ const houseEnvPath = join(platformRoot, "config", "cloudflare-house.env");
328
+ const houseCred = readEnvFile(houseEnvPath);
327
329
  const houseToken = houseCred.CLOUDFLARE_API_TOKEN;
328
330
  if (!houseToken) {
329
331
  console.error("[calendar-reconcile] skip reason=no-house-cloudflare-credential");
330
332
  return;
331
333
  }
332
334
  const houseAccountId = houseCred.CLOUDFLARE_ACCOUNT_ID;
335
+ // Task 1670 — the house credential is a minter; mint (then reuse) a D1-only
336
+ // scoped token from it via cf-token.sh and run wrangler on THAT, never the
337
+ // minter directly (a minter returns 10000 on wrangler d1).
338
+ const cfTokenSh = join(platformRoot, "plugins/cloudflare/bin/cf-token.sh");
339
+ let scopedToken;
340
+ try {
341
+ scopedToken = resolveHouseScopedToken("calendar-d1", houseEnvPath, cfTokenSh);
342
+ }
343
+ catch (err) {
344
+ console.error(`[calendar-reconcile] skip reason=scoped-token-mint-failed err="${err.message}"`);
345
+ return;
346
+ }
333
347
  driver = connectNeo4j();
334
348
  for (const accountId of accountIds) {
335
349
  try {
336
- await reconcileAccount(driver, accountId, join(accountsDir, accountId), houseToken, houseAccountId);
350
+ await reconcileAccount(driver, accountId, join(accountsDir, accountId), scopedToken, houseAccountId);
337
351
  }
338
352
  catch (err) {
339
353
  console.error(`[calendar-reconcile] account=${accountId} run-failed err="${err.message}"`);