@aexhq/sdk 0.38.1 → 0.40.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.
Files changed (100) hide show
  1. package/README.md +23 -17
  2. package/dist/_contracts/api-key.d.ts +49 -0
  3. package/dist/_contracts/api-key.js +87 -0
  4. package/dist/_contracts/bundle-manifest.d.ts +86 -0
  5. package/dist/_contracts/bundle-manifest.js +157 -0
  6. package/dist/_contracts/error-codes.d.ts +26 -0
  7. package/dist/_contracts/error-codes.js +79 -0
  8. package/dist/_contracts/error-factory.d.ts +32 -0
  9. package/dist/_contracts/error-factory.js +142 -0
  10. package/dist/_contracts/event-envelope.d.ts +33 -10
  11. package/dist/_contracts/event-envelope.js +46 -10
  12. package/dist/_contracts/event-view.d.ts +123 -0
  13. package/dist/_contracts/event-view.js +120 -0
  14. package/dist/_contracts/http.js +12 -3
  15. package/dist/_contracts/index.d.ts +8 -4
  16. package/dist/_contracts/index.js +11 -7
  17. package/dist/_contracts/models.d.ts +15 -0
  18. package/dist/_contracts/models.js +33 -0
  19. package/dist/_contracts/operations.d.ts +70 -2
  20. package/dist/_contracts/operations.js +143 -7
  21. package/dist/_contracts/run-config.d.ts +35 -10
  22. package/dist/_contracts/run-config.js +17 -5
  23. package/dist/_contracts/run-record.d.ts +3 -2
  24. package/dist/_contracts/runtime-types.d.ts +148 -36
  25. package/dist/_contracts/runtime-types.js +33 -1
  26. package/dist/_contracts/sdk-errors.d.ts +61 -2
  27. package/dist/_contracts/sdk-errors.js +83 -3
  28. package/dist/_contracts/sdk-secrets.js +31 -6
  29. package/dist/_contracts/stable.d.ts +14 -0
  30. package/dist/_contracts/stable.js +14 -0
  31. package/dist/_contracts/status.d.ts +28 -1
  32. package/dist/_contracts/status.js +48 -3
  33. package/dist/_contracts/submission.d.ts +157 -14
  34. package/dist/_contracts/submission.js +319 -55
  35. package/dist/_contracts/suggest.d.ts +15 -0
  36. package/dist/_contracts/suggest.js +54 -0
  37. package/dist/asset-upload.d.ts +27 -1
  38. package/dist/asset-upload.js +219 -4
  39. package/dist/asset-upload.js.map +1 -1
  40. package/dist/bundle.d.ts +23 -14
  41. package/dist/bundle.js +39 -20
  42. package/dist/bundle.js.map +1 -1
  43. package/dist/canonical-zip.d.ts +68 -0
  44. package/dist/canonical-zip.js +307 -0
  45. package/dist/canonical-zip.js.map +1 -0
  46. package/dist/cli.mjs +1927 -326
  47. package/dist/cli.mjs.sha256 +1 -1
  48. package/dist/client.d.ts +273 -70
  49. package/dist/client.js +885 -335
  50. package/dist/client.js.map +1 -1
  51. package/dist/fetch-archive.js +14 -14
  52. package/dist/fetch-archive.js.map +1 -1
  53. package/dist/file.d.ts +33 -6
  54. package/dist/file.js +120 -54
  55. package/dist/file.js.map +1 -1
  56. package/dist/index.d.ts +23 -14
  57. package/dist/index.js +31 -14
  58. package/dist/index.js.map +1 -1
  59. package/dist/node-fs.d.ts +26 -9
  60. package/dist/node-fs.js +13 -38
  61. package/dist/node-fs.js.map +1 -1
  62. package/dist/node-walk.d.ts +69 -0
  63. package/dist/node-walk.js +146 -0
  64. package/dist/node-walk.js.map +1 -0
  65. package/dist/retry.d.ts +9 -13
  66. package/dist/retry.js +18 -17
  67. package/dist/retry.js.map +1 -1
  68. package/dist/skill.d.ts +151 -0
  69. package/dist/skill.js +298 -0
  70. package/dist/skill.js.map +1 -0
  71. package/dist/tool.d.ts +14 -2
  72. package/dist/tool.js +33 -7
  73. package/dist/tool.js.map +1 -1
  74. package/dist/version.d.ts +1 -1
  75. package/dist/version.js +1 -1
  76. package/docs/authentication.md +29 -5
  77. package/docs/billing.md +6 -0
  78. package/docs/concepts/agent-tools.md +11 -0
  79. package/docs/concepts/composition.md +3 -3
  80. package/docs/defaults.md +1 -0
  81. package/docs/errors.md +64 -4
  82. package/docs/events.md +84 -49
  83. package/docs/limits-and-quotas.md +24 -0
  84. package/docs/mcp.md +3 -2
  85. package/docs/networking.md +7 -1
  86. package/docs/outputs.md +36 -7
  87. package/docs/provider-runtime-capabilities.md +1 -1
  88. package/docs/quickstart.md +17 -7
  89. package/docs/run-config.md +3 -3
  90. package/docs/secrets.md +14 -0
  91. package/docs/skills.md +74 -44
  92. package/docs/vision-skills.md +3 -3
  93. package/examples/feature-tour.ts +4 -6
  94. package/examples/spike-settle-latency.ts +125 -0
  95. package/package.json +4 -3
  96. package/dist/_contracts/event-guards.d.ts +0 -67
  97. package/dist/_contracts/event-guards.js +0 -36
  98. package/dist/skill-tool.d.ts +0 -102
  99. package/dist/skill-tool.js +0 -190
  100. package/dist/skill-tool.js.map +0 -1
package/dist/skill.js ADDED
@@ -0,0 +1,298 @@
1
+ import { SKILL_NAME_PATTERN, SKILL_RESERVED_NAMES } from "./_contracts/index.js";
2
+ import { bundleSkillFiles, hashSkillBundle } from "./bundle.js";
3
+ import { fetchSkillArchive } from "./fetch-archive.js";
4
+ import { readDirectoryWithFidelity } from "./node-fs.js";
5
+ import { unzipSync } from "fflate";
6
+ /**
7
+ * A Skill is a FIRST-CLASS, workspace-scoped, by-name bundle of instructional /
8
+ * executable content (`SKILL.md` at the bundle root plus any supporting files).
9
+ * It is DISTINCT from a {@link Tool}: skills are passed on the session's separate
10
+ * `skills:` input, not `tools:`, and a run gets a single `skills` meta-tool
11
+ * (list/load) rather than one load-tool per skill.
12
+ *
13
+ * Lifecycle mirrors `Secret` promotion, but keyed to a workspace name:
14
+ * - The `Skill.from*` factories read a bundle, lift `name` + `description` from
15
+ * the `SKILL.md` YAML frontmatter (an explicit `{ name }` overrides), and
16
+ * canonically zip + hash the bytes → a DRAFT skill.
17
+ * - `skill.upload(client)` UPSERTS the workspace skill by name: it stages the
18
+ * bytes to the content-addressed asset store (presign/finalize) and PUTs the
19
+ * registry entry. Identical bytes are a no-op. Returns an uploaded `Skill`
20
+ * whose wire ref is `{ kind:"skill", name }` (BY NAME — no assetId, no hash).
21
+ * - Passing a DRAFT skill in `skills:` auto-upserts it on submit (same
22
+ * ergonomic as a draft `Tool` / `File`).
23
+ *
24
+ * Binding is by name and mutable: a re-upload under the same name changes what
25
+ * every future run referencing that name sees.
26
+ */
27
+ export class Skill {
28
+ #ref;
29
+ #description;
30
+ #bundleBytes;
31
+ /** Set once this instance has upserted its bytes, so reuse skips the round-trip. */
32
+ #uploadedName;
33
+ /** Internal constructor. Use the `Skill.from*` factories. */
34
+ constructor(ref, description, bundleBytes) {
35
+ this.#ref = ref;
36
+ this.#description = description;
37
+ this.#bundleBytes = bundleBytes;
38
+ if (ref.kind === "skill") {
39
+ this.#uploadedName = ref.name;
40
+ }
41
+ }
42
+ /** The wire ref: `{ kind:"skill", name }` once uploaded, or the draft shape before. */
43
+ get ref() {
44
+ return this.#ref;
45
+ }
46
+ /** True for a local-bytes skill that has not been upserted to the workspace yet. */
47
+ get isDraft() {
48
+ return this.#ref.kind === "draft";
49
+ }
50
+ get name() {
51
+ return this.#ref.name;
52
+ }
53
+ get description() {
54
+ return this.#description;
55
+ }
56
+ /** Internal: the workspace name this instance already upserted, or undefined. */
57
+ get _cachedName() {
58
+ return this.#uploadedName;
59
+ }
60
+ /** Internal: remember that this instance's bytes were upserted under `name`. */
61
+ _rememberUpload(name) {
62
+ this.#uploadedName = name;
63
+ }
64
+ // --- factories (source symmetry with File / AgentsMd / Tool) --------------
65
+ /**
66
+ * Read a local skill directory. It must contain `SKILL.md` at its root, whose
67
+ * YAML frontmatter supplies `description` and (unless `args.name` is given)
68
+ * `name`. When neither an explicit name nor a frontmatter name is present, the
69
+ * slugified directory basename is used.
70
+ *
71
+ * The directory is walked with FIDELITY (the same walk `File.fromPath` uses):
72
+ * `.aexignore` + the always-on defaults (`.git/`, `node_modules/`, …) prune the
73
+ * upload — so a skill dir carrying `node_modules` no longer ships it — and
74
+ * executable bits + symlinks are captured into a `.aexmeta.json` sidecar
75
+ * (emitted only when such metadata exists, so a pure-content skill dir stays
76
+ * byte-identical → dedup continuity). Bun/Node filesystem runtimes only.
77
+ */
78
+ static async fromDir(rootDir, args = {}) {
79
+ const { files, meta } = await readDirectoryWithFidelity(rootDir, args.ignore);
80
+ return Skill.#fromFiles("Skill.fromDir", files, args.name, dirBasename(rootDir), meta);
81
+ }
82
+ /**
83
+ * Fetch a zip-archived skill from a URL. The archive is downloaded in the SDK
84
+ * process (caller-controlled URL — no SSRF surface), optionally integrity-checked
85
+ * against `sha256`, and reduced to the same files map as `Skill.fromDir` (a
86
+ * single wrapping top-level folder is stripped). It must expose `SKILL.md` at
87
+ * the root. The signed URL only needs to be valid for this call.
88
+ */
89
+ static async fromUrl(url, args = {}) {
90
+ const files = await fetchSkillArchive(url, {
91
+ ...(args.sha256 !== undefined ? { sha256: args.sha256 } : {}),
92
+ ...(args.timeoutMs !== undefined ? { timeoutMs: args.timeoutMs } : {}),
93
+ ...(args.fetch !== undefined ? { fetch: args.fetch } : {})
94
+ });
95
+ // A URL has no reliable directory basename, so no slug fallback.
96
+ return Skill.#fromFiles("Skill.fromUrl", files, args.name, undefined);
97
+ }
98
+ /**
99
+ * Build a draft skill from an in-memory files map (path -> string | bytes).
100
+ * Requires a root `SKILL.md`. Universal (no filesystem access). An optional
101
+ * `meta` (exec bits + symlinks) is threaded to the bundler for callers that
102
+ * carry fidelity metadata alongside a hand-built map; omit it and a plain map
103
+ * stays byte-identical to the pre-fidelity output.
104
+ */
105
+ static async fromFiles(args) {
106
+ if (!args || typeof args !== "object" || args.files === undefined) {
107
+ throw new Error("Skill.fromFiles: { files } is required");
108
+ }
109
+ return Skill.#fromFiles("Skill.fromFiles", args.files, args.name, undefined, args.meta);
110
+ }
111
+ /** Convenience: build a single-file skill from a `SKILL.md` string. */
112
+ static async fromContent(skillMd, args = {}) {
113
+ if (typeof skillMd !== "string" || skillMd.length === 0) {
114
+ throw new Error("Skill.fromContent: skillMd must be a non-empty string");
115
+ }
116
+ return Skill.#fromFiles("Skill.fromContent", { "SKILL.md": skillMd }, args.name, undefined);
117
+ }
118
+ /**
119
+ * Build a draft skill from an already-zipped bundle. The zip is unpacked to a
120
+ * files map (directory entries dropped), then re-canonicalised so a
121
+ * `fromBytes` skill and the identical `fromDir` / `fromFiles` skill dedup by
122
+ * content hash. Requires `SKILL.md` at the archive root.
123
+ */
124
+ static async fromBytes(args) {
125
+ if (!args || !(args.zip instanceof Uint8Array) || args.zip.byteLength === 0) {
126
+ throw new Error("Skill.fromBytes: { zip } must be a non-empty Uint8Array");
127
+ }
128
+ let entries;
129
+ try {
130
+ entries = unzipSync(args.zip);
131
+ }
132
+ catch (err) {
133
+ throw new Error(`Skill.fromBytes: could not unzip the bundle (expected a .zip): ${err.message}`);
134
+ }
135
+ const files = {};
136
+ for (const [rawPath, bytes] of Object.entries(entries)) {
137
+ const path = rawPath.replace(/\\/g, "/");
138
+ if (path.endsWith("/"))
139
+ continue; // directory entry
140
+ files[path] = bytes;
141
+ }
142
+ return Skill.#fromFiles("Skill.fromBytes", files, args.name, undefined);
143
+ }
144
+ // --- workspace upsert -----------------------------------------------------
145
+ /**
146
+ * UPSERT this skill into the workspace registry by name and return an uploaded
147
+ * `Skill` whose ref is `{ kind:"skill", name }`. Two steps: stage the bytes to
148
+ * the content-addressed asset store (dedup makes identical bytes a no-op PUT),
149
+ * then PUT the registry entry (identical `contentHash` ⇒ server no-op). Reusing
150
+ * the SAME instance across submits skips both round-trips.
151
+ *
152
+ * Throws on an already-uploaded (non-draft) skill, mirroring `Tool.upload`.
153
+ */
154
+ async upload(client) {
155
+ const bundle = this._takeDraftBundle();
156
+ if (!bundle) {
157
+ throw new Error("Skill.upload: only draft skills can be uploaded. This skill is already a workspace ref " +
158
+ "({ kind:'skill', name }); reference it by name in skills:[...].");
159
+ }
160
+ if (this.#uploadedName === undefined) {
161
+ await client._uploadAsset({
162
+ bytes: bundle.bytes,
163
+ hash: bundle.contentHash,
164
+ contentType: "application/zip"
165
+ });
166
+ await client._upsertSkill({
167
+ name: bundle.name,
168
+ contentHash: bundle.contentHash,
169
+ description: bundle.description,
170
+ sizeBytes: bundle.bytes.byteLength
171
+ });
172
+ this.#uploadedName = bundle.name;
173
+ }
174
+ return new Skill({ kind: "skill", name: bundle.name }, bundle.description);
175
+ }
176
+ /**
177
+ * Internal: yield the draft's bytes + metadata so `client.run` / `openSession`
178
+ * can auto-upsert it. Non-consuming: a Skill is reusable across sessions — the
179
+ * first use caches the resolved name so later uses skip the round-trip. Returns
180
+ * undefined for an already-uploaded skill.
181
+ */
182
+ _takeDraftBundle() {
183
+ if (this.#ref.kind !== "draft" || !this.#bundleBytes) {
184
+ return undefined;
185
+ }
186
+ return {
187
+ name: this.#ref.name,
188
+ description: this.#ref.description,
189
+ contentHash: this.#ref.contentHash,
190
+ bytes: this.#bundleBytes
191
+ };
192
+ }
193
+ toJSON() {
194
+ if (this.#ref.kind === "draft") {
195
+ throw new Error("Skill: a draft skill cannot be JSON-serialised — it only becomes a by-name wire ref once " +
196
+ "skill.upload(client) upserts it (or run / openSession auto-upserts it from skills:[...]).");
197
+ }
198
+ return this.#ref;
199
+ }
200
+ static async #fromFiles(source, files, explicitName, dirBasename, meta) {
201
+ const front = extractSkillFrontmatter(source, files);
202
+ const name = deriveSkillName(source, front.name, explicitName, dirBasename);
203
+ const description = front.description;
204
+ if (typeof description !== "string" || description.trim().length === 0) {
205
+ throw new Error(`${source}: a skill description is required — add a \`description:\` field to the SKILL.md YAML frontmatter`);
206
+ }
207
+ if (description.length > 2048) {
208
+ throw new Error(`${source}: description must be <= 2048 chars`);
209
+ }
210
+ const bundled = bundleSkillFiles(files, meta);
211
+ const contentHash = await hashSkillBundle(bundled.zip);
212
+ const ref = { kind: "draft", name, description, contentHash };
213
+ return new Skill(ref, description, bundled.zip);
214
+ }
215
+ }
216
+ /**
217
+ * Resolve a skill name: `{ name }` arg → SKILL.md frontmatter `name:` →
218
+ * (fromDir only) slugified directory basename; else error. Then validate the
219
+ * pattern, reject the `__` MCP separator, and reject reserved names. Never
220
+ * returns an invalid name silently — an underivable / non-conforming name throws.
221
+ */
222
+ function deriveSkillName(source, frontmatterName, explicitName, dirBasename) {
223
+ let name = explicitName ?? frontmatterName;
224
+ if (name === undefined && dirBasename !== undefined) {
225
+ const slug = slugifyName(dirBasename);
226
+ if (slug.length > 0) {
227
+ name = slug;
228
+ }
229
+ }
230
+ if (typeof name !== "string" || name.length === 0) {
231
+ throw new Error(`${source}: a skill name is required — pass { name }, add a \`name:\` field to the SKILL.md ` +
232
+ `YAML frontmatter, or (for fromDir) use a directory whose basename slugifies to a valid name`);
233
+ }
234
+ if (!SKILL_NAME_PATTERN.test(name)) {
235
+ throw new Error(`${source}: name ${JSON.stringify(name)} must match ${SKILL_NAME_PATTERN.source}`);
236
+ }
237
+ if (name.includes("__")) {
238
+ throw new Error(`${source}: name must not contain "__"; that separator is reserved for MCP tools`);
239
+ }
240
+ if (SKILL_RESERVED_NAMES.has(name)) {
241
+ throw new Error(`${source}: name ${JSON.stringify(name)} is reserved (${[...SKILL_RESERVED_NAMES].join(", ")}); pick another`);
242
+ }
243
+ return name;
244
+ }
245
+ /** Lowercase, collapse non-`[a-z0-9]` runs to `-`, trim leading/trailing `-`. */
246
+ function slugifyName(input) {
247
+ return input.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
248
+ }
249
+ /** Directory basename of a filesystem path (handles `/` and `\`, trailing slashes). */
250
+ function dirBasename(path) {
251
+ const normalised = path.replace(/\\/g, "/").replace(/\/+$/, "");
252
+ return normalised.split("/").at(-1) ?? "";
253
+ }
254
+ /**
255
+ * Read `SKILL.md` from a bundle files map and parse its YAML frontmatter for
256
+ * `name` + `description`. Throws when the bundle has no root `SKILL.md` (that is
257
+ * what makes a bundle a skill).
258
+ */
259
+ function extractSkillFrontmatter(source, files) {
260
+ const raw = files["SKILL.md"];
261
+ if (raw === undefined) {
262
+ throw new Error(`${source}: the skill bundle must contain a SKILL.md at its root`);
263
+ }
264
+ const text = typeof raw === "string" ? raw : new TextDecoder().decode(raw);
265
+ return parseSkillFrontmatter(text);
266
+ }
267
+ /**
268
+ * Minimal YAML-frontmatter reader: pulls the `name` and `description` scalar
269
+ * values out of the leading `--- … ---` block. Only simple single-line
270
+ * `key: value` entries are supported (surrounding single/double quotes are
271
+ * stripped); anything else is ignored.
272
+ */
273
+ function parseSkillFrontmatter(text) {
274
+ const src = text.charCodeAt(0) === 0xfeff ? text.slice(1) : text;
275
+ const match = /^---[ \t]*\r?\n([\s\S]*?)\r?\n---[ \t]*(?:\r?\n|$)/.exec(src);
276
+ if (!match) {
277
+ return {};
278
+ }
279
+ const out = {};
280
+ for (const line of match[1].split(/\r?\n/)) {
281
+ const kv = /^([A-Za-z0-9_-]+)[ \t]*:[ \t]*(.*)$/.exec(line);
282
+ if (!kv)
283
+ continue;
284
+ const key = kv[1].toLowerCase();
285
+ if (key !== "name" && key !== "description")
286
+ continue;
287
+ let value = kv[2].trim();
288
+ if (value.length >= 2 &&
289
+ ((value.startsWith('"') && value.endsWith('"')) || (value.startsWith("'") && value.endsWith("'")))) {
290
+ value = value.slice(1, -1);
291
+ }
292
+ if (value.length > 0) {
293
+ out[key] = value;
294
+ }
295
+ }
296
+ return out;
297
+ }
298
+ //# sourceMappingURL=skill.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skill.js","sourceRoot":"","sources":["../src/skill.ts"],"names":[],"mappings":"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"}
package/dist/tool.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import { type ToolInputSchema, type ToolRef } from "./_contracts/index.js";
2
- import { type SkillFiles } from "./bundle.js";
2
+ import { type BundleMeta, type SkillFiles } from "./bundle.js";
3
+ import type { IgnoreOptions } from "./node-walk.js";
3
4
  export interface ToolManifestInput {
4
5
  readonly name: string;
5
6
  readonly description: string;
@@ -18,8 +19,19 @@ export declare class Tool {
18
19
  _rememberAsset(assetId: string): void;
19
20
  static fromFiles(args: ToolManifestInput & {
20
21
  readonly files: SkillFiles;
22
+ readonly meta?: BundleMeta;
23
+ }): Promise<Tool>;
24
+ /**
25
+ * Read a local tool bundle directory (`tool.json` at its root + support files).
26
+ * The directory is walked with FIDELITY (the same walk `File.fromPath` uses):
27
+ * `.aexignore` + the always-on defaults (`.git/`, `node_modules/`, …) prune the
28
+ * upload, and executable bits + symlinks are captured into a `.aexmeta.json`
29
+ * sidecar (emitted only when such metadata exists, so a pure-content tool dir
30
+ * stays byte-identical → dedup continuity). Bun/Node filesystem runtimes only.
31
+ */
32
+ static fromPath(rootDir: string, args?: {
33
+ readonly ignore?: IgnoreOptions;
21
34
  }): Promise<Tool>;
22
- static fromPath(rootDir: string): Promise<Tool>;
23
35
  static fromAsset(ref: ToolRef): Tool;
24
36
  _takeDraftBundle(): {
25
37
  ref: ToolRef;
package/dist/tool.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { TOOL_NAME_PATTERN, normaliseSkillBundlePath } from "./_contracts/index.js";
2
2
  import { bundleToolFiles, hashSkillBundle } from "./bundle.js";
3
- import { readDirectoryAsFiles } from "./node-fs.js";
3
+ import { readDirectoryWithFidelity } from "./node-fs.js";
4
4
  export class Tool {
5
5
  #ref;
6
6
  #inlineBytes;
@@ -28,8 +28,8 @@ export class Tool {
28
28
  if (!args || typeof args !== "object") {
29
29
  throw new Error("Tool.fromFiles: args is required");
30
30
  }
31
- const manifest = normalizeToolManifest("Tool.fromFiles", args);
32
- const bundled = bundleToolFiles(args.files, manifest);
31
+ const manifest = normalizeToolManifest("Tool.fromFiles", args, args.files);
32
+ const bundled = bundleToolFiles(args.files, manifest, args.meta);
33
33
  const contentHash = await hashSkillBundle(bundled.zip);
34
34
  const ref = {
35
35
  kind: "draft",
@@ -39,8 +39,16 @@ export class Tool {
39
39
  };
40
40
  return new Tool(ref, bundled.zip);
41
41
  }
42
- static async fromPath(rootDir) {
43
- const files = await readDirectoryAsFiles(rootDir);
42
+ /**
43
+ * Read a local tool bundle directory (`tool.json` at its root + support files).
44
+ * The directory is walked with FIDELITY (the same walk `File.fromPath` uses):
45
+ * `.aexignore` + the always-on defaults (`.git/`, `node_modules/`, …) prune the
46
+ * upload, and executable bits + symlinks are captured into a `.aexmeta.json`
47
+ * sidecar (emitted only when such metadata exists, so a pure-content tool dir
48
+ * stays byte-identical → dedup continuity). Bun/Node filesystem runtimes only.
49
+ */
50
+ static async fromPath(rootDir, args) {
51
+ const { files, meta } = await readDirectoryWithFidelity(rootDir, args?.ignore);
44
52
  const rawManifest = files["tool.json"];
45
53
  if (rawManifest === undefined) {
46
54
  throw new Error('Tool.fromPath: tool.json is required at the tool bundle root');
@@ -59,7 +67,8 @@ export class Tool {
59
67
  const { ["tool.json"]: _manifest, ...bundleFiles } = files;
60
68
  return Tool.fromFiles({
61
69
  ...parsed,
62
- files: bundleFiles
70
+ files: bundleFiles,
71
+ meta
63
72
  });
64
73
  }
65
74
  static fromAsset(ref) {
@@ -95,7 +104,7 @@ export class Tool {
95
104
  return this.#ref;
96
105
  }
97
106
  }
98
- function normalizeToolManifest(source, input) {
107
+ function normalizeToolManifest(source, input, files) {
99
108
  const name = input.name;
100
109
  if (typeof name !== "string" || !TOOL_NAME_PATTERN.test(name)) {
101
110
  throw new Error(`${source}: name must match ${TOOL_NAME_PATTERN.source}`);
@@ -115,6 +124,7 @@ function normalizeToolManifest(source, input) {
115
124
  throw new Error(`${source}: inputSchema.type must be "object"`);
116
125
  }
117
126
  const entry = normaliseSkillBundlePath(input.entry);
127
+ assertJsModuleEntry(source, entry, input.entry, files);
118
128
  return {
119
129
  name,
120
130
  description,
@@ -122,6 +132,22 @@ function normalizeToolManifest(source, input) {
122
132
  entry
123
133
  };
124
134
  }
135
+ const JS_MODULE_ENTRY = /\.(?:js|mjs|cjs)$/i;
136
+ /**
137
+ * Validate the tool's ENTRY is a JS module at authoring time (fail-fast), not
138
+ * mid-run when the runtime module-loader rejects a `run.sh`. The entry must end
139
+ * in `.js`/`.mjs`/`.cjs` and — when the bundle files are known
140
+ * ({@link Tool.fromFiles}) — must be present in `files`.
141
+ */
142
+ function assertJsModuleEntry(source, entry, rawEntry, files) {
143
+ const basename = entry.split("/").pop() ?? entry;
144
+ if (!JS_MODULE_ENTRY.test(basename)) {
145
+ throw new Error(`${source}: entry must be a JS module (.js/.mjs/.cjs) that default-exports a function or { execute }; got ${JSON.stringify(rawEntry)}`);
146
+ }
147
+ if (files !== undefined && !(entry in files) && !(rawEntry in files)) {
148
+ throw new Error(`${source}: entry ${JSON.stringify(rawEntry)} is not present in files (keys: ${Object.keys(files).join(", ") || "(none)"})`);
149
+ }
150
+ }
125
151
  function normalizeToolRef(source, ref) {
126
152
  const manifest = normalizeToolManifest(source, {
127
153
  name: ref.name,
package/dist/tool.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"tool.js","sourceRoot":"","sources":["../src/tool.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"tool.js","sourceRoot":"","sources":["../src/tool.ts"],"names":[],"mappings":"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"}
package/dist/version.d.ts CHANGED
@@ -6,4 +6,4 @@
6
6
  *
7
7
  * Used by the (future) User-Agent header on outbound SDK requests.
8
8
  */
9
- export declare const SDK_VERSION = "0.38.1";
9
+ export declare const SDK_VERSION = "0.40.0";
package/dist/version.js CHANGED
@@ -6,5 +6,5 @@
6
6
  *
7
7
  * Used by the (future) User-Agent header on outbound SDK requests.
8
8
  */
9
- export const SDK_VERSION = "0.38.1";
9
+ export const SDK_VERSION = "0.40.0";
10
10
  //# sourceMappingURL=version.js.map
@@ -25,22 +25,46 @@ it once with `aex login`:
25
25
  ```ts
26
26
  import { Aex } from "@aexhq/sdk";
27
27
 
28
- const aex = new Aex(process.env.AEX_API_KEY!); // preferred
29
- // also accepted: new Aex({ apiKey: ... }) and the alias new Aex({ apiKey: ... })
28
+ const aex = new Aex(process.env.AEX_API_KEY!);
30
29
  ```
31
30
 
32
31
  ```bash
33
- aex whoami --api-key "$AEX_API_KEY"
32
+ npx aex whoami --api-key "$AEX_API_KEY"
34
33
 
35
34
  # or persist it once, then omit --api-key on later commands:
36
- aex login --api-key "$AEX_API_KEY"
37
- aex whoami
35
+ npx aex login --api-key "$AEX_API_KEY"
36
+ npx aex whoami
38
37
  ```
39
38
 
39
+ (`new Aex(apiKey)` is the canonical constructor; the equivalent options form is
40
+ documented once in [Credentials](credentials.md).)
41
+
40
42
  The token travels as a standard `Authorization: Bearer` header. Treat it like
41
43
  any other secret: keep it in environment variables or a secret manager, never
42
44
  in run config, prompts, or committed files.
43
45
 
46
+ ## Plane routing and the `baseUrl` guard
47
+
48
+ An aex API key is **self-describing**: it embeds the plane (`dev` / `prd`) and
49
+ region it was minted for. The constructor parses the key and routes accordingly,
50
+ with **zero network**:
51
+
52
+ - **Omit `baseUrl`** and a `prd` key routes to the canonical hosted API plane
53
+ (`https://api.aex.dev`). A `dev` key has no stable public host yet, so a dev
54
+ key with no `baseUrl` throws `CredentialValidationError` asking you to pass one.
55
+ - **Supply a `baseUrl` whose plane disagrees with the key** (e.g. a `dev` key
56
+ pointed at `https://api.aex.dev`) and the constructor throws
57
+ `CredentialValidationError` **before any request** — you no longer discover the
58
+ mismatch as a late `401 token_invalid` after a full round-trip.
59
+
60
+ ```ts
61
+ // prd key → routes to https://api.aex.dev automatically:
62
+ const prd = new Aex(process.env.AEX_PRD_KEY!);
63
+
64
+ // dev key → pass the dev plane's baseUrl explicitly:
65
+ const dev = new Aex(process.env.AEX_DEV_KEY!, { baseUrl: process.env.AEX_DEV_URL! });
66
+ ```
67
+
44
68
  ## Scopes
45
69
 
46
70
  A token carries a set of **scopes**; every API route requires one, and a token
package/docs/billing.md CHANGED
@@ -8,6 +8,12 @@ Workspace-level billing, subscription, and webhook verification calls are
8
8
  token-scoped like every other client call — the workspace is derived
9
9
  server-side from the API key.
10
10
 
11
+ The billing reads — `aex.billing()`, `aex.billingLedger()`, and the CLI
12
+ `aex billing` (and its `ledger` sub-verb) — require the **`billing:read`**
13
+ scope; a token without it fails with `403 insufficient_scope` (see
14
+ [Errors](errors.md)). This is why the [Quickstart](quickstart.md) mints
15
+ `billing:read` alongside `runs:read` / `runs:write` / `outputs:read`.
16
+
11
17
  ## Read the billing summary
12
18
 
13
19
  `aex.billing()` returns the workspace's prepaid balance, current-month spend,
@@ -10,6 +10,7 @@ Managed runs inject the complete builtin tool set into the agent by default:
10
10
  - `read_file`, `write_file`, `edit_file` — file read/create/patch
11
11
  - `grep`, `glob` — search file contents and paths
12
12
  - `head`, `tail` — read bounded file slices
13
+ - `ls`, `stat`, `wc` — list a directory, inspect path metadata, count lines/words/bytes
13
14
  - `web_fetch`, `web_search` — fetch a URL / managed web search
14
15
  - `todo_write` — maintain a todo list
15
16
  - `subagent`, `subagent_result` — delegate to and read back from child runs (see [Subagents](subagents.md))
@@ -32,6 +33,16 @@ to pick a narrow subset alongside `includeBuiltinTools: false`.
32
33
  The final tool list is ordered: resolved builtin tools, then custom tools, then
33
34
  MCP tools.
34
35
 
36
+ ## Custom tools
37
+
38
+ Attach your own tool in `tools` as a bundle built with `Tool.fromFiles(...)` (an
39
+ explicit `{ entry, files }`) or `Tool.fromPath(dir)` (a directory with a
40
+ `tool.json` at its root). The bundle's **entry must be a JS module** — a
41
+ `.js`/`.mjs`/`.cjs` file present in the bundle that **default-exports a function
42
+ or an object with an `execute` method**. This is validated at authoring time, so
43
+ a non-JS entry (e.g. a `run.sh`) is rejected right where you build the tool, not
44
+ opaquely mid-run when the runtime's module loader would fail to import it.
45
+
35
46
  Networking is open by default within the platform's managed egress ceiling and
36
47
  a fixed SSRF deny-list. `web_fetch` and `web_search` reach the network over a
37
48
  managed, SSRF-guarded path that is **not** governed by `environment.networking`,
@@ -10,7 +10,7 @@ runtime before the first agent turn.
10
10
 
11
11
  | Need | Primitive |
12
12
  | --- | --- |
13
- | Executable or instructional skill bundles (load-tools) | `Tools.fromSkillDir`, `Tools.fromSkillUrl` |
13
+ | Instructional skill bundles | `Skill.fromDir`, `Skill.fromUrl`, `Skill.fromFiles` |
14
14
  | Agent instructions | `AgentsMd.fromPath`, `AgentsMd.fromContent` |
15
15
  | Reference files and folders | `File.fromPath`, `File.fromBytes` |
16
16
  | Remote tools | `McpServer.remote`, `McpServer.fromId` |
@@ -18,14 +18,14 @@ runtime before the first agent turn.
18
18
  | Runtime secrets for your code | `Secret.value`, `Secret.ref`, `environment.secrets` |
19
19
 
20
20
  ```ts
21
- import { AgentsMd, File, McpServer, Models, Secret, Tools } from "@aexhq/sdk";
21
+ import { AgentsMd, File, McpServer, Models, Secret, Skill } from "@aexhq/sdk";
22
22
 
23
23
  await aex.run({
24
24
  model: Models.CLAUDE_HAIKU_4_5,
25
25
  message: "Use the attached docs and tools to produce a report.",
26
26
  agentsMd: [await AgentsMd.fromContent("Follow the repo conventions.", { name: "repo-rules" })],
27
27
  files: [await File.fromPath("./input")],
28
- tools: [await Tools.fromSkillDir("./skills/report-writer", { name: "report-writer" })],
28
+ skills: [await Skill.fromDir("./skills/report-writer", { name: "report-writer" })],
29
29
  mcpServers: [McpServer.remote({ name: "github", url: "https://example.com/mcp" })],
30
30
  environment: {
31
31
  secrets: { INTERNAL_API_TOKEN: Secret.value(process.env.INTERNAL_API_TOKEN!) },
package/docs/defaults.md CHANGED
@@ -23,6 +23,7 @@ For the hard ceilings and who can raise them, see
23
23
  | `timeout` (run deadline) | 8 hours (also the ceiling) | Per-session via `overrides.timeout` (e.g. `"30m"`, `"2h"`). Values outside the run-timeout floor (1 minute) / ceiling (8 hours) are rejected with `RunConfigValidationError` before submission. | `RUN_DEFAULT_TIMEOUT_MS` |
24
24
  | `runtime` (machine size) | `shared-0.25x-1gb` — 0.25 vCPU, 1 GB | Per-session via `runtime` (use `Sizes.*` in TypeScript). | `RUN_DEFAULT_RUNTIME_SIZE` |
25
25
  | `overrides.maxSpendUsd` (per-session spend cap) | None — no spend cap (the session is still bounded by its `timeout` and any workspace-level cap) | Per-session via `overrides.maxSpendUsd` (a positive USD amount); the session is stopped once its spend would exceed the cap. | — |
26
+ | `overrides.maxTurns` (agent iterations per run) | 20 (ceiling 200) | Per-session via `overrides.maxTurns` (a positive integer, clamped to the ceiling). | `RUN_DEFAULT_MAX_TURNS` |
26
27
 
27
28
  ## Tools
28
29