@rubytech/create-maxy-code 0.1.458 → 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 (116) hide show
  1. package/package.json +1 -1
  2. package/payload/platform/lib/storage-broker/dist/__tests__/cf-exec.test.js +188 -3
  3. package/payload/platform/lib/storage-broker/dist/__tests__/cf-exec.test.js.map +1 -1
  4. package/payload/platform/lib/storage-broker/dist/__tests__/object-limits.test.d.ts +2 -0
  5. package/payload/platform/lib/storage-broker/dist/__tests__/object-limits.test.d.ts.map +1 -0
  6. package/payload/platform/lib/storage-broker/dist/__tests__/object-limits.test.js +59 -0
  7. package/payload/platform/lib/storage-broker/dist/__tests__/object-limits.test.js.map +1 -0
  8. package/payload/platform/lib/storage-broker/dist/cf-exec.d.ts +12 -1
  9. package/payload/platform/lib/storage-broker/dist/cf-exec.d.ts.map +1 -1
  10. package/payload/platform/lib/storage-broker/dist/cf-exec.js +97 -0
  11. package/payload/platform/lib/storage-broker/dist/cf-exec.js.map +1 -1
  12. package/payload/platform/lib/storage-broker/dist/house-credential.d.ts.map +1 -1
  13. package/payload/platform/lib/storage-broker/dist/house-credential.js +4 -2
  14. package/payload/platform/lib/storage-broker/dist/house-credential.js.map +1 -1
  15. package/payload/platform/lib/storage-broker/dist/index.d.ts +1 -0
  16. package/payload/platform/lib/storage-broker/dist/index.d.ts.map +1 -1
  17. package/payload/platform/lib/storage-broker/dist/index.js +1 -0
  18. package/payload/platform/lib/storage-broker/dist/index.js.map +1 -1
  19. package/payload/platform/lib/storage-broker/dist/object-limits.d.ts +53 -0
  20. package/payload/platform/lib/storage-broker/dist/object-limits.d.ts.map +1 -0
  21. package/payload/platform/lib/storage-broker/dist/object-limits.js +72 -0
  22. package/payload/platform/lib/storage-broker/dist/object-limits.js.map +1 -0
  23. package/payload/platform/lib/storage-broker/src/__tests__/cf-exec.test.ts +211 -5
  24. package/payload/platform/lib/storage-broker/src/__tests__/object-limits.test.ts +76 -0
  25. package/payload/platform/lib/storage-broker/src/cf-exec.ts +148 -6
  26. package/payload/platform/lib/storage-broker/src/house-credential.ts +4 -2
  27. package/payload/platform/lib/storage-broker/src/index.ts +1 -0
  28. package/payload/platform/lib/storage-broker/src/object-limits.ts +75 -0
  29. package/payload/platform/plugins/admin/skills/platform-architecture/SKILL.md +5 -5
  30. package/payload/platform/plugins/cloudflare/bin/cf-token.sh +4 -3
  31. package/payload/platform/plugins/cloudflare/references/api.md +1 -1
  32. package/payload/platform/plugins/docs/references/outlook-guide.md +4 -4
  33. package/payload/platform/plugins/outlook/.claude-plugin/plugin.json +1 -1
  34. package/payload/platform/plugins/outlook/PLUGIN.md +2 -2
  35. package/payload/platform/plugins/outlook/mcp/dist/__tests__/attach.test.d.ts +2 -0
  36. package/payload/platform/plugins/outlook/mcp/dist/__tests__/attach.test.d.ts.map +1 -0
  37. package/payload/platform/plugins/outlook/mcp/dist/__tests__/attach.test.js +138 -0
  38. package/payload/platform/plugins/outlook/mcp/dist/__tests__/attach.test.js.map +1 -0
  39. package/payload/platform/plugins/outlook/mcp/dist/__tests__/draft-attachments.test.d.ts +2 -0
  40. package/payload/platform/plugins/outlook/mcp/dist/__tests__/draft-attachments.test.d.ts.map +1 -0
  41. package/payload/platform/plugins/outlook/mcp/dist/__tests__/draft-attachments.test.js +121 -0
  42. package/payload/platform/plugins/outlook/mcp/dist/__tests__/draft-attachments.test.js.map +1 -0
  43. package/payload/platform/plugins/outlook/mcp/dist/__tests__/draft-edit-attachments.test.d.ts +2 -0
  44. package/payload/platform/plugins/outlook/mcp/dist/__tests__/draft-edit-attachments.test.d.ts.map +1 -0
  45. package/payload/platform/plugins/outlook/mcp/dist/__tests__/draft-edit-attachments.test.js +102 -0
  46. package/payload/platform/plugins/outlook/mcp/dist/__tests__/draft-edit-attachments.test.js.map +1 -0
  47. package/payload/platform/plugins/outlook/mcp/dist/__tests__/draft-edit.test.js +1 -1
  48. package/payload/platform/plugins/outlook/mcp/dist/__tests__/draft-edit.test.js.map +1 -1
  49. package/payload/platform/plugins/outlook/mcp/dist/__tests__/mail-send-attachments.test.d.ts +2 -0
  50. package/payload/platform/plugins/outlook/mcp/dist/__tests__/mail-send-attachments.test.d.ts.map +1 -0
  51. package/payload/platform/plugins/outlook/mcp/dist/__tests__/mail-send-attachments.test.js +209 -0
  52. package/payload/platform/plugins/outlook/mcp/dist/__tests__/mail-send-attachments.test.js.map +1 -0
  53. package/payload/platform/plugins/outlook/mcp/dist/index.js +10 -7
  54. package/payload/platform/plugins/outlook/mcp/dist/index.js.map +1 -1
  55. package/payload/platform/plugins/outlook/mcp/dist/lib/attach.d.ts +37 -0
  56. package/payload/platform/plugins/outlook/mcp/dist/lib/attach.d.ts.map +1 -0
  57. package/payload/platform/plugins/outlook/mcp/dist/lib/attach.js +79 -0
  58. package/payload/platform/plugins/outlook/mcp/dist/lib/attach.js.map +1 -0
  59. package/payload/platform/plugins/outlook/mcp/dist/lib/message.d.ts +8 -0
  60. package/payload/platform/plugins/outlook/mcp/dist/lib/message.d.ts.map +1 -1
  61. package/payload/platform/plugins/outlook/mcp/dist/lib/message.js +4 -0
  62. package/payload/platform/plugins/outlook/mcp/dist/lib/message.js.map +1 -1
  63. package/payload/platform/plugins/outlook/mcp/dist/lib/outbound-attachments.d.ts +31 -8
  64. package/payload/platform/plugins/outlook/mcp/dist/lib/outbound-attachments.d.ts.map +1 -1
  65. package/payload/platform/plugins/outlook/mcp/dist/lib/outbound-attachments.js +40 -13
  66. package/payload/platform/plugins/outlook/mcp/dist/lib/outbound-attachments.js.map +1 -1
  67. package/payload/platform/plugins/outlook/mcp/dist/lib/upload-session.d.ts +9 -5
  68. package/payload/platform/plugins/outlook/mcp/dist/lib/upload-session.d.ts.map +1 -1
  69. package/payload/platform/plugins/outlook/mcp/dist/lib/upload-session.js +12 -8
  70. package/payload/platform/plugins/outlook/mcp/dist/lib/upload-session.js.map +1 -1
  71. package/payload/platform/plugins/outlook/mcp/dist/tools/draft-edit.d.ts +29 -4
  72. package/payload/platform/plugins/outlook/mcp/dist/tools/draft-edit.d.ts.map +1 -1
  73. package/payload/platform/plugins/outlook/mcp/dist/tools/draft-edit.js +46 -13
  74. package/payload/platform/plugins/outlook/mcp/dist/tools/draft-edit.js.map +1 -1
  75. package/payload/platform/plugins/outlook/mcp/dist/tools/draft.d.ts +8 -2
  76. package/payload/platform/plugins/outlook/mcp/dist/tools/draft.d.ts.map +1 -1
  77. package/payload/platform/plugins/outlook/mcp/dist/tools/draft.js +13 -4
  78. package/payload/platform/plugins/outlook/mcp/dist/tools/draft.js.map +1 -1
  79. package/payload/platform/plugins/outlook/mcp/dist/tools/mail-reply.d.ts.map +1 -1
  80. package/payload/platform/plugins/outlook/mcp/dist/tools/mail-reply.js +3 -20
  81. package/payload/platform/plugins/outlook/mcp/dist/tools/mail-reply.js.map +1 -1
  82. package/payload/platform/plugins/outlook/mcp/dist/tools/mail-send.d.ts +27 -3
  83. package/payload/platform/plugins/outlook/mcp/dist/tools/mail-send.d.ts.map +1 -1
  84. package/payload/platform/plugins/outlook/mcp/dist/tools/mail-send.js +53 -8
  85. package/payload/platform/plugins/outlook/mcp/dist/tools/mail-send.js.map +1 -1
  86. package/payload/platform/plugins/outlook/references/graph-surfaces.md +29 -6
  87. package/payload/platform/plugins/outlook/skills/outlook/SKILL.md +22 -5
  88. package/payload/platform/plugins/storage-broker/PLUGIN.md +41 -2
  89. package/payload/platform/plugins/storage-broker/mcp/dist/__tests__/confine-path.test.d.ts +2 -0
  90. package/payload/platform/plugins/storage-broker/mcp/dist/__tests__/confine-path.test.d.ts.map +1 -0
  91. package/payload/platform/plugins/storage-broker/mcp/dist/__tests__/confine-path.test.js +85 -0
  92. package/payload/platform/plugins/storage-broker/mcp/dist/__tests__/confine-path.test.js.map +1 -0
  93. package/payload/platform/plugins/storage-broker/mcp/dist/__tests__/put-source.test.d.ts +2 -0
  94. package/payload/platform/plugins/storage-broker/mcp/dist/__tests__/put-source.test.d.ts.map +1 -0
  95. package/payload/platform/plugins/storage-broker/mcp/dist/__tests__/put-source.test.js +77 -0
  96. package/payload/platform/plugins/storage-broker/mcp/dist/__tests__/put-source.test.js.map +1 -0
  97. package/payload/platform/plugins/storage-broker/mcp/dist/confine-path.d.ts +12 -0
  98. package/payload/platform/plugins/storage-broker/mcp/dist/confine-path.d.ts.map +1 -0
  99. package/payload/platform/plugins/storage-broker/mcp/dist/confine-path.js +107 -0
  100. package/payload/platform/plugins/storage-broker/mcp/dist/confine-path.js.map +1 -0
  101. package/payload/platform/plugins/storage-broker/mcp/dist/index.js +86 -0
  102. package/payload/platform/plugins/storage-broker/mcp/dist/index.js.map +1 -1
  103. package/payload/platform/plugins/storage-broker/mcp/dist/put-source.d.ts +11 -0
  104. package/payload/platform/plugins/storage-broker/mcp/dist/put-source.d.ts.map +1 -0
  105. package/payload/platform/plugins/storage-broker/mcp/dist/put-source.js +35 -0
  106. package/payload/platform/plugins/storage-broker/mcp/dist/put-source.js.map +1 -0
  107. package/payload/platform/scripts/logs-read-jsonl.test.sh +118 -0
  108. package/payload/platform/scripts/logs-read.sh +63 -9
  109. package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.d.ts.map +1 -1
  110. package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.js +4 -0
  111. package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.js.map +1 -1
  112. package/payload/server/{chunk-F4D35LKL.js → chunk-POBXIHOF.js} +34 -0
  113. package/payload/server/{chunk-64FGYKNZ.js → chunk-Q6W4U6HL.js} +104 -0
  114. package/payload/server/maxy-edge.js +1 -1
  115. package/payload/server/server.js +206 -6
  116. package/payload/server/{src-S7C4P6TT.js → src-3I2RYZFB.js} +9 -1
@@ -627,7 +627,7 @@ tail_mode() {
627
627
  # non-interactive SSH PATH. argv[1] selects the mode (timeline|scan); the
628
628
  # program is fed via -c so logs-read.sh stays a single self-contained file.
629
629
  JSONL_PY=$(cat <<'PY'
630
- import sys, os, re, json, glob
630
+ import sys, os, re, json, glob, collections
631
631
 
632
632
  MODE = sys.argv[1] if len(sys.argv) > 1 else ''
633
633
 
@@ -776,7 +776,40 @@ def subagent_dir(projects_root, uuid):
776
776
  # failure (the task's target, flagged 'SUBAGENT ERROR' and counted) from the
777
777
  # parent session's own tool error (shown plainly, never counted as a subagent
778
778
  # error). Returns the count of SUBAGENT errors found (0 for the parent).
779
- def collect_events(path, source, events, is_sub):
779
+ # A harness rejection is a call that NEVER REACHED its tool: the CLI refused the
780
+ # model's arguments, so no MCP dispatch happened and no plugin line exists
781
+ # anywhere (not in server.log, not in mcp-<server>-<sessionId>.log, not in
782
+ # mcp-lifeline). Rendering it as a plain tool error reads as "the tool is broken"
783
+ # when the tool was never called -- the confusion that produced a false
784
+ # customer-facing fault report (task 1692).
785
+ #
786
+ # InputValidationError has two sub-classes and BOTH are rejections, because
787
+ # neither dispatches. The label says 'never dispatched', not 'malformed', because
788
+ # only the first is malformed:
789
+ # A. "...could not be parsed as JSON" -- args unparseable; the tool_use block
790
+ # carries __unparsedToolInput. 52 of 170 measured 2026-07-16.
791
+ # B. "...failed due to the following issue(s)" -- the JSON parsed fine and
792
+ # violated the schema (wrong type, missing required). No __unparsedToolInput.
793
+ # 118 of 170, so the majority; calling it 'malformed' would be wrong.
794
+ #
795
+ # This is the ONLY class relabelled. Deliberately NOT covered, all of which keep
796
+ # rendering as '‼ tool error':
797
+ # 'Error: No such tool available:' / 'Unknown skill:' -- different fault, and
798
+ # the missing-tool case already has a PostToolUse hook (mcp-tool-missing.sh)
799
+ # 'MCP error -32602' -- reached the server; its SDK rejected it
800
+ # every unwrapped is_error payload -- the tool ran and returned a failure
801
+ #
802
+ # The <tool_use_error> wrapper alone is NOT a rejection discriminator: measured
803
+ # 2026-07-16 across 733 SiteDesk transcripts it wraps mostly built-in tools that
804
+ # RAN and failed ('File has not been read yet' x60, 'File has been modified
805
+ # since read' x16). Match the error class, not the wrapper.
806
+ def is_rejection(text):
807
+ if not isinstance(text, str):
808
+ return False
809
+ return text.lstrip().startswith('<tool_use_error>InputValidationError:')
810
+
811
+
812
+ def collect_events(path, source, events, is_sub, rejects=None):
780
813
  rows = load_jsonl(path)
781
814
  id2tool = {}
782
815
  for r in rows:
@@ -812,10 +845,18 @@ def collect_events(path, source, events, is_sub):
812
845
  for b in content:
813
846
  if isinstance(b, dict) and b.get('type') == 'tool_result' and b.get('is_error'):
814
847
  tool = id2tool.get(b.get('tool_use_id'))
815
- flag = '‼ SUBAGENT ERROR' if is_sub else '‼ tool error'
816
- events.append((ts, source, 'error', '%s tool=%s error="%s"' % (flag, tool or '?', clip(result_text(b, r), 200))))
817
- if is_sub:
818
- n_err += 1
848
+ body = result_text(b, r)
849
+ if is_rejection(body):
850
+ # Not a tool failure: the call never ran. Never
851
+ # counted as a subagent error for the same reason.
852
+ flag = '‼ REJECTED (never dispatched)'
853
+ if rejects is not None:
854
+ rejects[tool or '?'] += 1
855
+ else:
856
+ flag = '‼ SUBAGENT ERROR' if is_sub else '‼ tool error'
857
+ if is_sub:
858
+ n_err += 1
859
+ events.append((ts, source, 'error', '%s tool=%s error="%s"' % (flag, tool or '?', clip(body, 200))))
819
860
  elif isinstance(content, str) and content.strip():
820
861
  events.append((ts, source, 'text', 'user: ' + clip(content, 160)))
821
862
  return n_err
@@ -826,18 +867,25 @@ def timeline(projects_root, sessions_dir, key):
826
867
  sys.stderr.write('-- trailer: key=%s resolved=no reason=%s\n' % (key, via))
827
868
  return 1
828
869
  events = []
870
+ rejects = collections.Counter()
829
871
  if parent_path and os.path.exists(parent_path):
830
- collect_events(parent_path, 'parent', events, False)
872
+ collect_events(parent_path, 'parent', events, False, rejects)
831
873
  sdir = subagent_dir(projects_root, uuid)
832
874
  sub_count = err_count = 0
833
875
  if sdir:
834
876
  for af in sorted(glob.glob(os.path.join(sdir, 'agent-*.jsonl'))):
835
877
  sub_count += 1
836
- err_count += collect_events(af, agent_type(af) or os.path.basename(af)[:-6], events, True)
878
+ err_count += collect_events(af, agent_type(af) or os.path.basename(af)[:-6], events, True, rejects)
837
879
  events.sort(key=lambda e: e[0])
838
880
  print('# session %s (resolved via %s)' % (uuid, via))
839
881
  print('# parent: %s' % (parent_path or '(no parent transcript on disk)'))
840
882
  print('# subagents: %d subagent-errors: %d' % (sub_count, err_count))
883
+ # Repetition is the diagnostic fact: one fat-fingered call is a typo, N
884
+ # identical ones against a single tool is a wedged loop. Counting it here
885
+ # makes that one greppable line instead of N unrelated ones.
886
+ if rejects:
887
+ top = ' '.join('%s x%d' % (t, n) for t, n in rejects.most_common())
888
+ print('# rejections: %d (%s)' % (sum(rejects.values()), top))
841
889
  print('')
842
890
  for ts, source, _kind, text in events:
843
891
  print('%s [%s] %s' % (ts or ('-' * 24), source, text))
@@ -871,7 +919,13 @@ def scan(projects_root, limit):
871
919
  if isinstance(content, list):
872
920
  for b in content:
873
921
  if isinstance(b, dict) and b.get('type') == 'tool_result' and b.get('is_error'):
874
- errs.append((id2tool.get(b.get('tool_use_id')), result_text(b, r)))
922
+ body = result_text(b, r)
923
+ # A rejection is not a subagent failure: the subagent did
924
+ # not fail, a call was never dispatched. Counting it here
925
+ # would re-create the conflation the timeline just fixed.
926
+ if is_rejection(body):
927
+ continue
928
+ errs.append((id2tool.get(b.get('tool_use_id')), body))
875
929
  if errs:
876
930
  parent_uuid = os.path.basename(os.path.dirname(os.path.dirname(af)))
877
931
  findings.append((af, agent_type(af), parent_uuid, errs))
@@ -1 +1 @@
1
- {"version":3,"file":"canonical-tool-names.generated.d.ts","sourceRoot":"","sources":["../src/canonical-tool-names.generated.ts"],"names":[],"mappings":"AAQA,+EAA+E;AAC/E,eAAO,MAAM,gBAAgB,EAAE,SAAS,MAAM,EAuB7C,CAAA;AAED,gEAAgE;AAChE,eAAO,MAAM,yBAAyB,EAAE,SAAS,MAAM,EAgStD,CAAA"}
1
+ {"version":3,"file":"canonical-tool-names.generated.d.ts","sourceRoot":"","sources":["../src/canonical-tool-names.generated.ts"],"names":[],"mappings":"AAQA,+EAA+E;AAC/E,eAAO,MAAM,gBAAgB,EAAE,SAAS,MAAM,EAuB7C,CAAA;AAED,gEAAgE;AAChE,eAAO,MAAM,yBAAyB,EAAE,SAAS,MAAM,EAoStD,CAAA"}
@@ -276,6 +276,10 @@ export const CANONICAL_MAXY_TOOL_NAMES = [
276
276
  "mcp__plugin_storage-broker_storage-broker__storage-d1-query",
277
277
  "mcp__plugin_storage-broker_storage-broker__storage-r2-bucket-create",
278
278
  "mcp__plugin_storage-broker_storage-broker__storage-r2-bucket-list",
279
+ "mcp__plugin_storage-broker_storage-broker__storage-r2-object-delete",
280
+ "mcp__plugin_storage-broker_storage-broker__storage-r2-object-get",
281
+ "mcp__plugin_storage-broker_storage-broker__storage-r2-object-list",
282
+ "mcp__plugin_storage-broker_storage-broker__storage-r2-object-put",
279
283
  "mcp__plugin_telegram_telegram__message",
280
284
  "mcp__plugin_telegram_telegram__message-history",
281
285
  "mcp__plugin_telegram_telegram__telegram-webhook-register",
@@ -1 +1 @@
1
- {"version":3,"file":"canonical-tool-names.generated.js","sourceRoot":"","sources":["../src/canonical-tool-names.generated.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"canonical-tool-names.generated.js","sourceRoot":"","sources":["../src/canonical-tool-names.generated.ts"],"names":[],"mappings":"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"}
@@ -44,6 +44,39 @@ var compose = (middleware, onError, onNotFound) => {
44
44
  };
45
45
  };
46
46
 
47
+ // node_modules/hono/dist/http-exception.js
48
+ var HTTPException = class extends Error {
49
+ res;
50
+ status;
51
+ /**
52
+ * Creates an instance of `HTTPException`.
53
+ * @param status - HTTP status code for the exception. Defaults to 500.
54
+ * @param options - Additional options for the exception.
55
+ */
56
+ constructor(status = 500, options) {
57
+ super(options?.message, { cause: options?.cause });
58
+ this.res = options?.res;
59
+ this.status = status;
60
+ }
61
+ /**
62
+ * Returns the response object associated with the exception.
63
+ * If a response object is not provided, a new response is created with the error message and status code.
64
+ * @returns The response object.
65
+ */
66
+ getResponse() {
67
+ if (this.res) {
68
+ const newResponse = new Response(this.res.body, {
69
+ status: this.status,
70
+ headers: this.res.headers
71
+ });
72
+ return newResponse;
73
+ }
74
+ return new Response(this.message, {
75
+ status: this.status
76
+ });
77
+ }
78
+ };
79
+
47
80
  // node_modules/hono/dist/request/constants.js
48
81
  var GET_MATCH_RESULT = /* @__PURE__ */ Symbol();
49
82
 
@@ -5886,6 +5919,7 @@ var clientIpMiddleware = async (c, next) => {
5886
5919
  };
5887
5920
 
5888
5921
  export {
5922
+ HTTPException,
5889
5923
  HtmlEscapedCallbackPhase,
5890
5924
  resolveCallback,
5891
5925
  Hono2 as Hono,
@@ -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) => {
@@ -219,6 +241,84 @@ function makeCfExec(cred, run = defaultRun2, fetchFn = defaultFetch) {
219
241
  },
220
242
  async r2Create(name) {
221
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), {
296
+ method: "GET",
297
+ headers: { Authorization: `Bearer ${cred.apiToken}` }
298
+ });
299
+ if (!res.ok) {
300
+ throw new Error(
301
+ `storage-broker: r2 object get failed: ${res.status}
302
+ ${await res.text()}`
303
+ );
304
+ }
305
+ return new Uint8Array(await res.arrayBuffer());
306
+ },
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
+ );
222
322
  }
223
323
  };
224
324
  }
@@ -282,6 +382,10 @@ function stripAccountWideTokens(contents) {
282
382
 
283
383
  export {
284
384
  authorizeAccess,
385
+ R2_OBJECT_MAX_BYTES,
386
+ base64Ceiling,
387
+ R2_OBJECT_PUT_MAX_BODY_BYTES,
388
+ tooLargeMessage,
285
389
  registerResource,
286
390
  resolveOwner,
287
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-64FGYKNZ.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-S7C4P6TT.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-64FGYKNZ.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
  };