@aexhq/cli 0.13.6 → 0.13.8

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/dist/cli.mjs CHANGED
@@ -10,8 +10,14 @@ import { readFile as readFile2, writeFile, readdir as readdir2, stat as stat2 }
10
10
  import { resolve as resolvePath4 } from "node:path";
11
11
 
12
12
  // ../contracts/dist/proxy-protocol.js
13
- var PROXY_PROTOCOL_VERSION = "1";
13
+ var PROXY_PROTOCOL_VERSION_V2 = "2";
14
14
  var PROXY_PROTOCOL_HEADER = "x-aex-proxy-protocol";
15
+ var PROXY_RESP_STATUS_HEADER = "x-aex-proxy-status";
16
+ var PROXY_RESP_MODE_HEADER = "x-aex-proxy-effective-mode";
17
+ var PROXY_RESP_TRUNCATED_HEADER = "x-aex-proxy-truncated";
18
+ var PROXY_RESP_REMAINING_CALLS_HEADER = "x-aex-proxy-remaining-calls";
19
+ var PROXY_RESP_REMAINING_BYTES_HEADER = "x-aex-proxy-remaining-bytes";
20
+ var PROXY_RESP_UPSTREAM_HEADERS_HEADER = "x-aex-proxy-upstream-headers";
15
21
  var PROXY_METHOD_HEADER = "x-aex-method";
16
22
  var PROXY_PATH_HEADER = "x-aex-path";
17
23
  var PROXY_QUERY_HEADER = "x-aex-query";
@@ -114,6 +120,13 @@ var terminalRunStatuses = new Set(TERMINAL_RUN_STATUSES);
114
120
  var SKILL_BUNDLE_LIMITS = {
115
121
  /** Compressed (.zip) ceiling. */
116
122
  maxCompressedBytes: 10 * 1024 * 1024,
123
+ /**
124
+ * Hard ceiling for the direct-to-storage (presigned PUT) upload path, where
125
+ * bytes never transit the hosted API so its memory/request-payload limits no
126
+ * longer cap the bundle. Kept well under the object store's 5 GiB single-PUT
127
+ * limit; objects above this would need S3 multipart, which is out of scope.
128
+ */
129
+ maxBytes: 2 * 1024 * 1024 * 1024,
117
130
  /** Sum of uncompressed file sizes. */
118
131
  maxDecompressedBytes: 50 * 1024 * 1024,
119
132
  /** Number of regular file entries (directories don't count). */
@@ -302,32 +315,63 @@ function rejectStdioMcpShape(record) {
302
315
  }
303
316
  }
304
317
  }
305
- function denyReasonForMcpHost(parsed) {
306
- const host = parsed.hostname.toLowerCase().replace(/^\[|\]$/g, "");
307
- if (host === "localhost" || host.endsWith(".localhost")) {
308
- return "must not target a loopback hostname";
318
+ function denyReasonForHostIp(host) {
319
+ const mappedDotted = /^::(?:ffff:)?(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})$/.exec(host);
320
+ if (mappedDotted) {
321
+ return denyReasonForV4(mappedDotted[1]);
309
322
  }
310
- if (/^127(?:\.[0-9]+){3}$/.test(host)) {
311
- return "must not target loopback IPv4 (127.0.0.0/8)";
323
+ const mappedHex = /^::ffff:([0-9a-f]{1,4}):([0-9a-f]{1,4})$/.exec(host);
324
+ if (mappedHex) {
325
+ const hi = Number.parseInt(mappedHex[1], 16);
326
+ const lo = Number.parseInt(mappedHex[2], 16);
327
+ const dotted = `${hi >> 8}.${hi & 255}.${lo >> 8}.${lo & 255}`;
328
+ return denyReasonForV4(dotted);
312
329
  }
330
+ const v4 = denyReasonForV4(host);
331
+ if (v4)
332
+ return v4;
313
333
  if (host === "::1" || host === "0:0:0:0:0:0:0:1") {
314
334
  return "must not target loopback IPv6 (::1)";
315
335
  }
316
336
  if (/^fe[89ab][0-9a-f]?:/.test(host)) {
317
337
  return "must not target link-local IPv6 (fe80::/10)";
318
338
  }
319
- if (/^169\.254\.[0-9]+\.[0-9]+$/.test(host)) {
339
+ if (/^f[cd][0-9a-f]{0,2}:/.test(host)) {
340
+ return "must not target unique-local IPv6 (fc00::/7)";
341
+ }
342
+ return null;
343
+ }
344
+ function denyReasonForV4(host) {
345
+ if (!/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/.test(host))
346
+ return null;
347
+ const octets = host.split(".").map((o) => Number.parseInt(o, 10));
348
+ if (octets.some((o) => o > 255))
349
+ return null;
350
+ const [a, b] = octets;
351
+ if (a === 127)
352
+ return "must not target loopback IPv4 (127.0.0.0/8)";
353
+ if (a === 169 && b === 254) {
320
354
  return "must not target link-local IPv4 (169.254.0.0/16) \u2014 cloud metadata range";
321
355
  }
322
- if (/^10\.[0-9]+\.[0-9]+\.[0-9]+$/.test(host)) {
323
- return "must not target RFC1918 IPv4 (10.0.0.0/8)";
356
+ if (a === 100 && b >= 64 && b <= 127) {
357
+ return "must not target CGNAT IPv4 (100.64.0.0/10)";
324
358
  }
325
- if (/^172\.(1[6-9]|2[0-9]|3[01])\.[0-9]+\.[0-9]+$/.test(host)) {
359
+ if (a === 10)
360
+ return "must not target RFC1918 IPv4 (10.0.0.0/8)";
361
+ if (a === 172 && b >= 16 && b <= 31)
326
362
  return "must not target RFC1918 IPv4 (172.16.0.0/12)";
327
- }
328
- if (/^192\.168\.[0-9]+\.[0-9]+$/.test(host)) {
363
+ if (a === 192 && b === 168)
329
364
  return "must not target RFC1918 IPv4 (192.168.0.0/16)";
365
+ return null;
366
+ }
367
+ function denyReasonForMcpHost(parsed) {
368
+ const host = parsed.hostname.toLowerCase().replace(/^\[|\]$/g, "");
369
+ if (host === "localhost" || host.endsWith(".localhost")) {
370
+ return "must not target a loopback hostname";
330
371
  }
372
+ const ipDenial = denyReasonForHostIp(host);
373
+ if (ipDenial)
374
+ return ipDenial;
331
375
  if (parsed.protocol === "https:" && parsed.port !== "" && parsed.port !== "443") {
332
376
  return `must use port 443 for https (got ${parsed.port})`;
333
377
  }
@@ -544,7 +588,7 @@ var BLOCKED_MANAGED_KEY_POLICY_V1 = Object.freeze({
544
588
  schemaVersion: MANAGED_KEY_POLICY_SCHEMA_VERSION,
545
589
  credentialMode: "managed",
546
590
  launchStage: "blocked",
547
- serviceAvailable: false,
591
+ privateImplementationAvailable: false,
548
592
  billingRequired: true,
549
593
  providers: Object.freeze([]),
550
594
  runtimes: Object.freeze([]),
@@ -624,7 +668,7 @@ var forbiddenStringPatterns = Object.freeze([
624
668
  regex: /\b(?:sk-(?:ant|proj|live|test|deepseek|openai)|xox[baprs]-|AIza)[A-Za-z0-9_-]{8,}/i
625
669
  },
626
670
  { reason: "signed_url", regex: /[?&](?:X-Amz-Signature|X-Amz-Credential|X-Amz-Algorithm|AWSAccessKeyId)=/i },
627
- { reason: "r2_object_key", regex: /(^|[\s"'`])(?:runs|assets)\/[^?<#\s"'`]+/i },
671
+ { reason: "object_store_key", regex: /(^|[\s"'`])(?:runs|assets)\/[^?<#\s"'`]+/i },
628
672
  { reason: "vault_id", regex: /\b(?:vault|vlt|secret)[_:-][A-Za-z0-9][A-Za-z0-9_-]{7,}\b/i },
629
673
  {
630
674
  reason: "private_resource_handle",
@@ -633,7 +677,7 @@ var forbiddenStringPatterns = Object.freeze([
633
677
  { reason: "high_entropy_token", regex: /\b(?=[A-Za-z0-9_-]{40,}\b)(?=.*[A-Za-z])(?=.*\d)[A-Za-z0-9_-]{40,}\b/ }
634
678
  ]);
635
679
  function isForbiddenCustodyFieldName(key) {
636
- return /^(apiKey|secretValue|bearerHash|signedUrl|r2Key|objectKey|vaultId|providerResponseBody|responseBody|privateResourceHandle|resourceHandle|rawBody)$/i.test(key);
680
+ return /^(apiKey|secretValue|bearerHash|signedUrl|objectStoreKey|objectKey|vaultId|providerResponseBody|responseBody|privateResourceHandle|resourceHandle|rawBody)$/i.test(key);
637
681
  }
638
682
 
639
683
  // ../contracts/dist/run-record.js
@@ -650,7 +694,6 @@ var RunRecordArchiveRedactionError = class extends Error {
650
694
  };
651
695
  function buildRunRecordDownloadManifestV1(input) {
652
696
  const outputs = input.outputs.map((file2) => normalizeArtifactSummary(file2));
653
- const logs = input.logs.map((file2) => normalizeArtifactSummary(file2));
654
697
  const errors = (input.errors ?? []).map((error) => Object.freeze({ ...error }));
655
698
  return Object.freeze({
656
699
  schemaVersion: RUN_RECORD_MANIFEST_SCHEMA_VERSION,
@@ -658,9 +701,8 @@ function buildRunRecordDownloadManifestV1(input) {
658
701
  runId: input.runId,
659
702
  namespaces: Object.freeze([
660
703
  namespace("metadata", "Run metadata, submission snapshot, custody, and cost files."),
661
- namespace("events", "Typed event-channel exports and optional full-stream/log-channel exports."),
662
- namespace("outputs", "Captured deliverables produced by the run."),
663
- namespace("logs", "Platform diagnostics and runtime log artifacts.")
704
+ namespace("events", "Typed event-channel exports."),
705
+ namespace("outputs", "Captured deliverables produced by the run.")
664
706
  ]),
665
707
  files: Object.freeze([
666
708
  file("metadata", "metadata/run.json", "run_metadata", "present"),
@@ -670,14 +712,10 @@ function buildRunRecordDownloadManifestV1(input) {
670
712
  file("events", "events/events.jsonl", "typed_events", "present", {
671
713
  recordCount: input.typedEventCount ?? 0
672
714
  }),
673
- file("events", "events/logs.jsonl", "log_events", input.logEvents?.status ?? "unavailable", recordCountExtra(input.logEvents)),
674
- file("events", "events/all.jsonl", "all_events", input.allEvents?.status ?? "unavailable", recordCountExtra(input.allEvents)),
675
715
  file("events", "events/manifest.json", "coordinator_events_manifest", input.coordinatorEventsManifest?.status ?? "unavailable"),
676
- ...outputs.map((output) => artifactFile("outputs", "output", "outputs/", output)),
677
- ...logs.map((log) => artifactFile("logs", "log", "logs/", log))
716
+ ...outputs.map((output) => artifactFile("outputs", "output", "outputs/", output))
678
717
  ]),
679
718
  outputs: Object.freeze(outputs),
680
- logs: Object.freeze(logs),
681
719
  errors: Object.freeze(errors)
682
720
  });
683
721
  }
@@ -698,9 +736,6 @@ function file(namespaceName, path, role, status, extra) {
698
736
  ...extra?.recordCount !== void 0 ? { recordCount: extra.recordCount } : {}
699
737
  });
700
738
  }
701
- function recordCountExtra(input) {
702
- return input?.status === "present" && input.recordCount !== void 0 ? { recordCount: input.recordCount } : void 0;
703
- }
704
739
  function artifactFile(namespaceName, role, prefix, artifact) {
705
740
  return Object.freeze({
706
741
  namespace: namespaceName,
@@ -767,7 +802,7 @@ function isAllowedArchiveHighEntropyField(entryPath, finding) {
767
802
  if (finding.reason !== "high_entropy_token" || !entryPath.endsWith("manifest.json")) {
768
803
  return false;
769
804
  }
770
- return /^\$(?:\.files\[\d+\]|\.outputs\[\d+\]|\.logs\[\d+\])\.id$/.test(finding.path);
805
+ return /^\$(?:\.files\[\d+\]|\.outputs\[\d+\])\.id$/.test(finding.path);
771
806
  }
772
807
  function parseArchiveTextValues(path, text) {
773
808
  if (/\.json$/i.test(path)) {
@@ -806,7 +841,7 @@ function formatArchiveFindingPaths(findings) {
806
841
  // ../contracts/dist/run-retention.js
807
842
  var forbiddenStringPatterns2 = Object.freeze([
808
843
  { reason: "signed_url", regex: /[?&](?:X-Amz-Signature|X-Amz-Credential|X-Amz-Algorithm|AWSAccessKeyId)=/i },
809
- { reason: "r2_object_key", regex: /(^|[\s"'`])(?:runs|assets)\/[^?<#\s"'`]+/i },
844
+ { reason: "object_store_key", regex: /(^|[\s"'`])(?:runs|assets)\/[^?<#\s"'`]+/i },
810
845
  { reason: "vault_id", regex: /\b(?:vault|vlt|secret)[_:-][A-Za-z0-9][A-Za-z0-9_-]{7,}\b/i },
811
846
  {
812
847
  reason: "private_resource_handle",
@@ -823,7 +858,7 @@ var forbiddenStringPatterns3 = Object.freeze([
823
858
  regex: /\b(?:sk-(?:ant|proj|live|test|deepseek|openai)|xox[baprs]-|AIza)[A-Za-z0-9_-]{8,}/i
824
859
  },
825
860
  { reason: "signed_url", regex: /[?&](?:X-Amz-Signature|X-Amz-Credential|X-Amz-Algorithm|AWSAccessKeyId)=/i },
826
- { reason: "r2_object_key", regex: /(^|[\s"'`])(?:runs|assets)\/[^?<#\s"'`]+/i },
861
+ { reason: "object_store_key", regex: /(^|[\s"'`])(?:runs|assets)\/[^?<#\s"'`]+/i },
827
862
  { reason: "vault_id", regex: /\b(?:vault|vlt|secret)[_:-][A-Za-z0-9][A-Za-z0-9_-]{7,}\b/i },
828
863
  {
829
864
  reason: "private_resource_handle",
@@ -1062,39 +1097,6 @@ function extractErrorMessage(body) {
1062
1097
  return "aex API request failed";
1063
1098
  }
1064
1099
 
1065
- // ../contracts/dist/run-artifacts.js
1066
- function runArtifactRel(rel) {
1067
- if (rel.startsWith(".runtime-logs/"))
1068
- return `runtime/${rel.slice(".runtime-logs/".length)}`;
1069
- if (rel.startsWith("runtime/"))
1070
- return rel;
1071
- if (rel.startsWith(".host-logs/"))
1072
- return `host/${rel.slice(".host-logs/".length)}`;
1073
- if (rel.startsWith("host/"))
1074
- return rel;
1075
- if (rel.startsWith(".provider-proxy/"))
1076
- return `provider-proxy/${rel.slice(".provider-proxy/".length)}`;
1077
- if (rel.startsWith("provider-proxy/"))
1078
- return rel;
1079
- if (rel.startsWith(".control-plane/"))
1080
- return `control-plane/${rel.slice(".control-plane/".length)}`;
1081
- if (rel.startsWith("control-plane/"))
1082
- return rel;
1083
- if (rel.startsWith(".goose-logs/"))
1084
- return `runtime/${rel.slice(".goose-logs/".length)}`;
1085
- if (rel.startsWith("goose-logs/"))
1086
- return `runtime/${rel.slice("goose-logs/".length)}`;
1087
- if (rel.startsWith(".fly-logs/"))
1088
- return `host/${rel.slice(".fly-logs/".length)}`;
1089
- if (rel.startsWith("fly-logs/"))
1090
- return `host/${rel.slice("fly-logs/".length)}`;
1091
- if (rel.startsWith(".anthropic-debug/"))
1092
- return `provider-proxy/${rel.slice(".anthropic-debug/".length)}`;
1093
- if (rel.startsWith("anthropic-debug/"))
1094
- return `provider-proxy/${rel.slice("anthropic-debug/".length)}`;
1095
- return rel;
1096
- }
1097
-
1098
1100
  // ../contracts/dist/operations.js
1099
1101
  var operations_exports = {};
1100
1102
  __export(operations_exports, {
@@ -1111,7 +1113,6 @@ __export(operations_exports, {
1111
1113
  deleteWorkspaceAsset: () => deleteWorkspaceAsset,
1112
1114
  download: () => download,
1113
1115
  downloadEvents: () => downloadEvents,
1114
- downloadLogs: () => downloadLogs,
1115
1116
  downloadMetadata: () => downloadMetadata,
1116
1117
  downloadOutput: () => downloadOutput,
1117
1118
  downloadOutputs: () => downloadOutputs,
@@ -1125,7 +1126,6 @@ __export(operations_exports, {
1125
1126
  getSkill: () => getSkill,
1126
1127
  listAgentsMd: () => listAgentsMd,
1127
1128
  listFiles: () => listFiles,
1128
- listLogs: () => listLogs,
1129
1129
  listOutputs: () => listOutputs,
1130
1130
  listRunEvents: () => listRunEvents,
1131
1131
  listSkills: () => listSkills,
@@ -1860,10 +1860,20 @@ async function getRun(http, runId) {
1860
1860
  async function getRunUnit(http, runId) {
1861
1861
  return http.request(`/api/runs/${encodeURIComponent(runId)}`);
1862
1862
  }
1863
- async function listRunEvents(http, runId, options = {}) {
1864
- const query = options.channel && options.channel !== "event" ? { channel: options.channel } : {};
1865
- const result = await http.request(`/api/runs/${encodeURIComponent(runId)}/events`, {}, query);
1866
- return result.events;
1863
+ var LIST_EVENTS_PAGE_BUDGET = 1e3;
1864
+ async function listRunEvents(http, runId) {
1865
+ const path = `/api/runs/${encodeURIComponent(runId)}/events`;
1866
+ const all = [];
1867
+ let cursor;
1868
+ for (let page = 0; page < LIST_EVENTS_PAGE_BUDGET; page++) {
1869
+ const query = cursor !== void 0 ? { cursor: String(cursor) } : {};
1870
+ const result = await http.request(path, {}, query);
1871
+ all.push(...result.events);
1872
+ if (typeof result.nextCursor !== "number")
1873
+ break;
1874
+ cursor = result.nextCursor;
1875
+ }
1876
+ return all;
1867
1877
  }
1868
1878
  async function getCoordinatorTicket(http, runId) {
1869
1879
  return http.request(`/api/runs/${encodeURIComponent(runId)}/events/ticket`, { method: "POST" });
@@ -1872,10 +1882,6 @@ async function listOutputs(http, runId) {
1872
1882
  const result = await http.request(`/api/runs/${encodeURIComponent(runId)}/outputs`);
1873
1883
  return result.outputs;
1874
1884
  }
1875
- async function listLogs(http, runId) {
1876
- const result = await http.request(`/api/runs/${encodeURIComponent(runId)}/logs`);
1877
- return result.logs.map((log) => typeof log.filename === "string" ? { ...log, filename: runArtifactRel(log.filename) } : log);
1878
- }
1879
1885
  async function createOutputLink(http, runId, outputId) {
1880
1886
  return http.request(`/api/runs/${encodeURIComponent(runId)}/outputs/${encodeURIComponent(outputId)}/link`, { method: "POST" });
1881
1887
  }
@@ -1939,7 +1945,7 @@ async function collectArtifactBytes(http, runId, items, zipPrefix, namespace2) {
1939
1945
  path: `${zipPrefix}${rel}`,
1940
1946
  bytes: new Uint8Array(await response.arrayBuffer()),
1941
1947
  ...item.contentType !== void 0 ? { contentType: item.contentType } : {},
1942
- ...namespace2 === "outputs" ? { customerContent: true } : {}
1948
+ customerContent: true
1943
1949
  });
1944
1950
  captured.push({
1945
1951
  id: item.id,
@@ -1956,23 +1962,6 @@ async function collectArtifactBytes(http, runId, items, zipPrefix, namespace2) {
1956
1962
  function eventsJsonl(events) {
1957
1963
  return strToU8(events.map((event) => JSON.stringify(event)).join("\n"));
1958
1964
  }
1959
- async function tryListOptionalRunEvents(http, runId, channel) {
1960
- try {
1961
- const events = await listRunEvents(http, runId, { channel });
1962
- if (channel === "log") {
1963
- return events.length > 0 && events.every(isLogChannelEvent) ? { status: "present", events } : { status: "unavailable", events: [] };
1964
- }
1965
- return hasUnifiedStreamEvidence(events) ? { status: "present", events } : { status: "unavailable", events: [] };
1966
- } catch {
1967
- return { status: "unavailable", events: [] };
1968
- }
1969
- }
1970
- function isLogChannelEvent(event) {
1971
- return event.channel === "log";
1972
- }
1973
- function hasUnifiedStreamEvidence(events) {
1974
- return events.some((event) => event.channel === "log" || event.channel === "event");
1975
- }
1976
1965
  function isPathSelector(selector) {
1977
1966
  return Boolean(selector && typeof selector === "object" && "path" in selector);
1978
1967
  }
@@ -1980,38 +1969,28 @@ function normalizeOutputLookupPath(path) {
1980
1969
  return path.replace(/\\/g, "/").replace(/^\/+/, "");
1981
1970
  }
1982
1971
  async function download(http, runId) {
1983
- const [run, events, logEvents, allEvents, outputs, logItems] = await Promise.all([
1972
+ const [run, events, outputs] = await Promise.all([
1984
1973
  getRun(http, runId),
1985
1974
  listRunEvents(http, runId),
1986
- tryListOptionalRunEvents(http, runId, "log"),
1987
- tryListOptionalRunEvents(http, runId, "all"),
1988
- listOutputs(http, runId),
1989
- listLogs(http, runId)
1975
+ listOutputs(http, runId)
1990
1976
  ]);
1991
1977
  const out = await collectArtifactBytes(http, runId, outputs, "outputs/", "outputs");
1992
- const logs = await collectArtifactBytes(http, runId, logItems, "logs/", "logs");
1993
1978
  const submissionSnapshot = extractSubmissionSnapshot(run);
1994
1979
  const costTelemetry = extractCostTelemetry(run);
1995
1980
  const manifest = buildRunRecordDownloadManifestV1({
1996
1981
  runId,
1997
1982
  outputs: out.captured,
1998
- logs: logs.captured,
1999
- errors: [...out.errors, ...logs.errors],
1983
+ errors: out.errors,
2000
1984
  typedEventCount: events.length,
2001
1985
  ...submissionSnapshot ? { submission: { status: "present" } } : {},
2002
- ...costTelemetry ? { cost: { status: "present" } } : {},
2003
- logEvents: { status: logEvents.status, recordCount: logEvents.events.length },
2004
- allEvents: { status: allEvents.status, recordCount: allEvents.events.length }
1986
+ ...costTelemetry ? { cost: { status: "present" } } : {}
2005
1987
  });
2006
1988
  return zipEntries([
2007
1989
  jsonEntry("metadata/run.json", run),
2008
1990
  ...submissionSnapshot ? [jsonEntry("metadata/submission.json", submissionSnapshot)] : [],
2009
1991
  ...costTelemetry ? [jsonEntry("metadata/cost.json", costTelemetry)] : [],
2010
1992
  jsonlEntry("events/events.jsonl", events),
2011
- ...logEvents.status === "present" ? [jsonlEntry("events/logs.jsonl", logEvents.events)] : [],
2012
- ...allEvents.status === "present" ? [jsonlEntry("events/all.jsonl", allEvents.events)] : [],
2013
1993
  ...out.entries,
2014
- ...logs.entries,
2015
1994
  jsonEntry("manifest.json", manifest)
2016
1995
  ]);
2017
1996
  }
@@ -2023,25 +2002,9 @@ async function downloadOutputs(http, runId) {
2023
2002
  jsonEntry("manifest.json", { runId, namespace: "outputs", outputs: captured, errors })
2024
2003
  ]);
2025
2004
  }
2026
- async function downloadLogs(http, runId) {
2027
- const logItems = await listLogs(http, runId);
2028
- const { entries, captured, errors } = await collectArtifactBytes(http, runId, logItems, "", "logs");
2029
- return zipEntries([
2030
- ...entries,
2031
- jsonEntry("manifest.json", { runId, namespace: "logs", logs: captured, errors })
2032
- ]);
2033
- }
2034
2005
  async function downloadEvents(http, runId) {
2035
- const [events, logEvents, allEvents] = await Promise.all([
2036
- listRunEvents(http, runId),
2037
- tryListOptionalRunEvents(http, runId, "log"),
2038
- tryListOptionalRunEvents(http, runId, "all")
2039
- ]);
2040
- return zipEntries([
2041
- jsonlEntry("events.jsonl", events),
2042
- ...logEvents.status === "present" ? [jsonlEntry("logs.jsonl", logEvents.events)] : [],
2043
- ...allEvents.status === "present" ? [jsonlEntry("all.jsonl", allEvents.events)] : []
2044
- ]);
2006
+ const events = await listRunEvents(http, runId);
2007
+ return zipEntries([jsonlEntry("events.jsonl", events)]);
2045
2008
  }
2046
2009
  async function downloadMetadata(http, runId) {
2047
2010
  const run = await getRun(http, runId);
@@ -2742,7 +2705,7 @@ async function runProxy(io2, rest) {
2742
2705
  const url = `${manifest.proxyBaseUrl.replace(/\/+$/, "")}/${encodeURIComponent(f.endpointName)}`;
2743
2706
  const requestHeaders = new Headers();
2744
2707
  requestHeaders.set("authorization", `Bearer ${token}`);
2745
- requestHeaders.set(PROXY_PROTOCOL_HEADER, PROXY_PROTOCOL_VERSION);
2708
+ requestHeaders.set(PROXY_PROTOCOL_HEADER, PROXY_PROTOCOL_VERSION_V2);
2746
2709
  requestHeaders.set(PROXY_METHOD_HEADER, f.method.toUpperCase());
2747
2710
  requestHeaders.set(PROXY_PATH_HEADER, f.path);
2748
2711
  if (f.query) {
@@ -2776,6 +2739,11 @@ async function runProxy(io2, rest) {
2776
2739
  });
2777
2740
  return RUNTIME_ERR;
2778
2741
  }
2742
+ if (response.headers.get(PROXY_RESP_STATUS_HEADER) !== null) {
2743
+ const envelope = await readStreamedEnvelope(response, f.endpointName);
2744
+ io2.stdout(JSON.stringify(envelope) + "\n");
2745
+ return SUCCESS;
2746
+ }
2779
2747
  const text = await response.text();
2780
2748
  let parsedBody;
2781
2749
  try {
@@ -2813,6 +2781,39 @@ async function resolveBody(io2, spec) {
2813
2781
  function emitError(io2, body) {
2814
2782
  io2.stderr(JSON.stringify(body) + "\n");
2815
2783
  }
2784
+ async function readStreamedEnvelope(response, endpointName) {
2785
+ const effectiveResponseMode = response.headers.get(PROXY_RESP_MODE_HEADER) ?? "headers_only";
2786
+ const upstreamStatus = Number.parseInt(response.headers.get(PROXY_RESP_STATUS_HEADER) ?? "0", 10);
2787
+ const remainingCalls = Number.parseInt(response.headers.get(PROXY_RESP_REMAINING_CALLS_HEADER) ?? "0", 10);
2788
+ const remainingResponseBytes = Number.parseInt(response.headers.get(PROXY_RESP_REMAINING_BYTES_HEADER) ?? "0", 10);
2789
+ let upstreamHeaders = {};
2790
+ const rawHeaders = response.headers.get(PROXY_RESP_UPSTREAM_HEADERS_HEADER);
2791
+ if (rawHeaders) {
2792
+ try {
2793
+ const parsed = JSON.parse(rawHeaders);
2794
+ if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
2795
+ upstreamHeaders = parsed;
2796
+ }
2797
+ } catch {
2798
+ }
2799
+ }
2800
+ const truncatedRaw = response.headers.get(PROXY_RESP_TRUNCATED_HEADER);
2801
+ const bytes = new Uint8Array(await response.arrayBuffer());
2802
+ return {
2803
+ endpointName,
2804
+ upstreamStatus,
2805
+ upstreamHeaders,
2806
+ effectiveResponseMode,
2807
+ // The streamed path can't echo the request-side clamp decision (it
2808
+ // isn't carried back); the effective mode is authoritative for the
2809
+ // agent and matches what v1 surfaced for an un-clamped call.
2810
+ modeClamped: false,
2811
+ remainingCalls,
2812
+ remainingResponseBytes,
2813
+ ...effectiveResponseMode === "full" && bytes.byteLength > 0 ? { upstreamBodyBase64: Buffer.from(bytes).toString("base64") } : {},
2814
+ ...truncatedRaw === "true" ? { truncated: true } : {}
2815
+ };
2816
+ }
2816
2817
  async function tryReadManifest(io2) {
2817
2818
  try {
2818
2819
  const raw = await io2.readFile(AEX_INDEX_PATH);
@@ -3814,7 +3815,6 @@ async function runOutputsCmd(io2, argv) {
3814
3815
  import { resolve as resolvePath3 } from "node:path";
3815
3816
  var NAMESPACE_DOWNLOADERS = {
3816
3817
  outputs: operations_exports.downloadOutputs,
3817
- logs: operations_exports.downloadLogs,
3818
3818
  events: operations_exports.downloadEvents,
3819
3819
  metadata: operations_exports.downloadMetadata
3820
3820
  };
@@ -3847,7 +3847,7 @@ async function runDownloadCmd(io2, argv) {
3847
3847
  const namespace2 = onlyFlag.value;
3848
3848
  const positional = onlyFlag.remaining.filter((arg) => !arg.startsWith("--"));
3849
3849
  if (positional.length !== 1) {
3850
- io2.stderr("usage: aex download <run-id> [--only outputs|logs|events|metadata] [--out path] [common flags]\n");
3850
+ io2.stderr("usage: aex download <run-id> [--only outputs|events|metadata] [--out path] [common flags]\n");
3851
3851
  return USAGE_ERR;
3852
3852
  }
3853
3853
  const runId = positional[0];
@@ -1 +1 @@
1
- bbc00f3784013aefc17bd7b5253652f3290d1fcdef98a2302d32befb4f6bf2ec cli.mjs
1
+ 2e7ad715af0e691bcc91e7f403c611f03d6e9a1e0566889dd32fd4b956b71779 cli.mjs
@@ -3,14 +3,11 @@
3
3
  * a run's content as a zip, assembled client-side from the public read
4
4
  * endpoints (no per-output id required).
5
5
  *
6
- * Without `--only`, downloads EVERYTHING — organised into the four
7
- * namespace folders `metadata/run.json`, typed `events/events.jsonl`,
8
- * optional `events/logs.jsonl` / `events/all.jsonl` when the event API
9
- * serves channel opt-ins, `outputs/<rel>` (deliverables), `logs/<rel>`
10
- * (the `.anthropic-debug/` / `.goose-logs/` / `.fly-logs/` diagnostics)
11
- * — plus `manifest.json`.
6
+ * Without `--only`, downloads everything public — organised into
7
+ * `metadata/run.json`, typed `events/events.jsonl`, `outputs/<rel>`
8
+ * (deliverables), plus `manifest.json`.
12
9
  *
13
- * `--only outputs|logs|events|metadata` downloads just that one
10
+ * `--only outputs|events|metadata` downloads just that one
14
11
  * namespace (files at the zip root).
15
12
  *
16
13
  * `--out` resolves relative to the host CWD; if omitted the file is
@@ -22,7 +19,6 @@ import { operations } from "@aexhq/contracts";
22
19
  import { SUCCESS, USAGE_ERR, emitJsonError, makeHttpClient, parseCommonHostFlags, refuseInsideManagedRun, takeFlagValue } from "./common.js";
23
20
  const NAMESPACE_DOWNLOADERS = {
24
21
  outputs: operations.downloadOutputs,
25
- logs: operations.downloadLogs,
26
22
  events: operations.downloadEvents,
27
23
  metadata: operations.downloadMetadata
28
24
  };
@@ -51,7 +47,7 @@ export async function runDownloadCmd(io, argv) {
51
47
  const namespace = onlyFlag.value;
52
48
  const positional = onlyFlag.remaining.filter((arg) => !arg.startsWith("--"));
53
49
  if (positional.length !== 1) {
54
- io.stderr("usage: aex download <run-id> [--only outputs|logs|events|metadata] [--out path] [common flags]\n");
50
+ io.stderr("usage: aex download <run-id> [--only outputs|events|metadata] [--out path] [common flags]\n");
55
51
  return USAGE_ERR;
56
52
  }
57
53
  const runId = positional[0];
@@ -1 +1 @@
1
- {"version":3,"file":"download.js","sourceRoot":"","sources":["../../src/host/download.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"download.js","sourceRoot":"","sources":["../../src/host/download.ts"],"names":[],"mappings":"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"}
package/dist/proxy.js CHANGED
@@ -7,7 +7,7 @@
7
7
  * This file was extracted from run.ts when the host-side subcommands
8
8
  * (run/status/events/outputs/download/cancel/whoami) were added.
9
9
  */
10
- import { PROXY_PROTOCOL_HEADER, PROXY_PROTOCOL_VERSION, PROXY_METHOD_HEADER, PROXY_PATH_HEADER, PROXY_QUERY_HEADER, PROXY_HEADERS_HEADER, PROXY_RESPONSE_MODE_HEADER, PROXY_RESPONSE_MODES } from "@aexhq/contracts";
10
+ import { PROXY_PROTOCOL_HEADER, PROXY_PROTOCOL_VERSION_V2, PROXY_METHOD_HEADER, PROXY_PATH_HEADER, PROXY_QUERY_HEADER, PROXY_HEADERS_HEADER, PROXY_RESPONSE_MODE_HEADER, PROXY_RESPONSE_MODES, PROXY_RESP_MODE_HEADER, PROXY_RESP_REMAINING_BYTES_HEADER, PROXY_RESP_REMAINING_CALLS_HEADER, PROXY_RESP_STATUS_HEADER, PROXY_RESP_TRUNCATED_HEADER, PROXY_RESP_UPSTREAM_HEADERS_HEADER } from "@aexhq/contracts";
11
11
  import { AEX_INDEX_PATH, AEX_RUN_TOKEN_PATH } from "./internal.js";
12
12
  import { SUCCESS, USAGE_ERR, RUNTIME_ERR } from "./host/common.js";
13
13
  function parseProxyFlags(rest) {
@@ -167,7 +167,7 @@ export async function runProxy(io, rest) {
167
167
  const url = `${manifest.proxyBaseUrl.replace(/\/+$/, "")}/${encodeURIComponent(f.endpointName)}`;
168
168
  const requestHeaders = new Headers();
169
169
  requestHeaders.set("authorization", `Bearer ${token}`);
170
- requestHeaders.set(PROXY_PROTOCOL_HEADER, PROXY_PROTOCOL_VERSION);
170
+ requestHeaders.set(PROXY_PROTOCOL_HEADER, PROXY_PROTOCOL_VERSION_V2);
171
171
  requestHeaders.set(PROXY_METHOD_HEADER, f.method.toUpperCase());
172
172
  requestHeaders.set(PROXY_PATH_HEADER, f.path);
173
173
  if (f.query) {
@@ -202,6 +202,17 @@ export async function runProxy(io, rest) {
202
202
  });
203
203
  return RUNTIME_ERR;
204
204
  }
205
+ // v2 streamed success: the Worker carries the envelope metadata in the
206
+ // x-aex-proxy-* response headers and streams the (already byte-capped)
207
+ // body. Reconstruct the same ProxyResponseEnvelope JSON the agent saw
208
+ // under v1 so the stdout contract is unchanged. A BFF-level error (e.g.
209
+ // unsupported_protocol, policy_denied) still returns a JSON error body
210
+ // with no status header, so it falls through to the JSON path below.
211
+ if (response.headers.get(PROXY_RESP_STATUS_HEADER) !== null) {
212
+ const envelope = await readStreamedEnvelope(response, f.endpointName);
213
+ io.stdout(JSON.stringify(envelope) + "\n");
214
+ return SUCCESS;
215
+ }
205
216
  const text = await response.text();
206
217
  let parsedBody;
207
218
  try {
@@ -244,6 +255,51 @@ async function resolveBody(io, spec) {
244
255
  function emitError(io, body) {
245
256
  io.stderr(JSON.stringify(body) + "\n");
246
257
  }
258
+ /**
259
+ * Reassemble a {@link ProxyResponseEnvelope} from a v2 streamed response.
260
+ * The Worker has already enforced the byte-cap, so reading the body to the
261
+ * end here is bounded by `maxResponseBytes` — the OOM risk lived on the
262
+ * Worker isolate, not in this per-call container process.
263
+ */
264
+ async function readStreamedEnvelope(response, endpointName) {
265
+ const effectiveResponseMode = (response.headers.get(PROXY_RESP_MODE_HEADER) ??
266
+ "headers_only");
267
+ const upstreamStatus = Number.parseInt(response.headers.get(PROXY_RESP_STATUS_HEADER) ?? "0", 10);
268
+ const remainingCalls = Number.parseInt(response.headers.get(PROXY_RESP_REMAINING_CALLS_HEADER) ?? "0", 10);
269
+ const remainingResponseBytes = Number.parseInt(response.headers.get(PROXY_RESP_REMAINING_BYTES_HEADER) ?? "0", 10);
270
+ let upstreamHeaders = {};
271
+ const rawHeaders = response.headers.get(PROXY_RESP_UPSTREAM_HEADERS_HEADER);
272
+ if (rawHeaders) {
273
+ try {
274
+ const parsed = JSON.parse(rawHeaders);
275
+ if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
276
+ upstreamHeaders = parsed;
277
+ }
278
+ }
279
+ catch {
280
+ // The metadata header is Worker-controlled; a malformed value is a
281
+ // protocol bug, not agent input. Degrade to empty rather than crash.
282
+ }
283
+ }
284
+ const truncatedRaw = response.headers.get(PROXY_RESP_TRUNCATED_HEADER);
285
+ const bytes = new Uint8Array(await response.arrayBuffer());
286
+ return {
287
+ endpointName,
288
+ upstreamStatus,
289
+ upstreamHeaders,
290
+ effectiveResponseMode,
291
+ // The streamed path can't echo the request-side clamp decision (it
292
+ // isn't carried back); the effective mode is authoritative for the
293
+ // agent and matches what v1 surfaced for an un-clamped call.
294
+ modeClamped: false,
295
+ remainingCalls,
296
+ remainingResponseBytes,
297
+ ...(effectiveResponseMode === "full" && bytes.byteLength > 0
298
+ ? { upstreamBodyBase64: Buffer.from(bytes).toString("base64") }
299
+ : {}),
300
+ ...(truncatedRaw === "true" ? { truncated: true } : {})
301
+ };
302
+ }
247
303
  export async function tryReadManifest(io) {
248
304
  try {
249
305
  const raw = await io.readFile(AEX_INDEX_PATH);
package/dist/proxy.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"proxy.js","sourceRoot":"","sources":["../src/proxy.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"proxy.js","sourceRoot":"","sources":["../src/proxy.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aexhq/cli",
3
- "version": "0.13.6",
3
+ "version": "0.13.8",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/aexhq/aex.git"
@@ -27,13 +27,13 @@
27
27
  },
28
28
  "dependencies": {
29
29
  "fflate": "^0.8.2",
30
- "@aexhq/contracts": "0.13.6"
30
+ "@aexhq/contracts": "0.13.8"
31
31
  },
32
32
  "devDependencies": {
33
33
  "esbuild": "^0.28.0"
34
34
  },
35
35
  "scripts": {
36
- "build": "tsc -p tsconfig.build.json && node ./scripts/finalize-bundle.mjs",
36
+ "build": "pnpm --filter @aexhq/contracts run build && tsc -p tsconfig.build.json && node ./scripts/finalize-bundle.mjs",
37
37
  "lint": "tsc --noEmit -p tsconfig.json",
38
38
  "pretest": "pnpm run build",
39
39
  "test": "pnpm test:unit",
@@ -3,14 +3,11 @@
3
3
  * a run's content as a zip, assembled client-side from the public read
4
4
  * endpoints (no per-output id required).
5
5
  *
6
- * Without `--only`, downloads EVERYTHING — organised into the four
7
- * namespace folders `metadata/run.json`, typed `events/events.jsonl`,
8
- * optional `events/logs.jsonl` / `events/all.jsonl` when the event API
9
- * serves channel opt-ins, `outputs/<rel>` (deliverables), `logs/<rel>`
10
- * (the `.anthropic-debug/` / `.goose-logs/` / `.fly-logs/` diagnostics)
11
- * — plus `manifest.json`.
6
+ * Without `--only`, downloads everything public — organised into
7
+ * `metadata/run.json`, typed `events/events.jsonl`, `outputs/<rel>`
8
+ * (deliverables), plus `manifest.json`.
12
9
  *
13
- * `--only outputs|logs|events|metadata` downloads just that one
10
+ * `--only outputs|events|metadata` downloads just that one
14
11
  * namespace (files at the zip root).
15
12
  *
16
13
  * `--out` resolves relative to the host CWD; if omitted the file is
@@ -31,11 +28,10 @@ import {
31
28
  takeFlagValue
32
29
  } from "./common.js";
33
30
 
34
- type Namespace = "outputs" | "logs" | "events" | "metadata";
31
+ type Namespace = "outputs" | "events" | "metadata";
35
32
 
36
33
  const NAMESPACE_DOWNLOADERS = {
37
34
  outputs: operations.downloadOutputs,
38
- logs: operations.downloadLogs,
39
35
  events: operations.downloadEvents,
40
36
  metadata: operations.downloadMetadata
41
37
  } satisfies Record<Namespace, typeof operations.download>;
@@ -66,7 +62,7 @@ export async function runDownloadCmd(io: CliIO, argv: readonly string[]): Promis
66
62
 
67
63
  const positional = onlyFlag.remaining.filter((arg) => !arg.startsWith("--"));
68
64
  if (positional.length !== 1) {
69
- io.stderr("usage: aex download <run-id> [--only outputs|logs|events|metadata] [--out path] [common flags]\n");
65
+ io.stderr("usage: aex download <run-id> [--only outputs|events|metadata] [--out path] [common flags]\n");
70
66
  return USAGE_ERR;
71
67
  }
72
68
  const runId = positional[0]!;
package/src/proxy.ts CHANGED
@@ -9,15 +9,23 @@
9
9
  */
10
10
  import {
11
11
  PROXY_PROTOCOL_HEADER,
12
- PROXY_PROTOCOL_VERSION,
12
+ PROXY_PROTOCOL_VERSION_V2,
13
13
  PROXY_METHOD_HEADER,
14
14
  PROXY_PATH_HEADER,
15
15
  PROXY_QUERY_HEADER,
16
16
  PROXY_HEADERS_HEADER,
17
17
  PROXY_RESPONSE_MODE_HEADER,
18
18
  PROXY_RESPONSE_MODES,
19
+ PROXY_RESP_MODE_HEADER,
20
+ PROXY_RESP_REMAINING_BYTES_HEADER,
21
+ PROXY_RESP_REMAINING_CALLS_HEADER,
22
+ PROXY_RESP_STATUS_HEADER,
23
+ PROXY_RESP_TRUNCATED_HEADER,
24
+ PROXY_RESP_UPSTREAM_HEADERS_HEADER,
19
25
  type ProxyErrorBody,
20
- type ProxyIndexFile
26
+ type ProxyIndexFile,
27
+ type ProxyResponseEnvelope,
28
+ type ProxyResponseMode
21
29
  } from "@aexhq/contracts";
22
30
  import { AEX_INDEX_PATH, AEX_RUN_TOKEN_PATH, type CliIO } from "./internal.js";
23
31
  import { SUCCESS, USAGE_ERR, RUNTIME_ERR, type CliExitCode } from "./host/common.js";
@@ -196,7 +204,7 @@ export async function runProxy(io: CliIO, rest: readonly string[]): Promise<CliE
196
204
  const url = `${manifest.proxyBaseUrl.replace(/\/+$/, "")}/${encodeURIComponent(f.endpointName)}`;
197
205
  const requestHeaders = new Headers();
198
206
  requestHeaders.set("authorization", `Bearer ${token}`);
199
- requestHeaders.set(PROXY_PROTOCOL_HEADER, PROXY_PROTOCOL_VERSION);
207
+ requestHeaders.set(PROXY_PROTOCOL_HEADER, PROXY_PROTOCOL_VERSION_V2);
200
208
  requestHeaders.set(PROXY_METHOD_HEADER, f.method.toUpperCase());
201
209
  requestHeaders.set(PROXY_PATH_HEADER, f.path);
202
210
  if (f.query) {
@@ -233,6 +241,18 @@ export async function runProxy(io: CliIO, rest: readonly string[]): Promise<CliE
233
241
  return RUNTIME_ERR;
234
242
  }
235
243
 
244
+ // v2 streamed success: the Worker carries the envelope metadata in the
245
+ // x-aex-proxy-* response headers and streams the (already byte-capped)
246
+ // body. Reconstruct the same ProxyResponseEnvelope JSON the agent saw
247
+ // under v1 so the stdout contract is unchanged. A BFF-level error (e.g.
248
+ // unsupported_protocol, policy_denied) still returns a JSON error body
249
+ // with no status header, so it falls through to the JSON path below.
250
+ if (response.headers.get(PROXY_RESP_STATUS_HEADER) !== null) {
251
+ const envelope = await readStreamedEnvelope(response, f.endpointName);
252
+ io.stdout(JSON.stringify(envelope) + "\n");
253
+ return SUCCESS;
254
+ }
255
+
236
256
  const text = await response.text();
237
257
  let parsedBody: unknown;
238
258
  try {
@@ -278,6 +298,61 @@ function emitError(io: CliIO, body: ProxyErrorBody): void {
278
298
  io.stderr(JSON.stringify(body) + "\n");
279
299
  }
280
300
 
301
+ /**
302
+ * Reassemble a {@link ProxyResponseEnvelope} from a v2 streamed response.
303
+ * The Worker has already enforced the byte-cap, so reading the body to the
304
+ * end here is bounded by `maxResponseBytes` — the OOM risk lived on the
305
+ * Worker isolate, not in this per-call container process.
306
+ */
307
+ async function readStreamedEnvelope(
308
+ response: Response,
309
+ endpointName: string
310
+ ): Promise<ProxyResponseEnvelope> {
311
+ const effectiveResponseMode = (response.headers.get(PROXY_RESP_MODE_HEADER) ??
312
+ "headers_only") as ProxyResponseMode;
313
+ const upstreamStatus = Number.parseInt(response.headers.get(PROXY_RESP_STATUS_HEADER) ?? "0", 10);
314
+ const remainingCalls = Number.parseInt(
315
+ response.headers.get(PROXY_RESP_REMAINING_CALLS_HEADER) ?? "0",
316
+ 10
317
+ );
318
+ const remainingResponseBytes = Number.parseInt(
319
+ response.headers.get(PROXY_RESP_REMAINING_BYTES_HEADER) ?? "0",
320
+ 10
321
+ );
322
+ let upstreamHeaders: Record<string, string> = {};
323
+ const rawHeaders = response.headers.get(PROXY_RESP_UPSTREAM_HEADERS_HEADER);
324
+ if (rawHeaders) {
325
+ try {
326
+ const parsed = JSON.parse(rawHeaders);
327
+ if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
328
+ upstreamHeaders = parsed as Record<string, string>;
329
+ }
330
+ } catch {
331
+ // The metadata header is Worker-controlled; a malformed value is a
332
+ // protocol bug, not agent input. Degrade to empty rather than crash.
333
+ }
334
+ }
335
+ const truncatedRaw = response.headers.get(PROXY_RESP_TRUNCATED_HEADER);
336
+ const bytes = new Uint8Array(await response.arrayBuffer());
337
+
338
+ return {
339
+ endpointName,
340
+ upstreamStatus,
341
+ upstreamHeaders,
342
+ effectiveResponseMode,
343
+ // The streamed path can't echo the request-side clamp decision (it
344
+ // isn't carried back); the effective mode is authoritative for the
345
+ // agent and matches what v1 surfaced for an un-clamped call.
346
+ modeClamped: false,
347
+ remainingCalls,
348
+ remainingResponseBytes,
349
+ ...(effectiveResponseMode === "full" && bytes.byteLength > 0
350
+ ? { upstreamBodyBase64: Buffer.from(bytes).toString("base64") }
351
+ : {}),
352
+ ...(truncatedRaw === "true" ? { truncated: true } : {})
353
+ };
354
+ }
355
+
281
356
  export async function tryReadManifest(io: CliIO): Promise<ProxyIndexFile | null> {
282
357
  try {
283
358
  const raw = await io.readFile(AEX_INDEX_PATH);
package/test/cli.test.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { describe, expect, it, vi } from "vitest";
2
- import { PROXY_PROTOCOL_VERSION } from "@aexhq/contracts";
2
+ import { PROXY_PROTOCOL_VERSION, PROXY_PROTOCOL_VERSION_V2 } from "@aexhq/contracts";
3
3
  import { runCli } from "../src/run.js";
4
4
  import { AEX_INDEX_PATH, AEX_RUN_TOKEN_PATH, type CliIO } from "../src/internal.js";
5
5
 
@@ -228,13 +228,48 @@ describe("aex proxy — successful call", () => {
228
228
  expect(call.url).toBe("https://dash.example.com/api/runs/run-1/proxy/stripe");
229
229
  const headers = new Headers((call.init as RequestInit).headers);
230
230
  expect(headers.get("authorization")).toBe("Bearer bearer-xyz");
231
- expect(headers.get("x-aex-proxy-protocol")).toBe(PROXY_PROTOCOL_VERSION);
231
+ expect(headers.get("x-aex-proxy-protocol")).toBe(PROXY_PROTOCOL_VERSION_V2);
232
232
  expect(headers.get("x-aex-method")).toBe("POST");
233
233
  expect(headers.get("x-aex-path")).toBe("/v1/refunds");
234
234
  const body = JSON.parse(cap.stdout.trim());
235
235
  expect(body.upstreamStatus).toBe(200);
236
236
  });
237
237
 
238
+ it("reconstructs the envelope from a v2 streamed response (headers + raw body)", async () => {
239
+ const upstreamPayload = JSON.stringify({ streamed: true });
240
+ const cap = makeIo({
241
+ argv: ["proxy", "stripe", "--method", "POST", "--path", "/v1/refunds", "--response-mode", "full"],
242
+ files: {
243
+ [AEX_INDEX_PATH]: manifestJson({ endpoints: [{ name: "stripe", allowMethods: ["POST"] }] }),
244
+ [AEX_RUN_TOKEN_PATH]: "bearer-xyz"
245
+ },
246
+ // Mirror the Worker v2 streamed response: raw upstream body + the
247
+ // x-aex-proxy-* metadata headers (no JSON envelope, no base64).
248
+ fetchHandler: async () =>
249
+ new Response(upstreamPayload, {
250
+ status: 200,
251
+ headers: {
252
+ "x-aex-proxy-status": "200",
253
+ "x-aex-proxy-effective-mode": "full",
254
+ "x-aex-proxy-truncated": "false",
255
+ "x-aex-proxy-remaining-calls": "59",
256
+ "x-aex-proxy-remaining-bytes": "999000",
257
+ "x-aex-proxy-upstream-headers": JSON.stringify({ "content-type": "application/json" }),
258
+ "content-type": "application/octet-stream"
259
+ }
260
+ })
261
+ });
262
+ await runCli(cap.io);
263
+ expect(cap.exitCode).toBe(0);
264
+ const body = JSON.parse(cap.stdout.trim());
265
+ expect(body.upstreamStatus).toBe(200);
266
+ expect(body.effectiveResponseMode).toBe("full");
267
+ expect(body.remainingCalls).toBe(59);
268
+ expect(body.upstreamHeaders["content-type"]).toBe("application/json");
269
+ // Body round-trips through the same base64 field v1 used.
270
+ expect(Buffer.from(body.upstreamBodyBase64, "base64").toString("utf8")).toBe(upstreamPayload);
271
+ });
272
+
238
273
  it("forwards --header K=V via the X-Aex-Headers JSON record", async () => {
239
274
  let captured: Headers | null = null;
240
275
  const cap = makeIo({
package/test/host.test.ts CHANGED
@@ -446,9 +446,7 @@ describe("aex cancel + delete", () => {
446
446
 
447
447
  describe("aex download", () => {
448
448
  // Route the reads the download verbs fan out to: getRun + listEvents +
449
- // listOutputs + listLogs + per-artifact /download. The run has one
450
- // deliverable (report.txt in the outputs namespace) and one legacy-named
451
- // diagnostic in the logs namespace.
449
+ // listOutputs + per-output /download.
452
450
  const json = (body: unknown) =>
453
451
  new Response(JSON.stringify(body), { status: 200, headers: { "content-type": "application/json" } });
454
452
  const wholeRunHandler =
@@ -458,19 +456,13 @@ describe("aex download", () => {
458
456
  if (url.endsWith(`/api/runs/${runId}/outputs`)) {
459
457
  return json({ outputs: [{ id: "o1", filename: "report.txt", sizeBytes: 5, contentType: "text/plain" }] });
460
458
  }
461
- if (url.endsWith(`/api/runs/${runId}/logs`)) {
462
- return json({ logs: [{ id: "o2", filename: "goose-logs/stderr.log", sizeBytes: 3, contentType: "text/plain" }] });
463
- }
464
459
  if (url.endsWith(`/api/runs/${runId}/outputs/o1/download`)) {
465
460
  return new Response(strToU8("hello").buffer, { status: 200, headers: { "content-type": "text/plain" } });
466
461
  }
467
- if (url.endsWith(`/api/runs/${runId}/logs/o2/download`)) {
468
- return new Response(strToU8("err").buffer, { status: 200, headers: { "content-type": "text/plain" } });
469
- }
470
462
  return json({ id: runId, status: "succeeded" });
471
463
  };
472
464
 
473
- it("assembles the whole-run zip client-side (four namespace folders) and writes it to --out", async () => {
465
+ it("assembles the public whole-run zip client-side and writes it to --out", async () => {
474
466
  const writes = new Map<string, Uint8Array>();
475
467
  const cap = makeHostIo({
476
468
  argv: ["download", "run-1", "--out", "run-1.zip", ...COMMON],
@@ -479,16 +471,14 @@ describe("aex download", () => {
479
471
  });
480
472
  await runCli(cap.io);
481
473
  expect(cap.exitCode).toBe(0);
482
- // getRun + events + optional log/all event reads + outputs + logs +
483
- // two per-artifact downloads.
484
- expect(cap.calls).toHaveLength(8);
474
+ // getRun + events + outputs + one per-output download.
475
+ expect(cap.calls).toHaveLength(4);
485
476
 
486
477
  const writtenKey = [...writes.keys()][0]!;
487
478
  expect(writtenKey).toMatch(/run-1\.zip$/);
488
479
  const entries = unzipSync(writes.get(writtenKey)!);
489
480
  expect(Object.keys(entries).sort()).toEqual([
490
481
  "events/events.jsonl",
491
- "logs/runtime/stderr.log",
492
482
  "manifest.json",
493
483
  "metadata/run.json",
494
484
  "outputs/report.txt"
@@ -532,17 +522,15 @@ describe("aex download", () => {
532
522
  expect((JSON.parse(cap.stdout.trim()) as { namespace: string }).namespace).toBe("outputs");
533
523
  });
534
524
 
535
- it("--only logs zips just the diagnostics", async () => {
536
- const writes = new Map<string, Uint8Array>();
525
+ it("rejects --only logs with a usage error", async () => {
537
526
  const cap = makeHostIo({
538
527
  argv: ["download", "run-1", "--only", "logs", ...COMMON],
539
- writes,
540
528
  fetchHandler: wholeRunHandler("run-1")
541
529
  });
542
530
  await runCli(cap.io);
543
- expect(cap.exitCode).toBe(0);
544
- const entries = unzipSync(writes.get([...writes.keys()][0]!)!);
545
- expect(Object.keys(entries).sort()).toEqual(["manifest.json", "runtime/stderr.log"]);
531
+ expect(cap.exitCode).toBe(2);
532
+ expect(cap.stderr).toContain("--only must be one of");
533
+ expect(cap.calls).toHaveLength(0);
546
534
  });
547
535
 
548
536
  it("--only metadata reads only the run record", async () => {
@@ -1031,14 +1019,14 @@ describe("aex skills", () => {
1031
1019
  JSON.stringify({
1032
1020
  ok: true,
1033
1021
  skillId: "skl_cli_42",
1034
- uploadUrl: "https://acct.r2.cloudflarestorage.com/bucket/assets/ws/hash?X-Amz-Signature=sig",
1022
+ uploadUrl: "https://object-storage.example.test/bucket/assets/ws/hash?X-Amz-Signature=sig",
1035
1023
  requiredHeaders: { "x-amz-checksum-sha256": "Y2hlY2tzdW0=" },
1036
1024
  expiresInSeconds: 300
1037
1025
  }),
1038
1026
  { status: 201, headers: { "content-type": "application/json" } }
1039
1027
  );
1040
1028
  }
1041
- if (call.url.includes("r2.cloudflarestorage.com")) {
1029
+ if (call.url.includes("object-storage.example.test")) {
1042
1030
  return new Response("", { status: 200 }); // object storage accepts the direct PUT
1043
1031
  }
1044
1032
  if (call.url.endsWith("/api/skills/skl_cli_42/finalize")) {
@@ -1058,11 +1046,11 @@ describe("aex skills", () => {
1058
1046
  expect(cap.exitCode).toBe(0);
1059
1047
  const urls = cap.calls.map((c) => c.url);
1060
1048
  expect(urls).toContain("https://dash.example/api/skills/presign");
1061
- expect(urls.some((u) => u.includes("r2.cloudflarestorage.com"))).toBe(true);
1049
+ expect(urls.some((u) => u.includes("object-storage.example.test"))).toBe(true);
1062
1050
  expect(urls).toContain("https://dash.example/api/skills/skl_cli_42/finalize");
1063
- const r2Put = cap.calls.find((c) => c.url.includes("r2.cloudflarestorage.com"))!;
1064
- expect(r2Put.init.method).toBe("PUT");
1065
- expect((r2Put.init.headers as Record<string, string>)["x-amz-checksum-sha256"]).toBe("Y2hlY2tzdW0=");
1051
+ const storagePut = cap.calls.find((c) => c.url.includes("object-storage.example.test"))!;
1052
+ expect(storagePut.init.method).toBe("PUT");
1053
+ expect((storagePut.init.headers as Record<string, string>)["x-amz-checksum-sha256"]).toBe("Y2hlY2tzdW0=");
1066
1054
  const printed = JSON.parse(cap.stdout.trim()) as { id: string; name: string };
1067
1055
  expect(printed.id).toBe("skl_cli_42");
1068
1056
  expect(printed.name).toBe("rules-cli");
@@ -1099,7 +1087,7 @@ describe("aex skills", () => {
1099
1087
  const urls = cap.calls.map((c) => c.url);
1100
1088
  expect(urls).toContain("https://dash.example/api/skills/presign");
1101
1089
  expect(urls).toContain("https://dash.example/api/skills");
1102
- expect(urls.some((u) => u.includes("r2.cloudflarestorage.com"))).toBe(false);
1090
+ expect(urls.some((u) => u.includes("object-storage.example.test"))).toBe(false);
1103
1091
  const printed = JSON.parse(cap.stdout.trim()) as { id: string };
1104
1092
  expect(printed.id).toBe("skl_fb");
1105
1093
  } finally {