@aexhq/sdk 0.38.1 → 0.39.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.
@@ -2,7 +2,7 @@ import { unzipSync } from "fflate";
2
2
  import { SKILL_BUNDLE_LIMITS } from "./_contracts/index.js";
3
3
  /**
4
4
  * Fetch a zip-archived skill from a URL and reduce it to the same in-memory
5
- * `SkillFiles` map that `Tools.fromSkillDir` consumes.
5
+ * `SkillFiles` map that `Skill.fromDir` consumes.
6
6
  *
7
7
  * This runs in the SDK process (the caller's own app), so the URL is
8
8
  * caller-controlled — there is no SSRF surface here. Host the skill yourself
@@ -16,11 +16,11 @@ import { SKILL_BUNDLE_LIMITS } from "./_contracts/index.js";
16
16
  const DEFAULT_TIMEOUT_MS = 30_000;
17
17
  export async function fetchSkillArchive(url, opts = {}) {
18
18
  if (typeof url !== "string" || url.length === 0) {
19
- throw new Error("Tools.fromSkillUrl: url is required");
19
+ throw new Error("Skill.fromUrl: url is required");
20
20
  }
21
21
  const fetchImpl = opts.fetch ?? globalThis.fetch;
22
22
  if (typeof fetchImpl !== "function") {
23
- throw new Error("Tools.fromSkillUrl: global fetch is unavailable; pass args.fetch " +
23
+ throw new Error("Skill.fromUrl: global fetch is unavailable; pass args.fetch " +
24
24
  "(Bun, Node 18+, or a fetch-capable runtime is required)");
25
25
  }
26
26
  const bytes = await download(url, fetchImpl, opts.timeoutMs ?? DEFAULT_TIMEOUT_MS);
@@ -41,40 +41,40 @@ async function download(url, fetchImpl, timeoutMs) {
41
41
  res = await fetchImpl(url, { signal: controller.signal });
42
42
  }
43
43
  catch (err) {
44
- throw new Error(`Tools.fromSkillUrl: fetch failed for ${redactUrl(url)}: ${errMessage(err)}`);
44
+ throw new Error(`Skill.fromUrl: fetch failed for ${redactUrl(url)}: ${errMessage(err)}`);
45
45
  }
46
46
  finally {
47
47
  clearTimeout(timer);
48
48
  }
49
49
  if (!res.ok) {
50
- throw new Error(`Tools.fromSkillUrl: fetch for ${redactUrl(url)} returned HTTP ${res.status}`);
50
+ throw new Error(`Skill.fromUrl: fetch for ${redactUrl(url)} returned HTTP ${res.status}`);
51
51
  }
52
52
  // Early guard on a declared size so a clearly-too-big archive fails before
53
53
  // we buffer it. The authoritative caps are re-checked by bundleSkillFiles.
54
54
  const declared = Number(res.headers.get("content-length"));
55
55
  if (Number.isFinite(declared) && declared > SKILL_BUNDLE_LIMITS.maxCompressedBytes) {
56
- throw new Error(`Tools.fromSkillUrl: archive at ${redactUrl(url)} declares ${declared} bytes, ` +
56
+ throw new Error(`Skill.fromUrl: archive at ${redactUrl(url)} declares ${declared} bytes, ` +
57
57
  `exceeding the ${SKILL_BUNDLE_LIMITS.maxCompressedBytes}-byte compressed cap`);
58
58
  }
59
59
  const bytes = new Uint8Array(await res.arrayBuffer());
60
60
  if (bytes.byteLength > SKILL_BUNDLE_LIMITS.maxCompressedBytes) {
61
- throw new Error(`Tools.fromSkillUrl: archive at ${redactUrl(url)} is ${bytes.byteLength} bytes, ` +
61
+ throw new Error(`Skill.fromUrl: archive at ${redactUrl(url)} is ${bytes.byteLength} bytes, ` +
62
62
  `exceeding the ${SKILL_BUNDLE_LIMITS.maxCompressedBytes}-byte compressed cap`);
63
63
  }
64
64
  if (bytes.byteLength === 0) {
65
- throw new Error(`Tools.fromSkillUrl: archive at ${redactUrl(url)} is empty`);
65
+ throw new Error(`Skill.fromUrl: archive at ${redactUrl(url)} is empty`);
66
66
  }
67
67
  return bytes;
68
68
  }
69
69
  async function verifySha256(bytes, expected, url) {
70
70
  const want = (expected.startsWith("sha256:") ? expected.slice("sha256:".length) : expected).toLowerCase();
71
71
  if (!/^[0-9a-f]{64}$/.test(want)) {
72
- throw new Error(`Tools.fromSkillUrl: sha256 must be 64 hex chars (optionally prefixed "sha256:"), ` +
72
+ throw new Error(`Skill.fromUrl: sha256 must be 64 hex chars (optionally prefixed "sha256:"), ` +
73
73
  `got ${JSON.stringify(expected)}`);
74
74
  }
75
75
  const got = await sha256Hex(bytes);
76
76
  if (got !== want) {
77
- throw new Error(`Tools.fromSkillUrl: archive integrity check failed for ${redactUrl(url)}: ` +
77
+ throw new Error(`Skill.fromUrl: archive integrity check failed for ${redactUrl(url)}: ` +
78
78
  `expected sha256:${want} but downloaded bytes hash to sha256:${got}`);
79
79
  }
80
80
  }
@@ -86,7 +86,7 @@ function unzip(bytes, url) {
86
86
  return unzipSync(bytes);
87
87
  }
88
88
  catch (err) {
89
- throw new Error(`Tools.fromSkillUrl: could not unzip the archive at ${redactUrl(url)} ` +
89
+ throw new Error(`Skill.fromUrl: could not unzip the archive at ${redactUrl(url)} ` +
90
90
  `(expected a .zip): ${errMessage(err)}`);
91
91
  }
92
92
  }
@@ -114,7 +114,7 @@ function resolveSkillRoot(entries, url) {
114
114
  }
115
115
  const paths = Object.keys(files);
116
116
  if (paths.length === 0) {
117
- throw new Error(`Tools.fromSkillUrl: archive at ${redactUrl(url)} contains no files`);
117
+ throw new Error(`Skill.fromUrl: archive at ${redactUrl(url)} contains no files`);
118
118
  }
119
119
  if (Object.prototype.hasOwnProperty.call(files, "SKILL.md")) {
120
120
  return files;
@@ -131,7 +131,7 @@ function resolveSkillRoot(entries, url) {
131
131
  }
132
132
  }
133
133
  const roots = [...new Set(paths.map((p) => (p.includes("/") ? `${p.split("/")[0]}/` : p)))].sort();
134
- throw new Error(`Tools.fromSkillUrl: fetched archive at ${redactUrl(url)} must contain SKILL.md at its root, ` +
134
+ throw new Error(`Skill.fromUrl: fetched archive at ${redactUrl(url)} must contain SKILL.md at its root, ` +
135
135
  `or inside a single top-level folder. Found top-level entries: ${roots.join(", ")}`);
136
136
  }
137
137
  // ---------------------------------------------------------------------------
@@ -154,7 +154,7 @@ function errMessage(err) {
154
154
  async function sha256Hex(bytes) {
155
155
  const subtle = globalThis.crypto?.subtle;
156
156
  if (!subtle) {
157
- throw new Error("Tools.fromSkillUrl: globalThis.crypto.subtle is unavailable; " +
157
+ throw new Error("Skill.fromUrl: globalThis.crypto.subtle is unavailable; " +
158
158
  "Bun, Node 18+, or a Web-Crypto-capable runtime is required");
159
159
  }
160
160
  const copy = new Uint8Array(bytes.byteLength);
@@ -1 +1 @@
1
- {"version":3,"file":"fetch-archive.js","sourceRoot":"","sources":["../src/fetch-archive.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"fetch-archive.js","sourceRoot":"","sources":["../src/fetch-archive.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -1,14 +1,14 @@
1
1
  /**
2
2
  * Public surface of the `aex` SDK.
3
3
  *
4
- * `Aex` is the single SDK client. Composition primitives are `Tool` / `Tools`
5
- * (skill-tools), `McpServer`, `AgentsMd`, `File`, and `Secret`. Everything else
6
- * is types, errors, and event type guards re-exported from `@aexhq/contracts`.
4
+ * `Aex` is the single SDK client. Composition primitives are `Tool`, `Skill`,
5
+ * `McpServer`, `AgentsMd`, `File`, and `Secret`. Everything else is types,
6
+ * errors, and event type guards re-exported from `@aexhq/contracts`.
7
7
  */
8
- export { Aex, AgentsMdClient, FilesClient, SecretsClient, SessionClient, SessionHandle, SessionTurnStream } from "./client.js";
8
+ export { Aex, AgentsMdClient, FilesClient, SecretsClient, SessionClient, SessionHandle, SessionTurnStream, SkillsClient } from "./client.js";
9
9
  export type { AexOptions, Message, OutputDownloadOptions, OutputFilePathMatch, OutputFilePathSelector, OutputFileSelector, OutputLinkSelector, RunCollectOptions, RunResult, SessionCreateOptions, SessionEnvironmentOptions, SessionEvents, SessionInput, SessionMessages, SessionOutputs, SessionOverrides, SessionRunOptions, SessionRunResult, SessionSendOptions, SessionTurnResult, SessionWebhooks, StreamEventsOptions, WaitForRunOptions } from "./client.js";
10
10
  export { Tool } from "./tool.js";
11
- export { SkillTool, Tools } from "./skill-tool.js";
11
+ export { Skill } from "./skill.js";
12
12
  export { AgentsMd } from "./agents-md.js";
13
13
  export { File } from "./file.js";
14
14
  export { McpServer } from "./mcp-server.js";
@@ -19,8 +19,8 @@ export type { BundledSkill, BundledTool, SkillFiles, ToolBundleManifest } from "
19
19
  export { AexApiError, AexError, AexNetworkError, CleanupError, CredentialValidationError, ProviderError, RunConfigValidationError, RunStateError } from "./_contracts/index.js";
20
20
  export { AexRateLimitError, isRateLimited, isThrottleFault, parseProviderFault } from "./retry.js";
21
21
  export type { ProviderFault, RetryOptions } from "./retry.js";
22
- export { MCP_SERVER_NAME_PATTERN, SKILL_BUNDLE_LIMITS, SkillBundleValidationError, normaliseSkillBundlePath, validateSkillBundleEntry, validateSkillBundleManifest } from "./_contracts/index.js";
23
- export type { AssetRef, AgentsMdRef, FileRef, McpServerRef, SkillBundleEntry, SkillBundleManifest, SkillToolRef, ToolInputSchema, ToolRef } from "./_contracts/index.js";
22
+ export { MCP_SERVER_NAME_PATTERN, SKILL_BUNDLE_LIMITS, SKILL_NAME_PATTERN, SKILL_RESERVED_NAMES, SkillBundleValidationError, normaliseSkillBundlePath, validateSkillBundleEntry, validateSkillBundleManifest } from "./_contracts/index.js";
23
+ export type { AssetRef, AgentsMdRef, FileRef, McpServerRef, SkillBundleEntry, SkillBundleManifest, SkillRecord as SkillRecordWire, SkillRef, ToolInputSchema, ToolRef } from "./_contracts/index.js";
24
24
  export type { AgentsMdRecord as AgentsMdRecordWire, BillingCheckoutPlanKey, BillingCheckoutRequest, BillingHostedSession, BillingLedgerEntry, BillingLedgerPage, BillingLedgerQuery, BillingPortalRequest, BillingSummary, FileRecord as FileRecordWire, Output, OutputFileType, OutputLink, OutputLinkOptions, OutputQuery, OutputSearchQuery, OutputSearchHit, OutputSearchPage, OutputText, ProviderEvent, ReadOutputTextOptions, Run, Session, SessionEvent, SessionListPage, SessionListQuery, SessionRetentionPolicy, SessionStatus, SessionSummary, SessionTurn, RunRecordArchiveFileV1, RunRecordArchiveFileRoleV1, RunRecordArchiveNamespaceV1, RunRecordCostV1, RunRecordDownloadErrorV1, RunRecordFileStatusV1, RunRecordManifestV1, RunRecordMetadataV1, RunRecordNamespaceV1, RunRecordSubmissionSnapshotV1, RunRecordV1, RunEvent, RunWebhookDelivery, RunWebhookDeliveryStatus, RuntimeManifest, SecretRecord, UsageSummary, WebhookSigningSecret, WhoAmI } from "./_contracts/index.js";
25
25
  export type { PlatformInlineSecrets as InlineSecrets, PlatformMcpServerSecret as McpServerSecret, PlatformEnvironment as RunEnvironment, PlatformRunSubmissionRequest, RunLimits, RunWebhookSpec, } from "./_contracts/index.js";
26
26
  export { CUSTODY_MANIFEST_SCHEMA_VERSION, RUN_RECORD_MANIFEST_SCHEMA_VERSION, RUN_RECORD_SCHEMA_VERSION, DEFAULT_RUNTIME_SIZE, RUNTIME_SIZE_PRESETS, RUNTIME_SIZES } from "./_contracts/index.js";
package/dist/index.js CHANGED
@@ -1,14 +1,14 @@
1
1
  /**
2
2
  * Public surface of the `aex` SDK.
3
3
  *
4
- * `Aex` is the single SDK client. Composition primitives are `Tool` / `Tools`
5
- * (skill-tools), `McpServer`, `AgentsMd`, `File`, and `Secret`. Everything else
6
- * is types, errors, and event type guards re-exported from `@aexhq/contracts`.
4
+ * `Aex` is the single SDK client. Composition primitives are `Tool`, `Skill`,
5
+ * `McpServer`, `AgentsMd`, `File`, and `Secret`. Everything else is types,
6
+ * errors, and event type guards re-exported from `@aexhq/contracts`.
7
7
  */
8
- export { Aex, AgentsMdClient, FilesClient, SecretsClient, SessionClient, SessionHandle, SessionTurnStream } from "./client.js";
8
+ export { Aex, AgentsMdClient, FilesClient, SecretsClient, SessionClient, SessionHandle, SessionTurnStream, SkillsClient } from "./client.js";
9
9
  // Composition primitives
10
10
  export { Tool } from "./tool.js";
11
- export { SkillTool, Tools } from "./skill-tool.js";
11
+ export { Skill } from "./skill.js";
12
12
  export { AgentsMd } from "./agents-md.js";
13
13
  export { File } from "./file.js";
14
14
  export { McpServer } from "./mcp-server.js";
@@ -23,7 +23,7 @@ export { AexApiError, AexError, AexNetworkError, CleanupError, CredentialValidat
23
23
  // `isRateLimited`), which can carry an upstream `ProviderFault`.
24
24
  export { AexRateLimitError, isRateLimited, isThrottleFault, parseProviderFault } from "./retry.js";
25
25
  // Skill-bundle / MCP wire types
26
- export { MCP_SERVER_NAME_PATTERN, SKILL_BUNDLE_LIMITS, SkillBundleValidationError, normaliseSkillBundlePath, validateSkillBundleEntry, validateSkillBundleManifest } from "./_contracts/index.js";
26
+ export { MCP_SERVER_NAME_PATTERN, SKILL_BUNDLE_LIMITS, SKILL_NAME_PATTERN, SKILL_RESERVED_NAMES, SkillBundleValidationError, normaliseSkillBundlePath, validateSkillBundleEntry, validateSkillBundleManifest } from "./_contracts/index.js";
27
27
  // Runtime sizing — the closed set of valid managed runtime presets.
28
28
  // Prefer the `Sizes` symbol const (e.g. `Sizes.SHARED_2X_8GB`)
29
29
  // so an invalid token is a compile error, not a runtime 400.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EACL,GAAG,EACH,cAAc,EACd,WAAW,EACX,aAAa,EACb,aAAa,EACb,aAAa,EACb,iBAAiB,EAClB,MAAM,aAAa,CAAC;AA2BrB,yBAAyB;AACzB,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAErC,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAGhE,SAAS;AACT,OAAO,EACL,WAAW,EACX,QAAQ,EACR,eAAe,EACf,YAAY,EACZ,yBAAyB,EACzB,aAAa,EACb,wBAAwB,EACxB,aAAa,EACd,MAAM,kBAAkB,CAAC;AAE1B,2EAA2E;AAC3E,yEAAyE;AACzE,2EAA2E;AAC3E,qEAAqE;AACrE,iEAAiE;AACjE,OAAO,EAAE,iBAAiB,EAAE,aAAa,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAGnG,gCAAgC;AAChC,OAAO,EACL,uBAAuB,EACvB,mBAAmB,EACnB,0BAA0B,EAC1B,wBAAwB,EACxB,wBAAwB,EACxB,2BAA2B,EAC5B,MAAM,kBAAkB,CAAC;AA6E1B,oEAAoE;AACpE,+DAA+D;AAC/D,6DAA6D;AAC7D,OAAO,EACL,+BAA+B,EAC/B,kCAAkC,EAClC,yBAAyB,EACzB,oBAAoB,EACpB,oBAAoB,EACpB,aAAa,EACd,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,YAAY,IAAI,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAGzD,8EAA8E;AAC9E,oFAAoF;AACpF,wEAAwE;AACxE,8EAA8E;AAC9E,OAAO,EAAE,kBAAkB,EAAE,YAAY,EAAE,qBAAqB,EAAE,uBAAuB,EAAE,MAAM,kBAAkB,CAAC;AAGpH,4EAA4E;AAC5E,mCAAmC;AACnC,OAAO,EACL,oBAAoB,EACpB,UAAU,EACV,sBAAsB,EACtB,kBAAkB,EAClB,MAAM,EACN,gBAAgB,EAChB,iBAAiB,EACjB,sBAAsB,EACtB,UAAU,EACV,aAAa,EACb,SAAS,EACT,aAAa,EACd,MAAM,kBAAkB,CAAC;AAM1B,gFAAgF;AAChF,2EAA2E;AAC3E,iFAAiF;AACjF,2EAA2E;AAC3E,OAAO,EACL,oBAAoB,EACpB,QAAQ,EACR,cAAc,EACd,YAAY,EACZ,KAAK,EACL,UAAU,EACV,aAAa,EACb,YAAY,EACZ,YAAY,EACZ,aAAa,EACb,aAAa,EACb,gBAAgB,EAChB,eAAe,EAChB,MAAM,kBAAkB,CAAC;AAQ1B,mBAAmB;AACnB,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAE/D,yEAAyE;AACzE,6EAA6E;AAC7E,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EACL,GAAG,EACH,cAAc,EACd,WAAW,EACX,aAAa,EACb,aAAa,EACb,aAAa,EACb,iBAAiB,EACjB,YAAY,EACb,MAAM,aAAa,CAAC;AA2BrB,yBAAyB;AACzB,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAErC,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAGhE,SAAS;AACT,OAAO,EACL,WAAW,EACX,QAAQ,EACR,eAAe,EACf,YAAY,EACZ,yBAAyB,EACzB,aAAa,EACb,wBAAwB,EACxB,aAAa,EACd,MAAM,kBAAkB,CAAC;AAE1B,2EAA2E;AAC3E,yEAAyE;AACzE,2EAA2E;AAC3E,qEAAqE;AACrE,iEAAiE;AACjE,OAAO,EAAE,iBAAiB,EAAE,aAAa,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAGnG,gCAAgC;AAChC,OAAO,EACL,uBAAuB,EACvB,mBAAmB,EACnB,kBAAkB,EAClB,oBAAoB,EACpB,0BAA0B,EAC1B,wBAAwB,EACxB,wBAAwB,EACxB,2BAA2B,EAC5B,MAAM,kBAAkB,CAAC;AA8E1B,oEAAoE;AACpE,+DAA+D;AAC/D,6DAA6D;AAC7D,OAAO,EACL,+BAA+B,EAC/B,kCAAkC,EAClC,yBAAyB,EACzB,oBAAoB,EACpB,oBAAoB,EACpB,aAAa,EACd,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,YAAY,IAAI,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAGzD,8EAA8E;AAC9E,oFAAoF;AACpF,wEAAwE;AACxE,8EAA8E;AAC9E,OAAO,EAAE,kBAAkB,EAAE,YAAY,EAAE,qBAAqB,EAAE,uBAAuB,EAAE,MAAM,kBAAkB,CAAC;AAGpH,4EAA4E;AAC5E,mCAAmC;AACnC,OAAO,EACL,oBAAoB,EACpB,UAAU,EACV,sBAAsB,EACtB,kBAAkB,EAClB,MAAM,EACN,gBAAgB,EAChB,iBAAiB,EACjB,sBAAsB,EACtB,UAAU,EACV,aAAa,EACb,SAAS,EACT,aAAa,EACd,MAAM,kBAAkB,CAAC;AAM1B,gFAAgF;AAChF,2EAA2E;AAC3E,iFAAiF;AACjF,2EAA2E;AAC3E,OAAO,EACL,oBAAoB,EACpB,QAAQ,EACR,cAAc,EACd,YAAY,EACZ,KAAK,EACL,UAAU,EACV,aAAa,EACb,YAAY,EACZ,YAAY,EACZ,aAAa,EACb,aAAa,EACb,gBAAgB,EAChB,eAAe,EAChB,MAAM,kBAAkB,CAAC;AAQ1B,mBAAmB;AACnB,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAE/D,yEAAyE;AACzE,6EAA6E;AAC7E,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC"}
@@ -0,0 +1,139 @@
1
+ import { type FetchLike, type SkillRef } from "./_contracts/index.js";
2
+ import { type SkillFiles } from "./bundle.js";
3
+ /**
4
+ * A Skill is a FIRST-CLASS, workspace-scoped, by-name bundle of instructional /
5
+ * executable content (`SKILL.md` at the bundle root plus any supporting files).
6
+ * It is DISTINCT from a {@link Tool}: skills are passed on the session's separate
7
+ * `skills:` input, not `tools:`, and a run gets a single `skills` meta-tool
8
+ * (list/load) rather than one load-tool per skill.
9
+ *
10
+ * Lifecycle mirrors `Secret` promotion, but keyed to a workspace name:
11
+ * - The `Skill.from*` factories read a bundle, lift `name` + `description` from
12
+ * the `SKILL.md` YAML frontmatter (an explicit `{ name }` overrides), and
13
+ * canonically zip + hash the bytes → a DRAFT skill.
14
+ * - `skill.upload(client)` UPSERTS the workspace skill by name: it stages the
15
+ * bytes to the content-addressed asset store (presign/finalize) and PUTs the
16
+ * registry entry. Identical bytes are a no-op. Returns an uploaded `Skill`
17
+ * whose wire ref is `{ kind:"skill", name }` (BY NAME — no assetId, no hash).
18
+ * - Passing a DRAFT skill in `skills:` auto-upserts it on submit (same
19
+ * ergonomic as a draft `Tool` / `File`).
20
+ *
21
+ * Binding is by name and mutable: a re-upload under the same name changes what
22
+ * every future run referencing that name sees.
23
+ */
24
+ export declare class Skill {
25
+ #private;
26
+ /** Internal constructor. Use the `Skill.from*` factories. */
27
+ private constructor();
28
+ /** The wire ref: `{ kind:"skill", name }` once uploaded, or the draft shape before. */
29
+ get ref(): SkillRef | DraftSkillRef;
30
+ /** True for a local-bytes skill that has not been upserted to the workspace yet. */
31
+ get isDraft(): boolean;
32
+ get name(): string;
33
+ get description(): string;
34
+ /** Internal: the workspace name this instance already upserted, or undefined. */
35
+ get _cachedName(): string | undefined;
36
+ /** Internal: remember that this instance's bytes were upserted under `name`. */
37
+ _rememberUpload(name: string): void;
38
+ /**
39
+ * Read a local skill directory. It must contain `SKILL.md` at its root, whose
40
+ * YAML frontmatter supplies `description` and (unless `args.name` is given)
41
+ * `name`. When neither an explicit name nor a frontmatter name is present, the
42
+ * slugified directory basename is used. Symlinks / non-regular files are
43
+ * skipped. Bun/Node filesystem runtimes only.
44
+ */
45
+ static fromDir(rootDir: string, args?: {
46
+ readonly name?: string;
47
+ }): Promise<Skill>;
48
+ /**
49
+ * Fetch a zip-archived skill from a URL. The archive is downloaded in the SDK
50
+ * process (caller-controlled URL — no SSRF surface), optionally integrity-checked
51
+ * against `sha256`, and reduced to the same files map as `Skill.fromDir` (a
52
+ * single wrapping top-level folder is stripped). It must expose `SKILL.md` at
53
+ * the root. The signed URL only needs to be valid for this call.
54
+ */
55
+ static fromUrl(url: string, args?: {
56
+ readonly name?: string;
57
+ readonly sha256?: string;
58
+ readonly timeoutMs?: number;
59
+ readonly fetch?: FetchLike;
60
+ }): Promise<Skill>;
61
+ /**
62
+ * Build a draft skill from an in-memory files map (path -> string | bytes).
63
+ * Requires a root `SKILL.md`. Universal (no filesystem access).
64
+ */
65
+ static fromFiles(args: {
66
+ readonly name?: string;
67
+ readonly files: SkillFiles;
68
+ }): Promise<Skill>;
69
+ /** Convenience: build a single-file skill from a `SKILL.md` string. */
70
+ static fromContent(skillMd: string, args?: {
71
+ readonly name?: string;
72
+ }): Promise<Skill>;
73
+ /**
74
+ * Build a draft skill from an already-zipped bundle. The zip is unpacked to a
75
+ * files map (directory entries dropped), then re-canonicalised so a
76
+ * `fromBytes` skill and the identical `fromDir` / `fromFiles` skill dedup by
77
+ * content hash. Requires `SKILL.md` at the archive root.
78
+ */
79
+ static fromBytes(args: {
80
+ readonly name?: string;
81
+ readonly zip: Uint8Array;
82
+ }): Promise<Skill>;
83
+ /**
84
+ * UPSERT this skill into the workspace registry by name and return an uploaded
85
+ * `Skill` whose ref is `{ kind:"skill", name }`. Two steps: stage the bytes to
86
+ * the content-addressed asset store (dedup makes identical bytes a no-op PUT),
87
+ * then PUT the registry entry (identical `contentHash` ⇒ server no-op). Reusing
88
+ * the SAME instance across submits skips both round-trips.
89
+ *
90
+ * Throws on an already-uploaded (non-draft) skill, mirroring `Tool.upload`.
91
+ */
92
+ upload(client: SkillUploader): Promise<Skill>;
93
+ /**
94
+ * Internal: yield the draft's bytes + metadata so `client.run` / `openSession`
95
+ * can auto-upsert it. Non-consuming: a Skill is reusable across sessions — the
96
+ * first use caches the resolved name so later uses skip the round-trip. Returns
97
+ * undefined for an already-uploaded skill.
98
+ */
99
+ _takeDraftBundle(): {
100
+ name: string;
101
+ description: string;
102
+ contentHash: string;
103
+ bytes: Uint8Array;
104
+ } | undefined;
105
+ toJSON(): SkillRef;
106
+ }
107
+ /**
108
+ * SDK-internal draft marker. Never reaches the wire; `skill.upload` /
109
+ * `run` / `openSession` converts it to a by-name {@link SkillRef} once the bytes
110
+ * are upserted.
111
+ */
112
+ export interface DraftSkillRef {
113
+ readonly kind: "draft";
114
+ readonly name: string;
115
+ readonly description: string;
116
+ readonly contentHash: string;
117
+ }
118
+ /**
119
+ * Minimal client surface `skill.upload` needs to upsert a workspace skill.
120
+ * `Aex` satisfies it; defined structurally here so `skill.ts` does not import
121
+ * `client.ts` (which would be circular — `client.ts` imports `Skill`).
122
+ */
123
+ export interface SkillUploader {
124
+ _uploadAsset(args: {
125
+ readonly bytes: Uint8Array;
126
+ readonly hash: string;
127
+ readonly contentType?: string;
128
+ }): Promise<{
129
+ readonly assetId: string;
130
+ }>;
131
+ _upsertSkill(args: {
132
+ readonly name: string;
133
+ readonly contentHash: string;
134
+ readonly description: string;
135
+ readonly sizeBytes: number;
136
+ }): Promise<{
137
+ readonly updated: boolean;
138
+ }>;
139
+ }
package/dist/skill.js ADDED
@@ -0,0 +1,289 @@
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 { readDirectoryAsFiles } 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. Symlinks / non-regular files are
70
+ * skipped. Bun/Node filesystem runtimes only.
71
+ */
72
+ static async fromDir(rootDir, args = {}) {
73
+ const files = await readDirectoryAsFiles(rootDir);
74
+ return Skill.#fromFiles("Skill.fromDir", files, args.name, dirBasename(rootDir));
75
+ }
76
+ /**
77
+ * Fetch a zip-archived skill from a URL. The archive is downloaded in the SDK
78
+ * process (caller-controlled URL — no SSRF surface), optionally integrity-checked
79
+ * against `sha256`, and reduced to the same files map as `Skill.fromDir` (a
80
+ * single wrapping top-level folder is stripped). It must expose `SKILL.md` at
81
+ * the root. The signed URL only needs to be valid for this call.
82
+ */
83
+ static async fromUrl(url, args = {}) {
84
+ const files = await fetchSkillArchive(url, {
85
+ ...(args.sha256 !== undefined ? { sha256: args.sha256 } : {}),
86
+ ...(args.timeoutMs !== undefined ? { timeoutMs: args.timeoutMs } : {}),
87
+ ...(args.fetch !== undefined ? { fetch: args.fetch } : {})
88
+ });
89
+ // A URL has no reliable directory basename, so no slug fallback.
90
+ return Skill.#fromFiles("Skill.fromUrl", files, args.name, undefined);
91
+ }
92
+ /**
93
+ * Build a draft skill from an in-memory files map (path -> string | bytes).
94
+ * Requires a root `SKILL.md`. Universal (no filesystem access).
95
+ */
96
+ static async fromFiles(args) {
97
+ if (!args || typeof args !== "object" || args.files === undefined) {
98
+ throw new Error("Skill.fromFiles: { files } is required");
99
+ }
100
+ return Skill.#fromFiles("Skill.fromFiles", args.files, args.name, undefined);
101
+ }
102
+ /** Convenience: build a single-file skill from a `SKILL.md` string. */
103
+ static async fromContent(skillMd, args = {}) {
104
+ if (typeof skillMd !== "string" || skillMd.length === 0) {
105
+ throw new Error("Skill.fromContent: skillMd must be a non-empty string");
106
+ }
107
+ return Skill.#fromFiles("Skill.fromContent", { "SKILL.md": skillMd }, args.name, undefined);
108
+ }
109
+ /**
110
+ * Build a draft skill from an already-zipped bundle. The zip is unpacked to a
111
+ * files map (directory entries dropped), then re-canonicalised so a
112
+ * `fromBytes` skill and the identical `fromDir` / `fromFiles` skill dedup by
113
+ * content hash. Requires `SKILL.md` at the archive root.
114
+ */
115
+ static async fromBytes(args) {
116
+ if (!args || !(args.zip instanceof Uint8Array) || args.zip.byteLength === 0) {
117
+ throw new Error("Skill.fromBytes: { zip } must be a non-empty Uint8Array");
118
+ }
119
+ let entries;
120
+ try {
121
+ entries = unzipSync(args.zip);
122
+ }
123
+ catch (err) {
124
+ throw new Error(`Skill.fromBytes: could not unzip the bundle (expected a .zip): ${err.message}`);
125
+ }
126
+ const files = {};
127
+ for (const [rawPath, bytes] of Object.entries(entries)) {
128
+ const path = rawPath.replace(/\\/g, "/");
129
+ if (path.endsWith("/"))
130
+ continue; // directory entry
131
+ files[path] = bytes;
132
+ }
133
+ return Skill.#fromFiles("Skill.fromBytes", files, args.name, undefined);
134
+ }
135
+ // --- workspace upsert -----------------------------------------------------
136
+ /**
137
+ * UPSERT this skill into the workspace registry by name and return an uploaded
138
+ * `Skill` whose ref is `{ kind:"skill", name }`. Two steps: stage the bytes to
139
+ * the content-addressed asset store (dedup makes identical bytes a no-op PUT),
140
+ * then PUT the registry entry (identical `contentHash` ⇒ server no-op). Reusing
141
+ * the SAME instance across submits skips both round-trips.
142
+ *
143
+ * Throws on an already-uploaded (non-draft) skill, mirroring `Tool.upload`.
144
+ */
145
+ async upload(client) {
146
+ const bundle = this._takeDraftBundle();
147
+ if (!bundle) {
148
+ throw new Error("Skill.upload: only draft skills can be uploaded. This skill is already a workspace ref " +
149
+ "({ kind:'skill', name }); reference it by name in skills:[...].");
150
+ }
151
+ if (this.#uploadedName === undefined) {
152
+ await client._uploadAsset({
153
+ bytes: bundle.bytes,
154
+ hash: bundle.contentHash,
155
+ contentType: "application/zip"
156
+ });
157
+ await client._upsertSkill({
158
+ name: bundle.name,
159
+ contentHash: bundle.contentHash,
160
+ description: bundle.description,
161
+ sizeBytes: bundle.bytes.byteLength
162
+ });
163
+ this.#uploadedName = bundle.name;
164
+ }
165
+ return new Skill({ kind: "skill", name: bundle.name }, bundle.description);
166
+ }
167
+ /**
168
+ * Internal: yield the draft's bytes + metadata so `client.run` / `openSession`
169
+ * can auto-upsert it. Non-consuming: a Skill is reusable across sessions — the
170
+ * first use caches the resolved name so later uses skip the round-trip. Returns
171
+ * undefined for an already-uploaded skill.
172
+ */
173
+ _takeDraftBundle() {
174
+ if (this.#ref.kind !== "draft" || !this.#bundleBytes) {
175
+ return undefined;
176
+ }
177
+ return {
178
+ name: this.#ref.name,
179
+ description: this.#ref.description,
180
+ contentHash: this.#ref.contentHash,
181
+ bytes: this.#bundleBytes
182
+ };
183
+ }
184
+ toJSON() {
185
+ if (this.#ref.kind === "draft") {
186
+ throw new Error("Skill: a draft skill cannot be JSON-serialised — it only becomes a by-name wire ref once " +
187
+ "skill.upload(client) upserts it (or run / openSession auto-upserts it from skills:[...]).");
188
+ }
189
+ return this.#ref;
190
+ }
191
+ static async #fromFiles(source, files, explicitName, dirBasename) {
192
+ const front = extractSkillFrontmatter(source, files);
193
+ const name = deriveSkillName(source, front.name, explicitName, dirBasename);
194
+ const description = front.description;
195
+ if (typeof description !== "string" || description.trim().length === 0) {
196
+ throw new Error(`${source}: a skill description is required — add a \`description:\` field to the SKILL.md YAML frontmatter`);
197
+ }
198
+ if (description.length > 2048) {
199
+ throw new Error(`${source}: description must be <= 2048 chars`);
200
+ }
201
+ const bundled = bundleSkillFiles(files);
202
+ const contentHash = await hashSkillBundle(bundled.zip);
203
+ const ref = { kind: "draft", name, description, contentHash };
204
+ return new Skill(ref, description, bundled.zip);
205
+ }
206
+ }
207
+ /**
208
+ * Resolve a skill name: `{ name }` arg → SKILL.md frontmatter `name:` →
209
+ * (fromDir only) slugified directory basename; else error. Then validate the
210
+ * pattern, reject the `__` MCP separator, and reject reserved names. Never
211
+ * returns an invalid name silently — an underivable / non-conforming name throws.
212
+ */
213
+ function deriveSkillName(source, frontmatterName, explicitName, dirBasename) {
214
+ let name = explicitName ?? frontmatterName;
215
+ if (name === undefined && dirBasename !== undefined) {
216
+ const slug = slugifyName(dirBasename);
217
+ if (slug.length > 0) {
218
+ name = slug;
219
+ }
220
+ }
221
+ if (typeof name !== "string" || name.length === 0) {
222
+ throw new Error(`${source}: a skill name is required — pass { name }, add a \`name:\` field to the SKILL.md ` +
223
+ `YAML frontmatter, or (for fromDir) use a directory whose basename slugifies to a valid name`);
224
+ }
225
+ if (!SKILL_NAME_PATTERN.test(name)) {
226
+ throw new Error(`${source}: name ${JSON.stringify(name)} must match ${SKILL_NAME_PATTERN.source}`);
227
+ }
228
+ if (name.includes("__")) {
229
+ throw new Error(`${source}: name must not contain "__"; that separator is reserved for MCP tools`);
230
+ }
231
+ if (SKILL_RESERVED_NAMES.has(name)) {
232
+ throw new Error(`${source}: name ${JSON.stringify(name)} is reserved (${[...SKILL_RESERVED_NAMES].join(", ")}); pick another`);
233
+ }
234
+ return name;
235
+ }
236
+ /** Lowercase, collapse non-`[a-z0-9]` runs to `-`, trim leading/trailing `-`. */
237
+ function slugifyName(input) {
238
+ return input.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
239
+ }
240
+ /** Directory basename of a filesystem path (handles `/` and `\`, trailing slashes). */
241
+ function dirBasename(path) {
242
+ const normalised = path.replace(/\\/g, "/").replace(/\/+$/, "");
243
+ return normalised.split("/").at(-1) ?? "";
244
+ }
245
+ /**
246
+ * Read `SKILL.md` from a bundle files map and parse its YAML frontmatter for
247
+ * `name` + `description`. Throws when the bundle has no root `SKILL.md` (that is
248
+ * what makes a bundle a skill).
249
+ */
250
+ function extractSkillFrontmatter(source, files) {
251
+ const raw = files["SKILL.md"];
252
+ if (raw === undefined) {
253
+ throw new Error(`${source}: the skill bundle must contain a SKILL.md at its root`);
254
+ }
255
+ const text = typeof raw === "string" ? raw : new TextDecoder().decode(raw);
256
+ return parseSkillFrontmatter(text);
257
+ }
258
+ /**
259
+ * Minimal YAML-frontmatter reader: pulls the `name` and `description` scalar
260
+ * values out of the leading `--- … ---` block. Only simple single-line
261
+ * `key: value` entries are supported (surrounding single/double quotes are
262
+ * stripped); anything else is ignored.
263
+ */
264
+ function parseSkillFrontmatter(text) {
265
+ const src = text.charCodeAt(0) === 0xfeff ? text.slice(1) : text;
266
+ const match = /^---[ \t]*\r?\n([\s\S]*?)\r?\n---[ \t]*(?:\r?\n|$)/.exec(src);
267
+ if (!match) {
268
+ return {};
269
+ }
270
+ const out = {};
271
+ for (const line of match[1].split(/\r?\n/)) {
272
+ const kv = /^([A-Za-z0-9_-]+)[ \t]*:[ \t]*(.*)$/.exec(line);
273
+ if (!kv)
274
+ continue;
275
+ const key = kv[1].toLowerCase();
276
+ if (key !== "name" && key !== "description")
277
+ continue;
278
+ let value = kv[2].trim();
279
+ if (value.length >= 2 &&
280
+ ((value.startsWith('"') && value.endsWith('"')) || (value.startsWith("'") && value.endsWith("'")))) {
281
+ value = value.slice(1, -1);
282
+ }
283
+ if (value.length > 0) {
284
+ out[key] = value;
285
+ }
286
+ }
287
+ return out;
288
+ }
289
+ //# sourceMappingURL=skill.js.map