@executioncontrolprotocol/core 0.11.3 → 0.13.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 (174) hide show
  1. package/README.md +25 -1
  2. package/dist/browser-runtime-entry.d.ts +11 -2
  3. package/dist/browser-runtime-entry.d.ts.map +1 -1
  4. package/dist/browser-runtime-entry.js +10 -1
  5. package/dist/browser-runtime-entry.js.map +1 -1
  6. package/dist/compile/transpile-browser.d.ts +25 -2
  7. package/dist/compile/transpile-browser.d.ts.map +1 -1
  8. package/dist/compile/transpile-browser.js +32 -5
  9. package/dist/compile/transpile-browser.js.map +1 -1
  10. package/dist/compile/transpile.d.ts +6 -0
  11. package/dist/compile/transpile.d.ts.map +1 -1
  12. package/dist/compile/transpile.js +19 -8
  13. package/dist/compile/transpile.js.map +1 -1
  14. package/dist/definitions/capability.d.ts +4 -1
  15. package/dist/definitions/capability.d.ts.map +1 -1
  16. package/dist/definitions/capability.js +7 -0
  17. package/dist/definitions/capability.js.map +1 -1
  18. package/dist/definitions/types.d.ts +3 -1
  19. package/dist/definitions/types.d.ts.map +1 -1
  20. package/dist/encoding/normalize-workflow.d.ts.map +1 -1
  21. package/dist/encoding/normalize-workflow.js +2 -0
  22. package/dist/encoding/normalize-workflow.js.map +1 -1
  23. package/dist/encoding/schemas.d.ts +26 -26
  24. package/dist/environment/describe.d.ts +1 -2
  25. package/dist/environment/describe.d.ts.map +1 -1
  26. package/dist/environment/describe.js +2 -0
  27. package/dist/environment/describe.js.map +1 -1
  28. package/dist/environment/ecp.d.ts +8 -0
  29. package/dist/environment/ecp.d.ts.map +1 -1
  30. package/dist/environment/ecp.js +12 -0
  31. package/dist/environment/ecp.js.map +1 -1
  32. package/dist/environment/environment.d.ts +31 -0
  33. package/dist/environment/environment.d.ts.map +1 -1
  34. package/dist/environment/environment.js +73 -1
  35. package/dist/environment/environment.js.map +1 -1
  36. package/dist/file/file-ref.d.ts +28 -0
  37. package/dist/file/file-ref.d.ts.map +1 -0
  38. package/dist/{image/image-ref.js → file/file-ref.js} +20 -20
  39. package/dist/file/file-ref.js.map +1 -0
  40. package/dist/fluent/render-workflow.d.ts +1 -1
  41. package/dist/fluent/render-workflow.d.ts.map +1 -1
  42. package/dist/fluent/render-workflow.js +10 -2
  43. package/dist/fluent/render-workflow.js.map +1 -1
  44. package/dist/harness/authoring/context-policy.d.ts.map +1 -1
  45. package/dist/harness/authoring/context-policy.js +2 -2
  46. package/dist/harness/authoring/context-policy.js.map +1 -1
  47. package/dist/harness/authoring/index.d.ts +1 -1
  48. package/dist/harness/authoring/index.d.ts.map +1 -1
  49. package/dist/harness/authoring/index.js +1 -1
  50. package/dist/harness/authoring/index.js.map +1 -1
  51. package/dist/harness/authoring/summarize-capability-schema.d.ts.map +1 -1
  52. package/dist/harness/authoring/summarize-capability-schema.js +14 -10
  53. package/dist/harness/authoring/summarize-capability-schema.js.map +1 -1
  54. package/dist/harness/authoring/summarize-environment.d.ts +11 -0
  55. package/dist/harness/authoring/summarize-environment.d.ts.map +1 -1
  56. package/dist/harness/authoring/summarize-environment.js +55 -10
  57. package/dist/harness/authoring/summarize-environment.js.map +1 -1
  58. package/dist/harness/authoring/summarize-workflow.d.ts +2 -0
  59. package/dist/harness/authoring/summarize-workflow.d.ts.map +1 -1
  60. package/dist/harness/authoring/summarize-workflow.js +40 -1
  61. package/dist/harness/authoring/summarize-workflow.js.map +1 -1
  62. package/dist/harness/execute-harness.d.ts.map +1 -1
  63. package/dist/harness/execute-harness.js +14 -10
  64. package/dist/harness/execute-harness.js.map +1 -1
  65. package/dist/harness/prompts/eql-primer.d.ts +1 -0
  66. package/dist/harness/prompts/eql-primer.d.ts.map +1 -1
  67. package/dist/harness/prompts/eql-primer.js +22 -0
  68. package/dist/harness/prompts/eql-primer.js.map +1 -1
  69. package/dist/harness/prompts/typescript-primer.d.ts.map +1 -1
  70. package/dist/harness/prompts/typescript-primer.js +15 -3
  71. package/dist/harness/prompts/typescript-primer.js.map +1 -1
  72. package/dist/index.d.ts +13 -2
  73. package/dist/index.d.ts.map +1 -1
  74. package/dist/index.js +12 -1
  75. package/dist/index.js.map +1 -1
  76. package/dist/invoke/execute-invoke.d.ts.map +1 -1
  77. package/dist/invoke/execute-invoke.js +20 -6
  78. package/dist/invoke/execute-invoke.js.map +1 -1
  79. package/dist/loaders/files.d.ts.map +1 -1
  80. package/dist/loaders/files.js +4 -2
  81. package/dist/loaders/files.js.map +1 -1
  82. package/dist/loaders/read-media-file.d.ts +6 -0
  83. package/dist/loaders/read-media-file.d.ts.map +1 -0
  84. package/dist/loaders/read-media-file.js +10 -0
  85. package/dist/loaders/read-media-file.js.map +1 -0
  86. package/dist/media/artifact-filename.d.ts +41 -0
  87. package/dist/media/artifact-filename.d.ts.map +1 -0
  88. package/dist/media/artifact-filename.js +119 -0
  89. package/dist/media/artifact-filename.js.map +1 -0
  90. package/dist/media/assert-media-type.d.ts +11 -0
  91. package/dist/media/assert-media-type.d.ts.map +1 -0
  92. package/dist/media/assert-media-type.js +43 -0
  93. package/dist/media/assert-media-type.js.map +1 -0
  94. package/dist/media/index.d.ts +13 -0
  95. package/dist/media/index.d.ts.map +1 -0
  96. package/dist/media/index.js +13 -0
  97. package/dist/media/index.js.map +1 -0
  98. package/dist/media/resolve-file.d.ts +32 -0
  99. package/dist/media/resolve-file.d.ts.map +1 -0
  100. package/dist/media/resolve-file.js +110 -0
  101. package/dist/media/resolve-file.js.map +1 -0
  102. package/dist/media/write-media.d.ts +19 -0
  103. package/dist/media/write-media.d.ts.map +1 -0
  104. package/dist/media/write-media.js +46 -0
  105. package/dist/media/write-media.js.map +1 -0
  106. package/dist/patch/patch-document.d.ts +2 -2
  107. package/dist/runtime/artifacts.d.ts +31 -0
  108. package/dist/runtime/artifacts.d.ts.map +1 -0
  109. package/dist/runtime/artifacts.js +26 -0
  110. package/dist/runtime/artifacts.js.map +1 -0
  111. package/dist/runtime/blobs.d.ts +72 -0
  112. package/dist/runtime/blobs.d.ts.map +1 -0
  113. package/dist/runtime/blobs.js +129 -0
  114. package/dist/runtime/blobs.js.map +1 -0
  115. package/dist/runtime/capability-execution.d.ts +22 -0
  116. package/dist/runtime/capability-execution.d.ts.map +1 -0
  117. package/dist/runtime/capability-execution.js +25 -0
  118. package/dist/runtime/capability-execution.js.map +1 -0
  119. package/dist/runtime/context.d.ts +9 -1
  120. package/dist/runtime/context.d.ts.map +1 -1
  121. package/dist/runtime/context.js.map +1 -1
  122. package/dist/runtime/dispatch-capability.d.ts +42 -0
  123. package/dist/runtime/dispatch-capability.d.ts.map +1 -0
  124. package/dist/runtime/dispatch-capability.js +94 -0
  125. package/dist/runtime/dispatch-capability.js.map +1 -0
  126. package/dist/runtime/executor.d.ts +9 -0
  127. package/dist/runtime/executor.d.ts.map +1 -1
  128. package/dist/runtime/in-memory-executor.d.ts.map +1 -1
  129. package/dist/runtime/in-memory-executor.js +70 -10
  130. package/dist/runtime/in-memory-executor.js.map +1 -1
  131. package/dist/runtime/mixed-blob-upload.d.ts +37 -0
  132. package/dist/runtime/mixed-blob-upload.d.ts.map +1 -0
  133. package/dist/runtime/mixed-blob-upload.js +65 -0
  134. package/dist/runtime/mixed-blob-upload.js.map +1 -0
  135. package/dist/runtime/remote-invoke.d.ts +21 -0
  136. package/dist/runtime/remote-invoke.d.ts.map +1 -0
  137. package/dist/runtime/remote-invoke.js +83 -0
  138. package/dist/runtime/remote-invoke.js.map +1 -0
  139. package/dist/runtime/runtime-ids.d.ts +5 -0
  140. package/dist/runtime/runtime-ids.d.ts.map +1 -0
  141. package/dist/runtime/runtime-ids.js +5 -0
  142. package/dist/runtime/runtime-ids.js.map +1 -0
  143. package/dist/schema/json-schema.d.ts +47 -0
  144. package/dist/schema/json-schema.d.ts.map +1 -0
  145. package/dist/schema/json-schema.js +209 -0
  146. package/dist/schema/json-schema.js.map +1 -0
  147. package/dist/schema/workflow-io.d.ts +18 -0
  148. package/dist/schema/workflow-io.d.ts.map +1 -0
  149. package/dist/schema/workflow-io.js +33 -0
  150. package/dist/schema/workflow-io.js.map +1 -0
  151. package/dist/testing/test-extension.d.ts.map +1 -1
  152. package/dist/testing/test-extension.js +6 -0
  153. package/dist/testing/test-extension.js.map +1 -1
  154. package/dist/testing/test-lifecycle-extension.d.ts +3 -1
  155. package/dist/testing/test-lifecycle-extension.d.ts.map +1 -1
  156. package/dist/testing/test-lifecycle-extension.js +7 -1
  157. package/dist/testing/test-lifecycle-extension.js.map +1 -1
  158. package/dist/validate/environment.d.ts.map +1 -1
  159. package/dist/validate/environment.js +26 -4
  160. package/dist/validate/environment.js.map +1 -1
  161. package/dist/validate/workflow-schema.d.ts +16 -6
  162. package/dist/validate/workflow-schema.d.ts.map +1 -1
  163. package/dist/validate/workflow-schema.js +2 -0
  164. package/dist/validate/workflow-schema.js.map +1 -1
  165. package/dist/workflow/builder.d.ts +13 -0
  166. package/dist/workflow/builder.d.ts.map +1 -1
  167. package/dist/workflow/builder.js +40 -0
  168. package/dist/workflow/builder.js.map +1 -1
  169. package/fixtures/schema-examples/workflow.output.eql +6 -2
  170. package/fixtures/schema-examples/workflow.output.json +17 -3
  171. package/package.json +6 -6
  172. package/dist/image/image-ref.d.ts +0 -28
  173. package/dist/image/image-ref.d.ts.map +0 -1
  174. package/dist/image/image-ref.js.map +0 -1
@@ -0,0 +1,13 @@
1
+ /**
2
+
3
+ * Unified file resolve/write for extensions.
4
+
5
+ * @packageDocumentation
6
+
7
+ * @category File
8
+
9
+ */
10
+ export { resolveFile, STORAGE_ARTIFACT_URI_PREFIX, type ResolvedFile, type ResolveFileOptions, type FileCapabilityContext, } from "./resolve-file.js";
11
+ export { writeMediaArtifact, type WriteMediaArtifactOptions, } from "./write-media.js";
12
+ export { ARTIFACT_HTTP_PATH_PREFIX, artifactFetchPathname, defaultArtifactFilename, extensionForMediaType, isArtifactFetchPathname, parseArtifactFetchPathname, resolveArtifactFilename, type ArtifactFetchPathnameOptions, } from "./artifact-filename.js";
13
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/media/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,OAAO,EAEL,WAAW,EAEX,2BAA2B,EAE3B,KAAK,YAAY,EAEjB,KAAK,kBAAkB,EAEvB,KAAK,qBAAqB,GAE3B,MAAM,mBAAmB,CAAA;AAE1B,OAAO,EAEL,kBAAkB,EAElB,KAAK,yBAAyB,GAE/B,MAAM,kBAAkB,CAAA;AAEzB,OAAO,EAEL,yBAAyB,EAEzB,qBAAqB,EAErB,uBAAuB,EAEvB,qBAAqB,EAErB,uBAAuB,EAEvB,0BAA0B,EAE1B,uBAAuB,EAEvB,KAAK,4BAA4B,GAElC,MAAM,wBAAwB,CAAA"}
@@ -0,0 +1,13 @@
1
+ /**
2
+
3
+ * Unified file resolve/write for extensions.
4
+
5
+ * @packageDocumentation
6
+
7
+ * @category File
8
+
9
+ */
10
+ export { resolveFile, STORAGE_ARTIFACT_URI_PREFIX, } from "./resolve-file.js";
11
+ export { writeMediaArtifact, } from "./write-media.js";
12
+ export { ARTIFACT_HTTP_PATH_PREFIX, artifactFetchPathname, defaultArtifactFilename, extensionForMediaType, isArtifactFetchPathname, parseArtifactFetchPathname, resolveArtifactFilename, } from "./artifact-filename.js";
13
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/media/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,OAAO,EAEL,WAAW,EAEX,2BAA2B,GAQ5B,MAAM,mBAAmB,CAAA;AAE1B,OAAO,EAEL,kBAAkB,GAInB,MAAM,kBAAkB,CAAA;AAEzB,OAAO,EAEL,yBAAyB,EAEzB,qBAAqB,EAErB,uBAAuB,EAEvB,qBAAqB,EAErB,uBAAuB,EAEvB,0BAA0B,EAE1B,uBAAuB,GAIxB,MAAM,wBAAwB,CAAA"}
@@ -0,0 +1,32 @@
1
+ import { type FileRef } from "@executioncontrolprotocol/types";
2
+ import type { CapabilityContext } from "../runtime/context.js";
3
+ /** URI prefix for durable storage-backed artifacts. @category File */
4
+ export declare const STORAGE_ARTIFACT_URI_PREFIX = "ecp://storage/";
5
+ /** Resolved file bytes from {@link resolveFile}. @category File */
6
+ export interface ResolvedFile {
7
+ /** Raw bytes. */
8
+ bytes: Uint8Array;
9
+ /** MIME type when known. */
10
+ mediaType?: string;
11
+ /** Byte length. */
12
+ sizeBytes: number;
13
+ /** Optional display name. */
14
+ name?: string;
15
+ }
16
+ /** Options for {@link resolveFile}. @category File */
17
+ export interface ResolveFileOptions {
18
+ /** When false (default), `kind: "url"` refs are rejected. */
19
+ allowRemoteUrls?: boolean;
20
+ }
21
+ /** Context required to resolve {@link FileRef} values. @category File */
22
+ export type FileCapabilityContext = CapabilityContext & {
23
+ /** Bound extension config (limits / storage prefixes). */
24
+ extensionConfig?: Record<string, unknown>;
25
+ };
26
+ /**
27
+ * Resolve a portable {@link FileRef} to bytes using blobs, artifacts, fetch, or Node fs.
28
+ * Extensions should call this instead of reimplementing I/O.
29
+ * @category File
30
+ */
31
+ export declare function resolveFile(ref: FileRef, ctx: FileCapabilityContext, options?: ResolveFileOptions): Promise<ResolvedFile>;
32
+ //# sourceMappingURL=resolve-file.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolve-file.d.ts","sourceRoot":"","sources":["../../src/media/resolve-file.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,OAAO,EACb,MAAM,iCAAiC,CAAA;AAExC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAA;AAE9D,sEAAsE;AACtE,eAAO,MAAM,2BAA2B,mBAAmB,CAAA;AAE3D,mEAAmE;AACnE,MAAM,WAAW,YAAY;IAC3B,iBAAiB;IACjB,KAAK,EAAE,UAAU,CAAA;IACjB,4BAA4B;IAC5B,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,mBAAmB;IACnB,SAAS,EAAE,MAAM,CAAA;IACjB,6BAA6B;IAC7B,IAAI,CAAC,EAAE,MAAM,CAAA;CACd;AAED,sDAAsD;AACtD,MAAM,WAAW,kBAAkB;IACjC,6DAA6D;IAC7D,eAAe,CAAC,EAAE,OAAO,CAAA;CAC1B;AAED,yEAAyE;AACzE,MAAM,MAAM,qBAAqB,GAAG,iBAAiB,GAAG;IACtD,0DAA0D;IAC1D,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAC1C,CAAA;AAgDD;;;;GAIG;AACH,wBAAsB,WAAW,CAC/B,GAAG,EAAE,OAAO,EACZ,GAAG,EAAE,qBAAqB,EAC1B,OAAO,GAAE,kBAAuB,GAC/B,OAAO,CAAC,YAAY,CAAC,CAmEvB"}
@@ -0,0 +1,110 @@
1
+ import { FILE_REF_KINDS, } from "@executioncontrolprotocol/types";
2
+ import { isBrowserFileLocator } from "../runtime/blobs.js";
3
+ /** URI prefix for durable storage-backed artifacts. @category File */
4
+ export const STORAGE_ARTIFACT_URI_PREFIX = "ecp://storage/";
5
+ async function readFileFromPath(path) {
6
+ try {
7
+ const mod = await import("../loaders/read-media-file.js");
8
+ return mod.readMediaFileFromPath(path);
9
+ }
10
+ catch {
11
+ throw new Error("File media refs require Node.js (node:fs/promises is not available in this runtime)");
12
+ }
13
+ }
14
+ async function readBrowserLocator(locator, ctx, mediaType) {
15
+ const blob = ctx.blobs?.get(locator);
16
+ if (!blob) {
17
+ throw new Error(`No file stashed for locator ${locator}`);
18
+ }
19
+ const bytes = new Uint8Array(await blob.arrayBuffer());
20
+ return {
21
+ bytes,
22
+ mediaType: mediaType || blob.type || undefined,
23
+ sizeBytes: bytes.byteLength,
24
+ name: blob.name || undefined,
25
+ };
26
+ }
27
+ function readStoredArtifact(uri, ctx, mediaType) {
28
+ const fromCtx = ctx.artifacts?.get(uri);
29
+ if (!fromCtx) {
30
+ throw new Error(`Artifact not found: ${uri}`);
31
+ }
32
+ return {
33
+ bytes: fromCtx.bytes instanceof Uint8Array ? fromCtx.bytes : new Uint8Array(fromCtx.bytes),
34
+ mediaType: mediaType ?? fromCtx.mediaType,
35
+ sizeBytes: fromCtx.size,
36
+ name: fromCtx.name,
37
+ };
38
+ }
39
+ /**
40
+ * Resolve a portable {@link FileRef} to bytes using blobs, artifacts, fetch, or Node fs.
41
+ * Extensions should call this instead of reimplementing I/O.
42
+ * @category File
43
+ */
44
+ export async function resolveFile(ref, ctx, options = {}) {
45
+ const cfg = ctx.extensionConfig ?? {};
46
+ const limits = cfg.limits ?? {};
47
+ const allowRemoteUrls = options.allowRemoteUrls ?? limits.allowRemoteUrls ?? false;
48
+ switch (ref.kind) {
49
+ case FILE_REF_KINDS.BUFFER: {
50
+ const bytes = typeof Buffer !== "undefined"
51
+ ? new Uint8Array(Buffer.from(ref.data, "base64"))
52
+ : Uint8Array.from(atob(ref.data), (c) => c.charCodeAt(0));
53
+ return { bytes, mediaType: ref.mediaType, sizeBytes: bytes.byteLength };
54
+ }
55
+ case FILE_REF_KINDS.FILE: {
56
+ if (isBrowserFileLocator(ref.path)) {
57
+ return readBrowserLocator(ref.path, ctx, ref.mediaType);
58
+ }
59
+ const bytes = await readFileFromPath(ref.path);
60
+ return { bytes, mediaType: ref.mediaType, sizeBytes: bytes.byteLength };
61
+ }
62
+ case FILE_REF_KINDS.URL: {
63
+ if (!allowRemoteUrls) {
64
+ throw new Error("Remote URL media refs are disabled (allowRemoteUrls)");
65
+ }
66
+ const res = await fetch(ref.url, { headers: ref.headers });
67
+ if (!res.ok)
68
+ throw new Error(`Failed to fetch media URL: ${res.status}`);
69
+ const arrayBuf = await res.arrayBuffer();
70
+ const bytes = new Uint8Array(arrayBuf);
71
+ const mediaType = ref.mediaType ?? res.headers.get("content-type") ?? undefined;
72
+ return { bytes, mediaType, sizeBytes: bytes.byteLength };
73
+ }
74
+ case FILE_REF_KINDS.ARTIFACT: {
75
+ if (isBrowserFileLocator(ref.uri)) {
76
+ return readBrowserLocator(ref.uri, ctx, ref.mediaType);
77
+ }
78
+ if (ref.uri.startsWith(STORAGE_ARTIFACT_URI_PREFIX)) {
79
+ const key = ref.uri.slice(STORAGE_ARTIFACT_URI_PREFIX.length);
80
+ const result = (await ctx.capabilities.call("@executioncontrolprotocol/storage.read", {
81
+ key,
82
+ }));
83
+ if (result.value instanceof Uint8Array) {
84
+ return {
85
+ bytes: result.value,
86
+ mediaType: ref.mediaType,
87
+ sizeBytes: result.value.byteLength,
88
+ name: ref.name,
89
+ };
90
+ }
91
+ if (typeof result.value === "string") {
92
+ const bytes = typeof Buffer !== "undefined"
93
+ ? new Uint8Array(Buffer.from(result.value, "base64"))
94
+ : Uint8Array.from(atob(result.value), (c) => c.charCodeAt(0));
95
+ return {
96
+ bytes,
97
+ mediaType: ref.mediaType,
98
+ sizeBytes: bytes.byteLength,
99
+ name: ref.name,
100
+ };
101
+ }
102
+ throw new Error(`Artifact not found: ${ref.uri}`);
103
+ }
104
+ return readStoredArtifact(ref.uri, ctx, ref.mediaType);
105
+ }
106
+ default:
107
+ throw new Error("Unsupported file reference kind");
108
+ }
109
+ }
110
+ //# sourceMappingURL=resolve-file.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolve-file.js","sourceRoot":"","sources":["../../src/media/resolve-file.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ import { type FileRef } from "@executioncontrolprotocol/types";
2
+ import { type FileCapabilityContext } from "./resolve-file.js";
3
+ /** Options for {@link writeMediaArtifact}. @category Media */
4
+ export interface WriteMediaArtifactOptions {
5
+ /** MIME type. */
6
+ mediaType: string;
7
+ /** Optional filename. */
8
+ name?: string;
9
+ /** URI path prefix under `ecp://` (default `artifacts/media`). */
10
+ prefix?: string;
11
+ /** When `"storage"`, write via `@executioncontrolprotocol/storage.write`. */
12
+ store?: string;
13
+ }
14
+ /**
15
+ * Write bytes into the host artifact store (or durable storage) and return an artifact {@link FileRef}.
16
+ * @category Media
17
+ */
18
+ export declare function writeMediaArtifact(data: Uint8Array, options: WriteMediaArtifactOptions, ctx: FileCapabilityContext): Promise<FileRef>;
19
+ //# sourceMappingURL=write-media.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"write-media.d.ts","sourceRoot":"","sources":["../../src/media/write-media.ts"],"names":[],"mappings":"AAAA,OAAO,EAAkB,KAAK,OAAO,EAAE,MAAM,iCAAiC,CAAA;AAE9E,OAAO,EAEL,KAAK,qBAAqB,EAC3B,MAAM,mBAAmB,CAAA;AAE1B,8DAA8D;AAC9D,MAAM,WAAW,yBAAyB;IACxC,iBAAiB;IACjB,SAAS,EAAE,MAAM,CAAA;IACjB,yBAAyB;IACzB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,kEAAkE;IAClE,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,6EAA6E;IAC7E,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED;;;GAGG;AACH,wBAAsB,kBAAkB,CACtC,IAAI,EAAE,UAAU,EAChB,OAAO,EAAE,yBAAyB,EAClC,GAAG,EAAE,qBAAqB,GACzB,OAAO,CAAC,OAAO,CAAC,CA2ClB"}
@@ -0,0 +1,46 @@
1
+ import { FILE_REF_KINDS } from "@executioncontrolprotocol/types";
2
+ import { defaultArtifactFilename } from "./artifact-filename.js";
3
+ import { STORAGE_ARTIFACT_URI_PREFIX, } from "./resolve-file.js";
4
+ /**
5
+ * Write bytes into the host artifact store (or durable storage) and return an artifact {@link FileRef}.
6
+ * @category Media
7
+ */
8
+ export async function writeMediaArtifact(data, options, ctx) {
9
+ const cfg = ctx.extensionConfig ?? {};
10
+ const storage = cfg.storage ?? {};
11
+ const prefix = options.prefix ?? storage.outputPrefix ?? "artifacts/media";
12
+ const name = options.name ?? defaultArtifactFilename(options.mediaType);
13
+ const uri = `ecp://${prefix}/${name}`;
14
+ if (options.store === "storage" || storage.defaultStore === "storage") {
15
+ const key = `${prefix}/${name}`;
16
+ await ctx.capabilities.call("@executioncontrolprotocol/storage.write", {
17
+ key,
18
+ value: data,
19
+ });
20
+ return {
21
+ kind: FILE_REF_KINDS.ARTIFACT,
22
+ uri: `${STORAGE_ARTIFACT_URI_PREFIX}${key}`,
23
+ mediaType: options.mediaType,
24
+ name,
25
+ sizeBytes: data.byteLength,
26
+ };
27
+ }
28
+ if (!ctx.artifacts) {
29
+ throw new Error("No artifact store on capability context. Ensure the runtime wires ctx.artifacts (env.ensureArtifactStore).");
30
+ }
31
+ const bytes = data instanceof Uint8Array ? data : new Uint8Array(data);
32
+ ctx.artifacts.set(uri, {
33
+ mediaType: options.mediaType,
34
+ name,
35
+ size: bytes.byteLength,
36
+ bytes,
37
+ });
38
+ return {
39
+ kind: FILE_REF_KINDS.ARTIFACT,
40
+ uri,
41
+ mediaType: options.mediaType,
42
+ name,
43
+ sizeBytes: bytes.byteLength,
44
+ };
45
+ }
46
+ //# sourceMappingURL=write-media.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"write-media.js","sourceRoot":"","sources":["../../src/media/write-media.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAgB,MAAM,iCAAiC,CAAA;AAC9E,OAAO,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAA;AAChE,OAAO,EACL,2BAA2B,GAE5B,MAAM,mBAAmB,CAAA;AAc1B;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,IAAgB,EAChB,OAAkC,EAClC,GAA0B;IAE1B,MAAM,GAAG,GAAG,GAAG,CAAC,eAAe,IAAI,EAAE,CAAA;IACrC,MAAM,OAAO,GAAI,GAAG,CAAC,OAAwE,IAAI,EAAE,CAAA;IACnG,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,OAAO,CAAC,YAAY,IAAI,iBAAiB,CAAA;IAC1E,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,IAAI,uBAAuB,CAAC,OAAO,CAAC,SAAS,CAAC,CAAA;IACvE,MAAM,GAAG,GAAG,SAAS,MAAM,IAAI,IAAI,EAAE,CAAA;IAErC,IAAI,OAAO,CAAC,KAAK,KAAK,SAAS,IAAI,OAAO,CAAC,YAAY,KAAK,SAAS,EAAE,CAAC;QACtE,MAAM,GAAG,GAAG,GAAG,MAAM,IAAI,IAAI,EAAE,CAAA;QAC/B,MAAM,GAAG,CAAC,YAAY,CAAC,IAAI,CAAC,yCAAyC,EAAE;YACrE,GAAG;YACH,KAAK,EAAE,IAAI;SACZ,CAAC,CAAA;QACF,OAAO;YACL,IAAI,EAAE,cAAc,CAAC,QAAQ;YAC7B,GAAG,EAAE,GAAG,2BAA2B,GAAG,GAAG,EAAE;YAC3C,SAAS,EAAE,OAAO,CAAC,SAAS;YAC5B,IAAI;YACJ,SAAS,EAAE,IAAI,CAAC,UAAU;SAC3B,CAAA;IACH,CAAC;IAED,IAAI,CAAC,GAAG,CAAC,SAAS,EAAE,CAAC;QACnB,MAAM,IAAI,KAAK,CACb,4GAA4G,CAC7G,CAAA;IACH,CAAC;IAED,MAAM,KAAK,GAAG,IAAI,YAAY,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,UAAU,CAAC,IAAI,CAAC,CAAA;IACtE,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,EAAE;QACrB,SAAS,EAAE,OAAO,CAAC,SAAS;QAC5B,IAAI;QACJ,IAAI,EAAE,KAAK,CAAC,UAAU;QACtB,KAAK;KACN,CAAC,CAAA;IAEF,OAAO;QACL,IAAI,EAAE,cAAc,CAAC,QAAQ;QAC7B,GAAG;QACH,SAAS,EAAE,OAAO,CAAC,SAAS;QAC5B,IAAI;QACJ,SAAS,EAAE,KAAK,CAAC,UAAU;KAC5B,CAAA;AACH,CAAC"}
@@ -38,8 +38,8 @@ export declare const ecpPatchDocumentSchema: z.ZodObject<{
38
38
  mode?: "replace" | "merge" | undefined;
39
39
  }>, "many">;
40
40
  }, "strip", z.ZodTypeAny, {
41
- version: string;
42
41
  schema: "@executioncontrolprotocol.patch";
42
+ version: string;
43
43
  targetSchema: string;
44
44
  patches: {
45
45
  path: string;
@@ -48,8 +48,8 @@ export declare const ecpPatchDocumentSchema: z.ZodObject<{
48
48
  mode?: "replace" | "merge" | undefined;
49
49
  }[];
50
50
  }, {
51
- version: string;
52
51
  schema: "@executioncontrolprotocol.patch";
52
+ version: string;
53
53
  targetSchema: string;
54
54
  patches: {
55
55
  path: string;
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Host-side artifact bytes keyed by `ecp://…` URIs (invoke/run preview and hop outputs).
3
+ * @category Runtime
4
+ */
5
+ /** Stored host artifact (bytes + metadata). @category Runtime */
6
+ export interface CapabilityArtifact {
7
+ /** MIME type for HTTP / browser preview. */
8
+ readonly mediaType: string;
9
+ /** Optional display / download name. */
10
+ readonly name?: string;
11
+ /** Size in bytes. */
12
+ readonly size: number;
13
+ /** Artifact bytes. */
14
+ readonly bytes: Uint8Array;
15
+ }
16
+ /** Environment-scoped map of artifact URIs to bytes. @category Runtime */
17
+ export interface CapabilityArtifactStore {
18
+ /** Look up a stored artifact. */
19
+ get(uri: string): CapabilityArtifact | undefined;
20
+ /** Store an artifact under its URI. */
21
+ set(uri: string, artifact: CapabilityArtifact): void;
22
+ /** Remove a URI. */
23
+ delete(uri: string): void;
24
+ /** Drop all artifacts. */
25
+ clear(): void;
26
+ /** Number of stored artifacts. */
27
+ size(): number;
28
+ }
29
+ /** In-memory {@link CapabilityArtifactStore}. @category Runtime */
30
+ export declare function createCapabilityArtifactStore(): CapabilityArtifactStore;
31
+ //# sourceMappingURL=artifacts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"artifacts.d.ts","sourceRoot":"","sources":["../../src/runtime/artifacts.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,iEAAiE;AACjE,MAAM,WAAW,kBAAkB;IACjC,4CAA4C;IAC5C,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,wCAAwC;IACxC,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAA;IACtB,qBAAqB;IACrB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,sBAAsB;IACtB,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAA;CAC3B;AAED,0EAA0E;AAC1E,MAAM,WAAW,uBAAuB;IACtC,iCAAiC;IACjC,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,kBAAkB,GAAG,SAAS,CAAA;IAChD,uCAAuC;IACvC,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,kBAAkB,GAAG,IAAI,CAAA;IACpD,oBAAoB;IACpB,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAA;IACzB,0BAA0B;IAC1B,KAAK,IAAI,IAAI,CAAA;IACb,kCAAkC;IAClC,IAAI,IAAI,MAAM,CAAA;CACf;AAED,mEAAmE;AACnE,wBAAgB,6BAA6B,IAAI,uBAAuB,CAmBvE"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Host-side artifact bytes keyed by `ecp://…` URIs (invoke/run preview and hop outputs).
3
+ * @category Runtime
4
+ */
5
+ /** In-memory {@link CapabilityArtifactStore}. @category Runtime */
6
+ export function createCapabilityArtifactStore() {
7
+ const items = new Map();
8
+ return {
9
+ get(uri) {
10
+ return items.get(uri);
11
+ },
12
+ set(uri, artifact) {
13
+ items.set(uri, artifact);
14
+ },
15
+ delete(uri) {
16
+ items.delete(uri);
17
+ },
18
+ clear() {
19
+ items.clear();
20
+ },
21
+ size() {
22
+ return items.size;
23
+ },
24
+ };
25
+ }
26
+ //# sourceMappingURL=artifacts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"artifacts.js","sourceRoot":"","sources":["../../src/runtime/artifacts.ts"],"names":[],"mappings":"AAAA;;;GAGG;AA4BH,mEAAmE;AACnE,MAAM,UAAU,6BAA6B;IAC3C,MAAM,KAAK,GAAG,IAAI,GAAG,EAA8B,CAAA;IACnD,OAAO;QACL,GAAG,CAAC,GAAG;YACL,OAAO,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;QACvB,CAAC;QACD,GAAG,CAAC,GAAG,EAAE,QAAQ;YACf,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAA;QAC1B,CAAC;QACD,MAAM,CAAC,GAAG;YACR,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;QACnB,CAAC;QACD,KAAK;YACH,KAAK,CAAC,KAAK,EAAE,CAAA;QACf,CAAC;QACD,IAAI;YACF,OAAO,KAAK,CAAC,IAAI,CAAA;QACnB,CAAC;KACF,CAAA;AACH,CAAC"}
@@ -0,0 +1,72 @@
1
+ /**
2
+ * Locator prefix for files stashed in the browser run map.
3
+ * @category Runtime
4
+ */
5
+ export declare const BROWSER_FILE_LOCATOR_PREFIX = "ecp://browser/";
6
+ /** Browser-stashed file handle used by mixed upload handlers. @category Runtime */
7
+ export interface CapabilityBlob {
8
+ /** Original file name when available. */
9
+ readonly name: string;
10
+ /** MIME type. */
11
+ readonly type: string;
12
+ /** Size in bytes. */
13
+ readonly size: number;
14
+ /** Read file bytes. */
15
+ arrayBuffer(): Promise<ArrayBuffer>;
16
+ }
17
+ /** Run-scoped map of browser file locators to blobs. @category Runtime */
18
+ export interface CapabilityBlobStore {
19
+ /** Look up a stashed file. */
20
+ get(locator: string): CapabilityBlob | undefined;
21
+ /** Stash a file under a locator. */
22
+ set(locator: string, blob: CapabilityBlob): void;
23
+ /** Remove a locator. */
24
+ delete(locator: string): void;
25
+ /** Drop all locators. */
26
+ clear(): void;
27
+ /** Number of stashed files. */
28
+ size(): number;
29
+ }
30
+ /**
31
+ * Wire format for hopping browser blobs to a host invoke (transport only; not workflow state).
32
+ * @category Runtime
33
+ */
34
+ export interface SerializedCapabilityBlob {
35
+ /** Original file name when available. */
36
+ name: string;
37
+ /** MIME type. */
38
+ type: string;
39
+ /** Size in bytes. */
40
+ size: number;
41
+ /** File bytes as base64 (invoke hop transport). */
42
+ dataBase64: string;
43
+ }
44
+ /** Whether a string is a browser file locator. @category Runtime */
45
+ export declare function isBrowserFileLocator(value: string): boolean;
46
+ /** Create a unique browser file locator. @category Runtime */
47
+ export declare function createBrowserFileLocator(): string;
48
+ /** In-memory {@link CapabilityBlobStore}. @category Runtime */
49
+ export declare function createCapabilityBlobStore(): CapabilityBlobStore;
50
+ /**
51
+ * Stash a blob and return its locator.
52
+ * @category Runtime
53
+ */
54
+ export declare function stashCapabilityBlob(store: CapabilityBlobStore, blob: CapabilityBlob): string;
55
+ /**
56
+ * Collect `ecp://browser/<id>` locators from an invoke/run payload.
57
+ * Walks nested objects/arrays, including {@link FileRef} `file.path` and
58
+ * `artifact.uri` when they hold browser locators.
59
+ * @category Runtime
60
+ */
61
+ export declare function collectBrowserLocators(value: unknown, out?: string[]): string[];
62
+ /**
63
+ * Serialize selected locators for a host invoke hop (bytes travel on the wire only).
64
+ * @category Runtime
65
+ */
66
+ export declare function serializeCapabilityBlobs(store: CapabilityBlobStore, locators: string[]): Promise<Record<string, SerializedCapabilityBlob>>;
67
+ /**
68
+ * Hydrate a blob store from hop transport payloads.
69
+ * @category Runtime
70
+ */
71
+ export declare function hydrateCapabilityBlobs(store: CapabilityBlobStore, serialized: Record<string, SerializedCapabilityBlob>): void;
72
+ //# sourceMappingURL=blobs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"blobs.d.ts","sourceRoot":"","sources":["../../src/runtime/blobs.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,eAAO,MAAM,2BAA2B,mBAAmB,CAAA;AAE3D,mFAAmF;AACnF,MAAM,WAAW,cAAc;IAC7B,yCAAyC;IACzC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,iBAAiB;IACjB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,qBAAqB;IACrB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,uBAAuB;IACvB,WAAW,IAAI,OAAO,CAAC,WAAW,CAAC,CAAA;CACpC;AAED,0EAA0E;AAC1E,MAAM,WAAW,mBAAmB;IAClC,8BAA8B;IAC9B,GAAG,CAAC,OAAO,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS,CAAA;IAChD,oCAAoC;IACpC,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,cAAc,GAAG,IAAI,CAAA;IAChD,wBAAwB;IACxB,MAAM,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;IAC7B,yBAAyB;IACzB,KAAK,IAAI,IAAI,CAAA;IACb,+BAA+B;IAC/B,IAAI,IAAI,MAAM,CAAA;CACf;AAED;;;GAGG;AACH,MAAM,WAAW,wBAAwB;IACvC,yCAAyC;IACzC,IAAI,EAAE,MAAM,CAAA;IACZ,iBAAiB;IACjB,IAAI,EAAE,MAAM,CAAA;IACZ,qBAAqB;IACrB,IAAI,EAAE,MAAM,CAAA;IACZ,mDAAmD;IACnD,UAAU,EAAE,MAAM,CAAA;CACnB;AAED,oEAAoE;AACpE,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAE3D;AAED,8DAA8D;AAC9D,wBAAgB,wBAAwB,IAAI,MAAM,CAEjD;AAED,+DAA+D;AAC/D,wBAAgB,yBAAyB,IAAI,mBAAmB,CAmB/D;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,mBAAmB,EAAE,IAAI,EAAE,cAAc,GAAG,MAAM,CAI5F;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,GAAE,MAAM,EAAO,GAAG,MAAM,EAAE,CAcnF;AAwBD;;;GAGG;AACH,wBAAsB,wBAAwB,CAC5C,KAAK,EAAE,mBAAmB,EAC1B,QAAQ,EAAE,MAAM,EAAE,GACjB,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,wBAAwB,CAAC,CAAC,CAcnD;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,mBAAmB,EAC1B,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,wBAAwB,CAAC,GACnD,IAAI,CAaN"}
@@ -0,0 +1,129 @@
1
+ /**
2
+ * Locator prefix for files stashed in the browser run map.
3
+ * @category Runtime
4
+ */
5
+ export const BROWSER_FILE_LOCATOR_PREFIX = "ecp://browser/";
6
+ /** Whether a string is a browser file locator. @category Runtime */
7
+ export function isBrowserFileLocator(value) {
8
+ return value.startsWith(BROWSER_FILE_LOCATOR_PREFIX) && value.length > BROWSER_FILE_LOCATOR_PREFIX.length;
9
+ }
10
+ /** Create a unique browser file locator. @category Runtime */
11
+ export function createBrowserFileLocator() {
12
+ return `${BROWSER_FILE_LOCATOR_PREFIX}${globalThis.crypto.randomUUID()}`;
13
+ }
14
+ /** In-memory {@link CapabilityBlobStore}. @category Runtime */
15
+ export function createCapabilityBlobStore() {
16
+ const files = new Map();
17
+ return {
18
+ get(locator) {
19
+ return files.get(locator);
20
+ },
21
+ set(locator, blob) {
22
+ files.set(locator, blob);
23
+ },
24
+ delete(locator) {
25
+ files.delete(locator);
26
+ },
27
+ clear() {
28
+ files.clear();
29
+ },
30
+ size() {
31
+ return files.size;
32
+ },
33
+ };
34
+ }
35
+ /**
36
+ * Stash a blob and return its locator.
37
+ * @category Runtime
38
+ */
39
+ export function stashCapabilityBlob(store, blob) {
40
+ const locator = createBrowserFileLocator();
41
+ store.set(locator, blob);
42
+ return locator;
43
+ }
44
+ /**
45
+ * Collect `ecp://browser/<id>` locators from an invoke/run payload.
46
+ * Walks nested objects/arrays, including {@link FileRef} `file.path` and
47
+ * `artifact.uri` when they hold browser locators.
48
+ * @category Runtime
49
+ */
50
+ export function collectBrowserLocators(value, out = []) {
51
+ if (typeof value === "string") {
52
+ if (isBrowserFileLocator(value) && !out.includes(value))
53
+ out.push(value);
54
+ return out;
55
+ }
56
+ if (Array.isArray(value)) {
57
+ for (const item of value)
58
+ collectBrowserLocators(item, out);
59
+ return out;
60
+ }
61
+ if (value !== null && typeof value === "object") {
62
+ const row = value;
63
+ for (const child of Object.values(row))
64
+ collectBrowserLocators(child, out);
65
+ }
66
+ return out;
67
+ }
68
+ function bytesToBase64(bytes) {
69
+ if (typeof Buffer !== "undefined") {
70
+ return Buffer.from(bytes).toString("base64");
71
+ }
72
+ const chunk = 0x8000;
73
+ let binary = "";
74
+ for (let i = 0; i < bytes.length; i += chunk) {
75
+ binary += String.fromCharCode(...bytes.subarray(i, i + chunk));
76
+ }
77
+ return btoa(binary);
78
+ }
79
+ function base64ToBytes(dataBase64) {
80
+ if (typeof Buffer !== "undefined") {
81
+ return new Uint8Array(Buffer.from(dataBase64, "base64"));
82
+ }
83
+ const binary = atob(dataBase64);
84
+ const bytes = new Uint8Array(binary.length);
85
+ for (let i = 0; i < binary.length; i++)
86
+ bytes[i] = binary.charCodeAt(i);
87
+ return bytes;
88
+ }
89
+ /**
90
+ * Serialize selected locators for a host invoke hop (bytes travel on the wire only).
91
+ * @category Runtime
92
+ */
93
+ export async function serializeCapabilityBlobs(store, locators) {
94
+ const out = {};
95
+ for (const locator of locators) {
96
+ const blob = store.get(locator);
97
+ if (!blob)
98
+ continue;
99
+ const bytes = new Uint8Array(await blob.arrayBuffer());
100
+ out[locator] = {
101
+ name: blob.name,
102
+ type: blob.type,
103
+ size: blob.size,
104
+ dataBase64: bytesToBase64(bytes),
105
+ };
106
+ }
107
+ return out;
108
+ }
109
+ /**
110
+ * Hydrate a blob store from hop transport payloads.
111
+ * @category Runtime
112
+ */
113
+ export function hydrateCapabilityBlobs(store, serialized) {
114
+ for (const [locator, row] of Object.entries(serialized)) {
115
+ if (!isBrowserFileLocator(locator))
116
+ continue;
117
+ if (typeof row?.dataBase64 !== "string")
118
+ continue;
119
+ const bytes = base64ToBytes(row.dataBase64);
120
+ const copy = bytes.slice().buffer;
121
+ store.set(locator, {
122
+ name: typeof row.name === "string" ? row.name : "blob",
123
+ type: typeof row.type === "string" ? row.type : "application/octet-stream",
124
+ size: typeof row.size === "number" ? row.size : bytes.byteLength,
125
+ arrayBuffer: async () => copy,
126
+ });
127
+ }
128
+ }
129
+ //# sourceMappingURL=blobs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"blobs.js","sourceRoot":"","sources":["../../src/runtime/blobs.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ import type { CapabilityExecution } from "@executioncontrolprotocol/types";
2
+ /** Extension shape needed to infer capability execution. @category Runtime */
3
+ export interface ExecutionExtensionHint {
4
+ /** Runtimes this extension supports when restricted. */
5
+ supportedRuntimes?: readonly string[];
6
+ }
7
+ /** Capability shape needed to resolve execution. @category Runtime */
8
+ export interface ExecutionCapabilityHint {
9
+ /** Explicit execution declaration. */
10
+ execution?: CapabilityExecution;
11
+ }
12
+ /**
13
+ * Resolve capability execution, defaulting from extension `supportedRuntimes`.
14
+ * Unrestricted capabilities default to **host**; browser-only extensions default to **local**.
15
+ * @category Runtime
16
+ */
17
+ export declare function resolveCapabilityExecution(cap: ExecutionCapabilityHint, ext?: ExecutionExtensionHint): CapabilityExecution;
18
+ /** Whether this runtime id is the browser host. @category Runtime */
19
+ export declare function isBrowserRuntimeId(runtimeId: string): boolean;
20
+ /** Whether this runtime id is the Node host. @category Runtime */
21
+ export declare function isNodeRuntimeId(runtimeId: string): boolean;
22
+ //# sourceMappingURL=capability-execution.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"capability-execution.d.ts","sourceRoot":"","sources":["../../src/runtime/capability-execution.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,iCAAiC,CAAA;AAG1E,8EAA8E;AAC9E,MAAM,WAAW,sBAAsB;IACrC,wDAAwD;IACxD,iBAAiB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;CACtC;AAED,sEAAsE;AACtE,MAAM,WAAW,uBAAuB;IACtC,sCAAsC;IACtC,SAAS,CAAC,EAAE,mBAAmB,CAAA;CAChC;AAED;;;;GAIG;AACH,wBAAgB,0BAA0B,CACxC,GAAG,EAAE,uBAAuB,EAC5B,GAAG,CAAC,EAAE,sBAAsB,GAC3B,mBAAmB,CAMrB;AAED,qEAAqE;AACrE,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAE7D;AAED,kEAAkE;AAClE,wBAAgB,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAE1D"}
@@ -0,0 +1,25 @@
1
+ import { BROWSER_RUNTIME_ID, NODE_RUNTIME_ID } from "./runtime-ids.js";
2
+ /**
3
+ * Resolve capability execution, defaulting from extension `supportedRuntimes`.
4
+ * Unrestricted capabilities default to **host**; browser-only extensions default to **local**.
5
+ * @category Runtime
6
+ */
7
+ export function resolveCapabilityExecution(cap, ext) {
8
+ if (cap.execution)
9
+ return cap.execution;
10
+ const supported = ext?.supportedRuntimes;
11
+ if (supported?.length === 1 && supported[0] === NODE_RUNTIME_ID)
12
+ return "host";
13
+ if (supported?.length === 1 && supported[0] === BROWSER_RUNTIME_ID)
14
+ return "local";
15
+ return "host";
16
+ }
17
+ /** Whether this runtime id is the browser host. @category Runtime */
18
+ export function isBrowserRuntimeId(runtimeId) {
19
+ return runtimeId === BROWSER_RUNTIME_ID;
20
+ }
21
+ /** Whether this runtime id is the Node host. @category Runtime */
22
+ export function isNodeRuntimeId(runtimeId) {
23
+ return runtimeId === NODE_RUNTIME_ID;
24
+ }
25
+ //# sourceMappingURL=capability-execution.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"capability-execution.js","sourceRoot":"","sources":["../../src/runtime/capability-execution.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAA;AActE;;;;GAIG;AACH,MAAM,UAAU,0BAA0B,CACxC,GAA4B,EAC5B,GAA4B;IAE5B,IAAI,GAAG,CAAC,SAAS;QAAE,OAAO,GAAG,CAAC,SAAS,CAAA;IACvC,MAAM,SAAS,GAAG,GAAG,EAAE,iBAAiB,CAAA;IACxC,IAAI,SAAS,EAAE,MAAM,KAAK,CAAC,IAAI,SAAS,CAAC,CAAC,CAAC,KAAK,eAAe;QAAE,OAAO,MAAM,CAAA;IAC9E,IAAI,SAAS,EAAE,MAAM,KAAK,CAAC,IAAI,SAAS,CAAC,CAAC,CAAC,KAAK,kBAAkB;QAAE,OAAO,OAAO,CAAA;IAClF,OAAO,MAAM,CAAA;AACf,CAAC;AAED,qEAAqE;AACrE,MAAM,UAAU,kBAAkB,CAAC,SAAiB;IAClD,OAAO,SAAS,KAAK,kBAAkB,CAAA;AACzC,CAAC;AAED,kEAAkE;AAClE,MAAM,UAAU,eAAe,CAAC,SAAiB;IAC/C,OAAO,SAAS,KAAK,eAAe,CAAA;AACtC,CAAC"}