@aexhq/sdk 0.46.4-canary → 0.50.0
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/LICENSE +201 -0
- package/NOTICE +38 -0
- package/README.md +23 -31
- package/dist/client/aex.d.ts +33 -0
- package/dist/client/aex.js +98 -0
- package/dist/client/aex.js.map +1 -0
- package/dist/client/credentials.d.ts +25 -0
- package/dist/client/credentials.js +97 -0
- package/dist/client/credentials.js.map +1 -0
- package/dist/client/routing.d.ts +7 -0
- package/dist/client/routing.js +29 -0
- package/dist/client/routing.js.map +1 -0
- package/dist/downloads/download.d.ts +25 -0
- package/dist/downloads/download.js +53 -0
- package/dist/downloads/download.js.map +1 -0
- package/dist/generated/errors.d.ts +12 -0
- package/dist/generated/errors.js +81 -0
- package/dist/generated/errors.js.map +1 -0
- package/dist/generated/resources.d.ts +730 -0
- package/dist/generated/resources.js +606 -0
- package/dist/generated/resources.js.map +1 -0
- package/dist/generated/routes.d.ts +42 -0
- package/dist/generated/routes.js +2101 -0
- package/dist/generated/routes.js.map +1 -0
- package/dist/index.d.ts +20 -50
- package/dist/index.js +11 -62
- package/dist/index.js.map +1 -1
- package/dist/observations/stream.d.ts +1 -0
- package/dist/observations/stream.js +18 -0
- package/dist/observations/stream.js.map +1 -0
- package/dist/transport/errors.d.ts +60 -0
- package/dist/transport/errors.js +107 -0
- package/dist/transport/errors.js.map +1 -0
- package/dist/transport/pagination.d.ts +8 -0
- package/dist/transport/pagination.js +34 -0
- package/dist/transport/pagination.js.map +1 -0
- package/dist/transport/retry.d.ts +21 -0
- package/dist/transport/retry.js +37 -0
- package/dist/transport/retry.js.map +1 -0
- package/dist/transport/transport.d.ts +25 -0
- package/dist/transport/transport.js +28 -0
- package/dist/transport/transport.js.map +1 -0
- package/package.json +63 -30
- package/dist/_contracts/account-operations.d.ts +0 -101
- package/dist/_contracts/account-operations.js +0 -242
- package/dist/_contracts/account-types.d.ts +0 -461
- package/dist/_contracts/account-types.js +0 -1
- package/dist/_contracts/api-key.d.ts +0 -61
- package/dist/_contracts/api-key.js +0 -101
- package/dist/_contracts/api-routes.d.ts +0 -20
- package/dist/_contracts/api-routes.js +0 -109
- package/dist/_contracts/archive-limits.d.ts +0 -3
- package/dist/_contracts/archive-limits.js +0 -23
- package/dist/_contracts/asset-authoring.d.ts +0 -22
- package/dist/_contracts/asset-authoring.js +0 -106
- package/dist/_contracts/asset-bundle.d.ts +0 -64
- package/dist/_contracts/asset-bundle.js +0 -263
- package/dist/_contracts/asset-upload-helper.d.ts +0 -31
- package/dist/_contracts/asset-upload-helper.js +0 -84
- package/dist/_contracts/billing-admission.d.ts +0 -29
- package/dist/_contracts/billing-admission.js +0 -28
- package/dist/_contracts/bundle-manifest.d.ts +0 -89
- package/dist/_contracts/bundle-manifest.js +0 -158
- package/dist/_contracts/canonical-sha256.d.ts +0 -8
- package/dist/_contracts/canonical-sha256.js +0 -8
- package/dist/_contracts/connection-ticket.d.ts +0 -22
- package/dist/_contracts/connection-ticket.js +0 -54
- package/dist/_contracts/continuation-event.d.ts +0 -31
- package/dist/_contracts/continuation-event.js +0 -6
- package/dist/_contracts/contract-parse-error.d.ts +0 -12
- package/dist/_contracts/contract-parse-error.js +0 -51
- package/dist/_contracts/error-codes.d.ts +0 -26
- package/dist/_contracts/error-codes.js +0 -116
- package/dist/_contracts/error-factory.d.ts +0 -32
- package/dist/_contracts/error-factory.js +0 -174
- package/dist/_contracts/event-envelope.d.ts +0 -471
- package/dist/_contracts/event-envelope.js +0 -501
- package/dist/_contracts/event-stream-client.d.ts +0 -122
- package/dist/_contracts/event-stream-client.js +0 -445
- package/dist/_contracts/event-view.d.ts +0 -44
- package/dist/_contracts/event-view.js +0 -69
- package/dist/_contracts/failure-class.d.ts +0 -29
- package/dist/_contracts/failure-class.js +0 -73
- package/dist/_contracts/http.d.ts +0 -135
- package/dist/_contracts/http.js +0 -434
- package/dist/_contracts/ids.d.ts +0 -66
- package/dist/_contracts/ids.js +0 -119
- package/dist/_contracts/index.d.ts +0 -42
- package/dist/_contracts/index.js +0 -52
- package/dist/_contracts/internal.d.ts +0 -55
- package/dist/_contracts/internal.js +0 -113
- package/dist/_contracts/models.d.ts +0 -30
- package/dist/_contracts/models.js +0 -28
- package/dist/_contracts/operation-core.d.ts +0 -36
- package/dist/_contracts/operation-core.js +0 -70
- package/dist/_contracts/operations.d.ts +0 -218
- package/dist/_contracts/operations.js +0 -1496
- package/dist/_contracts/otlp-projection.d.ts +0 -78
- package/dist/_contracts/otlp-projection.js +0 -171
- package/dist/_contracts/post-hook.d.ts +0 -31
- package/dist/_contracts/post-hook.js +0 -61
- package/dist/_contracts/provider-fault.d.ts +0 -34
- package/dist/_contracts/provider-fault.js +0 -68
- package/dist/_contracts/retry-core.d.ts +0 -29
- package/dist/_contracts/retry-core.js +0 -79
- package/dist/_contracts/runner-event.d.ts +0 -117
- package/dist/_contracts/runner-event.js +0 -172
- package/dist/_contracts/runtime-kind.d.ts +0 -60
- package/dist/_contracts/runtime-kind.js +0 -70
- package/dist/_contracts/runtime-manifest.d.ts +0 -121
- package/dist/_contracts/runtime-manifest.js +0 -83
- package/dist/_contracts/runtime-security-profile.d.ts +0 -26
- package/dist/_contracts/runtime-security-profile.js +0 -73
- package/dist/_contracts/runtime-sizes.d.ts +0 -104
- package/dist/_contracts/runtime-sizes.js +0 -111
- package/dist/_contracts/runtime-types.d.ts +0 -618
- package/dist/_contracts/runtime-types.js +0 -58
- package/dist/_contracts/schemas/asset-bundle.d.ts +0 -70
- package/dist/_contracts/schemas/asset-bundle.js +0 -107
- package/dist/_contracts/schemas/asset-ref.d.ts +0 -61
- package/dist/_contracts/schemas/asset-ref.js +0 -118
- package/dist/_contracts/schemas/bundle-manifest.d.ts +0 -66
- package/dist/_contracts/schemas/bundle-manifest.js +0 -77
- package/dist/_contracts/schemas/index.d.ts +0 -32
- package/dist/_contracts/schemas/index.js +0 -30
- package/dist/_contracts/schemas/mcp-server.d.ts +0 -99
- package/dist/_contracts/schemas/mcp-server.js +0 -209
- package/dist/_contracts/schemas/models.d.ts +0 -29
- package/dist/_contracts/schemas/models.js +0 -51
- package/dist/_contracts/schemas/numeric.d.ts +0 -18
- package/dist/_contracts/schemas/numeric.js +0 -28
- package/dist/_contracts/schemas/post-hook.d.ts +0 -45
- package/dist/_contracts/schemas/post-hook.js +0 -68
- package/dist/_contracts/schemas/response-assets.d.ts +0 -75
- package/dist/_contracts/schemas/response-assets.js +0 -81
- package/dist/_contracts/schemas/response-billing.d.ts +0 -208
- package/dist/_contracts/schemas/response-billing.js +0 -139
- package/dist/_contracts/schemas/response-common.d.ts +0 -132
- package/dist/_contracts/schemas/response-common.js +0 -162
- package/dist/_contracts/schemas/response-identity.d.ts +0 -648
- package/dist/_contracts/schemas/response-identity.js +0 -131
- package/dist/_contracts/schemas/response-mcp-servers.d.ts +0 -51
- package/dist/_contracts/schemas/response-mcp-servers.js +0 -32
- package/dist/_contracts/schemas/response-secrets.d.ts +0 -50
- package/dist/_contracts/schemas/response-secrets.js +0 -32
- package/dist/_contracts/schemas/response-sessions-internal.d.ts +0 -200
- package/dist/_contracts/schemas/response-sessions-internal.js +0 -142
- package/dist/_contracts/schemas/response-sessions.d.ts +0 -1598
- package/dist/_contracts/schemas/response-sessions.js +0 -377
- package/dist/_contracts/schemas/response-webhooks.d.ts +0 -76
- package/dist/_contracts/schemas/response-webhooks.js +0 -42
- package/dist/_contracts/schemas/response-workspace.d.ts +0 -225
- package/dist/_contracts/schemas/response-workspace.js +0 -99
- package/dist/_contracts/schemas/runtime-kind.d.ts +0 -31
- package/dist/_contracts/schemas/runtime-kind.js +0 -29
- package/dist/_contracts/schemas/runtime-security-profile.d.ts +0 -28
- package/dist/_contracts/schemas/runtime-security-profile.js +0 -26
- package/dist/_contracts/schemas/runtime-sizes.d.ts +0 -70
- package/dist/_contracts/schemas/runtime-sizes.js +0 -127
- package/dist/_contracts/schemas/session-limits.d.ts +0 -34
- package/dist/_contracts/schemas/session-limits.js +0 -39
- package/dist/_contracts/schemas/session-machine.d.ts +0 -23
- package/dist/_contracts/schemas/session-machine.js +0 -24
- package/dist/_contracts/schemas/session-request-config.d.ts +0 -58
- package/dist/_contracts/schemas/session-request-config.js +0 -134
- package/dist/_contracts/schemas/session-webhook.d.ts +0 -11
- package/dist/_contracts/schemas/session-webhook.js +0 -38
- package/dist/_contracts/schemas/side-effect-audit.d.ts +0 -98
- package/dist/_contracts/schemas/side-effect-audit.js +0 -102
- package/dist/_contracts/schemas/submission-assets.d.ts +0 -117
- package/dist/_contracts/schemas/submission-assets.js +0 -147
- package/dist/_contracts/schemas/submission-body.d.ts +0 -251
- package/dist/_contracts/schemas/submission-body.js +0 -378
- package/dist/_contracts/schemas/submission-environment.d.ts +0 -79
- package/dist/_contracts/schemas/submission-environment.js +0 -179
- package/dist/_contracts/schemas/submission-request.d.ts +0 -158
- package/dist/_contracts/schemas/submission-request.js +0 -49
- package/dist/_contracts/schemas/submission-secrets.d.ts +0 -47
- package/dist/_contracts/schemas/submission-secrets.js +0 -108
- package/dist/_contracts/schemas/wire.d.ts +0 -118
- package/dist/_contracts/schemas/wire.js +0 -171
- package/dist/_contracts/schemas/workspace-resources.d.ts +0 -50
- package/dist/_contracts/schemas/workspace-resources.js +0 -87
- package/dist/_contracts/sdk-errors.d.ts +0 -212
- package/dist/_contracts/sdk-errors.js +0 -313
- package/dist/_contracts/sdk-secrets.d.ts +0 -67
- package/dist/_contracts/sdk-secrets.js +0 -427
- package/dist/_contracts/session-archive.d.ts +0 -16
- package/dist/_contracts/session-archive.js +0 -92
- package/dist/_contracts/session-artifacts.d.ts +0 -189
- package/dist/_contracts/session-artifacts.js +0 -264
- package/dist/_contracts/session-config.d.ts +0 -373
- package/dist/_contracts/session-config.js +0 -562
- package/dist/_contracts/session-cost-types.d.ts +0 -211
- package/dist/_contracts/session-cost-types.js +0 -69
- package/dist/_contracts/session-cost.d.ts +0 -8
- package/dist/_contracts/session-cost.js +0 -582
- package/dist/_contracts/session-custody.d.ts +0 -165
- package/dist/_contracts/session-custody.js +0 -345
- package/dist/_contracts/session-file-query.d.ts +0 -14
- package/dist/_contracts/session-file-query.js +0 -178
- package/dist/_contracts/session-record.d.ts +0 -112
- package/dist/_contracts/session-record.js +0 -165
- package/dist/_contracts/session-retention.d.ts +0 -201
- package/dist/_contracts/session-retention.js +0 -450
- package/dist/_contracts/side-effect-audit.d.ts +0 -126
- package/dist/_contracts/side-effect-audit.js +0 -520
- package/dist/_contracts/sse.d.ts +0 -74
- package/dist/_contracts/sse.js +0 -227
- package/dist/_contracts/stable.d.ts +0 -45
- package/dist/_contracts/stable.js +0 -62
- package/dist/_contracts/status.d.ts +0 -25
- package/dist/_contracts/status.js +0 -57
- package/dist/_contracts/submission-limits.d.ts +0 -61
- package/dist/_contracts/submission-limits.js +0 -60
- package/dist/_contracts/submission.d.ts +0 -547
- package/dist/_contracts/submission.js +0 -812
- package/dist/_contracts/suggest.d.ts +0 -15
- package/dist/_contracts/suggest.js +0 -53
- package/dist/_contracts/testing/response-bindings.d.ts +0 -45
- package/dist/_contracts/testing/response-bindings.js +0 -256
- package/dist/_contracts/testing/wire-conformance-entry.d.ts +0 -10
- package/dist/_contracts/testing/wire-conformance-entry.js +0 -8
- package/dist/_contracts/testing/wire-conformance.d.ts +0 -169
- package/dist/_contracts/testing/wire-conformance.js +0 -276
- package/dist/_contracts/turn-trace.d.ts +0 -28
- package/dist/_contracts/turn-trace.js +0 -1
- package/dist/_contracts/unknown-field-error.d.ts +0 -13
- package/dist/_contracts/unknown-field-error.js +0 -21
- package/dist/_contracts/value-guards.d.ts +0 -20
- package/dist/_contracts/value-guards.js +0 -34
- package/dist/_contracts/webhook-verify.d.ts +0 -34
- package/dist/_contracts/webhook-verify.js +0 -93
- package/dist/_contracts/wire-observer.d.ts +0 -49
- package/dist/_contracts/wire-observer.js +0 -34
- package/dist/_contracts/workflow-status.d.ts +0 -7
- package/dist/_contracts/workflow-status.js +0 -43
- package/dist/_contracts/workspace-resources.d.ts +0 -98
- package/dist/_contracts/workspace-resources.js +0 -39
- package/dist/archive-limits.d.ts +0 -1
- package/dist/archive-limits.js +0 -2
- package/dist/archive-limits.js.map +0 -1
- package/dist/asset-upload.d.ts +0 -47
- package/dist/asset-upload.js +0 -269
- package/dist/asset-upload.js.map +0 -1
- package/dist/bundle.d.ts +0 -9
- package/dist/bundle.js +0 -20
- package/dist/bundle.js.map +0 -1
- package/dist/canonical-zip.d.ts +0 -68
- package/dist/canonical-zip.js +0 -355
- package/dist/canonical-zip.js.map +0 -1
- package/dist/cli.mjs +0 -12048
- package/dist/cli.mjs.sha256 +0 -1
- package/dist/client-types.d.ts +0 -192
- package/dist/client-types.js +0 -2
- package/dist/client-types.js.map +0 -1
- package/dist/client.d.ts +0 -464
- package/dist/client.js +0 -1207
- package/dist/client.js.map +0 -1
- package/dist/event-projection.d.ts +0 -22
- package/dist/event-projection.js +0 -380
- package/dist/event-projection.js.map +0 -1
- package/dist/fetch-archive.d.ts +0 -16
- package/dist/fetch-archive.js +0 -252
- package/dist/fetch-archive.js.map +0 -1
- package/dist/file.d.ts +0 -96
- package/dist/file.js +0 -272
- package/dist/file.js.map +0 -1
- package/dist/instructions.d.ts +0 -20
- package/dist/instructions.js +0 -40
- package/dist/instructions.js.map +0 -1
- package/dist/legacy-session-provider-fault.d.ts +0 -7
- package/dist/legacy-session-provider-fault.js +0 -38
- package/dist/legacy-session-provider-fault.js.map +0 -1
- package/dist/mcp-server.d.ts +0 -84
- package/dist/mcp-server.js +0 -117
- package/dist/mcp-server.js.map +0 -1
- package/dist/node-fs.d.ts +0 -29
- package/dist/node-fs.js +0 -19
- package/dist/node-fs.js.map +0 -1
- package/dist/node-walk.d.ts +0 -69
- package/dist/node-walk.js +0 -151
- package/dist/node-walk.js.map +0 -1
- package/dist/path-basename.d.ts +0 -5
- package/dist/path-basename.js +0 -9
- package/dist/path-basename.js.map +0 -1
- package/dist/retry.d.ts +0 -70
- package/dist/retry.js +0 -155
- package/dist/retry.js.map +0 -1
- package/dist/secret.d.ts +0 -65
- package/dist/secret.js +0 -110
- package/dist/secret.js.map +0 -1
- package/dist/session-validate.d.ts +0 -100
- package/dist/session-validate.js +0 -303
- package/dist/session-validate.js.map +0 -1
- package/dist/skill.d.ts +0 -99
- package/dist/skill.js +0 -169
- package/dist/skill.js.map +0 -1
- package/dist/submission-wire.d.ts +0 -13
- package/dist/submission-wire.js +0 -69
- package/dist/submission-wire.js.map +0 -1
- package/dist/tool.d.ts +0 -41
- package/dist/tool.js +0 -76
- package/dist/tool.js.map +0 -1
- package/dist/version.d.ts +0 -9
- package/dist/version.js +0 -10
- package/dist/version.js.map +0 -1
- package/docs/authentication.md +0 -125
- package/docs/billing.md +0 -164
- package/docs/cleanup.md +0 -27
- package/docs/concepts/agent-tools.md +0 -47
- package/docs/concepts/composition.md +0 -60
- package/docs/concepts/providers-and-runtimes.md +0 -121
- package/docs/concepts/sessions.md +0 -51
- package/docs/concepts/subagents.md +0 -35
- package/docs/credentials.md +0 -116
- package/docs/defaults.md +0 -51
- package/docs/errors.md +0 -258
- package/docs/events.md +0 -143
- package/docs/files.md +0 -130
- package/docs/limits-and-quotas.md +0 -114
- package/docs/limits.md +0 -51
- package/docs/mcp.md +0 -47
- package/docs/networking.md +0 -114
- package/docs/provider-runtime-capabilities.md +0 -32
- package/docs/public-surface.json +0 -73
- package/docs/quickstart.md +0 -135
- package/docs/release.md +0 -44
- package/docs/retries.md +0 -108
- package/docs/secrets.md +0 -141
- package/docs/session-config.md +0 -51
- package/docs/session-record.md +0 -58
- package/docs/skills.md +0 -65
- package/docs/telemetry.md +0 -66
- package/docs/testing.md +0 -35
- package/docs/vision-skills.md +0 -94
- package/docs/webhooks.md +0 -143
|
@@ -1,84 +0,0 @@
|
|
|
1
|
-
import { extractErrorCode, redactUrl } from "./sdk-errors.js";
|
|
2
|
-
import { isRetryableHttpStatus, tryParseRetryAfterMs } from "./retry-core.js";
|
|
3
|
-
import { nextHttpRetryDelayMs, resolveHttpRetryDeps, resolveHttpRetryPolicy } from "./http.js";
|
|
4
|
-
export async function putDirectUploadWithRetry(fetchImpl, uploadUrl, init, options = {}) {
|
|
5
|
-
const policy = resolveHttpRetryPolicy(options);
|
|
6
|
-
const deps = resolveHttpRetryDeps(options);
|
|
7
|
-
const startedAtMs = deps.now();
|
|
8
|
-
for (let attempt = 1; attempt <= policy.maxAttempts; attempt++) {
|
|
9
|
-
let response;
|
|
10
|
-
try {
|
|
11
|
-
response = await fetchImpl(uploadUrl, init);
|
|
12
|
-
}
|
|
13
|
-
catch (err) {
|
|
14
|
-
const delayMs = isRetryableUploadError(err)
|
|
15
|
-
? nextHttpRetryDelayMs({ policy, attempt, startedAtMs, deps })
|
|
16
|
-
: undefined;
|
|
17
|
-
if (delayMs === undefined)
|
|
18
|
-
throw directUploadNetworkError(uploadUrl, err, attempt);
|
|
19
|
-
await deps.sleep(delayMs, init.signal ?? undefined);
|
|
20
|
-
continue;
|
|
21
|
-
}
|
|
22
|
-
if (response.ok)
|
|
23
|
-
return;
|
|
24
|
-
const retryAfterMs = tryParseRetryAfterMs(response.headers?.get("retry-after"), deps.now());
|
|
25
|
-
const delayMs = isRetryableUploadStatus(response.status)
|
|
26
|
-
? nextHttpRetryDelayMs({ policy, attempt, startedAtMs, deps, retryAfterMs })
|
|
27
|
-
: undefined;
|
|
28
|
-
if (delayMs !== undefined) {
|
|
29
|
-
await response.text().catch(() => "");
|
|
30
|
-
await deps.sleep(delayMs, init.signal ?? undefined);
|
|
31
|
-
continue;
|
|
32
|
-
}
|
|
33
|
-
const detail = await response.text().catch(() => "");
|
|
34
|
-
throw directUploadResponseError(uploadUrl, response.status, detail, attempt);
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
/**
|
|
38
|
-
* Object-store PUT retry set: the shared HTTP set from `retry-core.ts`, widened
|
|
39
|
-
* by the two statuses only a storage endpoint emits (408 Request Timeout, 425
|
|
40
|
-
* Too Early) plus the remaining 5xx an S3-compatible endpoint can return.
|
|
41
|
-
*/
|
|
42
|
-
export function isRetryableUploadStatus(status) {
|
|
43
|
-
return isRetryableHttpStatus(status) || status === 408 || status === 425 || (status >= 500 && status <= 599);
|
|
44
|
-
}
|
|
45
|
-
/** Every transport rejection except a caller-initiated abort is transient for a PUT. */
|
|
46
|
-
export function isRetryableUploadError(err) {
|
|
47
|
-
return err?.name !== "AbortError";
|
|
48
|
-
}
|
|
49
|
-
export function directUploadNetworkError(uploadUrl, err, attempts) {
|
|
50
|
-
const safeUrl = redactUrl(uploadUrl);
|
|
51
|
-
const code = extractErrorCode(err);
|
|
52
|
-
const detail = sanitizeUploadText(errorMessage(err)).slice(0, 500);
|
|
53
|
-
return new Error(`uploadAsset: direct upload PUT failed for ${safeUrl} after ${attemptsLabel(attempts)}` +
|
|
54
|
-
(code ? ` (${code})` : "") +
|
|
55
|
-
(detail ? `: ${detail}` : ""));
|
|
56
|
-
}
|
|
57
|
-
export function directUploadResponseError(uploadUrl, status, detail, attempts) {
|
|
58
|
-
const safeUrl = redactUrl(uploadUrl);
|
|
59
|
-
const safeDetail = sanitizeUploadText(detail).slice(0, 500);
|
|
60
|
-
return new Error(`uploadAsset: direct upload PUT failed for ${safeUrl} with status ${status}` +
|
|
61
|
-
(attempts > 1 ? ` after ${attemptsLabel(attempts)}` : "") +
|
|
62
|
-
(safeDetail ? `: ${safeDetail}` : ""));
|
|
63
|
-
}
|
|
64
|
-
export function sanitizeUploadText(text) {
|
|
65
|
-
return text
|
|
66
|
-
.replace(/https?:\/\/[^\s<>"'`]+/g, (raw) => redactUrlPreservingTrailingPunctuation(raw))
|
|
67
|
-
.replace(/\b(?:X-Amz-(?:Algorithm|Credential|Date|Expires|Security-Token|Signature|SignedHeaders)|AWSAccessKeyId|Signature|Credential|Security-Token|AccessKeyId|SecretAccessKey|SessionToken)=([^&\s<>"'`]+)/gi, "[redacted]")
|
|
68
|
-
.replace(/\bAKIA[0-9A-Z]{8,}\b/g, "[redacted]");
|
|
69
|
-
}
|
|
70
|
-
function attemptsLabel(attempts) {
|
|
71
|
-
return attempts === 1 ? "1 attempt" : `${attempts} attempts`;
|
|
72
|
-
}
|
|
73
|
-
function errorMessage(err) {
|
|
74
|
-
if (err instanceof Error)
|
|
75
|
-
return err.message || err.name;
|
|
76
|
-
if (typeof err === "string")
|
|
77
|
-
return err;
|
|
78
|
-
return String(err);
|
|
79
|
-
}
|
|
80
|
-
function redactUrlPreservingTrailingPunctuation(raw) {
|
|
81
|
-
const trailing = raw.match(/[),.;:!?]+$/)?.[0] ?? "";
|
|
82
|
-
const candidate = trailing ? raw.slice(0, -trailing.length) : raw;
|
|
83
|
-
return `${redactUrl(candidate)}${trailing}`;
|
|
84
|
-
}
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The admission vocabulary the money gates decide with.
|
|
3
|
-
*
|
|
4
|
-
* A LEAF module, importing nothing, for the same reason `schemas/runtime-kind.ts`
|
|
5
|
-
* is one: four modules need this list — `runtime-types.ts` for `WhoAmI.limits`,
|
|
6
|
-
* `account-types.ts` for `BillingSummary`, and the two response schemas that
|
|
7
|
-
* check both against the wire — and any of them owning it would make the other
|
|
8
|
-
* three import a much larger module for one constant, or force a cycle between a
|
|
9
|
-
* schema and the types derived from it.
|
|
10
|
-
*
|
|
11
|
-
* Contrast an allowance `dimension`, which is deliberately an OPEN string: the
|
|
12
|
-
* dimensions a free allowance is denominated in are hosted billing policy, and a
|
|
13
|
-
* closed copy of them in the public package would be the duplication the prepaid
|
|
14
|
-
* model was built to remove. These three are not policy. They are the whole
|
|
15
|
-
* public answer to "what sized this workspace", they change only when the
|
|
16
|
-
* product does, and a client switching on them wants the compiler to tell it
|
|
17
|
-
* when a fourth appears.
|
|
18
|
-
*/
|
|
19
|
-
/**
|
|
20
|
-
* How the money gates size a workspace. There is no plan catalog: a saved card
|
|
21
|
-
* and the auto-recharge flag are the only inputs, so the state is derived rather
|
|
22
|
-
* than sold.
|
|
23
|
-
*
|
|
24
|
-
* - `free` — no card on file. Free monthly allowances only.
|
|
25
|
-
* - `carded_manual` — a card is saved; credit is bought a top-up at a time.
|
|
26
|
-
* - `carded_auto` — a card is saved and auto-recharge is on.
|
|
27
|
-
*/
|
|
28
|
-
export declare const BILLING_ADMISSION_STATES: readonly ["free", "carded_manual", "carded_auto"];
|
|
29
|
-
export type BillingAdmissionState = (typeof BILLING_ADMISSION_STATES)[number];
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The admission vocabulary the money gates decide with.
|
|
3
|
-
*
|
|
4
|
-
* A LEAF module, importing nothing, for the same reason `schemas/runtime-kind.ts`
|
|
5
|
-
* is one: four modules need this list — `runtime-types.ts` for `WhoAmI.limits`,
|
|
6
|
-
* `account-types.ts` for `BillingSummary`, and the two response schemas that
|
|
7
|
-
* check both against the wire — and any of them owning it would make the other
|
|
8
|
-
* three import a much larger module for one constant, or force a cycle between a
|
|
9
|
-
* schema and the types derived from it.
|
|
10
|
-
*
|
|
11
|
-
* Contrast an allowance `dimension`, which is deliberately an OPEN string: the
|
|
12
|
-
* dimensions a free allowance is denominated in are hosted billing policy, and a
|
|
13
|
-
* closed copy of them in the public package would be the duplication the prepaid
|
|
14
|
-
* model was built to remove. These three are not policy. They are the whole
|
|
15
|
-
* public answer to "what sized this workspace", they change only when the
|
|
16
|
-
* product does, and a client switching on them wants the compiler to tell it
|
|
17
|
-
* when a fourth appears.
|
|
18
|
-
*/
|
|
19
|
-
/**
|
|
20
|
-
* How the money gates size a workspace. There is no plan catalog: a saved card
|
|
21
|
-
* and the auto-recharge flag are the only inputs, so the state is derived rather
|
|
22
|
-
* than sold.
|
|
23
|
-
*
|
|
24
|
-
* - `free` — no card on file. Free monthly allowances only.
|
|
25
|
-
* - `carded_manual` — a card is saved; credit is bought a top-up at a time.
|
|
26
|
-
* - `carded_auto` — a card is saved and auto-recharge is on.
|
|
27
|
-
*/
|
|
28
|
-
export const BILLING_ADMISSION_STATES = ["free", "carded_manual", "carded_auto"];
|
|
@@ -1,89 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Bundle fidelity sidecar — the shared source of truth for the `.aexmeta.json`
|
|
3
|
-
* metadata entry that rides inside a canonical bundle zip.
|
|
4
|
-
*
|
|
5
|
-
* A canonical bundle (skill / tool / file / instruction) is a deterministic zip of
|
|
6
|
-
* regular files. fflate's `unzipSync` on the restore side is asymmetric: it
|
|
7
|
-
* surfaces only entry bytes, never external attributes / os field / symlink
|
|
8
|
-
* flags. So exec bits and symlinks — the metadata a local dir → zip →
|
|
9
|
-
* container-restore round-trip must preserve — cannot travel in the zip's
|
|
10
|
-
* external attributes and be read back. Instead they travel in ONE reserved
|
|
11
|
-
* entry, `.aexmeta.json`, which both the SDK (encode) and the container
|
|
12
|
-
* materializer (restore) agree on. This module is that agreement.
|
|
13
|
-
*
|
|
14
|
-
* SECURITY: {@link symlinkTargetEscapes} is a restore-time boundary — it decides
|
|
15
|
-
* whether a captured symlink target may be recreated on the container FS. It is
|
|
16
|
-
* PURELY LEXICAL (no realpath, no FS access → no TOCTOU) and is fuzzed. Both
|
|
17
|
-
* repos import it; do not fork it.
|
|
18
|
-
*
|
|
19
|
-
* Determinism: the sidecar is emitted ONLY when there is metadata to carry (exec
|
|
20
|
-
* or symlinks non-empty) and is serialized canonically (fixed field order, sorted
|
|
21
|
-
* arrays, no insignificant whitespace, no trailing newline). A pure-content
|
|
22
|
-
* bundle emits NO sidecar → its bytes stay identical to the pre-fidelity output,
|
|
23
|
-
* so existing content-addressed dedup is preserved.
|
|
24
|
-
*/
|
|
25
|
-
/** Reserved zip entry carrying the fidelity sidecar. Rejected as a user file path. */
|
|
26
|
-
export declare const RESERVED_META_ENTRY = ".aexmeta.json";
|
|
27
|
-
/** Normalised mode for an executable regular file (has any exec bit). */
|
|
28
|
-
export declare const EXEC_MODE = 493;
|
|
29
|
-
/** Normalised mode for an ordinary regular file. */
|
|
30
|
-
export declare const DEFAULT_FILE_MODE = 420;
|
|
31
|
-
/** Bundle-time cap on a captured symlink target string. */
|
|
32
|
-
export declare const MAX_SYMLINK_TARGET_LENGTH = 4096;
|
|
33
|
-
/** A captured symlink: `path` is the bundle-relative link name, `target` the raw `readlink()` string. */
|
|
34
|
-
export interface BundleSymlink {
|
|
35
|
-
readonly path: string;
|
|
36
|
-
readonly target: string;
|
|
37
|
-
}
|
|
38
|
-
/**
|
|
39
|
-
* The fidelity sidecar. `exec` lists the bundle-relative paths that restore to
|
|
40
|
-
* {@link EXEC_MODE} (all other files stay {@link DEFAULT_FILE_MODE}); `symlinks`
|
|
41
|
-
* lists links to recreate (subject to {@link symlinkTargetEscapes}).
|
|
42
|
-
*/
|
|
43
|
-
export interface BundleManifest {
|
|
44
|
-
readonly v: 1;
|
|
45
|
-
readonly exec: readonly string[];
|
|
46
|
-
readonly symlinks: readonly BundleSymlink[];
|
|
47
|
-
}
|
|
48
|
-
/** True when a manifest carries no metadata worth emitting (so no sidecar is written). */
|
|
49
|
-
export declare function bundleManifestIsEmpty(manifest: {
|
|
50
|
-
readonly exec?: readonly string[];
|
|
51
|
-
readonly symlinks?: readonly {
|
|
52
|
-
readonly path: string;
|
|
53
|
-
}[];
|
|
54
|
-
}): boolean;
|
|
55
|
-
/**
|
|
56
|
-
* Serialize a manifest to canonical, byte-stable UTF-8 bytes: fixed field order
|
|
57
|
-
* (`v`, `exec`, `symlinks`), `exec` sorted ascending, `symlinks` sorted by
|
|
58
|
-
* `path`, no insignificant whitespace (compact JSON), no trailing newline. Two
|
|
59
|
-
* equal manifests always serialize to identical bytes → the sidecar never
|
|
60
|
-
* perturbs dedup determinism.
|
|
61
|
-
*/
|
|
62
|
-
export declare function serializeBundleManifest(manifest: BundleManifest): Uint8Array;
|
|
63
|
-
/**
|
|
64
|
-
* Parse the sidecar bytes into a validated {@link BundleManifest}, or `null` when
|
|
65
|
-
* the bytes are absent, not valid canonical JSON, or carry an unknown version.
|
|
66
|
-
* Forward-compatible: an unknown `v` yields `null`. A known-v1 manifest is
|
|
67
|
-
* atomic: every `exec` and `symlinks` entry must be structurally valid or the
|
|
68
|
-
* whole sidecar returns `null`, so callers cannot silently materialize a partial
|
|
69
|
-
* fidelity graph. The parse never throws.
|
|
70
|
-
*/
|
|
71
|
-
export declare function tryParseBundleManifest(bytes: Uint8Array | null | undefined): BundleManifest | null;
|
|
72
|
-
/** @deprecated Use {@link tryParseBundleManifest}; this compatibility wrapper is identical. */
|
|
73
|
-
export declare function parseBundleManifest(bytes: Uint8Array | null | undefined): BundleManifest | null;
|
|
74
|
-
/**
|
|
75
|
-
* SECURITY boundary — decide whether recreating a symlink `linkRelPath` → `target`
|
|
76
|
-
* would let the link escape the bundle root. PURELY LEXICAL (no realpath / no FS
|
|
77
|
-
* access → no TOCTOU). Returns `true` (REJECT / do not create) when ANY of:
|
|
78
|
-
*
|
|
79
|
-
* - `target` is empty or contains a NUL;
|
|
80
|
-
* - `target` is absolute — starts with `/`, matches a Windows drive (`C:`), is a
|
|
81
|
-
* UNC path (`\\host`), or contains any backslash;
|
|
82
|
-
* - the lexically-resolved target (join the link's dirname with the target, then
|
|
83
|
-
* normalise `.`/`..`) climbs at or above the bundle root (leading `..`).
|
|
84
|
-
*
|
|
85
|
-
* Otherwise the link is relative and resolves to a path inside (or at) the bundle
|
|
86
|
-
* root — safe to recreate with the ORIGINAL relative `target`. A dangling in-root
|
|
87
|
-
* target (pointing at a not-yet-existing sibling) is SAFE and allowed.
|
|
88
|
-
*/
|
|
89
|
-
export declare function symlinkTargetEscapes(linkRelPath: string, target: string): boolean;
|
|
@@ -1,158 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Bundle fidelity sidecar — the shared source of truth for the `.aexmeta.json`
|
|
3
|
-
* metadata entry that rides inside a canonical bundle zip.
|
|
4
|
-
*
|
|
5
|
-
* A canonical bundle (skill / tool / file / instruction) is a deterministic zip of
|
|
6
|
-
* regular files. fflate's `unzipSync` on the restore side is asymmetric: it
|
|
7
|
-
* surfaces only entry bytes, never external attributes / os field / symlink
|
|
8
|
-
* flags. So exec bits and symlinks — the metadata a local dir → zip →
|
|
9
|
-
* container-restore round-trip must preserve — cannot travel in the zip's
|
|
10
|
-
* external attributes and be read back. Instead they travel in ONE reserved
|
|
11
|
-
* entry, `.aexmeta.json`, which both the SDK (encode) and the container
|
|
12
|
-
* materializer (restore) agree on. This module is that agreement.
|
|
13
|
-
*
|
|
14
|
-
* SECURITY: {@link symlinkTargetEscapes} is a restore-time boundary — it decides
|
|
15
|
-
* whether a captured symlink target may be recreated on the container FS. It is
|
|
16
|
-
* PURELY LEXICAL (no realpath, no FS access → no TOCTOU) and is fuzzed. Both
|
|
17
|
-
* repos import it; do not fork it.
|
|
18
|
-
*
|
|
19
|
-
* Determinism: the sidecar is emitted ONLY when there is metadata to carry (exec
|
|
20
|
-
* or symlinks non-empty) and is serialized canonically (fixed field order, sorted
|
|
21
|
-
* arrays, no insignificant whitespace, no trailing newline). A pure-content
|
|
22
|
-
* bundle emits NO sidecar → its bytes stay identical to the pre-fidelity output,
|
|
23
|
-
* so existing content-addressed dedup is preserved.
|
|
24
|
-
*/
|
|
25
|
-
import { ASSET_ARCHIVE_LIMITS } from "./session-config.js";
|
|
26
|
-
import { bundleManifestSidecarSchema, serializableBundleManifestSchema, tryParseBundleManifestSidecar } from "./schemas/bundle-manifest.js";
|
|
27
|
-
import { parseWire } from "./schemas/wire.js";
|
|
28
|
-
/** Reserved zip entry carrying the fidelity sidecar. Rejected as a user file path. */
|
|
29
|
-
export const RESERVED_META_ENTRY = ".aexmeta.json";
|
|
30
|
-
/** Normalised mode for an executable regular file (has any exec bit). */
|
|
31
|
-
export const EXEC_MODE = 0o755;
|
|
32
|
-
/** Normalised mode for an ordinary regular file. */
|
|
33
|
-
export const DEFAULT_FILE_MODE = 0o644;
|
|
34
|
-
/** Bundle-time cap on a captured symlink target string. */
|
|
35
|
-
export const MAX_SYMLINK_TARGET_LENGTH = 4096;
|
|
36
|
-
/**
|
|
37
|
-
* Defensive cap on each metadata array, applied on both the encode and decode
|
|
38
|
-
* sides. The decode side reaches it only after `JSON.parse` has already
|
|
39
|
-
* materialised the array under {@link ASSET_ARCHIVE_LIMITS.maxMetadataBytes}, so
|
|
40
|
-
* it bounds what the fidelity graph may contain rather than what the parser may
|
|
41
|
-
* allocate.
|
|
42
|
-
*/
|
|
43
|
-
const MAX_BUNDLE_METADATA_RECORDS = ASSET_ARCHIVE_LIMITS.maxEntries;
|
|
44
|
-
/** True when a manifest carries no metadata worth emitting (so no sidecar is written). */
|
|
45
|
-
export function bundleManifestIsEmpty(manifest) {
|
|
46
|
-
return (manifest.exec?.length ?? 0) === 0 && (manifest.symlinks?.length ?? 0) === 0;
|
|
47
|
-
}
|
|
48
|
-
const META_TEXT_ENCODER = new TextEncoder();
|
|
49
|
-
const META_TEXT_DECODER = new TextDecoder("utf-8", { fatal: true });
|
|
50
|
-
// Built once: the caps are module constants, so there is nothing per-call to
|
|
51
|
-
// close over and no reason to pay schema construction on every sidecar.
|
|
52
|
-
const SIDECAR_SCHEMA = bundleManifestSidecarSchema(MAX_BUNDLE_METADATA_RECORDS, MAX_SYMLINK_TARGET_LENGTH);
|
|
53
|
-
const SERIALIZABLE_SCHEMA = serializableBundleManifestSchema(MAX_BUNDLE_METADATA_RECORDS, MAX_SYMLINK_TARGET_LENGTH);
|
|
54
|
-
/**
|
|
55
|
-
* Serialize a manifest to canonical, byte-stable UTF-8 bytes: fixed field order
|
|
56
|
-
* (`v`, `exec`, `symlinks`), `exec` sorted ascending, `symlinks` sorted by
|
|
57
|
-
* `path`, no insignificant whitespace (compact JSON), no trailing newline. Two
|
|
58
|
-
* equal manifests always serialize to identical bytes → the sidecar never
|
|
59
|
-
* perturbs dedup determinism.
|
|
60
|
-
*/
|
|
61
|
-
export function serializeBundleManifest(manifest) {
|
|
62
|
-
parseWire(SERIALIZABLE_SCHEMA, manifest);
|
|
63
|
-
const exec = [...manifest.exec].sort(byString);
|
|
64
|
-
const symlinks = [...manifest.symlinks]
|
|
65
|
-
.map((s) => ({ path: s.path, target: s.target }))
|
|
66
|
-
.sort((a, b) => byString(a.path, b.path));
|
|
67
|
-
// Object literal key order is the wire order under JSON.stringify (fixed).
|
|
68
|
-
const json = JSON.stringify({ v: 1, exec, symlinks });
|
|
69
|
-
const bytes = META_TEXT_ENCODER.encode(json);
|
|
70
|
-
if (bytes.byteLength > ASSET_ARCHIVE_LIMITS.maxMetadataBytes) {
|
|
71
|
-
throw new Error("bundle fidelity metadata exceeds the 8 MiB limit");
|
|
72
|
-
}
|
|
73
|
-
return bytes;
|
|
74
|
-
}
|
|
75
|
-
/**
|
|
76
|
-
* Parse the sidecar bytes into a validated {@link BundleManifest}, or `null` when
|
|
77
|
-
* the bytes are absent, not valid canonical JSON, or carry an unknown version.
|
|
78
|
-
* Forward-compatible: an unknown `v` yields `null`. A known-v1 manifest is
|
|
79
|
-
* atomic: every `exec` and `symlinks` entry must be structurally valid or the
|
|
80
|
-
* whole sidecar returns `null`, so callers cannot silently materialize a partial
|
|
81
|
-
* fidelity graph. The parse never throws.
|
|
82
|
-
*/
|
|
83
|
-
export function tryParseBundleManifest(bytes) {
|
|
84
|
-
if (!bytes || bytes.byteLength === 0)
|
|
85
|
-
return null;
|
|
86
|
-
if (bytes.byteLength > ASSET_ARCHIVE_LIMITS.maxMetadataBytes)
|
|
87
|
-
return null;
|
|
88
|
-
let parsed;
|
|
89
|
-
try {
|
|
90
|
-
parsed = JSON.parse(META_TEXT_DECODER.decode(bytes));
|
|
91
|
-
}
|
|
92
|
-
catch {
|
|
93
|
-
return null;
|
|
94
|
-
}
|
|
95
|
-
return tryParseBundleManifestSidecar(SIDECAR_SCHEMA, parsed);
|
|
96
|
-
}
|
|
97
|
-
/** @deprecated Use {@link tryParseBundleManifest}; this compatibility wrapper is identical. */
|
|
98
|
-
export function parseBundleManifest(bytes) {
|
|
99
|
-
return tryParseBundleManifest(bytes);
|
|
100
|
-
}
|
|
101
|
-
/**
|
|
102
|
-
* SECURITY boundary — decide whether recreating a symlink `linkRelPath` → `target`
|
|
103
|
-
* would let the link escape the bundle root. PURELY LEXICAL (no realpath / no FS
|
|
104
|
-
* access → no TOCTOU). Returns `true` (REJECT / do not create) when ANY of:
|
|
105
|
-
*
|
|
106
|
-
* - `target` is empty or contains a NUL;
|
|
107
|
-
* - `target` is absolute — starts with `/`, matches a Windows drive (`C:`), is a
|
|
108
|
-
* UNC path (`\\host`), or contains any backslash;
|
|
109
|
-
* - the lexically-resolved target (join the link's dirname with the target, then
|
|
110
|
-
* normalise `.`/`..`) climbs at or above the bundle root (leading `..`).
|
|
111
|
-
*
|
|
112
|
-
* Otherwise the link is relative and resolves to a path inside (or at) the bundle
|
|
113
|
-
* root — safe to recreate with the ORIGINAL relative `target`. A dangling in-root
|
|
114
|
-
* target (pointing at a not-yet-existing sibling) is SAFE and allowed.
|
|
115
|
-
*/
|
|
116
|
-
export function symlinkTargetEscapes(linkRelPath, target) {
|
|
117
|
-
if (typeof target !== "string" || target.length === 0)
|
|
118
|
-
return true;
|
|
119
|
-
if (target.includes("\0"))
|
|
120
|
-
return true;
|
|
121
|
-
// Absolute / platform-specific targets are always rejected.
|
|
122
|
-
if (target.startsWith("/"))
|
|
123
|
-
return true;
|
|
124
|
-
if (/^[A-Za-z]:/.test(target))
|
|
125
|
-
return true;
|
|
126
|
-
if (target.includes("\\"))
|
|
127
|
-
return true;
|
|
128
|
-
// Lexically resolve relative to the link's own directory.
|
|
129
|
-
const linkDir = posixDirname(linkRelPath);
|
|
130
|
-
const joined = linkDir.length > 0 ? `${linkDir}/${target}` : target;
|
|
131
|
-
const stack = [];
|
|
132
|
-
for (const segment of joined.split("/")) {
|
|
133
|
-
if (segment === "" || segment === ".")
|
|
134
|
-
continue;
|
|
135
|
-
if (segment === "..") {
|
|
136
|
-
// Pop an in-root component, or record an escaping climb.
|
|
137
|
-
if (stack.length > 0 && stack[stack.length - 1] !== "..") {
|
|
138
|
-
stack.pop();
|
|
139
|
-
}
|
|
140
|
-
else {
|
|
141
|
-
stack.push("..");
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
else {
|
|
145
|
-
stack.push(segment);
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
// A leading `..` means the resolved path is at or above the bundle root.
|
|
149
|
-
return stack.length > 0 && stack[0] === "..";
|
|
150
|
-
}
|
|
151
|
-
/** POSIX dirname of a forward-slash relative path ("" when there is no parent segment). */
|
|
152
|
-
function posixDirname(path) {
|
|
153
|
-
const idx = path.lastIndexOf("/");
|
|
154
|
-
return idx <= 0 ? "" : path.slice(0, idx);
|
|
155
|
-
}
|
|
156
|
-
function byString(a, b) {
|
|
157
|
-
return a < b ? -1 : a > b ? 1 : 0;
|
|
158
|
-
}
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Canonical algorithm-prefixed SHA-256 digest wire grammar.
|
|
3
|
-
*
|
|
4
|
-
* This accepts only the lowercase `sha256:` prefix followed by exactly 64
|
|
5
|
-
* lowercase hexadecimal characters. Changing the algorithm, case, prefix, or
|
|
6
|
-
* length is a wire-contract change.
|
|
7
|
-
*/
|
|
8
|
-
export declare const CANONICAL_SHA256_DIGEST_PATTERN: RegExp;
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Canonical algorithm-prefixed SHA-256 digest wire grammar.
|
|
3
|
-
*
|
|
4
|
-
* This accepts only the lowercase `sha256:` prefix followed by exactly 64
|
|
5
|
-
* lowercase hexadecimal characters. Changing the algorithm, case, prefix, or
|
|
6
|
-
* length is a wire-contract change.
|
|
7
|
-
*/
|
|
8
|
-
export const CANONICAL_SHA256_DIGEST_PATTERN = /^sha256:[0-9a-f]{64}$/;
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Connection tickets for the event-coordinator WebSocket handshake.
|
|
3
|
-
*
|
|
4
|
-
* A browser/runtime WebSocket handshake cannot carry an Authorization header,
|
|
5
|
-
* so a subscriber first obtains a short-lived ticket from an authenticated
|
|
6
|
-
* HTTP endpoint, then presents it as a `?ticket=` query parameter on the WS
|
|
7
|
-
* upgrade. The ticket is an HMAC over `${sessionId}.${channel}.${exp}` keyed by
|
|
8
|
-
* the coordinator secret — it binds the grant to one session, one stream channel,
|
|
9
|
-
* and one expiry and is verified without any per-ticket storage.
|
|
10
|
-
*
|
|
11
|
-
* This lives in shared so the coordinator (which verifies) and the API
|
|
12
|
-
* hosted API's ticket broker (which mints, on behalf of a workspace token) use
|
|
13
|
-
* ONE implementation. Pure Web Crypto — identical under Bun and Node.
|
|
14
|
-
*/
|
|
15
|
-
export type ConnectionTicketChannel = "event" | "log" | "all";
|
|
16
|
-
/** Mint a `${channel}.${exp}.${mac}` ticket valid for `ttlMs` from `nowMs`. */
|
|
17
|
-
export declare function mintConnectionTicket(sessionId: string, secret: string, nowMs: number, ttlMs?: number, channel?: ConnectionTicketChannel): Promise<{
|
|
18
|
-
ticket: string;
|
|
19
|
-
expiresAtMs: number;
|
|
20
|
-
}>;
|
|
21
|
-
/** Verify a ticket against `sessionId`, channel, and current time. Constant-time MAC compare. */
|
|
22
|
-
export declare function verifyConnectionTicket(ticket: string, sessionId: string, secret: string, nowMs: number, channel?: ConnectionTicketChannel): Promise<boolean>;
|
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Connection tickets for the event-coordinator WebSocket handshake.
|
|
3
|
-
*
|
|
4
|
-
* A browser/runtime WebSocket handshake cannot carry an Authorization header,
|
|
5
|
-
* so a subscriber first obtains a short-lived ticket from an authenticated
|
|
6
|
-
* HTTP endpoint, then presents it as a `?ticket=` query parameter on the WS
|
|
7
|
-
* upgrade. The ticket is an HMAC over `${sessionId}.${channel}.${exp}` keyed by
|
|
8
|
-
* the coordinator secret — it binds the grant to one session, one stream channel,
|
|
9
|
-
* and one expiry and is verified without any per-ticket storage.
|
|
10
|
-
*
|
|
11
|
-
* This lives in shared so the coordinator (which verifies) and the API
|
|
12
|
-
* hosted API's ticket broker (which mints, on behalf of a workspace token) use
|
|
13
|
-
* ONE implementation. Pure Web Crypto — identical under Bun and Node.
|
|
14
|
-
*/
|
|
15
|
-
const DEFAULT_TICKET_TTL_MS = 60_000;
|
|
16
|
-
const encoder = new TextEncoder();
|
|
17
|
-
function normalizeTicketChannel(channel) {
|
|
18
|
-
return channel === "log" || channel === "all" ? channel : "event";
|
|
19
|
-
}
|
|
20
|
-
async function hmacHex(secret, message) {
|
|
21
|
-
const key = await crypto.subtle.importKey("raw", encoder.encode(secret), { name: "HMAC", hash: "SHA-256" }, false, ["sign"]);
|
|
22
|
-
const sig = await crypto.subtle.sign("HMAC", key, encoder.encode(message));
|
|
23
|
-
return [...new Uint8Array(sig)].map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
24
|
-
}
|
|
25
|
-
/** Mint a `${channel}.${exp}.${mac}` ticket valid for `ttlMs` from `nowMs`. */
|
|
26
|
-
export async function mintConnectionTicket(sessionId, secret, nowMs, ttlMs = DEFAULT_TICKET_TTL_MS, channel = "event") {
|
|
27
|
-
const boundChannel = normalizeTicketChannel(channel);
|
|
28
|
-
const exp = nowMs + ttlMs;
|
|
29
|
-
const mac = await hmacHex(secret, `${sessionId}.${boundChannel}.${exp}`);
|
|
30
|
-
return { ticket: `${boundChannel}.${exp}.${mac}`, expiresAtMs: exp };
|
|
31
|
-
}
|
|
32
|
-
/** Verify a ticket against `sessionId`, channel, and current time. Constant-time MAC compare. */
|
|
33
|
-
export async function verifyConnectionTicket(ticket, sessionId, secret, nowMs, channel = "event") {
|
|
34
|
-
const [ticketChannel, expRaw, mac, ...rest] = ticket.split(".");
|
|
35
|
-
if (rest.length > 0 || !ticketChannel || !expRaw || !mac)
|
|
36
|
-
return false;
|
|
37
|
-
const boundChannel = normalizeTicketChannel(channel);
|
|
38
|
-
if (ticketChannel !== boundChannel)
|
|
39
|
-
return false;
|
|
40
|
-
const exp = Number(expRaw);
|
|
41
|
-
if (!Number.isFinite(exp) || exp < nowMs)
|
|
42
|
-
return false;
|
|
43
|
-
const expected = await hmacHex(secret, `${sessionId}.${boundChannel}.${exp}`);
|
|
44
|
-
return timingSafeEqual(mac, expected);
|
|
45
|
-
}
|
|
46
|
-
/** Length-then-constant-time comparison of two hex strings. */
|
|
47
|
-
function timingSafeEqual(a, b) {
|
|
48
|
-
if (a.length !== b.length)
|
|
49
|
-
return false;
|
|
50
|
-
let diff = 0;
|
|
51
|
-
for (let i = 0; i < a.length; i++)
|
|
52
|
-
diff |= a.charCodeAt(i) ^ b.charCodeAt(i);
|
|
53
|
-
return diff === 0;
|
|
54
|
-
}
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Dependency-free trace carrier used at continuation boundaries.
|
|
3
|
-
*
|
|
4
|
-
* This contract is internal to the aex runtime packages. It deliberately
|
|
5
|
-
* lives in the public contracts package so every runtime consumes one wire
|
|
6
|
-
* shape without importing a hosted-platform implementation package.
|
|
7
|
-
*/
|
|
8
|
-
export interface W3CTraceContext {
|
|
9
|
-
readonly traceparent: string;
|
|
10
|
-
readonly tracestate?: string;
|
|
11
|
-
}
|
|
12
|
-
export declare const CONTINUATION_KINDS: readonly ["user_message", "tool_result", "scheduled_wake", "subagent_done"];
|
|
13
|
-
export type ContinuationKind = (typeof CONTINUATION_KINDS)[number];
|
|
14
|
-
export type ContinuationToken = string;
|
|
15
|
-
/** Durable continuation payload shared by the outbox and queue transports. */
|
|
16
|
-
export interface ContinuationEvent {
|
|
17
|
-
readonly kind: ContinuationKind;
|
|
18
|
-
readonly token: ContinuationToken;
|
|
19
|
-
readonly agentId: string;
|
|
20
|
-
readonly sessionId: string;
|
|
21
|
-
readonly observedEpoch?: number;
|
|
22
|
-
readonly turnSeq?: number;
|
|
23
|
-
readonly callId?: string;
|
|
24
|
-
readonly childAgentId?: string;
|
|
25
|
-
readonly wakeId?: string;
|
|
26
|
-
/** Semantic identity of the next planned action; excluded from token identity. */
|
|
27
|
-
readonly decisionFp?: string;
|
|
28
|
-
readonly requeueAttempt?: number;
|
|
29
|
-
/** W3C context propagated across the asynchronous continuation boundary. */
|
|
30
|
-
readonly traceContext?: W3CTraceContext;
|
|
31
|
-
}
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
export declare const CONTRACT_PARSE_ERROR: "CONTRACT_PARSE_ERROR";
|
|
2
|
-
declare const CONTRACT_PARSE_ERROR_BRAND: unique symbol;
|
|
3
|
-
export type ContractParseError = Error & {
|
|
4
|
-
readonly code: typeof CONTRACT_PARSE_ERROR;
|
|
5
|
-
readonly parser: string;
|
|
6
|
-
readonly [CONTRACT_PARSE_ERROR_BRAND]: true;
|
|
7
|
-
};
|
|
8
|
-
export declare function isContractParseError(value: unknown): value is ContractParseError;
|
|
9
|
-
export declare function markContractParseError(error: Error, parser: string): ContractParseError;
|
|
10
|
-
export declare function rethrowContractParseError(error: unknown, parser: string): never;
|
|
11
|
-
export declare function withContractParseError<T>(parser: string, parse: () => T): T;
|
|
12
|
-
export {};
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
export const CONTRACT_PARSE_ERROR = "CONTRACT_PARSE_ERROR";
|
|
2
|
-
const CONTRACT_PARSE_ERROR_BRAND = Symbol("@aexhq/contracts/ContractParseError");
|
|
3
|
-
export function isContractParseError(value) {
|
|
4
|
-
try {
|
|
5
|
-
return (value instanceof Error &&
|
|
6
|
-
value.code === CONTRACT_PARSE_ERROR &&
|
|
7
|
-
typeof value.parser === "string" &&
|
|
8
|
-
value[CONTRACT_PARSE_ERROR_BRAND] === true);
|
|
9
|
-
}
|
|
10
|
-
catch {
|
|
11
|
-
return false;
|
|
12
|
-
}
|
|
13
|
-
}
|
|
14
|
-
export function markContractParseError(error, parser) {
|
|
15
|
-
if (isContractParseError(error))
|
|
16
|
-
return error;
|
|
17
|
-
Object.defineProperties(error, {
|
|
18
|
-
code: {
|
|
19
|
-
value: CONTRACT_PARSE_ERROR,
|
|
20
|
-
enumerable: false,
|
|
21
|
-
writable: false,
|
|
22
|
-
configurable: false
|
|
23
|
-
},
|
|
24
|
-
parser: {
|
|
25
|
-
value: parser,
|
|
26
|
-
enumerable: false,
|
|
27
|
-
writable: false,
|
|
28
|
-
configurable: false
|
|
29
|
-
},
|
|
30
|
-
[CONTRACT_PARSE_ERROR_BRAND]: {
|
|
31
|
-
value: true,
|
|
32
|
-
enumerable: false,
|
|
33
|
-
writable: false,
|
|
34
|
-
configurable: false
|
|
35
|
-
}
|
|
36
|
-
});
|
|
37
|
-
return error;
|
|
38
|
-
}
|
|
39
|
-
export function rethrowContractParseError(error, parser) {
|
|
40
|
-
if (error instanceof Error)
|
|
41
|
-
throw markContractParseError(error, parser);
|
|
42
|
-
throw error;
|
|
43
|
-
}
|
|
44
|
-
export function withContractParseError(parser, parse) {
|
|
45
|
-
try {
|
|
46
|
-
return parse();
|
|
47
|
-
}
|
|
48
|
-
catch (error) {
|
|
49
|
-
rethrowContractParseError(error, parser);
|
|
50
|
-
}
|
|
51
|
-
}
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* SSoT for the platform's STABLE API error codes.
|
|
3
|
-
*
|
|
4
|
-
* The server (platform `api.ts`) imports this table instead of keeping its
|
|
5
|
-
* own private copy, so a route emitting a code absent from the union fails to
|
|
6
|
-
* compile and adding a code without a message is caught. The SDK error factory
|
|
7
|
-
* ({@link import("./error-factory.js").apiErrorFromResponse}) dispatches on the
|
|
8
|
-
* code to a typed subclass; the CLI maps it to a human remedy.
|
|
9
|
-
*
|
|
10
|
-
* The code is the stable, machine-branchable identity of a failure — distinct
|
|
11
|
-
* from the human `message`. `idempotency_conflict` and `insufficient_scope`
|
|
12
|
-
* (previously message-less bare 409/403 bodies) are first-class here.
|
|
13
|
-
*/
|
|
14
|
-
export declare const AEX_API_ERROR_CODES: readonly ["unauthorized", "forbidden", "insufficient_scope", "token_invalid", "token_revoked", "token_expired", "malformed_token", "not_found", "idempotency_conflict", "session_busy", "checkpoint_not_available", "session_not_terminal", "session_terminal", "event_archive_too_large", "event_archive_deadline_exceeded", "unknown_workspace", "workspace_inactive", "workspace_concurrency_exceeded", "workspace_submit_rate_exceeded", "workspace_spend_cap_exceeded", "workspace_cap_exceeded", "insufficient_credits", "account_blocked", "quota_exhausted", "depth_exceeded", "rate_limited", "out_of_memory", "disk_full", "content_deleted", "upstream_error", "internal_error"];
|
|
15
|
-
export type AexApiErrorCode = (typeof AEX_API_ERROR_CODES)[number];
|
|
16
|
-
/**
|
|
17
|
-
* Human message per stable code. A `Record` (not `Partial`) so a code added to
|
|
18
|
-
* {@link AEX_API_ERROR_CODES} without a message is a COMPILE error. These are
|
|
19
|
-
* the fallback messages the factory uses when the server sends a BARE code with
|
|
20
|
-
* no `message` detail.
|
|
21
|
-
*/
|
|
22
|
-
export declare const AEX_API_ERROR_MESSAGES: Record<AexApiErrorCode, string>;
|
|
23
|
-
/** Optional per-code fix hint the CLI surfaces alongside the error message. */
|
|
24
|
-
export declare const AEX_API_ERROR_REMEDIES: Partial<Record<AexApiErrorCode, string>>;
|
|
25
|
-
/** Narrow an arbitrary value to a known {@link AexApiErrorCode}. */
|
|
26
|
-
export declare function isAexApiErrorCode(value: unknown): value is AexApiErrorCode;
|