@aexhq/sdk 0.13.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 (112) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +160 -0
  3. package/dist/_contracts/connection-ticket.d.ts +21 -0
  4. package/dist/_contracts/connection-ticket.js +49 -0
  5. package/dist/_contracts/event-envelope.d.ts +276 -0
  6. package/dist/_contracts/event-envelope.js +324 -0
  7. package/dist/_contracts/event-stream-client.d.ts +47 -0
  8. package/dist/_contracts/event-stream-client.js +141 -0
  9. package/dist/_contracts/http.d.ts +35 -0
  10. package/dist/_contracts/http.js +114 -0
  11. package/dist/_contracts/index.d.ts +28 -0
  12. package/dist/_contracts/index.js +29 -0
  13. package/dist/_contracts/managed-key.d.ts +74 -0
  14. package/dist/_contracts/managed-key.js +110 -0
  15. package/dist/_contracts/operations.d.ts +237 -0
  16. package/dist/_contracts/operations.js +632 -0
  17. package/dist/_contracts/provider-support.d.ts +220 -0
  18. package/dist/_contracts/provider-support.js +90 -0
  19. package/dist/_contracts/proxy-protocol.d.ts +257 -0
  20. package/dist/_contracts/proxy-protocol.js +234 -0
  21. package/dist/_contracts/proxy-validation.d.ts +19 -0
  22. package/dist/_contracts/proxy-validation.js +51 -0
  23. package/dist/_contracts/run-artifacts.d.ts +47 -0
  24. package/dist/_contracts/run-artifacts.js +101 -0
  25. package/dist/_contracts/run-config.d.ts +304 -0
  26. package/dist/_contracts/run-config.js +659 -0
  27. package/dist/_contracts/run-cost.d.ts +125 -0
  28. package/dist/_contracts/run-cost.js +616 -0
  29. package/dist/_contracts/run-custody.d.ts +226 -0
  30. package/dist/_contracts/run-custody.js +465 -0
  31. package/dist/_contracts/run-record.d.ts +127 -0
  32. package/dist/_contracts/run-record.js +177 -0
  33. package/dist/_contracts/run-retention.d.ts +213 -0
  34. package/dist/_contracts/run-retention.js +484 -0
  35. package/dist/_contracts/run-unit.d.ts +194 -0
  36. package/dist/_contracts/run-unit.js +215 -0
  37. package/dist/_contracts/runner-event.d.ts +114 -0
  38. package/dist/_contracts/runner-event.js +187 -0
  39. package/dist/_contracts/runtime-manifest.d.ts +106 -0
  40. package/dist/_contracts/runtime-manifest.js +98 -0
  41. package/dist/_contracts/runtime-security-profile.d.ts +27 -0
  42. package/dist/_contracts/runtime-security-profile.js +82 -0
  43. package/dist/_contracts/runtime-sizes.d.ts +144 -0
  44. package/dist/_contracts/runtime-sizes.js +136 -0
  45. package/dist/_contracts/runtime-types.d.ts +212 -0
  46. package/dist/_contracts/runtime-types.js +2 -0
  47. package/dist/_contracts/sdk-errors.d.ts +34 -0
  48. package/dist/_contracts/sdk-errors.js +52 -0
  49. package/dist/_contracts/sdk-secrets.d.ts +31 -0
  50. package/dist/_contracts/sdk-secrets.js +220 -0
  51. package/dist/_contracts/side-effect-audit.d.ts +129 -0
  52. package/dist/_contracts/side-effect-audit.js +494 -0
  53. package/dist/_contracts/sse.d.ts +74 -0
  54. package/dist/_contracts/sse.js +0 -0
  55. package/dist/_contracts/stable.d.ts +26 -0
  56. package/dist/_contracts/stable.js +44 -0
  57. package/dist/_contracts/status.d.ts +19 -0
  58. package/dist/_contracts/status.js +61 -0
  59. package/dist/_contracts/submission.d.ts +383 -0
  60. package/dist/_contracts/submission.js +1380 -0
  61. package/dist/agents-md.d.ts +46 -0
  62. package/dist/agents-md.js +83 -0
  63. package/dist/agents-md.js.map +1 -0
  64. package/dist/asset-upload.d.ts +66 -0
  65. package/dist/asset-upload.js +168 -0
  66. package/dist/asset-upload.js.map +1 -0
  67. package/dist/bundle.d.ts +33 -0
  68. package/dist/bundle.js +89 -0
  69. package/dist/bundle.js.map +1 -0
  70. package/dist/cli.mjs +4140 -0
  71. package/dist/cli.mjs.sha256 +1 -0
  72. package/dist/client.d.ts +460 -0
  73. package/dist/client.js +857 -0
  74. package/dist/client.js.map +1 -0
  75. package/dist/fetch-archive.d.ts +16 -0
  76. package/dist/fetch-archive.js +170 -0
  77. package/dist/fetch-archive.js.map +1 -0
  78. package/dist/file.d.ts +57 -0
  79. package/dist/file.js +153 -0
  80. package/dist/file.js.map +1 -0
  81. package/dist/index.d.ts +30 -0
  82. package/dist/index.js +34 -0
  83. package/dist/index.js.map +1 -0
  84. package/dist/mcp-server.d.ts +84 -0
  85. package/dist/mcp-server.js +114 -0
  86. package/dist/mcp-server.js.map +1 -0
  87. package/dist/node-fs.d.ts +12 -0
  88. package/dist/node-fs.js +44 -0
  89. package/dist/node-fs.js.map +1 -0
  90. package/dist/proxy-endpoint.d.ts +131 -0
  91. package/dist/proxy-endpoint.js +147 -0
  92. package/dist/proxy-endpoint.js.map +1 -0
  93. package/dist/skill.d.ts +117 -0
  94. package/dist/skill.js +169 -0
  95. package/dist/skill.js.map +1 -0
  96. package/dist/version.d.ts +9 -0
  97. package/dist/version.js +10 -0
  98. package/dist/version.js.map +1 -0
  99. package/docs/cleanup.md +38 -0
  100. package/docs/credentials.md +153 -0
  101. package/docs/events.md +76 -0
  102. package/docs/mcp.md +47 -0
  103. package/docs/outputs.md +157 -0
  104. package/docs/product-boundaries.md +57 -0
  105. package/docs/provider-runtime-capabilities.md +103 -0
  106. package/docs/quickstart.md +110 -0
  107. package/docs/release.md +99 -0
  108. package/docs/run-config.md +53 -0
  109. package/docs/run-record.md +39 -0
  110. package/docs/skills.md +139 -0
  111. package/docs/testing.md +29 -0
  112. package/package.json +47 -0
@@ -0,0 +1,114 @@
1
+ import { rejectStdioMcpShape } from "./_contracts/index.js";
2
+ const WORKSPACE_MCP_ID_PATTERN = /^mcp_[A-Za-z0-9_-]{8,128}$/;
3
+ /**
4
+ * Inline MCP server reference OR a workspace-persistent ref via
5
+ * `McpServer.fromId("mcp_...")`.
6
+ *
7
+ * For inline refs, headers (typically `Authorization`) are vaulted
8
+ * server-side under `secrets.mcpServers` and excluded from the
9
+ * idempotency hash; the non-secret `{name, url}` part is hashed.
10
+ *
11
+ * The SDK splits the header bag from the public ref BEFORE the wire
12
+ * payload is built, so a single inline `McpServer` instance becomes:
13
+ *
14
+ * - a `submission.mcpServers` entry of `{ name, url }`, and
15
+ * - (when `headers` is present) a `secrets.mcpServers` entry of
16
+ * `{ name, headers }`.
17
+ *
18
+ * For workspace refs (`McpServer.fromId(id)`), the submission entry
19
+ * is `{kind:"workspace", id}`; the BFF resolves it to inline at
20
+ * submit time. The user still supplies auth separately via
21
+ * `secrets.mcpServers[<workspace-name>]` keyed by the workspace
22
+ * MCP's persisted `name`.
23
+ */
24
+ export class McpServer {
25
+ kind;
26
+ name;
27
+ url;
28
+ transport;
29
+ id;
30
+ headers;
31
+ /** Internal constructor. Use `McpServer.remote(...)` or `McpServer.fromId(...)`. */
32
+ constructor(args) {
33
+ if (!args || typeof args !== "object") {
34
+ throw new Error("McpServer: args is required");
35
+ }
36
+ // Defence in depth: any stdio-shaped input that slips past the
37
+ // builder type (callers will reach in with `as never` to feed stdio
38
+ // shapes) is rejected with the canonical error.
39
+ rejectStdioMcpShape(args);
40
+ if (args.kind === "workspace") {
41
+ if (typeof args.id !== "string" || !WORKSPACE_MCP_ID_PATTERN.test(args.id)) {
42
+ throw new Error(`McpServer.fromId: id must match ${WORKSPACE_MCP_ID_PATTERN.source}`);
43
+ }
44
+ this.kind = "workspace";
45
+ this.id = args.id;
46
+ // `name` and `url` are resolved server-side; populate placeholders so
47
+ // type-level access never returns undefined, but mark the workspace
48
+ // ref so callers can branch.
49
+ this.name = "";
50
+ this.url = "";
51
+ this.transport = undefined;
52
+ this.headers = undefined;
53
+ return;
54
+ }
55
+ if (typeof args.name !== "string" || !args.name) {
56
+ throw new Error("McpServer: name is required");
57
+ }
58
+ if (typeof args.url !== "string" || !args.url) {
59
+ throw new Error("McpServer: url is required");
60
+ }
61
+ this.kind = "inline";
62
+ this.id = undefined;
63
+ this.name = args.name;
64
+ this.url = args.url;
65
+ this.transport = args.transport;
66
+ this.headers = args.headers && Object.keys(args.headers).length > 0 ? { ...args.headers } : undefined;
67
+ }
68
+ /**
69
+ * Inline remote MCP server reachable over HTTP(S) by URL. `transport`
70
+ * defaults to the runtime's choice when omitted; pass it explicitly
71
+ * to pin `"http"` (streamable) or `"sse"` (event-stream). Stdio is
72
+ * not supported — see {@link rejectStdioMcpShape}.
73
+ */
74
+ static remote(args) {
75
+ return new McpServer({ kind: "inline", ...args });
76
+ }
77
+ /**
78
+ * Reference a workspace-persistent MCP server by id. The BFF
79
+ * resolves the ref to inline `{name, url}` at submit time using the
80
+ * row from `workspace_mcp_servers`. Auth still arrives inline at
81
+ * the call site — pass it in `secrets.mcpServers[<workspace-name>]`.
82
+ */
83
+ static fromId(id) {
84
+ return new McpServer({ kind: "workspace", id });
85
+ }
86
+ /** Wire shape for the non-secret `submission.mcpServers` entry. */
87
+ toSubmissionEntry() {
88
+ if (this.kind === "workspace") {
89
+ return { kind: "workspace", id: this.id };
90
+ }
91
+ return this.transport
92
+ ? { name: this.name, transport: this.transport, url: this.url }
93
+ : { name: this.name, url: this.url };
94
+ }
95
+ /**
96
+ * Wire shape for the `secrets.mcpServers` entry, or `undefined`
97
+ * when no headers were provided. Returned headers are a defensive
98
+ * copy.
99
+ *
100
+ * Workspace refs never emit a secret entry from the SDK — the
101
+ * caller knows the resolved `name` (from the dashboard or from a
102
+ * prior list call) and supplies the headers under that name
103
+ * directly on the `secrets.mcpServers[]` array. Mixing SDK-side
104
+ * auth into a workspace ref's `name` would create a name/auth
105
+ * mismatch the BFF can't validate.
106
+ */
107
+ toSecretEntry() {
108
+ if (this.kind === "workspace" || !this.headers) {
109
+ return undefined;
110
+ }
111
+ return { name: this.name, url: this.url, headers: { ...this.headers } };
112
+ }
113
+ }
114
+ //# sourceMappingURL=mcp-server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-server.js","sourceRoot":"","sources":["../src/mcp-server.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import type { SkillFiles } from "./bundle.js";
2
+ /**
3
+ * Walk a local directory and load every regular file into an in-memory
4
+ * `SkillFiles` map. Symlinks and non-regular files are skipped (a
5
+ * symlink that points outside the root would still be skipped because
6
+ * we use `lstat` semantics). Paths are normalised to forward-slash
7
+ * relative form so they can flow into `bundleSkillFiles` directly.
8
+ *
9
+ * Node-only. Browser callers should use `bundleSkillFiles` with a
10
+ * pre-built files map instead.
11
+ */
12
+ export declare function readDirectoryAsFiles(rootDir: string): Promise<SkillFiles>;
@@ -0,0 +1,44 @@
1
+ import { readFile, readdir, stat } from "node:fs/promises";
2
+ import { join, posix, relative, sep } from "node:path";
3
+ /**
4
+ * Walk a local directory and load every regular file into an in-memory
5
+ * `SkillFiles` map. Symlinks and non-regular files are skipped (a
6
+ * symlink that points outside the root would still be skipped because
7
+ * we use `lstat` semantics). Paths are normalised to forward-slash
8
+ * relative form so they can flow into `bundleSkillFiles` directly.
9
+ *
10
+ * Node-only. Browser callers should use `bundleSkillFiles` with a
11
+ * pre-built files map instead.
12
+ */
13
+ export async function readDirectoryAsFiles(rootDir) {
14
+ if (typeof rootDir !== "string" || !rootDir) {
15
+ throw new Error("readDirectoryAsFiles: rootDir is required");
16
+ }
17
+ const rootStat = await stat(rootDir);
18
+ if (!rootStat.isDirectory()) {
19
+ throw new Error(`readDirectoryAsFiles: ${rootDir} is not a directory`);
20
+ }
21
+ const files = {};
22
+ await walk(rootDir, rootDir, files);
23
+ return files;
24
+ }
25
+ async function walk(rootDir, currentDir, out) {
26
+ const entries = await readdir(currentDir, { withFileTypes: true });
27
+ for (const dirent of entries) {
28
+ const full = join(currentDir, dirent.name);
29
+ if (dirent.isSymbolicLink()) {
30
+ continue;
31
+ }
32
+ if (dirent.isDirectory()) {
33
+ await walk(rootDir, full, out);
34
+ continue;
35
+ }
36
+ if (!dirent.isFile()) {
37
+ continue;
38
+ }
39
+ const rel = relative(rootDir, full);
40
+ const posixPath = sep === "/" ? rel : rel.split(sep).join(posix.sep);
41
+ out[posixPath] = await readFile(full);
42
+ }
43
+ }
44
+ //# sourceMappingURL=node-fs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"node-fs.js","sourceRoot":"","sources":["../src/node-fs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAC3D,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,EAAE,MAAM,WAAW,CAAC;AAGvD;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CAAC,OAAe;IACxD,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,CAAC,OAAO,EAAE,CAAC;QAC5C,MAAM,IAAI,KAAK,CAAC,2CAA2C,CAAC,CAAC;IAC/D,CAAC;IACD,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,CAAC;IACrC,IAAI,CAAC,QAAQ,CAAC,WAAW,EAAE,EAAE,CAAC;QAC5B,MAAM,IAAI,KAAK,CAAC,yBAAyB,OAAO,qBAAqB,CAAC,CAAC;IACzE,CAAC;IACD,MAAM,KAAK,GAA+B,EAAE,CAAC;IAC7C,MAAM,IAAI,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC;IACpC,OAAO,KAAK,CAAC;AACf,CAAC;AAED,KAAK,UAAU,IAAI,CAAC,OAAe,EAAE,UAAkB,EAAE,GAA+B;IACtF,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,UAAU,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;IACnE,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC7B,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC;QAC3C,IAAI,MAAM,CAAC,cAAc,EAAE,EAAE,CAAC;YAC5B,SAAS;QACX,CAAC;QACD,IAAI,MAAM,CAAC,WAAW,EAAE,EAAE,CAAC;YACzB,MAAM,IAAI,CAAC,OAAO,EAAE,IAAI,EAAE,GAAG,CAAC,CAAC;YAC/B,SAAS;QACX,CAAC;QACD,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,EAAE,CAAC;YACrB,SAAS;QACX,CAAC;QACD,MAAM,GAAG,GAAG,QAAQ,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;QACpC,MAAM,SAAS,GAAG,GAAG,KAAK,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACrE,GAAG,CAAC,SAAS,CAAC,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,CAAC;IACxC,CAAC;AACH,CAAC"}
@@ -0,0 +1,131 @@
1
+ import { type PlatformProxyAuthValue, type PlatformProxyEndpoint, type PlatformProxyEndpointAuth, type ProxyMethod, type ProxyResponseMode } from "./_contracts/index.js";
2
+ /**
3
+ * Constructor-only surface for declaring a per-run HTTP proxy endpoint.
4
+ *
5
+ * Why a class rather than a raw object literal: the raw
6
+ * `PlatformProxyEndpoint` + `PlatformProxyEndpointAuth` shape lets the
7
+ * caller assemble two halves of one logical thing (the auth shape and
8
+ * the auth value), and they often drift — agents writing freeform
9
+ * objects regularly hit runtime rejections with `responseMode: "json"`
10
+ * (real values are `status_only | headers_only | full`) or
11
+ * `authShape: { type: "header", header: "X-Api-Key" }` (real field is
12
+ * `name`). The constructor signatures here put the auth secret on the
13
+ * same call as the shape, so any drift becomes a TypeScript error at
14
+ * the call site, not an HTTP 400 a round-trip later.
15
+ *
16
+ * Wire-format unchanged: the SDK splits each `ProxyEndpoint` instance
17
+ * into a `PlatformProxyEndpoint` (the non-secret declaration) plus a
18
+ * `PlatformProxyEndpointAuth` entry (the per-request secret) at
19
+ * `submitRun` time, exactly the way `McpServer` already splits
20
+ * `headers` into `secrets.mcpServers`.
21
+ *
22
+ * Five named constructors:
23
+ *
24
+ * - `ProxyEndpoint.none ({ name, baseUrl, ... })` — keyless upstream
25
+ * - `ProxyEndpoint.bearer({ name, baseUrl, token, ... })`
26
+ * - `ProxyEndpoint.header({ name, baseUrl, header, value, ... })`
27
+ * - `ProxyEndpoint.basic ({ name, baseUrl, username, password, ... })`
28
+ * - `ProxyEndpoint.query ({ name, baseUrl, query, value, ... })`
29
+ *
30
+ * All five share the same allow-list / response-mode / cap parameters.
31
+ * The four authenticated variants split into `secrets.proxyEndpointAuth[].value`
32
+ * at submit time; `none` produces only a declaration (no secret).
33
+ */
34
+ export interface ProxyEndpointCommonOptions {
35
+ /**
36
+ * Endpoint name. Lowercase letters, digits, `_`, `-`, up to 63
37
+ * chars. Matches the BFF's `PROXY_ENDPOINT_NAME_PATTERN`. Used as
38
+ * the path segment in `/api/runs/:runId/proxy/:name` and as the
39
+ * cross-reference key in `secrets.proxyEndpointAuth`.
40
+ */
41
+ readonly name: string;
42
+ /** Upstream base URL. Must be an absolute `https://` URL. */
43
+ readonly baseUrl: string;
44
+ /** HTTP methods the in-container caller is allowed to use. */
45
+ readonly allowMethods: readonly ProxyMethod[];
46
+ /** Path prefixes the in-container caller is allowed to hit. */
47
+ readonly allowPathPrefixes: readonly string[];
48
+ /**
49
+ * Caller-supplied headers permitted to pass through the proxy. The
50
+ * auth header (Bearer/Basic/custom-name) is enforced by the proxy
51
+ * itself and MUST NOT appear here.
52
+ */
53
+ readonly allowHeaders?: readonly string[];
54
+ /** Default narrowest response disclosure mode. */
55
+ readonly responseMode?: ProxyResponseMode;
56
+ readonly maxRequestBytes?: number;
57
+ readonly maxResponseBytes?: number;
58
+ readonly timeoutMs?: number;
59
+ readonly perCallBudget?: number;
60
+ readonly responseByteBudget?: number;
61
+ }
62
+ export interface BearerProxyEndpointOptions extends ProxyEndpointCommonOptions {
63
+ /** Bearer token sent as `Authorization: Bearer <token>`. */
64
+ readonly token: string;
65
+ }
66
+ /**
67
+ * Options for `ProxyEndpoint.none` — keyless upstream. Same shape as
68
+ * `ProxyEndpointCommonOptions`; declared as an empty extension so the
69
+ * call site reads symmetrically with the other constructors and stays
70
+ * a stable extension point if a future field becomes auth-shape-only.
71
+ */
72
+ export interface NoneProxyEndpointOptions extends ProxyEndpointCommonOptions {
73
+ }
74
+ export interface BasicProxyEndpointOptions extends ProxyEndpointCommonOptions {
75
+ readonly username: string;
76
+ readonly password: string;
77
+ }
78
+ export interface HeaderProxyEndpointOptions extends ProxyEndpointCommonOptions {
79
+ /** Header name the upstream expects the auth value in. */
80
+ readonly header: string;
81
+ /** Header value (the actual secret). */
82
+ readonly value: string;
83
+ }
84
+ export interface QueryProxyEndpointOptions extends ProxyEndpointCommonOptions {
85
+ /** Query parameter name the upstream expects the auth value in. */
86
+ readonly query: string;
87
+ /** Query parameter value (the actual secret). */
88
+ readonly value: string;
89
+ }
90
+ export declare class ProxyEndpoint {
91
+ /** Non-secret half of the wire shape — declaration only. */
92
+ readonly declaration: PlatformProxyEndpoint;
93
+ /**
94
+ * Per-request secret half — auth value keyed by the same `name`.
95
+ * `null` for keyless (`ProxyEndpoint.none`) endpoints; `splitProxyEndpoints`
96
+ * filters those out so they never land in `secrets.proxyEndpointAuth`.
97
+ */
98
+ readonly auth: PlatformProxyEndpointAuth | null;
99
+ private constructor();
100
+ /**
101
+ * Keyless endpoint. Routes through the aex managed proxy for
102
+ * unified egress, audit, and budget enforcement, but the BFF injects
103
+ * no auth header or query parameter. Use for public APIs (Wikimedia
104
+ * Commons, NASA Images, Library of Congress, NARA, GDELT, etc.).
105
+ */
106
+ static none(options: NoneProxyEndpointOptions): ProxyEndpoint;
107
+ /** Bearer-token endpoint. */
108
+ static bearer(options: BearerProxyEndpointOptions): ProxyEndpoint;
109
+ /** Basic-auth endpoint. */
110
+ static basic(options: BasicProxyEndpointOptions): ProxyEndpoint;
111
+ /** Custom-header endpoint. */
112
+ static header(options: HeaderProxyEndpointOptions): ProxyEndpoint;
113
+ /** Query-string-auth endpoint. */
114
+ static query(options: QueryProxyEndpointOptions): ProxyEndpoint;
115
+ }
116
+ /**
117
+ * Split a list of `ProxyEndpoint` instances into the public declarations
118
+ * (`proxyEndpoints[]`) and the per-request auth bundle
119
+ * (`secrets.proxyEndpointAuth[]`). Mirrors the way `submitRun` already
120
+ * splits `McpServer.headers` into `secrets.mcpServers[]`.
121
+ *
122
+ * Throws on duplicate endpoint names — names are the cross-reference
123
+ * key between the two halves and the BFF rejects collisions; failing
124
+ * here gives the caller a precise message at the call site instead of
125
+ * an opaque HTTP error.
126
+ */
127
+ export declare function splitProxyEndpoints(inputs: readonly ProxyEndpoint[]): {
128
+ endpoints: readonly PlatformProxyEndpoint[];
129
+ auth: readonly PlatformProxyEndpointAuth[];
130
+ };
131
+ export type { PlatformProxyAuthValue as ProxyAuthValue };
@@ -0,0 +1,147 @@
1
+ import { authShapeHeaderName, PROXY_RESPONSE_MODES } from "./_contracts/index.js";
2
+ export class ProxyEndpoint {
3
+ /** Non-secret half of the wire shape — declaration only. */
4
+ declaration;
5
+ /**
6
+ * Per-request secret half — auth value keyed by the same `name`.
7
+ * `null` for keyless (`ProxyEndpoint.none`) endpoints; `splitProxyEndpoints`
8
+ * filters those out so they never land in `secrets.proxyEndpointAuth`.
9
+ */
10
+ auth;
11
+ constructor(declaration, auth) {
12
+ this.declaration = declaration;
13
+ this.auth = auth;
14
+ }
15
+ /**
16
+ * Keyless endpoint. Routes through the aex managed proxy for
17
+ * unified egress, audit, and budget enforcement, but the BFF injects
18
+ * no auth header or query parameter. Use for public APIs (Wikimedia
19
+ * Commons, NASA Images, Library of Congress, NARA, GDELT, etc.).
20
+ */
21
+ static none(options) {
22
+ const common = buildCommonDeclaration(options, { type: "none" });
23
+ return new ProxyEndpoint(common, null);
24
+ }
25
+ /** Bearer-token endpoint. */
26
+ static bearer(options) {
27
+ const common = buildCommonDeclaration(options, { type: "bearer" });
28
+ requireNonEmpty(options.token, "ProxyEndpoint.bearer: token is required");
29
+ return new ProxyEndpoint(common, {
30
+ name: common.name,
31
+ value: { type: "bearer", token: options.token }
32
+ });
33
+ }
34
+ /** Basic-auth endpoint. */
35
+ static basic(options) {
36
+ const common = buildCommonDeclaration(options, { type: "basic" });
37
+ requireNonEmpty(options.username, "ProxyEndpoint.basic: username is required");
38
+ requireNonEmpty(options.password, "ProxyEndpoint.basic: password is required");
39
+ return new ProxyEndpoint(common, {
40
+ name: common.name,
41
+ value: { type: "basic", username: options.username, password: options.password }
42
+ });
43
+ }
44
+ /** Custom-header endpoint. */
45
+ static header(options) {
46
+ requireNonEmpty(options.header, "ProxyEndpoint.header: header is required");
47
+ const common = buildCommonDeclaration(options, { type: "header", name: options.header });
48
+ requireNonEmpty(options.value, "ProxyEndpoint.header: value is required");
49
+ return new ProxyEndpoint(common, {
50
+ name: common.name,
51
+ value: { type: "header", value: options.value }
52
+ });
53
+ }
54
+ /** Query-string-auth endpoint. */
55
+ static query(options) {
56
+ requireNonEmpty(options.query, "ProxyEndpoint.query: query is required");
57
+ const common = buildCommonDeclaration(options, { type: "query", name: options.query });
58
+ requireNonEmpty(options.value, "ProxyEndpoint.query: value is required");
59
+ return new ProxyEndpoint(common, {
60
+ name: common.name,
61
+ value: { type: "query", value: options.value }
62
+ });
63
+ }
64
+ }
65
+ /**
66
+ * Split a list of `ProxyEndpoint` instances into the public declarations
67
+ * (`proxyEndpoints[]`) and the per-request auth bundle
68
+ * (`secrets.proxyEndpointAuth[]`). Mirrors the way `submitRun` already
69
+ * splits `McpServer.headers` into `secrets.mcpServers[]`.
70
+ *
71
+ * Throws on duplicate endpoint names — names are the cross-reference
72
+ * key between the two halves and the BFF rejects collisions; failing
73
+ * here gives the caller a precise message at the call site instead of
74
+ * an opaque HTTP error.
75
+ */
76
+ export function splitProxyEndpoints(inputs) {
77
+ if (inputs.length === 0) {
78
+ return { endpoints: [], auth: [] };
79
+ }
80
+ const endpoints = [];
81
+ const auth = [];
82
+ const seen = new Set();
83
+ for (let i = 0; i < inputs.length; i++) {
84
+ const entry = inputs[i];
85
+ if (!(entry instanceof ProxyEndpoint)) {
86
+ throw new TypeError(`proxyEndpoints[${i}] must be a ProxyEndpoint built via ProxyEndpoint.none / bearer / header / basic / query`);
87
+ }
88
+ if (seen.has(entry.declaration.name)) {
89
+ throw new Error(`proxyEndpoints duplicate name: ${entry.declaration.name}`);
90
+ }
91
+ seen.add(entry.declaration.name);
92
+ endpoints.push(entry.declaration);
93
+ if (entry.auth !== null) {
94
+ auth.push(entry.auth);
95
+ }
96
+ }
97
+ return { endpoints, auth };
98
+ }
99
+ function buildCommonDeclaration(options, authShape) {
100
+ requireNonEmpty(options.name, "ProxyEndpoint: name is required");
101
+ requireNonEmpty(options.baseUrl, "ProxyEndpoint: baseUrl is required");
102
+ if (!Array.isArray(options.allowMethods) || options.allowMethods.length === 0) {
103
+ throw new Error("ProxyEndpoint: allowMethods must be a non-empty array");
104
+ }
105
+ if (!Array.isArray(options.allowPathPrefixes) || options.allowPathPrefixes.length === 0) {
106
+ throw new Error("ProxyEndpoint: allowPathPrefixes must be a non-empty array");
107
+ }
108
+ if (options.responseMode !== undefined && !PROXY_RESPONSE_MODES.includes(options.responseMode)) {
109
+ throw new Error(`ProxyEndpoint: responseMode must be one of ${PROXY_RESPONSE_MODES.join(" | ")}`);
110
+ }
111
+ // Defence in depth: don't let the caller list the auth carrier
112
+ // header in `allowHeaders`. The BFF rejects this too, but a precise
113
+ // SDK-side error message is clearer.
114
+ if (options.allowHeaders) {
115
+ const carrier = authShapeHeaderName(authShape);
116
+ if (carrier) {
117
+ for (const h of options.allowHeaders) {
118
+ if (h.toLowerCase() === carrier) {
119
+ throw new Error(`ProxyEndpoint: allowHeaders MUST NOT include the auth header "${h}" — ` +
120
+ `it's set by the proxy on every request`);
121
+ }
122
+ }
123
+ }
124
+ }
125
+ return {
126
+ name: options.name,
127
+ baseUrl: options.baseUrl,
128
+ authShape,
129
+ allowMethods: options.allowMethods,
130
+ allowPathPrefixes: options.allowPathPrefixes,
131
+ ...(options.allowHeaders ? { allowHeaders: options.allowHeaders } : {}),
132
+ ...(options.responseMode ? { responseMode: options.responseMode } : {}),
133
+ ...(options.maxRequestBytes !== undefined ? { maxRequestBytes: options.maxRequestBytes } : {}),
134
+ ...(options.maxResponseBytes !== undefined ? { maxResponseBytes: options.maxResponseBytes } : {}),
135
+ ...(options.timeoutMs !== undefined ? { timeoutMs: options.timeoutMs } : {}),
136
+ ...(options.perCallBudget !== undefined ? { perCallBudget: options.perCallBudget } : {}),
137
+ ...(options.responseByteBudget !== undefined
138
+ ? { responseByteBudget: options.responseByteBudget }
139
+ : {})
140
+ };
141
+ }
142
+ function requireNonEmpty(value, message) {
143
+ if (typeof value !== "string" || !value) {
144
+ throw new Error(message);
145
+ }
146
+ }
147
+ //# sourceMappingURL=proxy-endpoint.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"proxy-endpoint.js","sourceRoot":"","sources":["../src/proxy-endpoint.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,mBAAmB,EACnB,oBAAoB,EAOrB,MAAM,kBAAkB,CAAC;AAiG1B,MAAM,OAAO,aAAa;IACxB,4DAA4D;IACnD,WAAW,CAAwB;IAC5C;;;;OAIG;IACM,IAAI,CAAmC;IAEhD,YAAoB,WAAkC,EAAE,IAAsC;QAC5F,IAAI,CAAC,WAAW,GAAG,WAAW,CAAC;QAC/B,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACnB,CAAC;IAED;;;;;OAKG;IACH,MAAM,CAAC,IAAI,CAAC,OAAiC;QAC3C,MAAM,MAAM,GAAG,sBAAsB,CAAC,OAAO,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;QACjE,OAAO,IAAI,aAAa,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IACzC,CAAC;IAED,6BAA6B;IAC7B,MAAM,CAAC,MAAM,CAAC,OAAmC;QAC/C,MAAM,MAAM,GAAG,sBAAsB,CAAC,OAAO,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC;QACnE,eAAe,CAAC,OAAO,CAAC,KAAK,EAAE,yCAAyC,CAAC,CAAC;QAC1E,OAAO,IAAI,aAAa,CAAC,MAAM,EAAE;YAC/B,IAAI,EAAE,MAAM,CAAC,IAAI;YACjB,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE;SAChD,CAAC,CAAC;IACL,CAAC;IAED,2BAA2B;IAC3B,MAAM,CAAC,KAAK,CAAC,OAAkC;QAC7C,MAAM,MAAM,GAAG,sBAAsB,CAAC,OAAO,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;QAClE,eAAe,CAAC,OAAO,CAAC,QAAQ,EAAE,2CAA2C,CAAC,CAAC;QAC/E,eAAe,CAAC,OAAO,CAAC,QAAQ,EAAE,2CAA2C,CAAC,CAAC;QAC/E,OAAO,IAAI,aAAa,CAAC,MAAM,EAAE;YAC/B,IAAI,EAAE,MAAM,CAAC,IAAI;YACjB,KAAK,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,CAAC,QAAQ,EAAE,QAAQ,EAAE,OAAO,CAAC,QAAQ,EAAE;SACjF,CAAC,CAAC;IACL,CAAC;IAED,8BAA8B;IAC9B,MAAM,CAAC,MAAM,CAAC,OAAmC;QAC/C,eAAe,CAAC,OAAO,CAAC,MAAM,EAAE,0CAA0C,CAAC,CAAC;QAC5E,MAAM,MAAM,GAAG,sBAAsB,CAAC,OAAO,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;QACzF,eAAe,CAAC,OAAO,CAAC,KAAK,EAAE,yCAAyC,CAAC,CAAC;QAC1E,OAAO,IAAI,aAAa,CAAC,MAAM,EAAE;YAC/B,IAAI,EAAE,MAAM,CAAC,IAAI;YACjB,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE;SAChD,CAAC,CAAC;IACL,CAAC;IAED,kCAAkC;IAClC,MAAM,CAAC,KAAK,CAAC,OAAkC;QAC7C,eAAe,CAAC,OAAO,CAAC,KAAK,EAAE,wCAAwC,CAAC,CAAC;QACzE,MAAM,MAAM,GAAG,sBAAsB,CAAC,OAAO,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC;QACvF,eAAe,CAAC,OAAO,CAAC,KAAK,EAAE,wCAAwC,CAAC,CAAC;QACzE,OAAO,IAAI,aAAa,CAAC,MAAM,EAAE;YAC/B,IAAI,EAAE,MAAM,CAAC,IAAI;YACjB,KAAK,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE;SAC/C,CAAC,CAAC;IACL,CAAC;CACF;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,mBAAmB,CAAC,MAAgC;IAIlE,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACxB,OAAO,EAAE,SAAS,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC;IACrC,CAAC;IACD,MAAM,SAAS,GAA4B,EAAE,CAAC;IAC9C,MAAM,IAAI,GAAgC,EAAE,CAAC;IAC7C,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACvC,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;QACxB,IAAI,CAAC,CAAC,KAAK,YAAY,aAAa,CAAC,EAAE,CAAC;YACtC,MAAM,IAAI,SAAS,CACjB,kBAAkB,CAAC,0FAA0F,CAC9G,CAAC;QACJ,CAAC;QACD,IAAI,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,CAAC;YACrC,MAAM,IAAI,KAAK,CAAC,kCAAkC,KAAK,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC,CAAC;QAC9E,CAAC;QACD,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;QACjC,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;QAClC,IAAI,KAAK,CAAC,IAAI,KAAK,IAAI,EAAE,CAAC;YACxB,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QACxB,CAAC;IACH,CAAC;IACD,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;AAC7B,CAAC;AAED,SAAS,sBAAsB,CAC7B,OAAmC,EACnC,SAAyB;IAEzB,eAAe,CAAC,OAAO,CAAC,IAAI,EAAE,iCAAiC,CAAC,CAAC;IACjE,eAAe,CAAC,OAAO,CAAC,OAAO,EAAE,oCAAoC,CAAC,CAAC;IACvE,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,YAAY,CAAC,IAAI,OAAO,CAAC,YAAY,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC9E,MAAM,IAAI,KAAK,CAAC,uDAAuD,CAAC,CAAC;IAC3E,CAAC;IACD,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,iBAAiB,CAAC,IAAI,OAAO,CAAC,iBAAiB,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACxF,MAAM,IAAI,KAAK,CAAC,4DAA4D,CAAC,CAAC;IAChF,CAAC;IACD,IAAI,OAAO,CAAC,YAAY,KAAK,SAAS,IAAI,CAAC,oBAAoB,CAAC,QAAQ,CAAC,OAAO,CAAC,YAAY,CAAC,EAAE,CAAC;QAC/F,MAAM,IAAI,KAAK,CACb,8CAA8C,oBAAoB,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CACjF,CAAC;IACJ,CAAC;IACD,+DAA+D;IAC/D,oEAAoE;IACpE,qCAAqC;IACrC,IAAI,OAAO,CAAC,YAAY,EAAE,CAAC;QACzB,MAAM,OAAO,GAAG,mBAAmB,CAAC,SAAS,CAAC,CAAC;QAC/C,IAAI,OAAO,EAAE,CAAC;YACZ,KAAK,MAAM,CAAC,IAAI,OAAO,CAAC,YAAY,EAAE,CAAC;gBACrC,IAAI,CAAC,CAAC,WAAW,EAAE,KAAK,OAAO,EAAE,CAAC;oBAChC,MAAM,IAAI,KAAK,CACb,iEAAiE,CAAC,MAAM;wBACtE,wCAAwC,CAC3C,CAAC;gBACJ,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO;QACL,IAAI,EAAE,OAAO,CAAC,IAAI;QAClB,OAAO,EAAE,OAAO,CAAC,OAAO;QACxB,SAAS;QACT,YAAY,EAAE,OAAO,CAAC,YAAY;QAClC,iBAAiB,EAAE,OAAO,CAAC,iBAAiB;QAC5C,GAAG,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACvE,GAAG,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACvE,GAAG,CAAC,OAAO,CAAC,eAAe,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,eAAe,EAAE,OAAO,CAAC,eAAe,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC9F,GAAG,CAAC,OAAO,CAAC,gBAAgB,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,gBAAgB,EAAE,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACjG,GAAG,CAAC,OAAO,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC5E,GAAG,CAAC,OAAO,CAAC,aAAa,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,OAAO,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACxF,GAAG,CAAC,OAAO,CAAC,kBAAkB,KAAK,SAAS;YAC1C,CAAC,CAAC,EAAE,kBAAkB,EAAE,OAAO,CAAC,kBAAkB,EAAE;YACpD,CAAC,CAAC,EAAE,CAAC;KACR,CAAC;AACJ,CAAC;AAED,SAAS,eAAe,CAAC,KAAc,EAAE,OAAe;IACtD,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,KAAK,EAAE,CAAC;QACxC,MAAM,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC;IAC3B,CAAC;AACH,CAAC"}
@@ -0,0 +1,117 @@
1
+ import { type AssetRef, type FetchLike, type SkillRef } from "./_contracts/index.js";
2
+ import { type SkillFiles } from "./bundle.js";
3
+ /**
4
+ * One `Skill` class for skill bytes. `client.submitRun` materializes the bytes
5
+ * as an uploaded asset before the run lands; the wire ref becomes
6
+ * `kind:"asset"`.
7
+ *
8
+ * Build from an inline files map (`Skill.fromFiles`), a local directory
9
+ * (`Skill.fromPath`), or a remote zip archive over a signed URL
10
+ * (`Skill.fromUrl`). All three converge on the same canonical bundle, so
11
+ * identical content dedups across sources.
12
+ *
13
+ * Asset deduplication makes the same bytes a no-op upload on subsequent runs.
14
+ * There is no `Skill.fromId(...)` and no `.upload(client)` — a URL is an
15
+ * ingestion source, not a persistent reference.
16
+ */
17
+ export declare class Skill {
18
+ #private;
19
+ /**
20
+ * Internal constructor. Use `Skill.fromFiles` or `Skill.fromPath` to create
21
+ * instances.
22
+ */
23
+ private constructor();
24
+ /**
25
+ * The wire-level reference. Returns the SDK-private draft shape for
26
+ * un-materialized skills (kind:"draft", with name + contentHash).
27
+ * `client.submitRun` walks these and uploads them before the run
28
+ * lands.
29
+ */
30
+ get ref(): AssetRef | DraftSkillRef;
31
+ /** True for local-bytes Skills that haven't been uploaded yet. */
32
+ get isDraft(): boolean;
33
+ get isConsumed(): boolean;
34
+ /**
35
+ * Build a draft Skill from an inline files map. The SDK validates
36
+ * basic safety (no path traversal, size caps, has `SKILL.md`),
37
+ * deterministically zips the bundle, and computes the
38
+ * `sha256:<hex>` content hash. `client.submitRun` materializes
39
+ * these before the run lands.
40
+ */
41
+ static fromFiles(args: {
42
+ readonly name: string;
43
+ readonly files: SkillFiles;
44
+ }): Promise<Skill>;
45
+ /**
46
+ * Read a local directory and build a draft Skill. Symlinks and
47
+ * non-regular files are skipped. Node-only.
48
+ */
49
+ static fromPath(rootDir: string, args: {
50
+ readonly name: string;
51
+ }): Promise<Skill>;
52
+ /**
53
+ * Fetch a zip-archived skill from a URL and build a draft Skill. The archive
54
+ * is downloaded in the SDK process, so the URL is caller-controlled — host
55
+ * the skill yourself and pass a temporary signed URL (e.g. an S3 presigned
56
+ * URL). Its bytes are optionally integrity-checked against `sha256`, unzipped,
57
+ * and reduced to the same files map as `Skill.fromFiles` — so a URL-sourced
58
+ * skill and the identical local skill produce the same canonical asset and
59
+ * dedup against each other.
60
+ *
61
+ * The archive must contain `SKILL.md` at its root, or inside a single
62
+ * top-level folder (which is stripped). The signed URL only needs to be valid
63
+ * for this call; `client.submitRun` snapshots the bytes into the run.
64
+ *
65
+ * Universal (Node 18+ / browser): requires a global `fetch`, or pass one.
66
+ */
67
+ static fromUrl(url: string, args: {
68
+ readonly name: string;
69
+ readonly sha256?: string;
70
+ readonly timeoutMs?: number;
71
+ readonly fetch?: FetchLike;
72
+ }): Promise<Skill>;
73
+ /**
74
+ * Reference a skill already uploaded to the workspace catalog
75
+ * (`aex skills upload` / `operations.createSkillBundle`) in a run.
76
+ *
77
+ * A catalog skill's bytes are a content-addressed asset, so referencing it
78
+ * is just an `{ kind:"asset" }` ref — once a run snapshots the bytes, it is
79
+ * the identical normalized flow as an inline or file-sourced skill. Pass the
80
+ * `Skill` record returned by `client.skills.list()` / `.get()`:
81
+ *
82
+ * const [s] = await client.skills.list();
83
+ * await client.submitRun({ ..., skills: [Skill.fromCatalog(s)] });
84
+ *
85
+ * The record must be `ready` (it has a content hash). Unlike the draft
86
+ * builders this performs no upload — the bytes already live in the catalog.
87
+ */
88
+ static fromCatalog(record: {
89
+ readonly name: string;
90
+ readonly hash?: string | null;
91
+ }): Skill;
92
+ /**
93
+ * Internal: yield the draft's bytes + metadata so `client.submitRun`
94
+ * can upload the asset. After this returns, the Skill is marked consumed
95
+ * so a second submitRun call against the same instance throws
96
+ * (avoid silently re-uploading; explicit re-construction is the
97
+ * supported retry pattern).
98
+ *
99
+ * Returns undefined for already-materialized Skills.
100
+ */
101
+ _takeDraftBundle(): {
102
+ name: string;
103
+ contentHash: string;
104
+ bytes: Uint8Array;
105
+ } | undefined;
106
+ toJSON(): SkillRef;
107
+ }
108
+ /**
109
+ * SDK-internal draft skill marker. Never reaches the wire; the
110
+ * materialize step inside `client.submitRun` converts these to
111
+ * `kind:"asset"` refs.
112
+ */
113
+ export interface DraftSkillRef {
114
+ readonly kind: "draft";
115
+ readonly name: string;
116
+ readonly contentHash: string;
117
+ }