@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.
- package/package.json +1 -1
- package/payload/platform/lib/mcp-lifeline/dist/index.d.ts.map +1 -1
- package/payload/platform/lib/mcp-lifeline/dist/index.js +22 -1
- package/payload/platform/lib/mcp-lifeline/dist/index.js.map +1 -1
- package/payload/platform/lib/mcp-lifeline/src/__tests__/lifeline.test.ts +26 -0
- package/payload/platform/lib/mcp-lifeline/src/index.ts +24 -1
- package/payload/platform/lib/storage-broker/dist/__tests__/cf-exec.test.js +322 -2
- package/payload/platform/lib/storage-broker/dist/__tests__/cf-exec.test.js.map +1 -1
- package/payload/platform/lib/storage-broker/dist/__tests__/object-limits.test.d.ts +2 -0
- package/payload/platform/lib/storage-broker/dist/__tests__/object-limits.test.d.ts.map +1 -0
- package/payload/platform/lib/storage-broker/dist/__tests__/object-limits.test.js +59 -0
- package/payload/platform/lib/storage-broker/dist/__tests__/object-limits.test.js.map +1 -0
- package/payload/platform/lib/storage-broker/dist/cf-exec.d.ts +12 -1
- package/payload/platform/lib/storage-broker/dist/cf-exec.d.ts.map +1 -1
- package/payload/platform/lib/storage-broker/dist/cf-exec.js +156 -26
- package/payload/platform/lib/storage-broker/dist/cf-exec.js.map +1 -1
- package/payload/platform/lib/storage-broker/dist/house-credential.d.ts.map +1 -1
- package/payload/platform/lib/storage-broker/dist/house-credential.js +8 -2
- package/payload/platform/lib/storage-broker/dist/house-credential.js.map +1 -1
- package/payload/platform/lib/storage-broker/dist/index.d.ts +1 -0
- package/payload/platform/lib/storage-broker/dist/index.d.ts.map +1 -1
- package/payload/platform/lib/storage-broker/dist/index.js +1 -0
- package/payload/platform/lib/storage-broker/dist/index.js.map +1 -1
- package/payload/platform/lib/storage-broker/dist/object-limits.d.ts +53 -0
- package/payload/platform/lib/storage-broker/dist/object-limits.d.ts.map +1 -0
- package/payload/platform/lib/storage-broker/dist/object-limits.js +72 -0
- package/payload/platform/lib/storage-broker/dist/object-limits.js.map +1 -0
- package/payload/platform/lib/storage-broker/src/__tests__/cf-exec.test.ts +362 -3
- package/payload/platform/lib/storage-broker/src/__tests__/object-limits.test.ts +76 -0
- package/payload/platform/lib/storage-broker/src/cf-exec.ts +230 -44
- package/payload/platform/lib/storage-broker/src/house-credential.ts +8 -2
- package/payload/platform/lib/storage-broker/src/index.ts +1 -0
- package/payload/platform/lib/storage-broker/src/object-limits.ts +75 -0
- package/payload/platform/plugins/admin/skills/platform-architecture/SKILL.md +5 -5
- package/payload/platform/plugins/cloudflare/bin/__tests__/cf-token.test.sh +145 -4
- package/payload/platform/plugins/cloudflare/bin/cf-token.sh +61 -3
- package/payload/platform/plugins/cloudflare/references/api.md +1 -1
- package/payload/platform/plugins/cloudflare/skills/cloudflare/SKILL.md +1 -1
- package/payload/platform/plugins/docs/references/outlook-guide.md +4 -4
- package/payload/platform/plugins/outlook/.claude-plugin/plugin.json +1 -1
- package/payload/platform/plugins/outlook/PLUGIN.md +2 -2
- package/payload/platform/plugins/outlook/mcp/dist/__tests__/attach.test.d.ts +2 -0
- package/payload/platform/plugins/outlook/mcp/dist/__tests__/attach.test.d.ts.map +1 -0
- package/payload/platform/plugins/outlook/mcp/dist/__tests__/attach.test.js +138 -0
- package/payload/platform/plugins/outlook/mcp/dist/__tests__/attach.test.js.map +1 -0
- package/payload/platform/plugins/outlook/mcp/dist/__tests__/draft-attachments.test.d.ts +2 -0
- package/payload/platform/plugins/outlook/mcp/dist/__tests__/draft-attachments.test.d.ts.map +1 -0
- package/payload/platform/plugins/outlook/mcp/dist/__tests__/draft-attachments.test.js +121 -0
- package/payload/platform/plugins/outlook/mcp/dist/__tests__/draft-attachments.test.js.map +1 -0
- package/payload/platform/plugins/outlook/mcp/dist/__tests__/draft-edit-attachments.test.d.ts +2 -0
- package/payload/platform/plugins/outlook/mcp/dist/__tests__/draft-edit-attachments.test.d.ts.map +1 -0
- package/payload/platform/plugins/outlook/mcp/dist/__tests__/draft-edit-attachments.test.js +102 -0
- package/payload/platform/plugins/outlook/mcp/dist/__tests__/draft-edit-attachments.test.js.map +1 -0
- package/payload/platform/plugins/outlook/mcp/dist/__tests__/draft-edit.test.js +16 -3
- package/payload/platform/plugins/outlook/mcp/dist/__tests__/draft-edit.test.js.map +1 -1
- package/payload/platform/plugins/outlook/mcp/dist/__tests__/graph-client.test.js +108 -1
- package/payload/platform/plugins/outlook/mcp/dist/__tests__/graph-client.test.js.map +1 -1
- package/payload/platform/plugins/outlook/mcp/dist/__tests__/mail-send-attachments.test.d.ts +2 -0
- package/payload/platform/plugins/outlook/mcp/dist/__tests__/mail-send-attachments.test.d.ts.map +1 -0
- package/payload/platform/plugins/outlook/mcp/dist/__tests__/mail-send-attachments.test.js +209 -0
- package/payload/platform/plugins/outlook/mcp/dist/__tests__/mail-send-attachments.test.js.map +1 -0
- package/payload/platform/plugins/outlook/mcp/dist/index.js +10 -7
- package/payload/platform/plugins/outlook/mcp/dist/index.js.map +1 -1
- package/payload/platform/plugins/outlook/mcp/dist/lib/attach.d.ts +37 -0
- package/payload/platform/plugins/outlook/mcp/dist/lib/attach.d.ts.map +1 -0
- package/payload/platform/plugins/outlook/mcp/dist/lib/attach.js +79 -0
- package/payload/platform/plugins/outlook/mcp/dist/lib/attach.js.map +1 -0
- package/payload/platform/plugins/outlook/mcp/dist/lib/graph-client.d.ts +42 -15
- package/payload/platform/plugins/outlook/mcp/dist/lib/graph-client.d.ts.map +1 -1
- package/payload/platform/plugins/outlook/mcp/dist/lib/graph-client.js +32 -1
- package/payload/platform/plugins/outlook/mcp/dist/lib/graph-client.js.map +1 -1
- package/payload/platform/plugins/outlook/mcp/dist/lib/message.d.ts +8 -0
- package/payload/platform/plugins/outlook/mcp/dist/lib/message.d.ts.map +1 -1
- package/payload/platform/plugins/outlook/mcp/dist/lib/message.js +4 -0
- package/payload/platform/plugins/outlook/mcp/dist/lib/message.js.map +1 -1
- package/payload/platform/plugins/outlook/mcp/dist/lib/outbound-attachments.d.ts +31 -8
- package/payload/platform/plugins/outlook/mcp/dist/lib/outbound-attachments.d.ts.map +1 -1
- package/payload/platform/plugins/outlook/mcp/dist/lib/outbound-attachments.js +40 -13
- package/payload/platform/plugins/outlook/mcp/dist/lib/outbound-attachments.js.map +1 -1
- package/payload/platform/plugins/outlook/mcp/dist/lib/upload-session.d.ts +9 -5
- package/payload/platform/plugins/outlook/mcp/dist/lib/upload-session.d.ts.map +1 -1
- package/payload/platform/plugins/outlook/mcp/dist/lib/upload-session.js +12 -8
- package/payload/platform/plugins/outlook/mcp/dist/lib/upload-session.js.map +1 -1
- package/payload/platform/plugins/outlook/mcp/dist/tools/calendar-event.d.ts.map +1 -1
- package/payload/platform/plugins/outlook/mcp/dist/tools/calendar-event.js +3 -5
- package/payload/platform/plugins/outlook/mcp/dist/tools/calendar-event.js.map +1 -1
- package/payload/platform/plugins/outlook/mcp/dist/tools/draft-edit.d.ts +36 -4
- package/payload/platform/plugins/outlook/mcp/dist/tools/draft-edit.d.ts.map +1 -1
- package/payload/platform/plugins/outlook/mcp/dist/tools/draft-edit.js +56 -9
- package/payload/platform/plugins/outlook/mcp/dist/tools/draft-edit.js.map +1 -1
- package/payload/platform/plugins/outlook/mcp/dist/tools/draft.d.ts +13 -2
- package/payload/platform/plugins/outlook/mcp/dist/tools/draft.d.ts.map +1 -1
- package/payload/platform/plugins/outlook/mcp/dist/tools/draft.js +18 -4
- package/payload/platform/plugins/outlook/mcp/dist/tools/draft.js.map +1 -1
- package/payload/platform/plugins/outlook/mcp/dist/tools/mail-attachment.d.ts.map +1 -1
- package/payload/platform/plugins/outlook/mcp/dist/tools/mail-attachment.js +3 -4
- package/payload/platform/plugins/outlook/mcp/dist/tools/mail-attachment.js.map +1 -1
- package/payload/platform/plugins/outlook/mcp/dist/tools/mail-fetch-body.d.ts.map +1 -1
- package/payload/platform/plugins/outlook/mcp/dist/tools/mail-fetch-body.js +2 -4
- package/payload/platform/plugins/outlook/mcp/dist/tools/mail-fetch-body.js.map +1 -1
- package/payload/platform/plugins/outlook/mcp/dist/tools/mail-reply.d.ts.map +1 -1
- package/payload/platform/plugins/outlook/mcp/dist/tools/mail-reply.js +3 -20
- package/payload/platform/plugins/outlook/mcp/dist/tools/mail-reply.js.map +1 -1
- package/payload/platform/plugins/outlook/mcp/dist/tools/mail-send.d.ts +27 -3
- package/payload/platform/plugins/outlook/mcp/dist/tools/mail-send.d.ts.map +1 -1
- package/payload/platform/plugins/outlook/mcp/dist/tools/mail-send.js +53 -8
- package/payload/platform/plugins/outlook/mcp/dist/tools/mail-send.js.map +1 -1
- package/payload/platform/plugins/outlook/references/graph-surfaces.md +41 -6
- package/payload/platform/plugins/outlook/skills/outlook/SKILL.md +22 -5
- package/payload/platform/plugins/storage-broker/PLUGIN.md +41 -2
- package/payload/platform/plugins/storage-broker/mcp/dist/__tests__/confine-path.test.d.ts +2 -0
- package/payload/platform/plugins/storage-broker/mcp/dist/__tests__/confine-path.test.d.ts.map +1 -0
- package/payload/platform/plugins/storage-broker/mcp/dist/__tests__/confine-path.test.js +85 -0
- package/payload/platform/plugins/storage-broker/mcp/dist/__tests__/confine-path.test.js.map +1 -0
- package/payload/platform/plugins/storage-broker/mcp/dist/__tests__/put-source.test.d.ts +2 -0
- package/payload/platform/plugins/storage-broker/mcp/dist/__tests__/put-source.test.d.ts.map +1 -0
- package/payload/platform/plugins/storage-broker/mcp/dist/__tests__/put-source.test.js +77 -0
- package/payload/platform/plugins/storage-broker/mcp/dist/__tests__/put-source.test.js.map +1 -0
- package/payload/platform/plugins/storage-broker/mcp/dist/confine-path.d.ts +12 -0
- package/payload/platform/plugins/storage-broker/mcp/dist/confine-path.d.ts.map +1 -0
- package/payload/platform/plugins/storage-broker/mcp/dist/confine-path.js +107 -0
- package/payload/platform/plugins/storage-broker/mcp/dist/confine-path.js.map +1 -0
- package/payload/platform/plugins/storage-broker/mcp/dist/index.js +86 -0
- package/payload/platform/plugins/storage-broker/mcp/dist/index.js.map +1 -1
- package/payload/platform/plugins/storage-broker/mcp/dist/put-source.d.ts +11 -0
- package/payload/platform/plugins/storage-broker/mcp/dist/put-source.d.ts.map +1 -0
- package/payload/platform/plugins/storage-broker/mcp/dist/put-source.js +35 -0
- package/payload/platform/plugins/storage-broker/mcp/dist/put-source.js.map +1 -0
- package/payload/platform/scripts/logs-read-jsonl.test.sh +118 -0
- package/payload/platform/scripts/logs-read.sh +63 -9
- package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.d.ts.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.js +4 -0
- package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.js.map +1 -1
- package/payload/server/{chunk-F4D35LKL.js → chunk-POBXIHOF.js} +34 -0
- package/payload/server/{chunk-SDYRKIYY.js → chunk-Q6W4U6HL.js} +153 -27
- package/payload/server/maxy-edge.js +1 -1
- package/payload/server/server.js +206 -6
- 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
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
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
|
-
|
|
161
|
-
|
|
162
|
-
const
|
|
163
|
-
if (
|
|
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
|
|
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
|
|
183
|
-
const
|
|
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(
|
|
190
|
-
${
|
|
191
|
-
|
|
192
|
-
|
|
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 (
|
|
305
|
+
return new Uint8Array(await res.arrayBuffer());
|
|
197
306
|
},
|
|
198
|
-
async
|
|
199
|
-
await
|
|
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,
|
package/payload/server/server.js
CHANGED
|
@@ -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-
|
|
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
|
-
|
|
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-
|
|
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-
|
|
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
|
};
|