@rubytech/create-maxy-code 0.1.457 → 0.1.459

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 (138) hide show
  1. package/package.json +1 -1
  2. package/payload/platform/lib/mcp-lifeline/dist/index.d.ts.map +1 -1
  3. package/payload/platform/lib/mcp-lifeline/dist/index.js +22 -1
  4. package/payload/platform/lib/mcp-lifeline/dist/index.js.map +1 -1
  5. package/payload/platform/lib/mcp-lifeline/src/__tests__/lifeline.test.ts +26 -0
  6. package/payload/platform/lib/mcp-lifeline/src/index.ts +24 -1
  7. package/payload/platform/lib/storage-broker/dist/__tests__/cf-exec.test.js +322 -2
  8. package/payload/platform/lib/storage-broker/dist/__tests__/cf-exec.test.js.map +1 -1
  9. package/payload/platform/lib/storage-broker/dist/__tests__/object-limits.test.d.ts +2 -0
  10. package/payload/platform/lib/storage-broker/dist/__tests__/object-limits.test.d.ts.map +1 -0
  11. package/payload/platform/lib/storage-broker/dist/__tests__/object-limits.test.js +59 -0
  12. package/payload/platform/lib/storage-broker/dist/__tests__/object-limits.test.js.map +1 -0
  13. package/payload/platform/lib/storage-broker/dist/cf-exec.d.ts +12 -1
  14. package/payload/platform/lib/storage-broker/dist/cf-exec.d.ts.map +1 -1
  15. package/payload/platform/lib/storage-broker/dist/cf-exec.js +156 -26
  16. package/payload/platform/lib/storage-broker/dist/cf-exec.js.map +1 -1
  17. package/payload/platform/lib/storage-broker/dist/house-credential.d.ts.map +1 -1
  18. package/payload/platform/lib/storage-broker/dist/house-credential.js +8 -2
  19. package/payload/platform/lib/storage-broker/dist/house-credential.js.map +1 -1
  20. package/payload/platform/lib/storage-broker/dist/index.d.ts +1 -0
  21. package/payload/platform/lib/storage-broker/dist/index.d.ts.map +1 -1
  22. package/payload/platform/lib/storage-broker/dist/index.js +1 -0
  23. package/payload/platform/lib/storage-broker/dist/index.js.map +1 -1
  24. package/payload/platform/lib/storage-broker/dist/object-limits.d.ts +53 -0
  25. package/payload/platform/lib/storage-broker/dist/object-limits.d.ts.map +1 -0
  26. package/payload/platform/lib/storage-broker/dist/object-limits.js +72 -0
  27. package/payload/platform/lib/storage-broker/dist/object-limits.js.map +1 -0
  28. package/payload/platform/lib/storage-broker/src/__tests__/cf-exec.test.ts +362 -3
  29. package/payload/platform/lib/storage-broker/src/__tests__/object-limits.test.ts +76 -0
  30. package/payload/platform/lib/storage-broker/src/cf-exec.ts +230 -44
  31. package/payload/platform/lib/storage-broker/src/house-credential.ts +8 -2
  32. package/payload/platform/lib/storage-broker/src/index.ts +1 -0
  33. package/payload/platform/lib/storage-broker/src/object-limits.ts +75 -0
  34. package/payload/platform/plugins/admin/skills/platform-architecture/SKILL.md +5 -5
  35. package/payload/platform/plugins/cloudflare/bin/__tests__/cf-token.test.sh +145 -4
  36. package/payload/platform/plugins/cloudflare/bin/cf-token.sh +61 -3
  37. package/payload/platform/plugins/cloudflare/references/api.md +1 -1
  38. package/payload/platform/plugins/cloudflare/skills/cloudflare/SKILL.md +1 -1
  39. package/payload/platform/plugins/docs/references/outlook-guide.md +4 -4
  40. package/payload/platform/plugins/outlook/.claude-plugin/plugin.json +1 -1
  41. package/payload/platform/plugins/outlook/PLUGIN.md +2 -2
  42. package/payload/platform/plugins/outlook/mcp/dist/__tests__/attach.test.d.ts +2 -0
  43. package/payload/platform/plugins/outlook/mcp/dist/__tests__/attach.test.d.ts.map +1 -0
  44. package/payload/platform/plugins/outlook/mcp/dist/__tests__/attach.test.js +138 -0
  45. package/payload/platform/plugins/outlook/mcp/dist/__tests__/attach.test.js.map +1 -0
  46. package/payload/platform/plugins/outlook/mcp/dist/__tests__/draft-attachments.test.d.ts +2 -0
  47. package/payload/platform/plugins/outlook/mcp/dist/__tests__/draft-attachments.test.d.ts.map +1 -0
  48. package/payload/platform/plugins/outlook/mcp/dist/__tests__/draft-attachments.test.js +121 -0
  49. package/payload/platform/plugins/outlook/mcp/dist/__tests__/draft-attachments.test.js.map +1 -0
  50. package/payload/platform/plugins/outlook/mcp/dist/__tests__/draft-edit-attachments.test.d.ts +2 -0
  51. package/payload/platform/plugins/outlook/mcp/dist/__tests__/draft-edit-attachments.test.d.ts.map +1 -0
  52. package/payload/platform/plugins/outlook/mcp/dist/__tests__/draft-edit-attachments.test.js +102 -0
  53. package/payload/platform/plugins/outlook/mcp/dist/__tests__/draft-edit-attachments.test.js.map +1 -0
  54. package/payload/platform/plugins/outlook/mcp/dist/__tests__/draft-edit.test.js +16 -3
  55. package/payload/platform/plugins/outlook/mcp/dist/__tests__/draft-edit.test.js.map +1 -1
  56. package/payload/platform/plugins/outlook/mcp/dist/__tests__/graph-client.test.js +108 -1
  57. package/payload/platform/plugins/outlook/mcp/dist/__tests__/graph-client.test.js.map +1 -1
  58. package/payload/platform/plugins/outlook/mcp/dist/__tests__/mail-send-attachments.test.d.ts +2 -0
  59. package/payload/platform/plugins/outlook/mcp/dist/__tests__/mail-send-attachments.test.d.ts.map +1 -0
  60. package/payload/platform/plugins/outlook/mcp/dist/__tests__/mail-send-attachments.test.js +209 -0
  61. package/payload/platform/plugins/outlook/mcp/dist/__tests__/mail-send-attachments.test.js.map +1 -0
  62. package/payload/platform/plugins/outlook/mcp/dist/index.js +10 -7
  63. package/payload/platform/plugins/outlook/mcp/dist/index.js.map +1 -1
  64. package/payload/platform/plugins/outlook/mcp/dist/lib/attach.d.ts +37 -0
  65. package/payload/platform/plugins/outlook/mcp/dist/lib/attach.d.ts.map +1 -0
  66. package/payload/platform/plugins/outlook/mcp/dist/lib/attach.js +79 -0
  67. package/payload/platform/plugins/outlook/mcp/dist/lib/attach.js.map +1 -0
  68. package/payload/platform/plugins/outlook/mcp/dist/lib/graph-client.d.ts +42 -15
  69. package/payload/platform/plugins/outlook/mcp/dist/lib/graph-client.d.ts.map +1 -1
  70. package/payload/platform/plugins/outlook/mcp/dist/lib/graph-client.js +32 -1
  71. package/payload/platform/plugins/outlook/mcp/dist/lib/graph-client.js.map +1 -1
  72. package/payload/platform/plugins/outlook/mcp/dist/lib/message.d.ts +8 -0
  73. package/payload/platform/plugins/outlook/mcp/dist/lib/message.d.ts.map +1 -1
  74. package/payload/platform/plugins/outlook/mcp/dist/lib/message.js +4 -0
  75. package/payload/platform/plugins/outlook/mcp/dist/lib/message.js.map +1 -1
  76. package/payload/platform/plugins/outlook/mcp/dist/lib/outbound-attachments.d.ts +31 -8
  77. package/payload/platform/plugins/outlook/mcp/dist/lib/outbound-attachments.d.ts.map +1 -1
  78. package/payload/platform/plugins/outlook/mcp/dist/lib/outbound-attachments.js +40 -13
  79. package/payload/platform/plugins/outlook/mcp/dist/lib/outbound-attachments.js.map +1 -1
  80. package/payload/platform/plugins/outlook/mcp/dist/lib/upload-session.d.ts +9 -5
  81. package/payload/platform/plugins/outlook/mcp/dist/lib/upload-session.d.ts.map +1 -1
  82. package/payload/platform/plugins/outlook/mcp/dist/lib/upload-session.js +12 -8
  83. package/payload/platform/plugins/outlook/mcp/dist/lib/upload-session.js.map +1 -1
  84. package/payload/platform/plugins/outlook/mcp/dist/tools/calendar-event.d.ts.map +1 -1
  85. package/payload/platform/plugins/outlook/mcp/dist/tools/calendar-event.js +3 -5
  86. package/payload/platform/plugins/outlook/mcp/dist/tools/calendar-event.js.map +1 -1
  87. package/payload/platform/plugins/outlook/mcp/dist/tools/draft-edit.d.ts +36 -4
  88. package/payload/platform/plugins/outlook/mcp/dist/tools/draft-edit.d.ts.map +1 -1
  89. package/payload/platform/plugins/outlook/mcp/dist/tools/draft-edit.js +56 -9
  90. package/payload/platform/plugins/outlook/mcp/dist/tools/draft-edit.js.map +1 -1
  91. package/payload/platform/plugins/outlook/mcp/dist/tools/draft.d.ts +13 -2
  92. package/payload/platform/plugins/outlook/mcp/dist/tools/draft.d.ts.map +1 -1
  93. package/payload/platform/plugins/outlook/mcp/dist/tools/draft.js +18 -4
  94. package/payload/platform/plugins/outlook/mcp/dist/tools/draft.js.map +1 -1
  95. package/payload/platform/plugins/outlook/mcp/dist/tools/mail-attachment.d.ts.map +1 -1
  96. package/payload/platform/plugins/outlook/mcp/dist/tools/mail-attachment.js +3 -4
  97. package/payload/platform/plugins/outlook/mcp/dist/tools/mail-attachment.js.map +1 -1
  98. package/payload/platform/plugins/outlook/mcp/dist/tools/mail-fetch-body.d.ts.map +1 -1
  99. package/payload/platform/plugins/outlook/mcp/dist/tools/mail-fetch-body.js +2 -4
  100. package/payload/platform/plugins/outlook/mcp/dist/tools/mail-fetch-body.js.map +1 -1
  101. package/payload/platform/plugins/outlook/mcp/dist/tools/mail-reply.d.ts.map +1 -1
  102. package/payload/platform/plugins/outlook/mcp/dist/tools/mail-reply.js +3 -20
  103. package/payload/platform/plugins/outlook/mcp/dist/tools/mail-reply.js.map +1 -1
  104. package/payload/platform/plugins/outlook/mcp/dist/tools/mail-send.d.ts +27 -3
  105. package/payload/platform/plugins/outlook/mcp/dist/tools/mail-send.d.ts.map +1 -1
  106. package/payload/platform/plugins/outlook/mcp/dist/tools/mail-send.js +53 -8
  107. package/payload/platform/plugins/outlook/mcp/dist/tools/mail-send.js.map +1 -1
  108. package/payload/platform/plugins/outlook/references/graph-surfaces.md +41 -6
  109. package/payload/platform/plugins/outlook/skills/outlook/SKILL.md +22 -5
  110. package/payload/platform/plugins/storage-broker/PLUGIN.md +41 -2
  111. package/payload/platform/plugins/storage-broker/mcp/dist/__tests__/confine-path.test.d.ts +2 -0
  112. package/payload/platform/plugins/storage-broker/mcp/dist/__tests__/confine-path.test.d.ts.map +1 -0
  113. package/payload/platform/plugins/storage-broker/mcp/dist/__tests__/confine-path.test.js +85 -0
  114. package/payload/platform/plugins/storage-broker/mcp/dist/__tests__/confine-path.test.js.map +1 -0
  115. package/payload/platform/plugins/storage-broker/mcp/dist/__tests__/put-source.test.d.ts +2 -0
  116. package/payload/platform/plugins/storage-broker/mcp/dist/__tests__/put-source.test.d.ts.map +1 -0
  117. package/payload/platform/plugins/storage-broker/mcp/dist/__tests__/put-source.test.js +77 -0
  118. package/payload/platform/plugins/storage-broker/mcp/dist/__tests__/put-source.test.js.map +1 -0
  119. package/payload/platform/plugins/storage-broker/mcp/dist/confine-path.d.ts +12 -0
  120. package/payload/platform/plugins/storage-broker/mcp/dist/confine-path.d.ts.map +1 -0
  121. package/payload/platform/plugins/storage-broker/mcp/dist/confine-path.js +107 -0
  122. package/payload/platform/plugins/storage-broker/mcp/dist/confine-path.js.map +1 -0
  123. package/payload/platform/plugins/storage-broker/mcp/dist/index.js +86 -0
  124. package/payload/platform/plugins/storage-broker/mcp/dist/index.js.map +1 -1
  125. package/payload/platform/plugins/storage-broker/mcp/dist/put-source.d.ts +11 -0
  126. package/payload/platform/plugins/storage-broker/mcp/dist/put-source.d.ts.map +1 -0
  127. package/payload/platform/plugins/storage-broker/mcp/dist/put-source.js +35 -0
  128. package/payload/platform/plugins/storage-broker/mcp/dist/put-source.js.map +1 -0
  129. package/payload/platform/scripts/logs-read-jsonl.test.sh +118 -0
  130. package/payload/platform/scripts/logs-read.sh +63 -9
  131. package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.d.ts.map +1 -1
  132. package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.js +4 -0
  133. package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.js.map +1 -1
  134. package/payload/server/{chunk-F4D35LKL.js → chunk-POBXIHOF.js} +34 -0
  135. package/payload/server/{chunk-SDYRKIYY.js → chunk-Q6W4U6HL.js} +153 -27
  136. package/payload/server/maxy-edge.js +1 -1
  137. package/payload/server/server.js +206 -6
  138. package/payload/server/{src-554BYJMN.js → src-3I2RYZFB.js} +9 -1
@@ -8,6 +8,22 @@ function authorizeAccess(params) {
8
8
  return { allow: true, reason: "owner" };
9
9
  }
10
10
 
11
+ // ../lib/storage-broker/src/object-limits.ts
12
+ var R2_OBJECT_MAX_BYTES = 100 * 1024 * 1024;
13
+ function base64Ceiling(bytes) {
14
+ return 4 * Math.ceil(bytes / 3);
15
+ }
16
+ var PUT_ENVELOPE_ALLOWANCE_BYTES = 64 * 1024;
17
+ var R2_OBJECT_PUT_MAX_BODY_BYTES = base64Ceiling(R2_OBJECT_MAX_BYTES) + PUT_ENVELOPE_ALLOWANCE_BYTES;
18
+ function formatMiB(bytes) {
19
+ return (bytes / 1024 / 1024).toFixed(1);
20
+ }
21
+ function tooLargeMessage(what, actualBytes) {
22
+ return `${what} is ${formatMiB(actualBytes)} MiB (${actualBytes} bytes), which exceeds the ${formatMiB(
23
+ R2_OBJECT_MAX_BYTES
24
+ )} MiB (${R2_OBJECT_MAX_BYTES} bytes) R2 object limit.`;
25
+ }
26
+
11
27
  // ../lib/storage-broker/src/registry.ts
12
28
  async function registerResource(session, r) {
13
29
  await session.run(
@@ -120,6 +136,12 @@ function keyForScope(scope) {
120
136
  }
121
137
 
122
138
  // ../lib/storage-broker/src/cf-exec.ts
139
+ function encodeObjectKey(key) {
140
+ return key.split("/").map(encodeURIComponent).join("/");
141
+ }
142
+ function objectUrl(accountId, bucket, key) {
143
+ return `https://api.cloudflare.com/client/v4/accounts/${accountId}/r2/buckets/${encodeURIComponent(bucket)}/objects/${encodeObjectKey(key)}`;
144
+ }
123
145
  var defaultFetch = (url, init) => fetch(url, init);
124
146
  var defaultRun2 = (cmd, args, env) => new Promise((resolve, reject) => {
125
147
  execFile2(cmd, args, { env }, (err, stdout, stderr) => {
@@ -138,6 +160,19 @@ function parseJson(raw, context) {
138
160
  throw new Error(`storage-broker: ${context} returned non-JSON output: ${raw}`);
139
161
  }
140
162
  }
163
+ async function cfApiJson(fetchFn, url, init, context) {
164
+ const res = await fetchFn(url, init);
165
+ const body = await res.text();
166
+ if (!res.ok) {
167
+ throw new Error(`storage-broker: ${context} failed: ${res.status}
168
+ ${body}`);
169
+ }
170
+ const parsed = parseJson(body, context);
171
+ if (parsed?.success !== true) {
172
+ throw new Error(`storage-broker: ${context} API error: ${body}`);
173
+ }
174
+ return { parsed, body };
175
+ }
141
176
  function makeCfExec(cred, run = defaultRun2, fetchFn = defaultFetch) {
142
177
  const env = {
143
178
  ...process.env,
@@ -151,24 +186,24 @@ function makeCfExec(cred, run = defaultRun2, fetchFn = defaultFetch) {
151
186
  },
152
187
  async d1Create(name) {
153
188
  const url = `https://api.cloudflare.com/client/v4/accounts/${cred.accountId}/d1/database`;
154
- const res = await fetchFn(url, {
155
- method: "POST",
156
- headers: {
157
- Authorization: `Bearer ${cred.apiToken}`,
158
- "Content-Type": "application/json"
189
+ const { parsed, body } = await cfApiJson(
190
+ fetchFn,
191
+ url,
192
+ {
193
+ method: "POST",
194
+ headers: {
195
+ Authorization: `Bearer ${cred.apiToken}`,
196
+ "Content-Type": "application/json"
197
+ },
198
+ body: JSON.stringify({ name })
159
199
  },
160
- body: JSON.stringify({ name })
161
- });
162
- const body = await res.text();
163
- if (!res.ok) {
164
- throw new Error(`storage-broker: d1 create failed: ${res.status}
165
- ${body}`);
166
- }
167
- const parsed = parseJson(body, "d1 create");
168
- if (parsed.success !== true || typeof parsed.result?.uuid !== "string") {
200
+ "d1 create"
201
+ );
202
+ const uuid = parsed.result?.uuid;
203
+ if (typeof uuid !== "string") {
169
204
  throw new Error(`storage-broker: d1 create API error: ${body}`);
170
205
  }
171
- return { uuid: parsed.result.uuid };
206
+ return { uuid };
172
207
  },
173
208
  async d1Query(name, sql) {
174
209
  const { stdout } = await run(
@@ -179,24 +214,111 @@ ${body}`);
179
214
  return parseJson(stdout, "d1 execute");
180
215
  },
181
216
  async r2List() {
182
- const url = `https://api.cloudflare.com/client/v4/accounts/${cred.accountId}/r2/buckets`;
183
- const res = await fetchFn(url, {
217
+ const base = `https://api.cloudflare.com/client/v4/accounts/${cred.accountId}/r2/buckets`;
218
+ const buckets = [];
219
+ const seen = /* @__PURE__ */ new Set();
220
+ let cursor;
221
+ for (; ; ) {
222
+ const url = cursor === void 0 ? base : `${base}?cursor=${encodeURIComponent(cursor)}`;
223
+ const { parsed } = await cfApiJson(
224
+ fetchFn,
225
+ url,
226
+ { method: "GET", headers: { Authorization: `Bearer ${cred.apiToken}` } },
227
+ "r2 bucket list"
228
+ );
229
+ const page = parsed;
230
+ for (const b of page.result?.buckets ?? []) buckets.push({ name: b.name });
231
+ const next = page.result_info?.cursor;
232
+ if (!next) return buckets;
233
+ if (seen.has(next)) {
234
+ throw new Error(
235
+ `storage-broker: r2 bucket list returned a repeated pagination cursor: ${next}`
236
+ );
237
+ }
238
+ seen.add(next);
239
+ cursor = next;
240
+ }
241
+ },
242
+ async r2Create(name) {
243
+ await run("npx", ["wrangler", "r2", "bucket", "create", name], env);
244
+ },
245
+ // --- R2 objects (Task 1691) -------------------------------------------
246
+ //
247
+ // The v4 REST API exposes the object surface under
248
+ // /accounts/{id}/r2/buckets/{bucket}/objects and accepts the same Bearer
249
+ // token as the bucket endpoints (account-level Workers R2 Storage Write).
250
+ // The r2/api/tokens/ note that "Object Read & Write" is S3-only constrains
251
+ // the bucket-item-scoped *permission types*, not these endpoints.
252
+ //
253
+ // Doc-confirmed, never measured: no house Cloudflare credential exists on
254
+ // the dev machine. The design keeps the unmeasured facts unable to affect
255
+ // correctness — per_page is never sent, and nothing fails silently.
256
+ async r2ObjectList(bucket, prefix) {
257
+ const base = `https://api.cloudflare.com/client/v4/accounts/${cred.accountId}/r2/buckets/${encodeURIComponent(bucket)}/objects`;
258
+ const objects = [];
259
+ const seen = /* @__PURE__ */ new Set();
260
+ let cursor;
261
+ for (; ; ) {
262
+ const params = new URLSearchParams();
263
+ if (prefix !== void 0) params.set("prefix", prefix);
264
+ if (cursor !== void 0) params.set("cursor", cursor);
265
+ const qs = params.toString();
266
+ const { parsed, body } = await cfApiJson(
267
+ fetchFn,
268
+ qs ? `${base}?${qs}` : base,
269
+ { method: "GET", headers: { Authorization: `Bearer ${cred.apiToken}` } },
270
+ "r2 object list"
271
+ );
272
+ const page = parsed;
273
+ for (const o of page.result ?? []) {
274
+ objects.push({ key: o.key, size: o.size, etag: o.etag, lastModified: o.last_modified });
275
+ }
276
+ const truncated = page.result_info?.is_truncated;
277
+ const next = page.result_info?.cursor;
278
+ if (truncated === false) return objects;
279
+ if (truncated === true && !next) {
280
+ throw new Error(
281
+ `storage-broker: r2 object list reported truncated but gave no pagination cursor: ${body}`
282
+ );
283
+ }
284
+ if (!next) return objects;
285
+ if (seen.has(next)) {
286
+ throw new Error(
287
+ `storage-broker: r2 object list returned a repeated pagination cursor: ${next}`
288
+ );
289
+ }
290
+ seen.add(next);
291
+ cursor = next;
292
+ }
293
+ },
294
+ async r2ObjectGet(bucket, key) {
295
+ const res = await fetchFn(objectUrl(cred.accountId, bucket, key), {
184
296
  method: "GET",
185
297
  headers: { Authorization: `Bearer ${cred.apiToken}` }
186
298
  });
187
- const body = await res.text();
188
299
  if (!res.ok) {
189
- throw new Error(`storage-broker: r2 bucket list failed: ${res.status}
190
- ${body}`);
191
- }
192
- const parsed = parseJson(body, "r2 bucket list");
193
- if (parsed.success !== true) {
194
- throw new Error(`storage-broker: r2 bucket list API error: ${body}`);
300
+ throw new Error(
301
+ `storage-broker: r2 object get failed: ${res.status}
302
+ ${await res.text()}`
303
+ );
195
304
  }
196
- return (parsed.result?.buckets ?? []).map((b) => ({ name: b.name }));
305
+ return new Uint8Array(await res.arrayBuffer());
197
306
  },
198
- async r2Create(name) {
199
- await run("npx", ["wrangler", "r2", "bucket", "create", name], env);
307
+ async r2ObjectPut(bucket, key, body) {
308
+ await cfApiJson(
309
+ fetchFn,
310
+ objectUrl(cred.accountId, bucket, key),
311
+ { method: "PUT", headers: { Authorization: `Bearer ${cred.apiToken}` }, body },
312
+ "r2 object put"
313
+ );
314
+ },
315
+ async r2ObjectDelete(bucket, key) {
316
+ await cfApiJson(
317
+ fetchFn,
318
+ objectUrl(cred.accountId, bucket, key),
319
+ { method: "DELETE", headers: { Authorization: `Bearer ${cred.apiToken}` } },
320
+ "r2 object delete"
321
+ );
200
322
  }
201
323
  };
202
324
  }
@@ -260,6 +382,10 @@ function stripAccountWideTokens(contents) {
260
382
 
261
383
  export {
262
384
  authorizeAccess,
385
+ R2_OBJECT_MAX_BYTES,
386
+ base64Ceiling,
387
+ R2_OBJECT_PUT_MAX_BODY_BYTES,
388
+ tooLargeMessage,
263
389
  registerResource,
264
390
  resolveOwner,
265
391
  listResources,
@@ -16,7 +16,7 @@ import {
16
16
  sanitizeClientCorrId,
17
17
  vncLog,
18
18
  websockifyLog
19
- } from "./chunk-F4D35LKL.js";
19
+ } from "./chunk-POBXIHOF.js";
20
20
  import "./chunk-PFF6I7KP.js";
21
21
 
22
22
  // server/edge.ts
@@ -9,6 +9,7 @@ import {
9
9
  CLAUDE_CREDENTIALS_FILE,
10
10
  COMMERCIAL_MODE,
11
11
  GREETING_DIRECTIVE,
12
+ HTTPException,
12
13
  Hono,
13
14
  HtmlEscapedCallbackPhase,
14
15
  INSTALL_OWNER_FILE,
@@ -110,14 +111,17 @@ import {
110
111
  vncLog,
111
112
  walkPremiumBundles,
112
113
  writeAdminUserAndPerson
113
- } from "./chunk-F4D35LKL.js";
114
+ } from "./chunk-POBXIHOF.js";
114
115
  import {
116
+ R2_OBJECT_MAX_BYTES,
117
+ R2_OBJECT_PUT_MAX_BODY_BYTES,
115
118
  authorizeAccess,
116
119
  listResources,
117
120
  makeHouseCfExec,
118
121
  registerResource,
119
- resolveOwner
120
- } from "./chunk-SDYRKIYY.js";
122
+ resolveOwner,
123
+ tooLargeMessage
124
+ } from "./chunk-Q6W4U6HL.js";
121
125
  import {
122
126
  __commonJS,
123
127
  __toESM
@@ -8664,6 +8668,65 @@ app2.get("/group-info", async (c) => {
8664
8668
  });
8665
8669
  var whatsapp_default = app2;
8666
8670
 
8671
+ // node_modules/hono/dist/middleware/body-limit/index.js
8672
+ var ERROR_MESSAGE = "Payload Too Large";
8673
+ var BodyLimitError = class extends Error {
8674
+ constructor(message) {
8675
+ super(message);
8676
+ this.name = "BodyLimitError";
8677
+ }
8678
+ };
8679
+ var bodyLimit = (options) => {
8680
+ const onError = options.onError || (() => {
8681
+ const res = new Response(ERROR_MESSAGE, {
8682
+ status: 413
8683
+ });
8684
+ throw new HTTPException(413, { res });
8685
+ });
8686
+ const maxSize = options.maxSize;
8687
+ return async function bodyLimit2(c, next) {
8688
+ if (!c.req.raw.body) {
8689
+ return next();
8690
+ }
8691
+ const hasTransferEncoding = c.req.raw.headers.has("transfer-encoding");
8692
+ const hasContentLength = c.req.raw.headers.has("content-length");
8693
+ if (hasTransferEncoding && hasContentLength) {
8694
+ }
8695
+ if (hasContentLength && !hasTransferEncoding) {
8696
+ const contentLength = parseInt(c.req.raw.headers.get("content-length") || "0", 10);
8697
+ return contentLength > maxSize ? onError(c) : next();
8698
+ }
8699
+ let size = 0;
8700
+ const rawReader = c.req.raw.body.getReader();
8701
+ const reader = new ReadableStream({
8702
+ async start(controller) {
8703
+ try {
8704
+ for (; ; ) {
8705
+ const { done, value } = await rawReader.read();
8706
+ if (done) {
8707
+ break;
8708
+ }
8709
+ size += value.length;
8710
+ if (size > maxSize) {
8711
+ controller.error(new BodyLimitError(ERROR_MESSAGE));
8712
+ break;
8713
+ }
8714
+ controller.enqueue(value);
8715
+ }
8716
+ } finally {
8717
+ controller.close();
8718
+ }
8719
+ }
8720
+ });
8721
+ const requestInit = { body: reader, duplex: "half" };
8722
+ c.req.raw = new Request(c.req.raw, requestInit);
8723
+ await next();
8724
+ if (c.error instanceof BodyLimitError) {
8725
+ c.res = await onError(c);
8726
+ }
8727
+ };
8728
+ };
8729
+
8667
8730
  // server/routes/storage-broker.ts
8668
8731
  import { join as join11, resolve as resolve11 } from "path";
8669
8732
  import { readdirSync as readdirSync6, readFileSync as readFileSync13, existsSync as existsSync8 } from "fs";
@@ -8674,9 +8737,9 @@ function platformRoot() {
8674
8737
  function caller(c) {
8675
8738
  return c.req.header("x-maxy-caller-account")?.trim() || null;
8676
8739
  }
8677
- function log(action, kind, account, target, owner, result) {
8740
+ function log(action, kind, account, target, owner, result, reason) {
8678
8741
  console.error(
8679
- `[storage-broker] op=storage-broker resource=${kind} action=${action} account=${account} target=${target} owner=${owner ?? "none"} result=${result}`
8742
+ `[storage-broker] op=storage-broker resource=${kind} action=${action} account=${account} target=${target} owner=${owner ?? "none"} result=${result}${reason ? ` reason=${reason}` : ""}`
8680
8743
  );
8681
8744
  }
8682
8745
  function cfExec() {
@@ -8774,9 +8837,146 @@ app3.post("/r2/create", async (c) => {
8774
8837
  await session.close();
8775
8838
  }
8776
8839
  });
8840
+ async function objectGate(c, action) {
8841
+ const account = caller(c);
8842
+ if (!account) return { ok: false, res: c.json({ error: "no-caller" }, 403) };
8843
+ let body;
8844
+ try {
8845
+ body = await c.req.json();
8846
+ } catch (err) {
8847
+ if (err instanceof Error && err.name === "BodyLimitError") throw err;
8848
+ return { ok: false, res: c.json({ error: "invalid-json" }, 400) };
8849
+ }
8850
+ const bucket = body.bucket;
8851
+ if (!bucket || typeof bucket !== "string") {
8852
+ return { ok: false, res: c.json({ error: "bucket-required" }, 400) };
8853
+ }
8854
+ const session = getSession();
8855
+ let owner;
8856
+ try {
8857
+ owner = await resolveOwner(session, "r2", bucket);
8858
+ } catch (err) {
8859
+ return { ok: false, res: c.json({ error: String(err) }, 500) };
8860
+ } finally {
8861
+ await session.close();
8862
+ }
8863
+ const decision = authorizeAccess({ caller: account, owner, action });
8864
+ log(action, "r2", account, bucket, owner, decision.allow ? "allow" : "deny");
8865
+ if (!decision.allow) return { ok: false, res: c.json({ error: decision.reason }, 403) };
8866
+ return { ok: true, bucket, body };
8867
+ }
8868
+ function readKey(body) {
8869
+ const key = body.key;
8870
+ return typeof key === "string" && key.length > 0 ? key : null;
8871
+ }
8872
+ app3.post("/r2/object/list", async (c) => {
8873
+ const gate = await objectGate(c, "list");
8874
+ if (!gate.ok) return gate.res;
8875
+ const prefix = gate.body.prefix;
8876
+ if (prefix !== void 0 && typeof prefix !== "string") {
8877
+ return c.json({ error: "prefix-must-be-string" }, 400);
8878
+ }
8879
+ try {
8880
+ const objects = await (await cfExec()).r2ObjectList(gate.bucket, prefix);
8881
+ return c.json({ objects });
8882
+ } catch (err) {
8883
+ return c.json({ error: String(err) }, 500);
8884
+ }
8885
+ });
8886
+ app3.post("/r2/object/get", async (c) => {
8887
+ const gate = await objectGate(c, "read");
8888
+ if (!gate.ok) return gate.res;
8889
+ const key = readKey(gate.body);
8890
+ if (!key) return c.json({ error: "key-required" }, 400);
8891
+ try {
8892
+ const cf = await cfExec();
8893
+ const listed = await cf.r2ObjectList(gate.bucket, key);
8894
+ const size = listed.find((o) => o.key === key)?.size;
8895
+ if (typeof size !== "number" || !Number.isFinite(size) || size < 0) {
8896
+ log("read", "r2", caller(c) ?? "none", key, caller(c), "deny", "size-unknown");
8897
+ return c.json(
8898
+ {
8899
+ error: `${key} has no recorded size in ${gate.bucket}; refusing to transfer an object that cannot be bounded.`
8900
+ },
8901
+ 409
8902
+ );
8903
+ }
8904
+ if (size > R2_OBJECT_MAX_BYTES) {
8905
+ log("read", "r2", caller(c) ?? "none", key, caller(c), "deny", "object-too-large");
8906
+ return c.json({ error: tooLargeMessage(key, size) }, 413);
8907
+ }
8908
+ const bytes = await cf.r2ObjectGet(gate.bucket, key);
8909
+ return c.json({ contentBase64: Buffer.from(bytes).toString("base64") });
8910
+ } catch (err) {
8911
+ return c.json({ error: String(err) }, 500);
8912
+ }
8913
+ });
8914
+ app3.post(
8915
+ "/r2/object/put",
8916
+ // Task 1695 — before the body is buffered, not after. This process runs
8917
+ // house-level and holds the account-wide credential, so an over-cap body
8918
+ // buffered here is an OOM kill of the brand server. The handler cannot do this
8919
+ // itself: objectGate's c.req.json() has already read the whole body by the time
8920
+ // any handler code runs.
8921
+ //
8922
+ // Not redundant with the MCP's statSync check. Every account shares one unix
8923
+ // user and the agent holds Bash, so these routes are reachable by curl with the
8924
+ // MCP nowhere in the path; a cap enforced only there is bypassed by one
8925
+ // command. The MCP check gives the precise, file-naming error; this one is what
8926
+ // actually bounds house memory.
8927
+ bodyLimit({
8928
+ maxSize: R2_OBJECT_PUT_MAX_BODY_BYTES,
8929
+ // The key is unknown here — the body is deliberately unparsed — so this names
8930
+ // the limit rather than the object. The MCP names the file. The limit is
8931
+ // stated in MiB like every other over-cap message, so an operator reading a
8932
+ // route rejection and an MCP rejection can see they are one rule rather than
8933
+ // two unrelated numbers.
8934
+ //
8935
+ // It logs, because a task filed on "the OOM emits nothing" must not ship a
8936
+ // rejection that also emits nothing. On the content-length branch — the shape
8937
+ // every real caller sends — no body is read and no handler runs, so this line
8938
+ // is the only trace the request ever existed.
8939
+ onError: (c) => {
8940
+ log("write", "r2", caller(c) ?? "none", "*", null, "deny", "body-too-large");
8941
+ return c.json(
8942
+ {
8943
+ error: `request body exceeds the ${(R2_OBJECT_PUT_MAX_BODY_BYTES / 1024 / 1024).toFixed(1)} MiB limit for an R2 object put (a base64-encoded ${(R2_OBJECT_MAX_BYTES / 1024 / 1024).toFixed(1)} MiB object plus its envelope).`
8944
+ },
8945
+ 413
8946
+ );
8947
+ }
8948
+ }),
8949
+ async (c) => {
8950
+ const gate = await objectGate(c, "write");
8951
+ if (!gate.ok) return gate.res;
8952
+ const key = readKey(gate.body);
8953
+ if (!key) return c.json({ error: "key-required" }, 400);
8954
+ const contentBase64 = gate.body.contentBase64;
8955
+ if (typeof contentBase64 !== "string") return c.json({ error: "contentBase64-required" }, 400);
8956
+ try {
8957
+ const bytes = new Uint8Array(Buffer.from(contentBase64, "base64"));
8958
+ await (await cfExec()).r2ObjectPut(gate.bucket, key, bytes);
8959
+ return c.json({ ok: true });
8960
+ } catch (err) {
8961
+ return c.json({ error: String(err) }, 500);
8962
+ }
8963
+ }
8964
+ );
8965
+ app3.post("/r2/object/delete", async (c) => {
8966
+ const gate = await objectGate(c, "write");
8967
+ if (!gate.ok) return gate.res;
8968
+ const key = readKey(gate.body);
8969
+ if (!key) return c.json({ error: "key-required" }, 400);
8970
+ try {
8971
+ await (await cfExec()).r2ObjectDelete(gate.bucket, key);
8972
+ return c.json({ ok: true });
8973
+ } catch (err) {
8974
+ return c.json({ error: String(err) }, 500);
8975
+ }
8976
+ });
8777
8977
  var storage_broker_default = app3;
8778
8978
  async function runStorageAudit(root) {
8779
- const { reconcileStorage } = await import("./src-554BYJMN.js");
8979
+ const { reconcileStorage } = await import("./src-3I2RYZFB.js");
8780
8980
  const session = getSession();
8781
8981
  try {
8782
8982
  const cf = await makeHouseCfExec(root);
@@ -1,6 +1,9 @@
1
1
  import { createRequire as __createRequire } from 'node:module'; const require = __createRequire(import.meta.url);
2
2
  import {
3
+ R2_OBJECT_MAX_BYTES,
4
+ R2_OBJECT_PUT_MAX_BODY_BYTES,
3
5
  authorizeAccess,
6
+ base64Ceiling,
4
7
  listResources,
5
8
  makeCfExec,
6
9
  makeHouseCfExec,
@@ -10,11 +13,15 @@ import {
10
13
  resolveHouseScopedToken,
11
14
  resolveOwner,
12
15
  stripAccountWideTokens,
16
+ tooLargeMessage,
13
17
  validateMapping
14
- } from "./chunk-SDYRKIYY.js";
18
+ } from "./chunk-Q6W4U6HL.js";
15
19
  import "./chunk-PFF6I7KP.js";
16
20
  export {
21
+ R2_OBJECT_MAX_BYTES,
22
+ R2_OBJECT_PUT_MAX_BODY_BYTES,
17
23
  authorizeAccess,
24
+ base64Ceiling,
18
25
  listResources,
19
26
  makeCfExec,
20
27
  makeHouseCfExec,
@@ -24,5 +31,6 @@ export {
24
31
  resolveHouseScopedToken,
25
32
  resolveOwner,
26
33
  stripAccountWideTokens,
34
+ tooLargeMessage,
27
35
  validateMapping
28
36
  };