@aexhq/sdk 0.40.5 → 0.40.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (77) hide show
  1. package/README.md +159 -159
  2. package/dist/_contracts/api-key.js +0 -1
  3. package/dist/_contracts/bundle-manifest.js +0 -1
  4. package/dist/_contracts/connection-ticket.js +0 -1
  5. package/dist/_contracts/error-codes.js +0 -1
  6. package/dist/_contracts/error-factory.js +0 -1
  7. package/dist/_contracts/event-envelope.js +0 -1
  8. package/dist/_contracts/event-stream-client.js +0 -1
  9. package/dist/_contracts/event-view.js +0 -1
  10. package/dist/_contracts/http.js +0 -1
  11. package/dist/_contracts/index.js +0 -1
  12. package/dist/_contracts/internal.d.ts +36 -0
  13. package/dist/_contracts/internal.js +155 -6
  14. package/dist/_contracts/models.js +0 -1
  15. package/dist/_contracts/operations.js +1 -2
  16. package/dist/_contracts/post-hook.js +0 -1
  17. package/dist/_contracts/provider-support.js +0 -1
  18. package/dist/_contracts/run-artifacts.js +0 -1
  19. package/dist/_contracts/run-config.js +0 -1
  20. package/dist/_contracts/run-cost.js +0 -1
  21. package/dist/_contracts/run-custody.js +0 -1
  22. package/dist/_contracts/run-record.js +0 -1
  23. package/dist/_contracts/run-retention.js +0 -1
  24. package/dist/_contracts/run-trace.js +0 -1
  25. package/dist/_contracts/run-unit.js +0 -1
  26. package/dist/_contracts/runner-event.js +0 -1
  27. package/dist/_contracts/runtime-manifest.js +0 -1
  28. package/dist/_contracts/runtime-security-profile.js +0 -1
  29. package/dist/_contracts/runtime-sizes.js +0 -1
  30. package/dist/_contracts/runtime-types.js +0 -1
  31. package/dist/_contracts/sdk-errors.js +0 -1
  32. package/dist/_contracts/sdk-secrets.js +0 -1
  33. package/dist/_contracts/side-effect-audit.js +0 -1
  34. package/dist/_contracts/sse.js +0 -0
  35. package/dist/_contracts/stable.js +0 -1
  36. package/dist/_contracts/status.js +0 -1
  37. package/dist/_contracts/submission.js +0 -1
  38. package/dist/_contracts/suggest.js +0 -1
  39. package/dist/_contracts/webhook-verify.js +0 -1
  40. package/dist/asset-upload.d.ts +3 -43
  41. package/dist/asset-upload.js +1 -109
  42. package/dist/asset-upload.js.map +1 -1
  43. package/dist/cli.mjs +354 -781
  44. package/dist/cli.mjs.sha256 +1 -1
  45. package/dist/fetch-archive.js +76 -16
  46. package/dist/fetch-archive.js.map +1 -1
  47. package/dist/version.d.ts +1 -1
  48. package/dist/version.js +1 -1
  49. package/docs/authentication.md +125 -125
  50. package/docs/billing.md +118 -118
  51. package/docs/concepts/agent-tools.md +66 -66
  52. package/docs/concepts/composition.md +37 -37
  53. package/docs/concepts/providers-and-runtimes.md +54 -54
  54. package/docs/concepts/runs.md +49 -49
  55. package/docs/concepts/subagents.md +88 -88
  56. package/docs/credentials.md +125 -125
  57. package/docs/defaults.md +64 -64
  58. package/docs/errors.md +196 -196
  59. package/docs/events.md +243 -243
  60. package/docs/limits-and-quotas.md +144 -144
  61. package/docs/limits.md +50 -50
  62. package/docs/mcp.md +44 -44
  63. package/docs/networking.md +163 -163
  64. package/docs/outputs.md +267 -267
  65. package/docs/public-surface.json +77 -77
  66. package/docs/quickstart.md +119 -119
  67. package/docs/release.md +38 -38
  68. package/docs/retries.md +129 -129
  69. package/docs/run-config.md +58 -58
  70. package/docs/run-record.md +55 -55
  71. package/docs/secrets.md +125 -130
  72. package/docs/testing.md +35 -35
  73. package/docs/vision-skills.md +91 -91
  74. package/docs/webhooks.md +127 -131
  75. package/examples/feature-tour.ts +282 -282
  76. package/examples/spike-settle-latency.ts +125 -125
  77. package/package.json +1 -1
@@ -1,80 +1,80 @@
1
- {
2
- "brand": "aex",
3
- "productName": "Agent Executor",
4
- "oneLine": "aex is an agent execution platform for launching autonomous agents from a simple TypeScript SDK and CLI.",
5
- "description": "Open durable agent sessions, send turns, stream events, capture outputs, and compose agents with skills, files, MCP, secrets, networking controls, and subagents across the managed runtime.",
6
- "alpha": {
7
- "label": "Alpha testing",
8
- "description": "Access is limited to invited testers while we harden the hosted runtime, dashboard, and SDK workflows."
9
- },
10
- "installCommand": "npm i @aexhq/sdk",
11
- "examples": {
12
- "typescriptLines": [
13
- "import { Aex, Models, Sizes } from \"@aexhq/sdk\";",
14
- "",
15
- "const aex = new Aex({ apiKey: process.env.AEX_API_KEY! });",
16
- "",
17
- "const session = await aex.openSession({",
18
- " model: Models.CLAUDE_HAIKU_4_5,",
19
- " system: \"You are a concise engineering assistant.\",",
20
- " runtime: Sizes.SHARED_0_25X_1GB,",
21
- " overrides: { idleTtl: \"3m\" },",
22
- " apiKeys: { anthropic: process.env.ANTHROPIC_API_KEY! }",
23
- "});",
24
- "",
25
- "const result = await session.send(\"Write a short report and save it as a file.\").done();",
26
- "console.log(result.status, result.text);"
27
- ],
28
- "cliLines": [
29
- "aex run \\",
30
- " --api-key \"$AEX_API_KEY\" \\",
31
- " --anthropic-api-key \"$ANTHROPIC_API_KEY\" \\",
32
- " --model claude-haiku-4-5 \\",
33
- " --prompt \"Write a short report and save it as a file.\" \\",
34
- " --follow"
35
- ]
36
- },
37
- "providers": [
38
- { "id": "anthropic", "name": "Anthropic" },
39
- { "id": "deepseek", "name": "DeepSeek" },
40
- { "id": "openai", "name": "OpenAI" },
41
- { "id": "gemini", "name": "Gemini" },
42
- { "id": "mistral", "name": "Mistral" },
43
- { "id": "openrouter", "name": "OpenRouter" },
44
- { "id": "doubao", "name": "Doubao" },
45
- { "id": "doubao-cn", "name": "Doubao China" }
46
- ],
47
- "featureAreas": [
48
- {
49
- "slug": "agent-runtime",
50
- "href": "/docs/features/#agent-runtime",
51
- "title": "Agent runtime",
52
- "description": "Managed autonomous runs with filesystem read/edit, grep/glob/head/tail, open web fetch/search, background commands, code execution, git, and subagents."
53
- },
54
- {
55
- "slug": "durable-infrastructure",
56
- "href": "/docs/features/#durable-infrastructure",
57
- "title": "Durable infrastructure",
58
- "description": "Run records, status, wait/cancel/delete, idempotency, typed events, output capture, downloads, timeouts, and runtime sizes."
59
- },
60
- {
61
- "slug": "agent-composition",
62
- "href": "/docs/features/#agent-composition",
63
- "title": "Agent composition",
64
- "description": "Skills, files, AGENTS.md, remote MCP servers, environment variables, packages, secrets, and networking controls."
65
- },
66
- {
67
- "slug": "subagents",
68
- "href": "/docs/features/#subagents",
69
- "title": "Subagents",
70
- "description": "Typed parent/child lineage for async child runs, output handoff, and bounded agent delegation."
71
- },
72
- {
73
- "slug": "models-and-providers",
74
- "href": "/docs/features/#models-and-providers",
75
- "title": "Models and providers",
76
- "description": "Anthropic, DeepSeek, OpenAI, Gemini, Mistral, OpenRouter, Doubao, and Doubao China behind one submission shape."
77
- },
1
+ {
2
+ "brand": "aex",
3
+ "productName": "Agent Executor",
4
+ "oneLine": "aex is an agent execution platform for launching autonomous agents from a simple TypeScript SDK and CLI.",
5
+ "description": "Open durable agent sessions, send turns, stream events, capture outputs, and compose agents with skills, files, MCP, secrets, networking controls, and subagents across the managed runtime.",
6
+ "alpha": {
7
+ "label": "Alpha testing",
8
+ "description": "Access is limited to invited testers while we harden the hosted runtime, dashboard, and SDK workflows."
9
+ },
10
+ "installCommand": "npm i @aexhq/sdk",
11
+ "examples": {
12
+ "typescriptLines": [
13
+ "import { Aex, Models, Sizes } from \"@aexhq/sdk\";",
14
+ "",
15
+ "const aex = new Aex({ apiKey: process.env.AEX_API_KEY! });",
16
+ "",
17
+ "const session = await aex.openSession({",
18
+ " model: Models.CLAUDE_HAIKU_4_5,",
19
+ " system: \"You are a concise engineering assistant.\",",
20
+ " runtime: Sizes.SHARED_0_25X_1GB,",
21
+ " overrides: { idleTtl: \"3m\" },",
22
+ " apiKeys: { anthropic: process.env.ANTHROPIC_API_KEY! }",
23
+ "});",
24
+ "",
25
+ "const result = await session.send(\"Write a short report and save it as a file.\").done();",
26
+ "console.log(result.status, result.text);"
27
+ ],
28
+ "cliLines": [
29
+ "aex run \\",
30
+ " --api-key \"$AEX_API_KEY\" \\",
31
+ " --anthropic-api-key \"$ANTHROPIC_API_KEY\" \\",
32
+ " --model claude-haiku-4-5 \\",
33
+ " --prompt \"Write a short report and save it as a file.\" \\",
34
+ " --follow"
35
+ ]
36
+ },
37
+ "providers": [
38
+ { "id": "anthropic", "name": "Anthropic" },
39
+ { "id": "deepseek", "name": "DeepSeek" },
40
+ { "id": "openai", "name": "OpenAI" },
41
+ { "id": "gemini", "name": "Gemini" },
42
+ { "id": "mistral", "name": "Mistral" },
43
+ { "id": "openrouter", "name": "OpenRouter" },
44
+ { "id": "doubao", "name": "Doubao" },
45
+ { "id": "doubao-cn", "name": "Doubao China" }
46
+ ],
47
+ "featureAreas": [
48
+ {
49
+ "slug": "agent-runtime",
50
+ "href": "/docs/features/#agent-runtime",
51
+ "title": "Agent runtime",
52
+ "description": "Managed autonomous runs with filesystem read/edit, grep/glob/head/tail, open web fetch/search, background commands, code execution, git, and subagents."
53
+ },
54
+ {
55
+ "slug": "durable-infrastructure",
56
+ "href": "/docs/features/#durable-infrastructure",
57
+ "title": "Durable infrastructure",
58
+ "description": "Run records, status, wait/cancel/delete, idempotency, typed events, output capture, downloads, timeouts, and runtime sizes."
59
+ },
60
+ {
61
+ "slug": "agent-composition",
62
+ "href": "/docs/features/#agent-composition",
63
+ "title": "Agent composition",
64
+ "description": "Skills, files, AGENTS.md, remote MCP servers, environment variables, packages, secrets, and networking controls."
65
+ },
66
+ {
67
+ "slug": "subagents",
68
+ "href": "/docs/features/#subagents",
69
+ "title": "Subagents",
70
+ "description": "Typed parent/child lineage for async child runs, output handoff, and bounded agent delegation."
71
+ },
72
+ {
73
+ "slug": "models-and-providers",
74
+ "href": "/docs/features/#models-and-providers",
75
+ "title": "Models and providers",
76
+ "description": "Anthropic, DeepSeek, OpenAI, Gemini, Mistral, OpenRouter, Doubao, and Doubao China behind one submission shape."
77
+ },
78
78
  {
79
79
  "slug": "typed-control-surface",
80
80
  "href": "/docs/features/#typed-control-surface",
@@ -1,122 +1,122 @@
1
- ---
2
- title: Quickstart
3
- ---
4
-
5
- # Quickstart
6
-
7
- ## 1. Install
8
-
9
- ```bash
10
- npm i @aexhq/sdk
11
- ```
12
-
13
- This installs the TypeScript SDK exports and the bundled `aex` CLI.
14
-
15
- ## 2. Set credentials
16
-
17
- aex is currently in **invite-only beta**: workspaces and API keys are issued
18
- by the aex team — contact <support@aex.dev> for beta access. Once you have
19
- access, create a quickstart SDK token with `runs:read`, `runs:write`,
20
- `outputs:read`, and `billing:read` in the dashboard at <https://aex.dev>. The
21
- examples also need your BYOK provider key for the model you choose. For the
22
- Claude examples below:
23
-
24
- ```bash
25
- export AEX_API_KEY="<your-aex-api-key>"
26
- export ANTHROPIC_API_KEY="<your-anthropic-api-key>"
27
- ```
28
-
29
- ## 3. Open a session
30
-
31
- ```ts
32
- import { Aex, Models, Sizes } from "@aexhq/sdk";
33
-
34
- const aex = new Aex(process.env.AEX_API_KEY!);
35
-
36
- const session = await aex.openSession({
37
- model: Models.CLAUDE_HAIKU_4_5,
38
- system: "You are a concise engineering assistant.",
39
- runtime: Sizes.SHARED_0_25X_1GB,
40
- overrides: { idleTtl: "3m" },
41
- apiKeys: { anthropic: process.env.ANTHROPIC_API_KEY! }
42
- });
43
-
44
- const first = await session.send("Write a short report and save it as a file.").done();
45
- console.log(first.status, first.costUsd, first.text);
46
- ```
47
-
48
- `send().done()` (and `run()`) **await settle by default**, so the result always
49
- carries a terminal `status` (`succeeded` / `failed` / `timed_out` / `cancelled`
50
- — never a bare `idle`) plus `costUsd` and `usage`. Pass `await: 'park'` to
51
- return early at the render-complete park event when you don't need cost/usage.
52
- `costUsd` is aex runtime/storage spend and **excludes** your BYOK provider
53
- charges — price those from `usage` token counts against your provider's rates.
54
-
55
- The session parks as `idle` between turns and automatically moves to
56
- `suspended` after the idle window. Keep the session id and resume later:
57
-
58
- ```ts
59
- const resumed = await aex.openSession(session.id);
60
- await resumed.send("Now run the validation command and summarize the result.").done();
61
- ```
62
-
63
- ## 4. One-shot convenience
64
-
65
- `run()` opens a session, sends `message` as one turn, and returns the collected
66
- result. Its `runId` is the session id.
67
-
68
- ```ts
69
- const result = await aex.run({
70
- model: Models.CLAUDE_HAIKU_4_5,
71
- apiKeys: { anthropic: process.env.ANTHROPIC_API_KEY! },
72
- message: "Write a short report and save it as a file."
73
- });
74
-
75
- console.log(result.runId, result.status, result.text);
76
- ```
77
-
78
- ## 5. Session control: stream, wait, download
79
-
80
- Sessions are the low-level API. The handle a session gives you can do everything
81
- to itself — stream its events, wait for it to park, and download its record:
82
-
83
- ```ts
84
- const session = await aex.openSession({
85
- model: Models.CLAUDE_HAIKU_4_5,
86
- apiKeys: { anthropic: process.env.ANTHROPIC_API_KEY! }
87
- });
88
-
89
- // A turn streams its own events; iterate them, then collect the result.
90
- const turn = session.send("Write a short report and save it as a file.");
91
- for await (const event of turn) {
92
- console.log(event.type);
93
- }
94
- await turn.done();
95
-
96
- const messages = await session.messages().list();
97
- console.log(messages.at(-1)?.text);
98
-
99
- // Poll the record until the session parks: a resumable `idle` / `suspended`,
100
- // or a terminal outcome (`succeeded` / `failed` / `timed_out` / `cancelled`).
101
- const record = await session.wait();
102
- console.log(record.status);
103
-
104
- // Download the whole session record (metadata, events, outputs) as a zip.
105
- await session.download({ to: "./session.zip" });
106
- ```
107
-
108
- The same run from the bundled CLI (`npx aex` on a local install; or
109
- `npm i -g @aexhq/sdk` for a bare `aex`):
110
-
111
- ```bash
112
- npx aex run \
113
- --api-key "$AEX_API_KEY" \
114
- --anthropic-api-key "$ANTHROPIC_API_KEY" \
115
- --model claude-haiku-4-5 \
116
- --prompt "Write a short report and save it as a file." \
117
- --follow
118
- ```
119
-
1
+ ---
2
+ title: Quickstart
3
+ ---
4
+
5
+ # Quickstart
6
+
7
+ ## 1. Install
8
+
9
+ ```bash
10
+ npm i @aexhq/sdk
11
+ ```
12
+
13
+ This installs the TypeScript SDK exports and the bundled `aex` CLI.
14
+
15
+ ## 2. Set credentials
16
+
17
+ aex is currently in **invite-only beta**: workspaces and API keys are issued
18
+ by the aex team — contact <support@aex.dev> for beta access. Once you have
19
+ access, create a quickstart SDK token with `runs:read`, `runs:write`,
20
+ `outputs:read`, and `billing:read` in the dashboard at <https://aex.dev>. The
21
+ examples also need your BYOK provider key for the model you choose. For the
22
+ Claude examples below:
23
+
24
+ ```bash
25
+ export AEX_API_KEY="<your-aex-api-key>"
26
+ export ANTHROPIC_API_KEY="<your-anthropic-api-key>"
27
+ ```
28
+
29
+ ## 3. Open a session
30
+
31
+ ```ts
32
+ import { Aex, Models, Sizes } from "@aexhq/sdk";
33
+
34
+ const aex = new Aex(process.env.AEX_API_KEY!);
35
+
36
+ const session = await aex.openSession({
37
+ model: Models.CLAUDE_HAIKU_4_5,
38
+ system: "You are a concise engineering assistant.",
39
+ runtime: Sizes.SHARED_0_25X_1GB,
40
+ overrides: { idleTtl: "3m" },
41
+ apiKeys: { anthropic: process.env.ANTHROPIC_API_KEY! }
42
+ });
43
+
44
+ const first = await session.send("Write a short report and save it as a file.").done();
45
+ console.log(first.status, first.costUsd, first.text);
46
+ ```
47
+
48
+ `send().done()` (and `run()`) **await settle by default**, so the result always
49
+ carries a terminal `status` (`succeeded` / `failed` / `timed_out` / `cancelled`
50
+ — never a bare `idle`) plus `costUsd` and `usage`. Pass `await: 'park'` to
51
+ return early at the render-complete park event when you don't need cost/usage.
52
+ `costUsd` is aex runtime/storage spend and **excludes** your BYOK provider
53
+ charges — price those from `usage` token counts against your provider's rates.
54
+
55
+ The session parks as `idle` between turns and automatically moves to
56
+ `suspended` after the idle window. Keep the session id and resume later:
57
+
58
+ ```ts
59
+ const resumed = await aex.openSession(session.id);
60
+ await resumed.send("Now run the validation command and summarize the result.").done();
61
+ ```
62
+
63
+ ## 4. One-shot convenience
64
+
65
+ `run()` opens a session, sends `message` as one turn, and returns the collected
66
+ result. Its `runId` is the session id.
67
+
68
+ ```ts
69
+ const result = await aex.run({
70
+ model: Models.CLAUDE_HAIKU_4_5,
71
+ apiKeys: { anthropic: process.env.ANTHROPIC_API_KEY! },
72
+ message: "Write a short report and save it as a file."
73
+ });
74
+
75
+ console.log(result.runId, result.status, result.text);
76
+ ```
77
+
78
+ ## 5. Session control: stream, wait, download
79
+
80
+ Sessions are the low-level API. The handle a session gives you can do everything
81
+ to itself — stream its events, wait for it to park, and download its record:
82
+
83
+ ```ts
84
+ const session = await aex.openSession({
85
+ model: Models.CLAUDE_HAIKU_4_5,
86
+ apiKeys: { anthropic: process.env.ANTHROPIC_API_KEY! }
87
+ });
88
+
89
+ // A turn streams its own events; iterate them, then collect the result.
90
+ const turn = session.send("Write a short report and save it as a file.");
91
+ for await (const event of turn) {
92
+ console.log(event.type);
93
+ }
94
+ await turn.done();
95
+
96
+ const messages = await session.messages().list();
97
+ console.log(messages.at(-1)?.text);
98
+
99
+ // Poll the record until the session parks: a resumable `idle` / `suspended`,
100
+ // or a terminal outcome (`succeeded` / `failed` / `timed_out` / `cancelled`).
101
+ const record = await session.wait();
102
+ console.log(record.status);
103
+
104
+ // Download the whole session record (metadata, events, outputs) as a zip.
105
+ await session.download({ to: "./session.zip" });
106
+ ```
107
+
108
+ The same run from the bundled CLI (`npx aex` on a local install; or
109
+ `npm i -g @aexhq/sdk` for a bare `aex`):
110
+
111
+ ```bash
112
+ npx aex run \
113
+ --api-key "$AEX_API_KEY" \
114
+ --anthropic-api-key "$ANTHROPIC_API_KEY" \
115
+ --model claude-haiku-4-5 \
116
+ --prompt "Write a short report and save it as a file." \
117
+ --follow
118
+ ```
119
+
120
120
  ## Add capabilities
121
121
 
122
122
  - Add files, skills, AGENTS.md, MCP servers, packages, and networking controls with [Composition](concepts/composition.md).
package/docs/release.md CHANGED
@@ -1,9 +1,9 @@
1
- ---
2
- title: Release
3
- ---
4
-
5
- # Release
6
-
1
+ ---
2
+ title: Release
3
+ ---
4
+
5
+ # Release
6
+
7
7
  The repository is Bun-first. Build, test, docs, package validation, user tests,
8
8
  and SDK packaging run through Bun. Registry publication uses npm on the
9
9
  Bun-packed SDK tarball so npm provenance and dist-tag controls stay explicit.
@@ -11,18 +11,18 @@ Bun-packed SDK tarball so npm provenance and dist-tag controls stay explicit.
11
11
  ## Package gate
12
12
 
13
13
  Before publishing, validate the package locally and in CI:
14
-
15
- ```text
16
- bun ci
17
- bun run lint
18
- bun run test
19
- bun run test:user:offline
20
- bun run docs:build
14
+
15
+ ```text
16
+ bun ci
17
+ bun run lint
18
+ bun run test
19
+ bun run test:user:offline
20
+ bun run docs:build
21
21
  bun run pack:sdk
22
22
  ```
23
-
24
- `bun run pack:sdk` builds the SDK, runs a Bun pack dry-run, and runs the public
25
- boundary gate. Offline user tests install the packed SDK into a clean Bun
23
+
24
+ `bun run pack:sdk` builds the SDK, runs a Bun pack dry-run, and runs the public
25
+ boundary gate. Offline user tests install the packed SDK into a clean Bun
26
26
  project and exercise the SDK and CLI from that install tree.
27
27
 
28
28
  ## Publish
@@ -66,28 +66,28 @@ The manual `.github/workflows/promote.yml` workflow assigns an npm dist-tag to
66
66
  an already-published `@aexhq/sdk` version, usually `latest` after canary and
67
67
  platform validation. It also runs in `npm-release`, requires `NPM_TOKEN`, and
68
68
  does not rebuild or republish the package.
69
-
70
- ## What ships in the tarball
71
-
72
- The SDK tarball is self-contained. It declares zero `@aexhq/*` runtime
73
- dependencies and is installable from a clean Bun project with no workspace
74
- access:
75
-
76
- - `@aexhq/contracts` lives in `packages/sdk/package.json#devDependencies`
77
- only. At build time, [`packages/sdk/scripts/inline-contracts.mjs`](../scripts/inline-contracts.mjs)
78
- copies `packages/contracts/dist/**` into `packages/sdk/dist/_contracts/` and
79
- rewrites `from "@aexhq/contracts"` to `from "./_contracts/index.js"` across
80
- the SDK dist tree. A sanity check at the end of that script refuses to finish
81
- if any bare `@aexhq/contracts` specifier survives.
82
- - `@aexhq/cli` is bundled at build time by
83
- [`packages/sdk/scripts/bundle-cli.mjs`](../scripts/bundle-cli.mjs) into a
84
- single `dist/cli.mjs`, which is the `bin: aex` entry in
85
- `packages/sdk/package.json`.
86
- - This invariant is mechanically enforced by
87
- `apps/user-tests/test/offline/install.test.ts` before publish.
88
-
89
- ## Rollback
90
-
69
+
70
+ ## What ships in the tarball
71
+
72
+ The SDK tarball is self-contained. It declares zero `@aexhq/*` runtime
73
+ dependencies and is installable from a clean Bun project with no workspace
74
+ access:
75
+
76
+ - `@aexhq/contracts` lives in `packages/sdk/package.json#devDependencies`
77
+ only. At build time, [`packages/sdk/scripts/inline-contracts.mjs`](../scripts/inline-contracts.mjs)
78
+ copies `packages/contracts/dist/**` into `packages/sdk/dist/_contracts/` and
79
+ rewrites `from "@aexhq/contracts"` to `from "./_contracts/index.js"` across
80
+ the SDK dist tree. A sanity check at the end of that script refuses to finish
81
+ if any bare `@aexhq/contracts` specifier survives.
82
+ - `@aexhq/cli` is bundled at build time by
83
+ [`packages/sdk/scripts/bundle-cli.mjs`](../scripts/bundle-cli.mjs) into a
84
+ single `dist/cli.mjs`, which is the `bin: aex` entry in
85
+ `packages/sdk/package.json`.
86
+ - This invariant is mechanically enforced by
87
+ `apps/user-tests/test/offline/install.test.ts` before publish.
88
+
89
+ ## Rollback
90
+
91
91
  Published version numbers are immutable. Bad releases are fixed by publishing a
92
92
  higher version and moving dist-tags forward; source rollback alone does not
93
93
  remove an npm artifact.