@elaraai/e3-types 1.0.30 → 1.0.31

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.
@@ -16,7 +16,7 @@
16
16
  * All fields hold object-store hashes, never inline file contents: the blobs
17
17
  * ride the existing content-addressed object store and transfer machinery.
18
18
  */
19
- import { ArrayType, StringType, StructType, ValueTypeOf, VariantType } from '@elaraai/east';
19
+ import { ArrayType, OptionType, StringType, StructType, ValueTypeOf, VariantType } from '@elaraai/east';
20
20
  /**
21
21
  * A Python (uv) project environment.
22
22
  *
@@ -85,12 +85,95 @@ export declare const ImageEnvironmentType: StructType<{
85
85
  }>;
86
86
  export type ImageEnvironmentType = typeof ImageEnvironmentType;
87
87
  export type ImageEnvironment = ValueTypeOf<typeof ImageEnvironmentType>;
88
+ /**
89
+ * A prebuilt-file ("tools") environment for C and custom runners.
90
+ *
91
+ * e3 never builds anything for this kind: the developer builds their binary
92
+ * (or any prebuilt artifact) however they like, and capture folds the named
93
+ * files' bytes into the environment hash and materializes them onto the
94
+ * runner's PATH. Rebuilding a captured file changes its blob hash → the
95
+ * environment hash → the tasks that use it re-run. This closes the
96
+ * pre-existing hole where a custom-runner binary resolved from PATH was
97
+ * never part of the cache key, so a rebuild silently served stale outputs.
98
+ *
99
+ * @remarks
100
+ * - `files`: the captured files, sorted by `path` so capture order never
101
+ * affects the environment hash.
102
+ * - `path`: environment-dir-relative POSIX path; v1 writers emit
103
+ * `bin/<basename>` (materialization writes it there and adds `bin` to
104
+ * PATH). Validated at materialization: no absolute paths, no `..`, no
105
+ * empty segments.
106
+ * - `hash`: object hash of the file's bytes. No mode is stored:
107
+ * materialization always applies a fixed mode, so an exec-bit-only
108
+ * change does not alter the environment yet also cannot go stale.
109
+ */
110
+ export declare const ToolsEnvironmentType: StructType<{
111
+ /** Captured files (env-relative path + object hash), sorted by path */
112
+ readonly files: ArrayType<StructType<{
113
+ readonly path: StringType;
114
+ readonly hash: StringType;
115
+ }>>;
116
+ }>;
117
+ export type ToolsEnvironmentType = typeof ToolsEnvironmentType;
118
+ export type ToolsEnvironment = ValueTypeOf<typeof ToolsEnvironmentType>;
119
+ /**
120
+ * A Node **workspace-member** environment (npm or pnpm workspaces).
121
+ *
122
+ * Where {@link NodeEnvironmentType} captures one self-contained project,
123
+ * this captures one member of a workspace together with the transitive
124
+ * closure of the local workspace packages it depends on — so editing a
125
+ * member's code re-runs only the environments whose closure contains it.
126
+ * Materialized by reconstructing a minimal workspace of exactly the closure
127
+ * members and running the frozen install against the verbatim root lock.
128
+ *
129
+ * @remarks
130
+ * - `packageJson`: object hash of the workspace **root** `package.json` blob.
131
+ * - `lock`: object hash of the **root** lockfile blob (content-sniffed as
132
+ * today; npm in v1, pnpm once the pnpm capture path ships).
133
+ * - `config`: pnpm only — object hash of the capture-synthesized
134
+ * `pnpm-workspace.yaml` blob; `none` for npm.
135
+ * - `subject`: workspace-relative POSIX path of the environment's own
136
+ * member. Must satisfy `members.some((m) => m.path === subject)` — this is
137
+ * enforced at capture and re-validated at materialization (BEAST2 typed
138
+ * decode is structural only and cannot check it).
139
+ * - `members`: the dependency closure sorted by `path`; each carries its
140
+ * package `name` (read from the member's `package.json` at capture) and
141
+ * the object `hash` of its `npm pack` tarball.
142
+ */
143
+ export declare const WorkspaceNodeEnvironmentType: StructType<{
144
+ /** Object hash of the workspace root package.json blob */
145
+ readonly packageJson: StringType;
146
+ /** Object hash of the root lockfile blob */
147
+ readonly lock: StringType;
148
+ /** pnpm only: object hash of the synthesized pnpm-workspace.yaml; none for npm */
149
+ readonly config: OptionType<StringType>;
150
+ /** Workspace-relative POSIX path of this environment's own member */
151
+ readonly subject: StringType;
152
+ /** Dependency closure (path + package name + tarball hash), sorted by path */
153
+ readonly members: ArrayType<StructType<{
154
+ readonly path: StringType;
155
+ readonly name: StringType;
156
+ readonly tarball: StringType;
157
+ }>>;
158
+ }>;
159
+ export type WorkspaceNodeEnvironmentType = typeof WorkspaceNodeEnvironmentType;
160
+ export type WorkspaceNodeEnvironment = ValueTypeOf<typeof WorkspaceNodeEnvironmentType>;
88
161
  /**
89
162
  * An execution environment specification.
90
163
  *
91
164
  * Stored beast2-encoded in the object store; the **environment hash** is the
92
165
  * object hash of the encoded spec. A task/function with no environment
93
166
  * (`none`) runs on the stock runtime image as today.
167
+ *
168
+ * @remarks
169
+ * BEAST2 encodes a variant's tag as the index of its case in the
170
+ * **alphabetically sorted** case list, so the case order is load-bearing: a
171
+ * repo persists specs by that order, and reordering the cases in a later
172
+ * edit would re-tag every case after the insertion point and mis-decode
173
+ * already-stored specs. New cases must therefore be added so the sorted
174
+ * order only grows at the end (`tools` and `workspace_node` sort after the
175
+ * original three). The frozen-order guard test in `environment.spec.ts`
176
+ * turns an accidental reorder into a red test.
94
177
  */
95
178
  export declare const EnvironmentSpecType: VariantType<{
96
179
  /** Python (uv) project environment */
@@ -119,6 +202,31 @@ export declare const EnvironmentSpecType: VariantType<{
119
202
  /** Full image digest reference: `repo@sha256:<64 hex chars>` */
120
203
  readonly digest: StringType;
121
204
  }>;
205
+ /** Prebuilt-file environment for C / custom runners */
206
+ readonly tools: StructType<{
207
+ /** Captured files (env-relative path + object hash), sorted by path */
208
+ readonly files: ArrayType<StructType<{
209
+ readonly path: StringType;
210
+ readonly hash: StringType;
211
+ }>>;
212
+ }>;
213
+ /** Node workspace-member environment (npm/pnpm workspaces) */
214
+ readonly workspace_node: StructType<{
215
+ /** Object hash of the workspace root package.json blob */
216
+ readonly packageJson: StringType;
217
+ /** Object hash of the root lockfile blob */
218
+ readonly lock: StringType;
219
+ /** pnpm only: object hash of the synthesized pnpm-workspace.yaml; none for npm */
220
+ readonly config: OptionType<StringType>;
221
+ /** Workspace-relative POSIX path of this environment's own member */
222
+ readonly subject: StringType;
223
+ /** Dependency closure (path + package name + tarball hash), sorted by path */
224
+ readonly members: ArrayType<StructType<{
225
+ readonly path: StringType;
226
+ readonly name: StringType;
227
+ readonly tarball: StringType;
228
+ }>>;
229
+ }>;
122
230
  }>;
123
231
  export type EnvironmentSpecType = typeof EnvironmentSpecType;
124
232
  export type EnvironmentSpec = ValueTypeOf<typeof EnvironmentSpecType>;
@@ -1 +1 @@
1
- {"version":3,"file":"environment.d.ts","sourceRoot":"","sources":["../../src/environment.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,UAAU,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAE5F;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,qBAAqB;IAChC,6CAA6C;;IAE7C,sCAAsC;;IAEtC,8EAA8E;;;;;EAE9E,CAAC;AACH,MAAM,MAAM,qBAAqB,GAAG,OAAO,qBAAqB,CAAC;AACjE,MAAM,MAAM,iBAAiB,GAAG,WAAW,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAE1E;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,mBAAmB;IAC9B,2CAA2C;;IAE3C,uCAAuC;;IAEvC,gEAAgE;;EAEhE,CAAC;AACH,MAAM,MAAM,mBAAmB,GAAG,OAAO,mBAAmB,CAAC;AAC7D,MAAM,MAAM,eAAe,GAAG,WAAW,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAEtE;;;;;;;;;;GAUG;AACH,eAAO,MAAM,oBAAoB;IAC/B,gEAAgE;;EAEhE,CAAC;AACH,MAAM,MAAM,oBAAoB,GAAG,OAAO,oBAAoB,CAAC;AAC/D,MAAM,MAAM,gBAAgB,GAAG,WAAW,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAExE;;;;;;GAMG;AACH,eAAO,MAAM,mBAAmB;IAC9B,sCAAsC;;QA5DtC,6CAA6C;;QAE7C,sCAAsC;;QAEtC,8EAA8E;;;;;;IA0D9E,+BAA+B;;QAtC/B,2CAA2C;;QAE3C,uCAAuC;;QAEvC,gEAAgE;;;IAoChE,yCAAyC;;QAlBzC,gEAAgE;;;EAoBhE,CAAC;AACH,MAAM,MAAM,mBAAmB,GAAG,OAAO,mBAAmB,CAAC;AAC7D,MAAM,MAAM,eAAe,GAAG,WAAW,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAEtE;;;;;;;;GAQG;AACH,wBAAgB,2BAA2B,CAAC,IAAI,EAAE,eAAe,GAAG,MAAM,EAAE,CAS3E"}
1
+ {"version":3,"file":"environment.d.ts","sourceRoot":"","sources":["../../src/environment.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAExG;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,qBAAqB;IAChC,6CAA6C;;IAE7C,sCAAsC;;IAEtC,8EAA8E;;;;;EAE9E,CAAC;AACH,MAAM,MAAM,qBAAqB,GAAG,OAAO,qBAAqB,CAAC;AACjE,MAAM,MAAM,iBAAiB,GAAG,WAAW,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAE1E;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,mBAAmB;IAC9B,2CAA2C;;IAE3C,uCAAuC;;IAEvC,gEAAgE;;EAEhE,CAAC;AACH,MAAM,MAAM,mBAAmB,GAAG,OAAO,mBAAmB,CAAC;AAC7D,MAAM,MAAM,eAAe,GAAG,WAAW,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAEtE;;;;;;;;;;GAUG;AACH,eAAO,MAAM,oBAAoB;IAC/B,gEAAgE;;EAEhE,CAAC;AACH,MAAM,MAAM,oBAAoB,GAAG,OAAO,oBAAoB,CAAC;AAC/D,MAAM,MAAM,gBAAgB,GAAG,WAAW,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAExE;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,eAAO,MAAM,oBAAoB;IAC/B,uEAAuE;;;;;EAEvE,CAAC;AACH,MAAM,MAAM,oBAAoB,GAAG,OAAO,oBAAoB,CAAC;AAC/D,MAAM,MAAM,gBAAgB,GAAG,WAAW,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAExE;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,eAAO,MAAM,4BAA4B;IACvC,0DAA0D;;IAE1D,4CAA4C;;IAE5C,kFAAkF;;IAElF,qEAAqE;;IAErE,8EAA8E;;;;;;EAE9E,CAAC;AACH,MAAM,MAAM,4BAA4B,GAAG,OAAO,4BAA4B,CAAC;AAC/E,MAAM,MAAM,wBAAwB,GAAG,WAAW,CAAC,OAAO,4BAA4B,CAAC,CAAC;AAExF;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,mBAAmB;IAC9B,sCAAsC;;QA1ItC,6CAA6C;;QAE7C,sCAAsC;;QAEtC,8EAA8E;;;;;;IAwI9E,+BAA+B;;QApH/B,2CAA2C;;QAE3C,uCAAuC;;QAEvC,gEAAgE;;;IAkHhE,yCAAyC;;QAhGzC,gEAAgE;;;IAkGhE,uDAAuD;;QArEvD,uEAAuE;;;;;;IAuEvE,8DAA8D;;QAxC9D,0DAA0D;;QAE1D,4CAA4C;;QAE5C,kFAAkF;;QAElF,qEAAqE;;QAErE,8EAA8E;;;;;;;EAkC9E,CAAC;AACH,MAAM,MAAM,mBAAmB,GAAG,OAAO,mBAAmB,CAAC;AAC7D,MAAM,MAAM,eAAe,GAAG,WAAW,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAEtE;;;;;;;;GAQG;AACH,wBAAgB,2BAA2B,CAAC,IAAI,EAAE,eAAe,GAAG,MAAM,EAAE,CAkB3E"}
@@ -16,7 +16,7 @@
16
16
  * All fields hold object-store hashes, never inline file contents: the blobs
17
17
  * ride the existing content-addressed object store and transfer machinery.
18
18
  */
19
- import { ArrayType, StringType, StructType, VariantType } from '@elaraai/east';
19
+ import { ArrayType, OptionType, StringType, StructType, VariantType } from '@elaraai/east';
20
20
  /**
21
21
  * A Python (uv) project environment.
22
22
  *
@@ -76,12 +76,84 @@ export const ImageEnvironmentType = StructType({
76
76
  /** Full image digest reference: `repo@sha256:<64 hex chars>` */
77
77
  digest: StringType,
78
78
  });
79
+ /**
80
+ * A prebuilt-file ("tools") environment for C and custom runners.
81
+ *
82
+ * e3 never builds anything for this kind: the developer builds their binary
83
+ * (or any prebuilt artifact) however they like, and capture folds the named
84
+ * files' bytes into the environment hash and materializes them onto the
85
+ * runner's PATH. Rebuilding a captured file changes its blob hash → the
86
+ * environment hash → the tasks that use it re-run. This closes the
87
+ * pre-existing hole where a custom-runner binary resolved from PATH was
88
+ * never part of the cache key, so a rebuild silently served stale outputs.
89
+ *
90
+ * @remarks
91
+ * - `files`: the captured files, sorted by `path` so capture order never
92
+ * affects the environment hash.
93
+ * - `path`: environment-dir-relative POSIX path; v1 writers emit
94
+ * `bin/<basename>` (materialization writes it there and adds `bin` to
95
+ * PATH). Validated at materialization: no absolute paths, no `..`, no
96
+ * empty segments.
97
+ * - `hash`: object hash of the file's bytes. No mode is stored:
98
+ * materialization always applies a fixed mode, so an exec-bit-only
99
+ * change does not alter the environment yet also cannot go stale.
100
+ */
101
+ export const ToolsEnvironmentType = StructType({
102
+ /** Captured files (env-relative path + object hash), sorted by path */
103
+ files: ArrayType(StructType({ path: StringType, hash: StringType })),
104
+ });
105
+ /**
106
+ * A Node **workspace-member** environment (npm or pnpm workspaces).
107
+ *
108
+ * Where {@link NodeEnvironmentType} captures one self-contained project,
109
+ * this captures one member of a workspace together with the transitive
110
+ * closure of the local workspace packages it depends on — so editing a
111
+ * member's code re-runs only the environments whose closure contains it.
112
+ * Materialized by reconstructing a minimal workspace of exactly the closure
113
+ * members and running the frozen install against the verbatim root lock.
114
+ *
115
+ * @remarks
116
+ * - `packageJson`: object hash of the workspace **root** `package.json` blob.
117
+ * - `lock`: object hash of the **root** lockfile blob (content-sniffed as
118
+ * today; npm in v1, pnpm once the pnpm capture path ships).
119
+ * - `config`: pnpm only — object hash of the capture-synthesized
120
+ * `pnpm-workspace.yaml` blob; `none` for npm.
121
+ * - `subject`: workspace-relative POSIX path of the environment's own
122
+ * member. Must satisfy `members.some((m) => m.path === subject)` — this is
123
+ * enforced at capture and re-validated at materialization (BEAST2 typed
124
+ * decode is structural only and cannot check it).
125
+ * - `members`: the dependency closure sorted by `path`; each carries its
126
+ * package `name` (read from the member's `package.json` at capture) and
127
+ * the object `hash` of its `npm pack` tarball.
128
+ */
129
+ export const WorkspaceNodeEnvironmentType = StructType({
130
+ /** Object hash of the workspace root package.json blob */
131
+ packageJson: StringType,
132
+ /** Object hash of the root lockfile blob */
133
+ lock: StringType,
134
+ /** pnpm only: object hash of the synthesized pnpm-workspace.yaml; none for npm */
135
+ config: OptionType(StringType),
136
+ /** Workspace-relative POSIX path of this environment's own member */
137
+ subject: StringType,
138
+ /** Dependency closure (path + package name + tarball hash), sorted by path */
139
+ members: ArrayType(StructType({ path: StringType, name: StringType, tarball: StringType })),
140
+ });
79
141
  /**
80
142
  * An execution environment specification.
81
143
  *
82
144
  * Stored beast2-encoded in the object store; the **environment hash** is the
83
145
  * object hash of the encoded spec. A task/function with no environment
84
146
  * (`none`) runs on the stock runtime image as today.
147
+ *
148
+ * @remarks
149
+ * BEAST2 encodes a variant's tag as the index of its case in the
150
+ * **alphabetically sorted** case list, so the case order is load-bearing: a
151
+ * repo persists specs by that order, and reordering the cases in a later
152
+ * edit would re-tag every case after the insertion point and mis-decode
153
+ * already-stored specs. New cases must therefore be added so the sorted
154
+ * order only grows at the end (`tools` and `workspace_node` sort after the
155
+ * original three). The frozen-order guard test in `environment.spec.ts`
156
+ * turns an accidental reorder into a red test.
85
157
  */
86
158
  export const EnvironmentSpecType = VariantType({
87
159
  /** Python (uv) project environment */
@@ -90,6 +162,10 @@ export const EnvironmentSpecType = VariantType({
90
162
  node: NodeEnvironmentType,
91
163
  /** Custom container image environment */
92
164
  image: ImageEnvironmentType,
165
+ /** Prebuilt-file environment for C / custom runners */
166
+ tools: ToolsEnvironmentType,
167
+ /** Node workspace-member environment (npm/pnpm workspaces) */
168
+ workspace_node: WorkspaceNodeEnvironmentType,
93
169
  });
94
170
  /**
95
171
  * Lists the object-store hashes an environment spec references.
@@ -108,6 +184,15 @@ export function environmentSpecObjectHashes(spec) {
108
184
  return [spec.value.packageJson, spec.value.lock, ...spec.value.tarballs];
109
185
  case 'image':
110
186
  return [];
187
+ case 'tools':
188
+ return spec.value.files.map((f) => f.hash);
189
+ case 'workspace_node':
190
+ return [
191
+ spec.value.packageJson,
192
+ spec.value.lock,
193
+ ...(spec.value.config.type === 'some' ? [spec.value.config.value] : []),
194
+ ...spec.value.members.map((m) => m.tarball),
195
+ ];
111
196
  }
112
197
  }
113
198
  //# sourceMappingURL=environment.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"environment.js","sourceRoot":"","sources":["../../src/environment.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,UAAU,EAAe,WAAW,EAAE,MAAM,eAAe,CAAC;AAE5F;;;;;;;;;;;;;;GAcG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,UAAU,CAAC;IAC9C,6CAA6C;IAC7C,SAAS,EAAE,UAAU;IACrB,sCAAsC;IACtC,IAAI,EAAE,UAAU;IAChB,8EAA8E;IAC9E,MAAM,EAAE,SAAS,CAAC,UAAU,CAAC,EAAE,QAAQ,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC,CAAC;CAC1E,CAAC,CAAC;AAIH;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,UAAU,CAAC;IAC5C,2CAA2C;IAC3C,WAAW,EAAE,UAAU;IACvB,uCAAuC;IACvC,IAAI,EAAE,UAAU;IAChB,gEAAgE;IAChE,QAAQ,EAAE,SAAS,CAAC,UAAU,CAAC;CAChC,CAAC,CAAC;AAIH;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,UAAU,CAAC;IAC7C,gEAAgE;IAChE,MAAM,EAAE,UAAU;CACnB,CAAC,CAAC;AAIH;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,WAAW,CAAC;IAC7C,sCAAsC;IACtC,MAAM,EAAE,qBAAqB;IAC7B,+BAA+B;IAC/B,IAAI,EAAE,mBAAmB;IACzB,yCAAyC;IACzC,KAAK,EAAE,oBAAoB;CAC5B,CAAC,CAAC;AAIH;;;;;;;;GAQG;AACH,MAAM,UAAU,2BAA2B,CAAC,IAAqB;IAC/D,QAAQ,IAAI,CAAC,IAAI,EAAE,CAAC;QAClB,KAAK,QAAQ;YACX,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;QAC1F,KAAK,MAAM;YACT,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;QAC3E,KAAK,OAAO;YACV,OAAO,EAAE,CAAC;IACd,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"environment.js","sourceRoot":"","sources":["../../src/environment.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Copyright (c) 2025 Elara AI Pty Ltd
3
+ * Dual-licensed under AGPL-3.0 and commercial license. See LICENSE for details.
4
+ */
5
+ export {};
6
+ //# sourceMappingURL=environment.spec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"environment.spec.d.ts","sourceRoot":"","sources":["../../src/environment.spec.ts"],"names":[],"mappings":"AAAA;;;GAGG"}
@@ -0,0 +1,90 @@
1
+ /**
2
+ * Copyright (c) 2025 Elara AI Pty Ltd
3
+ * Dual-licensed under AGPL-3.0 and commercial license. See LICENSE for details.
4
+ */
5
+ /**
6
+ * Encode/decode contract for {@link EnvironmentSpecType}.
7
+ *
8
+ * BEAST2 encodes a variant's tag as the index of its case in the
9
+ * alphabetically-sorted case list, so the case order is load-bearing: a repo
10
+ * persists specs by that order, and a later code edit that inserts a case
11
+ * before an existing one silently re-tags every later case and mis-decodes
12
+ * already-stored specs. The frozen-order test pins the order so that mistake
13
+ * is a red test; the round-trip tests pin the new cases.
14
+ */
15
+ import { describe, it } from 'node:test';
16
+ import * as assert from 'node:assert';
17
+ import { encodeBeast2For, decodeBeast2For, variant, some, none } from '@elaraai/east';
18
+ import { EnvironmentSpecType, environmentSpecObjectHashes, } from './environment.js';
19
+ const encodeCurrent = encodeBeast2For(EnvironmentSpecType);
20
+ const decodeCurrent = decodeBeast2For(EnvironmentSpecType);
21
+ const H = (c) => c.repeat(64); // stand-in 64-hex object hash
22
+ describe('EnvironmentSpecType frozen case order', () => {
23
+ it('is exactly [image, node, python, tools, workspace_node]', () => {
24
+ // BEAST2 tags are indices into this sorted list. A new case must be
25
+ // added so the order only grows at the end (or readers must migrate to
26
+ // name-based decoding first) — inserting before an existing case
27
+ // re-tags every later one and mis-decodes stored specs. This assertion
28
+ // turns that mistake into a red test.
29
+ assert.deepStrictEqual(Object.keys(EnvironmentSpecType.cases), ['image', 'node', 'python', 'tools', 'workspace_node']);
30
+ });
31
+ });
32
+ describe('EnvironmentSpecType round-trips every case', () => {
33
+ const specs = [
34
+ variant('python', { pyproject: H('a'), lock: H('b'), sdists: [{ filename: 'pricing-1.0.0.tar.gz', hash: H('c') }] }),
35
+ variant('node', { packageJson: H('d'), lock: H('e'), tarballs: [H('f')] }),
36
+ variant('image', { digest: `repo@sha256:${H('0')}` }),
37
+ variant('tools', { files: [{ path: 'bin/my-runner', hash: H('1') }] }),
38
+ variant('workspace_node', {
39
+ packageJson: H('2'), lock: H('3'), config: none, subject: 'packages/pricing',
40
+ members: [{ path: 'packages/pricing', name: '@acme/pricing', tarball: H('4') }],
41
+ }),
42
+ ];
43
+ it('encodes and decodes back to the same value', () => {
44
+ for (const spec of specs) {
45
+ assert.deepStrictEqual(decodeCurrent(encodeCurrent(spec)), spec);
46
+ }
47
+ });
48
+ it('round-trips a workspace_node spec carrying a pnpm config blob and multiple members', () => {
49
+ const withConfig = variant('workspace_node', {
50
+ packageJson: H('2'), lock: H('3'), config: some(H('5')), subject: 'packages/pricing',
51
+ members: [
52
+ { path: 'packages/common', name: '@acme/common', tarball: H('6') },
53
+ { path: 'packages/pricing', name: '@acme/pricing', tarball: H('7') },
54
+ ],
55
+ });
56
+ assert.deepStrictEqual(decodeCurrent(encodeCurrent(withConfig)), withConfig);
57
+ });
58
+ });
59
+ describe('environmentSpecObjectHashes', () => {
60
+ it('lists python blobs', () => {
61
+ assert.deepStrictEqual(environmentSpecObjectHashes(variant('python', {
62
+ pyproject: 'p', lock: 'l',
63
+ sdists: [{ filename: 'a-1.0.tar.gz', hash: 's1' }, { filename: 'b-1.0.tar.gz', hash: 's2' }],
64
+ })), ['p', 'l', 's1', 's2']);
65
+ });
66
+ it('lists node blobs', () => {
67
+ assert.deepStrictEqual(environmentSpecObjectHashes(variant('node', { packageJson: 'p', lock: 'l', tarballs: ['t'] })), ['p', 'l', 't']);
68
+ });
69
+ it('lists nothing for image', () => {
70
+ assert.deepStrictEqual(environmentSpecObjectHashes(variant('image', { digest: `repo@sha256:${H('0')}` })), []);
71
+ });
72
+ it('lists every tools file hash', () => {
73
+ assert.deepStrictEqual(environmentSpecObjectHashes(variant('tools', {
74
+ files: [{ path: 'bin/a', hash: 'h1' }, { path: 'bin/b', hash: 'h2' }],
75
+ })), ['h1', 'h2']);
76
+ });
77
+ it('lists workspace_node blobs including the config when present', () => {
78
+ assert.deepStrictEqual(environmentSpecObjectHashes(variant('workspace_node', {
79
+ packageJson: 'p', lock: 'l', config: some('cfg'), subject: 'packages/x',
80
+ members: [{ path: 'packages/x', name: '@acme/x', tarball: 't1' }, { path: 'packages/y', name: '@acme/y', tarball: 't2' }],
81
+ })), ['p', 'l', 'cfg', 't1', 't2']);
82
+ });
83
+ it('omits the config hash for an npm workspace_node (none)', () => {
84
+ assert.deepStrictEqual(environmentSpecObjectHashes(variant('workspace_node', {
85
+ packageJson: 'p', lock: 'l', config: none, subject: 'packages/x',
86
+ members: [{ path: 'packages/x', name: '@acme/x', tarball: 't1' }],
87
+ })), ['p', 'l', 't1']);
88
+ });
89
+ });
90
+ //# sourceMappingURL=environment.spec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"environment.spec.js","sourceRoot":"","sources":["../../src/environment.spec.ts"],"names":[],"mappings":"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"}
@@ -23,9 +23,9 @@
23
23
  export { DataRefType, type DataRef, unassignedRef, nullRef, DataTreeType, } from './dataset.js';
24
24
  export { VersionVectorType, type VersionVector, DatasetRefType, type DatasetRef, } from './dataset-ref.js';
25
25
  export { TaskObjectType, type TaskObject, decodeTaskObject, } from './task.js';
26
- export { EnvironmentSpecType, type EnvironmentSpec, PythonEnvironmentType, type PythonEnvironment, NodeEnvironmentType, type NodeEnvironment, ImageEnvironmentType, type ImageEnvironment, environmentSpecObjectHashes, } from './environment.js';
26
+ export { EnvironmentSpecType, type EnvironmentSpec, PythonEnvironmentType, type PythonEnvironment, NodeEnvironmentType, type NodeEnvironment, ImageEnvironmentType, type ImageEnvironment, ToolsEnvironmentType, type ToolsEnvironment, WorkspaceNodeEnvironmentType, type WorkspaceNodeEnvironment, environmentSpecObjectHashes, } from './environment.js';
27
27
  export { StructureType, type Structure, PathSegmentType, type PathSegment, TreePathType, type TreePath, type ParsePathResult, type ParseDatasetPathResult, type ParsePackageRefResult, treePath, pathToString, parsePath, parseDatasetPath, parsePackageRef, urlPathToTreePath, DatasetSchemaType, type DatasetSchema, } from './structure.js';
28
- export { RunnerType, type RunnerValue, runnerToArgv, } from './runner.js';
28
+ export { RunnerType, type RunnerValue, runnerToArgv, withRunnerVerbose, } from './runner.js';
29
29
  export { FunctionObjectType, type FunctionObject, decodeFunctionObject, } from './function.js';
30
30
  export { RecordCommitType, type RecordCommit, MutationObjectType, type MutationObject, RecordObjectType, type RecordObject, } from './record.js';
31
31
  export { PackageDataType, type PackageData, PackageObjectType, type PackageObject, decodePackageObject, PackageDatasetsType, type PackageDatasets, PackageTransferInitRequestType, type PackageTransferInitRequest, PackageTransferInitResponseType, type PackageTransferInitResponse, PackageJobResponseType, type PackageJobResponse, PackageImportResultType, type PackageImportResult, PackageExportResultType, type PackageExportResult, PackageImportProgressType, type PackageImportProgress, PackageImportStatusType, type PackageImportStatus, PackageExportProgressType, type PackageExportProgress, PackageExportStatusType, type PackageExportStatus, } from './package.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
package/dist/src/index.js CHANGED
@@ -27,13 +27,13 @@ export { VersionVectorType, DatasetRefType, } from './dataset-ref.js';
27
27
  // Task definitions
28
28
  export { TaskObjectType, decodeTaskObject, } from './task.js';
29
29
  // Execution environments
30
- export { EnvironmentSpecType, PythonEnvironmentType, NodeEnvironmentType, ImageEnvironmentType, environmentSpecObjectHashes, } from './environment.js';
30
+ export { EnvironmentSpecType, PythonEnvironmentType, NodeEnvironmentType, ImageEnvironmentType, ToolsEnvironmentType, WorkspaceNodeEnvironmentType, environmentSpecObjectHashes, } from './environment.js';
31
31
  // Data structure and paths
32
32
  export { StructureType, PathSegmentType, TreePathType, treePath, pathToString, parsePath, parseDatasetPath, parsePackageRef, urlPathToTreePath,
33
33
  // Backwards compatibility
34
34
  DatasetSchemaType, } from './structure.js';
35
35
  // Runner wire types (functions)
36
- export { RunnerType, runnerToArgv, } from './runner.js';
36
+ export { RunnerType, runnerToArgv, withRunnerVerbose, } from './runner.js';
37
37
  // Function objects
38
38
  export { FunctionObjectType, decodeFunctionObject, } from './function.js';
39
39
  // Record objects
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;;;;;;;;;;;;;;GAiBG;AAEH,4BAA4B;AAC5B,OAAO,EACL,WAAW,EAEX,aAAa,EACb,OAAO,EACP,YAAY,GACb,MAAM,cAAc,CAAC;AAEtB,2DAA2D;AAC3D,OAAO,EACL,iBAAiB,EAEjB,cAAc,GAEf,MAAM,kBAAkB,CAAC;AAE1B,mBAAmB;AACnB,OAAO,EACL,cAAc,EAEd,gBAAgB,GACjB,MAAM,WAAW,CAAC;AAEnB,yBAAyB;AACzB,OAAO,EACL,mBAAmB,EAEnB,qBAAqB,EAErB,mBAAmB,EAEnB,oBAAoB,EAEpB,2BAA2B,GAC5B,MAAM,kBAAkB,CAAC;AAE1B,2BAA2B;AAC3B,OAAO,EACL,aAAa,EAEb,eAAe,EAEf,YAAY,EAKZ,QAAQ,EACR,YAAY,EACZ,SAAS,EACT,gBAAgB,EAChB,eAAe,EACf,iBAAiB;AACjB,0BAA0B;AAC1B,iBAAiB,GAElB,MAAM,gBAAgB,CAAC;AAExB,gCAAgC;AAChC,OAAO,EACL,UAAU,EAEV,YAAY,GACb,MAAM,aAAa,CAAC;AAErB,mBAAmB;AACnB,OAAO,EACL,kBAAkB,EAElB,oBAAoB,GACrB,MAAM,eAAe,CAAC;AAEvB,iBAAiB;AACjB,OAAO,EACL,gBAAgB,EAEhB,kBAAkB,EAElB,gBAAgB,GAEjB,MAAM,aAAa,CAAC;AAErB,kBAAkB;AAClB,OAAO,EACL,eAAe,EAEf,iBAAiB,EAEjB,mBAAmB;AACnB,0BAA0B;AAC1B,mBAAmB;AAEnB,yBAAyB;AACzB,8BAA8B,EAE9B,+BAA+B,EAE/B,sBAAsB,EAEtB,uBAAuB,EAEvB,uBAAuB,EAEvB,yBAAyB,EAEzB,uBAAuB,EAEvB,yBAAyB,EAEzB,uBAAuB,GAExB,MAAM,cAAc,CAAC;AAEtB,kBAAkB;AAClB,OAAO,EACL,kBAAkB,GAEnB,MAAM,gBAAgB,CAAC;AAExB,mBAAmB;AACnB,OAAO,EACL,mBAAmB,GAEpB,MAAM,gBAAgB,CAAC;AAExB,aAAa;AACb,OAAO,EACL,iBAAiB,EAEjB,iBAAiB,EAEjB,aAAa,GAEd,MAAM,WAAW,CAAC;AAEnB,yBAAyB;AACzB,OAAO,EACL,yBAAyB,EAEzB,0BAA0B,EAE1B,wBAAwB,GAEzB,MAAM,eAAe,CAAC;AAEvB,wBAAwB;AACxB,OAAO,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAErD,kEAAkE;AAClE,OAAO;AACL,cAAc;AACd,0BAA0B,EAC1B,6BAA6B,EAC7B,wBAAwB,EACxB,cAAc,EACd,wBAAwB,EACxB,wBAAwB,EACxB,sBAAsB,EACtB,uBAAuB,EACvB,wBAAwB,EACxB,qBAAqB,EACrB,0BAA0B,EAC1B,uBAAuB,EACvB,iBAAiB,EACjB,yBAAyB,EACzB,iBAAiB,EACjB,2BAA2B,EAC3B,SAAS,EACT,YAAY;AACZ,aAAa;AACb,oBAAoB,EACpB,aAAa,EACb,YAAY,EACZ,wBAAwB,EACxB,iBAAiB,EACjB,kBAAkB;AAClB,WAAW;AACX,mBAAmB,EACnB,eAAe,EACf,kBAAkB;AAClB,aAAa;AACb,0BAA0B,EAC1B,iBAAiB,EACjB,0BAA0B,EAC1B,0BAA0B;AAC1B,mBAAmB;AACnB,iBAAiB,EACjB,sBAAsB,EACtB,qBAAqB,EACrB,wBAAwB,EACxB,oBAAoB,EACpB,mBAAmB,EACnB,0BAA0B,EAC1B,cAAc,EACd,qBAAqB,EACrB,kBAAkB,EAClB,0BAA0B,EAC1B,yBAAyB;AACzB,QAAQ;AACR,gBAAgB,EAChB,eAAe;AACf,YAAY;AACZ,mBAAmB,EACnB,YAAY,EACZ,uBAAuB,EACvB,kBAAkB;AAClB,uBAAuB;AACvB,iBAAiB,EACjB,sBAAsB,EACtB,4BAA4B,EAC5B,6BAA6B;AAC7B,yBAAyB;AACzB,0BAA0B,EAC1B,qBAAqB;AACrB,eAAe;AACf,YAAY,EACZ,aAAa;AACb,wBAAwB;AACxB,uBAAuB;AACvB,gCAAgC;AAChC,iBAAiB,EACjB,cAAc,EACd,iBAAiB,EACjB,uBAAuB,EACvB,qBAAqB,EACrB,kBAAkB,EAClB,uBAAuB,EACvB,kBAAkB,EAClB,mBAAmB,EACnB,oBAAoB,EACpB,uBAAuB,GA+CxB,MAAM,UAAU,CAAC;AAElB,2BAA2B;AAC3B,OAAO,EAGL,aAAa,EAEb,qBAAqB,EAErB,iBAAiB,EAEjB,kBAAkB,EAElB,0BAA0B;AAE1B,uBAAuB;AACvB,qBAAqB,EAErB,uBAAuB,EAEvB,sBAAsB,EAEtB,eAAe,GAEhB,MAAM,eAAe,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;;;;;;;;;;;;;;GAiBG;AAEH,4BAA4B;AAC5B,OAAO,EACL,WAAW,EAEX,aAAa,EACb,OAAO,EACP,YAAY,GACb,MAAM,cAAc,CAAC;AAEtB,2DAA2D;AAC3D,OAAO,EACL,iBAAiB,EAEjB,cAAc,GAEf,MAAM,kBAAkB,CAAC;AAE1B,mBAAmB;AACnB,OAAO,EACL,cAAc,EAEd,gBAAgB,GACjB,MAAM,WAAW,CAAC;AAEnB,yBAAyB;AACzB,OAAO,EACL,mBAAmB,EAEnB,qBAAqB,EAErB,mBAAmB,EAEnB,oBAAoB,EAEpB,oBAAoB,EAEpB,4BAA4B,EAE5B,2BAA2B,GAC5B,MAAM,kBAAkB,CAAC;AAE1B,2BAA2B;AAC3B,OAAO,EACL,aAAa,EAEb,eAAe,EAEf,YAAY,EAKZ,QAAQ,EACR,YAAY,EACZ,SAAS,EACT,gBAAgB,EAChB,eAAe,EACf,iBAAiB;AACjB,0BAA0B;AAC1B,iBAAiB,GAElB,MAAM,gBAAgB,CAAC;AAExB,gCAAgC;AAChC,OAAO,EACL,UAAU,EAEV,YAAY,EACZ,iBAAiB,GAClB,MAAM,aAAa,CAAC;AAErB,mBAAmB;AACnB,OAAO,EACL,kBAAkB,EAElB,oBAAoB,GACrB,MAAM,eAAe,CAAC;AAEvB,iBAAiB;AACjB,OAAO,EACL,gBAAgB,EAEhB,kBAAkB,EAElB,gBAAgB,GAEjB,MAAM,aAAa,CAAC;AAErB,kBAAkB;AAClB,OAAO,EACL,eAAe,EAEf,iBAAiB,EAEjB,mBAAmB;AACnB,0BAA0B;AAC1B,mBAAmB;AAEnB,yBAAyB;AACzB,8BAA8B,EAE9B,+BAA+B,EAE/B,sBAAsB,EAEtB,uBAAuB,EAEvB,uBAAuB,EAEvB,yBAAyB,EAEzB,uBAAuB,EAEvB,yBAAyB,EAEzB,uBAAuB,GAExB,MAAM,cAAc,CAAC;AAEtB,kBAAkB;AAClB,OAAO,EACL,kBAAkB,GAEnB,MAAM,gBAAgB,CAAC;AAExB,mBAAmB;AACnB,OAAO,EACL,mBAAmB,GAEpB,MAAM,gBAAgB,CAAC;AAExB,aAAa;AACb,OAAO,EACL,iBAAiB,EAEjB,iBAAiB,EAEjB,aAAa,GAEd,MAAM,WAAW,CAAC;AAEnB,yBAAyB;AACzB,OAAO,EACL,yBAAyB,EAEzB,0BAA0B,EAE1B,wBAAwB,GAEzB,MAAM,eAAe,CAAC;AAEvB,wBAAwB;AACxB,OAAO,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAErD,kEAAkE;AAClE,OAAO;AACL,cAAc;AACd,0BAA0B,EAC1B,6BAA6B,EAC7B,wBAAwB,EACxB,cAAc,EACd,wBAAwB,EACxB,wBAAwB,EACxB,sBAAsB,EACtB,uBAAuB,EACvB,wBAAwB,EACxB,qBAAqB,EACrB,0BAA0B,EAC1B,uBAAuB,EACvB,iBAAiB,EACjB,yBAAyB,EACzB,iBAAiB,EACjB,2BAA2B,EAC3B,SAAS,EACT,YAAY;AACZ,aAAa;AACb,oBAAoB,EACpB,aAAa,EACb,YAAY,EACZ,wBAAwB,EACxB,iBAAiB,EACjB,kBAAkB;AAClB,WAAW;AACX,mBAAmB,EACnB,eAAe,EACf,kBAAkB;AAClB,aAAa;AACb,0BAA0B,EAC1B,iBAAiB,EACjB,0BAA0B,EAC1B,0BAA0B;AAC1B,mBAAmB;AACnB,iBAAiB,EACjB,sBAAsB,EACtB,qBAAqB,EACrB,wBAAwB,EACxB,oBAAoB,EACpB,mBAAmB,EACnB,0BAA0B,EAC1B,cAAc,EACd,qBAAqB,EACrB,kBAAkB,EAClB,0BAA0B,EAC1B,yBAAyB;AACzB,QAAQ;AACR,gBAAgB,EAChB,eAAe;AACf,YAAY;AACZ,mBAAmB,EACnB,YAAY,EACZ,uBAAuB,EACvB,kBAAkB;AAClB,uBAAuB;AACvB,iBAAiB,EACjB,sBAAsB,EACtB,4BAA4B,EAC5B,6BAA6B;AAC7B,yBAAyB;AACzB,0BAA0B,EAC1B,qBAAqB;AACrB,eAAe;AACf,YAAY,EACZ,aAAa;AACb,wBAAwB;AACxB,uBAAuB;AACvB,gCAAgC;AAChC,iBAAiB,EACjB,cAAc,EACd,iBAAiB,EACjB,uBAAuB,EACvB,qBAAqB,EACrB,kBAAkB,EAClB,uBAAuB,EACvB,kBAAkB,EAClB,mBAAmB,EACnB,oBAAoB,EACpB,uBAAuB,GA+CxB,MAAM,UAAU,CAAC;AAElB,2BAA2B;AAC3B,OAAO,EAGL,aAAa,EAEb,qBAAqB,EAErB,iBAAiB,EAEjB,kBAAkB,EAElB,0BAA0B;AAE1B,uBAAuB;AACvB,qBAAqB,EAErB,uBAAuB,EAEvB,sBAAsB,EAEtB,eAAe,GAEhB,MAAM,eAAe,CAAC"}
@@ -52,4 +52,25 @@ export type RunnerValue = ValueTypeOf<typeof RunnerType>;
52
52
  * (`east-node`) here.
53
53
  */
54
54
  export declare function runnerToArgv(r: RunnerValue): string[];
55
+ /**
56
+ * Insert the runner's `-v/--verbose` flag into a fully-built argv, for the
57
+ * known runtimes only.
58
+ *
59
+ * All three known runners (`east-node`/`east-py`/`east-c run`) accept `-v`
60
+ * among their options and print timing/perf detail to stderr; a `custom`
61
+ * runner's argv is user-authored, so a flag is never spliced into it. A
62
+ * known-runtime argv always starts `[<bin>, 'run', …]` (see
63
+ * {@link runnerToArgv} and the SDK's `runnerToCommand`), so `-v` goes at
64
+ * index 2 — ahead of the `-p`/`-i`/`-o` flags and the trailing IR path.
65
+ *
66
+ * This is a pure **runtime** toggle: it is applied to the *evaluated* argv
67
+ * immediately before spawn and never touches the task's `commandIr`, the
68
+ * {@link RunnerType}, or any hash — so it cannot affect caching.
69
+ *
70
+ * @param runner - the runner the argv was built for (gates the injection)
71
+ * @param args - the fully-built argv (runner prefix + `-i`/`-o`/`<ir>` suffix)
72
+ * @param verbose - when true, request the runner's verbose output
73
+ * @returns the argv, with `-v` inserted for known runtimes when verbose
74
+ */
75
+ export declare function withRunnerVerbose(runner: RunnerValue, args: string[], verbose?: boolean): string[];
55
76
  //# sourceMappingURL=runner.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../../src/runner.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,SAAS,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAE5F;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,UAAU;;;;;;;;;;;;;EAKrB,CAAC;AACH,MAAM,MAAM,UAAU,GAAG,OAAO,UAAU,CAAC;AAE3C,MAAM,MAAM,WAAW,GAAG,WAAW,CAAC,OAAO,UAAU,CAAC,CAAC;AAMzD;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,CAAC,EAAE,WAAW,GAAG,MAAM,EAAE,CAOrD"}
1
+ {"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../../src/runner.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,SAAS,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAE5F;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,UAAU;;;;;;;;;;;;;EAKrB,CAAC;AACH,MAAM,MAAM,UAAU,GAAG,OAAO,UAAU,CAAC;AAE3C,MAAM,MAAM,WAAW,GAAG,WAAW,CAAC,OAAO,UAAU,CAAC,CAAC;AAMzD;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,CAAC,EAAE,WAAW,GAAG,MAAM,EAAE,CAOrD;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,OAAO,CAAC,EAAE,OAAO,GAAG,MAAM,EAAE,CAGlG"}
@@ -52,4 +52,29 @@ export function runnerToArgv(r) {
52
52
  case 'custom': return [...r.value.command];
53
53
  }
54
54
  }
55
+ /**
56
+ * Insert the runner's `-v/--verbose` flag into a fully-built argv, for the
57
+ * known runtimes only.
58
+ *
59
+ * All three known runners (`east-node`/`east-py`/`east-c run`) accept `-v`
60
+ * among their options and print timing/perf detail to stderr; a `custom`
61
+ * runner's argv is user-authored, so a flag is never spliced into it. A
62
+ * known-runtime argv always starts `[<bin>, 'run', …]` (see
63
+ * {@link runnerToArgv} and the SDK's `runnerToCommand`), so `-v` goes at
64
+ * index 2 — ahead of the `-p`/`-i`/`-o` flags and the trailing IR path.
65
+ *
66
+ * This is a pure **runtime** toggle: it is applied to the *evaluated* argv
67
+ * immediately before spawn and never touches the task's `commandIr`, the
68
+ * {@link RunnerType}, or any hash — so it cannot affect caching.
69
+ *
70
+ * @param runner - the runner the argv was built for (gates the injection)
71
+ * @param args - the fully-built argv (runner prefix + `-i`/`-o`/`<ir>` suffix)
72
+ * @param verbose - when true, request the runner's verbose output
73
+ * @returns the argv, with `-v` inserted for known runtimes when verbose
74
+ */
75
+ export function withRunnerVerbose(runner, args, verbose) {
76
+ if (!verbose || runner.type === 'custom' || args.length < 2)
77
+ return args;
78
+ return [...args.slice(0, 2), '-v', ...args.slice(2)];
79
+ }
55
80
  //# sourceMappingURL=runner.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"runner.js","sourceRoot":"","sources":["../../src/runner.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,SAAS,EAAE,UAAU,EAAe,MAAM,eAAe,CAAC;AAE5F;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,MAAM,UAAU,GAAG,WAAW,CAAC;IACpC,SAAS,EAAE,UAAU,CAAC,EAAE,SAAS,EAAE,SAAS,CAAC,UAAU,CAAC,EAAE,CAAC;IAC3D,OAAO,EAAI,UAAU,CAAC,EAAE,SAAS,EAAE,SAAS,CAAC,UAAU,CAAC,EAAE,CAAC;IAC3D,MAAM,EAAK,UAAU,CAAC,EAAE,SAAS,EAAE,SAAS,CAAC,UAAU,CAAC,EAAE,CAAC;IAC3D,MAAM,EAAK,UAAU,CAAC,EAAE,OAAO,EAAE,SAAS,CAAC,UAAU,CAAC,EAAE,CAAC;CAC1D,CAAC,CAAC;AAKH,SAAS,KAAK,CAAC,SAAmB;IAChC,OAAO,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;AAC7C,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,YAAY,CAAC,CAAc;IACzC,QAAQ,CAAC,CAAC,IAAI,EAAE,CAAC;QACf,KAAK,WAAW,CAAC,CAAC,OAAO,CAAC,WAAW,EAAE,KAAK,EAAE,GAAG,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC;QAC3E,KAAK,SAAS,CAAC,CAAG,OAAO,CAAC,SAAS,EAAI,KAAK,EAAE,GAAG,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC;QAC3E,KAAK,QAAQ,CAAC,CAAI,OAAO,CAAC,QAAQ,EAAK,KAAK,EAAE,GAAG,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC;QAC3E,KAAK,QAAQ,CAAC,CAAI,OAAO,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAChD,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"runner.js","sourceRoot":"","sources":["../../src/runner.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,SAAS,EAAE,UAAU,EAAe,MAAM,eAAe,CAAC;AAE5F;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,MAAM,UAAU,GAAG,WAAW,CAAC;IACpC,SAAS,EAAE,UAAU,CAAC,EAAE,SAAS,EAAE,SAAS,CAAC,UAAU,CAAC,EAAE,CAAC;IAC3D,OAAO,EAAI,UAAU,CAAC,EAAE,SAAS,EAAE,SAAS,CAAC,UAAU,CAAC,EAAE,CAAC;IAC3D,MAAM,EAAK,UAAU,CAAC,EAAE,SAAS,EAAE,SAAS,CAAC,UAAU,CAAC,EAAE,CAAC;IAC3D,MAAM,EAAK,UAAU,CAAC,EAAE,OAAO,EAAE,SAAS,CAAC,UAAU,CAAC,EAAE,CAAC;CAC1D,CAAC,CAAC;AAKH,SAAS,KAAK,CAAC,SAAmB;IAChC,OAAO,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;AAC7C,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,YAAY,CAAC,CAAc;IACzC,QAAQ,CAAC,CAAC,IAAI,EAAE,CAAC;QACf,KAAK,WAAW,CAAC,CAAC,OAAO,CAAC,WAAW,EAAE,KAAK,EAAE,GAAG,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC;QAC3E,KAAK,SAAS,CAAC,CAAG,OAAO,CAAC,SAAS,EAAI,KAAK,EAAE,GAAG,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC;QAC3E,KAAK,QAAQ,CAAC,CAAI,OAAO,CAAC,QAAQ,EAAK,KAAK,EAAE,GAAG,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC;QAC3E,KAAK,QAAQ,CAAC,CAAI,OAAO,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAChD,CAAC;AACH,CAAC;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,UAAU,iBAAiB,CAAC,MAAmB,EAAE,IAAc,EAAE,OAAiB;IACtF,IAAI,CAAC,OAAO,IAAI,MAAM,CAAC,IAAI,KAAK,QAAQ,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IACzE,OAAO,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;AACvD,CAAC"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Copyright (c) 2025 Elara AI Pty Ltd
3
+ * Dual-licensed under AGPL-3.0 and commercial license. See LICENSE for details.
4
+ */
5
+ export {};
6
+ //# sourceMappingURL=runner.spec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runner.spec.d.ts","sourceRoot":"","sources":["../../src/runner.spec.ts"],"names":[],"mappings":"AAAA;;;GAGG"}
@@ -0,0 +1,68 @@
1
+ /**
2
+ * Copyright (c) 2025 Elara AI Pty Ltd
3
+ * Dual-licensed under AGPL-3.0 and commercial license. See LICENSE for details.
4
+ */
5
+ /**
6
+ * Gating contract for {@link withRunnerVerbose}.
7
+ *
8
+ * `-v` is a pure runtime toggle: it is spliced into an already-built argv just
9
+ * before spawn. These tests pin the two things that make it safe — it reaches
10
+ * the known runtimes (which all accept `-v`) at the right argv position, and it
11
+ * never touches a `custom` runner's user-authored command. Because it only
12
+ * rewrites the argv (never the runner variant or any hash), it is
13
+ * cache-irrelevant by construction.
14
+ */
15
+ import { describe, it } from 'node:test';
16
+ import * as assert from 'node:assert';
17
+ import { variant } from '@elaraai/east';
18
+ import { runnerToArgv, withRunnerVerbose } from './runner.js';
19
+ /** A realistic fully-built argv: runner prefix + the `-i`/`-o`/`<ir>` suffix. */
20
+ function fullArgv(runner) {
21
+ return [...runnerToArgv(runner), '-i', 'in.beast2', '-o', 'out.beast2', 'body.beast2'];
22
+ }
23
+ const KNOWN = [
24
+ ['east_node', variant('east_node', { platforms: ['@elaraai/east-node-std'] }), 'east-node'],
25
+ ['east_py', variant('east_py', { platforms: ['east-py-std'] }), 'east-py'],
26
+ ['east_c', variant('east_c', { platforms: ['east-c-std'] }), 'east-c'],
27
+ ];
28
+ describe('withRunnerVerbose', () => {
29
+ for (const [tag, runner, bin] of KNOWN) {
30
+ it(`inserts -v after the 'run' subcommand for ${tag}`, () => {
31
+ const args = fullArgv(runner);
32
+ const out = withRunnerVerbose(runner, args, true);
33
+ // `[<bin>, 'run', '-v', …rest]` — position 2, ahead of -p/-i/-o and the IR.
34
+ assert.deepStrictEqual(out.slice(0, 3), [bin, 'run', '-v']);
35
+ // Exactly one -v, and the rest of the argv is preserved in order.
36
+ assert.strictEqual(out.filter((a) => a === '-v').length, 1);
37
+ assert.deepStrictEqual(out.slice(3), args.slice(2));
38
+ // The IR path is still last.
39
+ assert.strictEqual(out[out.length - 1], 'body.beast2');
40
+ });
41
+ it(`leaves the argv untouched when verbose is off for ${tag}`, () => {
42
+ const args = fullArgv(runner);
43
+ assert.deepStrictEqual(withRunnerVerbose(runner, args, false), args);
44
+ assert.deepStrictEqual(withRunnerVerbose(runner, args, undefined), args);
45
+ });
46
+ }
47
+ it('never splices -v into a custom runner (user-authored argv)', () => {
48
+ const runner = variant('custom', { command: ['uv', 'run', 'east-py', 'run'] });
49
+ const args = fullArgv(runner);
50
+ // Even with verbose requested, a custom command is passed through verbatim —
51
+ // we cannot know it understands `-v`.
52
+ assert.deepStrictEqual(withRunnerVerbose(runner, args, true), args);
53
+ assert.ok(!withRunnerVerbose(runner, args, true).includes('-v'));
54
+ });
55
+ it('does not mutate the input argv (returns a new array)', () => {
56
+ const runner = variant('east_node', { platforms: ['@elaraai/east-node-std'] });
57
+ const args = fullArgv(runner);
58
+ const before = [...args];
59
+ withRunnerVerbose(runner, args, true);
60
+ assert.deepStrictEqual(args, before, 'input array must be unchanged');
61
+ });
62
+ it('is a no-op on a degenerate (too-short) argv rather than throwing', () => {
63
+ const runner = variant('east_node', { platforms: [] });
64
+ assert.deepStrictEqual(withRunnerVerbose(runner, ['east-node'], true), ['east-node']);
65
+ assert.deepStrictEqual(withRunnerVerbose(runner, [], true), []);
66
+ });
67
+ });
68
+ //# sourceMappingURL=runner.spec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runner.spec.js","sourceRoot":"","sources":["../../src/runner.spec.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@elaraai/e3-types",
3
- "version": "1.0.30",
3
+ "version": "1.0.31",
4
4
  "description": "Shared type definitions for e3 (East Execution Engine)",
5
5
  "type": "module",
6
6
  "main": "dist/src/index.js",
@@ -18,9 +18,10 @@
18
18
  "directory": "libs/e3/packages/e3-types"
19
19
  },
20
20
  "peerDependencies": {
21
- "@elaraai/east": "1.0.30"
21
+ "@elaraai/east": "1.0.31"
22
22
  },
23
23
  "devDependencies": {
24
+ "@types/node": "^22.0.0",
24
25
  "@typescript-eslint/eslint-plugin": "^8.47.0",
25
26
  "@typescript-eslint/parser": "^8.47.0",
26
27
  "eslint-plugin-headers": "^1.3.3",
@@ -29,6 +30,7 @@
29
30
  "scripts": {
30
31
  "build": "tsc",
31
32
  "lint": "eslint .",
32
- "lint:fix": "eslint . --fix"
33
+ "lint:fix": "eslint . --fix",
34
+ "test": "npm run build && node --enable-source-maps --test-reporter=spec --test 'dist/src/**/*.spec.js'"
33
35
  }
34
36
  }
@@ -0,0 +1,128 @@
1
+ /**
2
+ * Copyright (c) 2025 Elara AI Pty Ltd
3
+ * Dual-licensed under AGPL-3.0 and commercial license. See LICENSE for details.
4
+ */
5
+
6
+ /**
7
+ * Encode/decode contract for {@link EnvironmentSpecType}.
8
+ *
9
+ * BEAST2 encodes a variant's tag as the index of its case in the
10
+ * alphabetically-sorted case list, so the case order is load-bearing: a repo
11
+ * persists specs by that order, and a later code edit that inserts a case
12
+ * before an existing one silently re-tags every later case and mis-decodes
13
+ * already-stored specs. The frozen-order test pins the order so that mistake
14
+ * is a red test; the round-trip tests pin the new cases.
15
+ */
16
+
17
+ import { describe, it } from 'node:test';
18
+ import * as assert from 'node:assert';
19
+ import { encodeBeast2For, decodeBeast2For, variant, some, none } from '@elaraai/east';
20
+ import {
21
+ EnvironmentSpecType,
22
+ environmentSpecObjectHashes,
23
+ type EnvironmentSpec,
24
+ } from './environment.js';
25
+
26
+ const encodeCurrent = encodeBeast2For(EnvironmentSpecType);
27
+ const decodeCurrent = decodeBeast2For(EnvironmentSpecType);
28
+
29
+ const H = (c: string): string => c.repeat(64); // stand-in 64-hex object hash
30
+
31
+ describe('EnvironmentSpecType frozen case order', () => {
32
+ it('is exactly [image, node, python, tools, workspace_node]', () => {
33
+ // BEAST2 tags are indices into this sorted list. A new case must be
34
+ // added so the order only grows at the end (or readers must migrate to
35
+ // name-based decoding first) — inserting before an existing case
36
+ // re-tags every later one and mis-decodes stored specs. This assertion
37
+ // turns that mistake into a red test.
38
+ assert.deepStrictEqual(
39
+ Object.keys((EnvironmentSpecType as unknown as { cases: Record<string, unknown> }).cases),
40
+ ['image', 'node', 'python', 'tools', 'workspace_node'],
41
+ );
42
+ });
43
+ });
44
+
45
+ describe('EnvironmentSpecType round-trips every case', () => {
46
+ const specs: EnvironmentSpec[] = [
47
+ variant('python', { pyproject: H('a'), lock: H('b'), sdists: [{ filename: 'pricing-1.0.0.tar.gz', hash: H('c') }] }),
48
+ variant('node', { packageJson: H('d'), lock: H('e'), tarballs: [H('f')] }),
49
+ variant('image', { digest: `repo@sha256:${H('0')}` }),
50
+ variant('tools', { files: [{ path: 'bin/my-runner', hash: H('1') }] }),
51
+ variant('workspace_node', {
52
+ packageJson: H('2'), lock: H('3'), config: none, subject: 'packages/pricing',
53
+ members: [{ path: 'packages/pricing', name: '@acme/pricing', tarball: H('4') }],
54
+ }),
55
+ ];
56
+
57
+ it('encodes and decodes back to the same value', () => {
58
+ for (const spec of specs) {
59
+ assert.deepStrictEqual(decodeCurrent(encodeCurrent(spec)), spec);
60
+ }
61
+ });
62
+
63
+ it('round-trips a workspace_node spec carrying a pnpm config blob and multiple members', () => {
64
+ const withConfig: EnvironmentSpec = variant('workspace_node', {
65
+ packageJson: H('2'), lock: H('3'), config: some(H('5')), subject: 'packages/pricing',
66
+ members: [
67
+ { path: 'packages/common', name: '@acme/common', tarball: H('6') },
68
+ { path: 'packages/pricing', name: '@acme/pricing', tarball: H('7') },
69
+ ],
70
+ });
71
+ assert.deepStrictEqual(decodeCurrent(encodeCurrent(withConfig)), withConfig);
72
+ });
73
+ });
74
+
75
+ describe('environmentSpecObjectHashes', () => {
76
+ it('lists python blobs', () => {
77
+ assert.deepStrictEqual(
78
+ environmentSpecObjectHashes(variant('python', {
79
+ pyproject: 'p', lock: 'l',
80
+ sdists: [{ filename: 'a-1.0.tar.gz', hash: 's1' }, { filename: 'b-1.0.tar.gz', hash: 's2' }],
81
+ })),
82
+ ['p', 'l', 's1', 's2'],
83
+ );
84
+ });
85
+
86
+ it('lists node blobs', () => {
87
+ assert.deepStrictEqual(
88
+ environmentSpecObjectHashes(variant('node', { packageJson: 'p', lock: 'l', tarballs: ['t'] })),
89
+ ['p', 'l', 't'],
90
+ );
91
+ });
92
+
93
+ it('lists nothing for image', () => {
94
+ assert.deepStrictEqual(
95
+ environmentSpecObjectHashes(variant('image', { digest: `repo@sha256:${H('0')}` })),
96
+ [],
97
+ );
98
+ });
99
+
100
+ it('lists every tools file hash', () => {
101
+ assert.deepStrictEqual(
102
+ environmentSpecObjectHashes(variant('tools', {
103
+ files: [{ path: 'bin/a', hash: 'h1' }, { path: 'bin/b', hash: 'h2' }],
104
+ })),
105
+ ['h1', 'h2'],
106
+ );
107
+ });
108
+
109
+ it('lists workspace_node blobs including the config when present', () => {
110
+ assert.deepStrictEqual(
111
+ environmentSpecObjectHashes(variant('workspace_node', {
112
+ packageJson: 'p', lock: 'l', config: some('cfg'), subject: 'packages/x',
113
+ members: [{ path: 'packages/x', name: '@acme/x', tarball: 't1' }, { path: 'packages/y', name: '@acme/y', tarball: 't2' }],
114
+ })),
115
+ ['p', 'l', 'cfg', 't1', 't2'],
116
+ );
117
+ });
118
+
119
+ it('omits the config hash for an npm workspace_node (none)', () => {
120
+ assert.deepStrictEqual(
121
+ environmentSpecObjectHashes(variant('workspace_node', {
122
+ packageJson: 'p', lock: 'l', config: none, subject: 'packages/x',
123
+ members: [{ path: 'packages/x', name: '@acme/x', tarball: 't1' }],
124
+ })),
125
+ ['p', 'l', 't1'],
126
+ );
127
+ });
128
+ });
@@ -18,7 +18,7 @@
18
18
  * ride the existing content-addressed object store and transfer machinery.
19
19
  */
20
20
 
21
- import { ArrayType, StringType, StructType, ValueTypeOf, VariantType } from '@elaraai/east';
21
+ import { ArrayType, OptionType, StringType, StructType, ValueTypeOf, VariantType } from '@elaraai/east';
22
22
 
23
23
  /**
24
24
  * A Python (uv) project environment.
@@ -88,12 +88,90 @@ export const ImageEnvironmentType = StructType({
88
88
  export type ImageEnvironmentType = typeof ImageEnvironmentType;
89
89
  export type ImageEnvironment = ValueTypeOf<typeof ImageEnvironmentType>;
90
90
 
91
+ /**
92
+ * A prebuilt-file ("tools") environment for C and custom runners.
93
+ *
94
+ * e3 never builds anything for this kind: the developer builds their binary
95
+ * (or any prebuilt artifact) however they like, and capture folds the named
96
+ * files' bytes into the environment hash and materializes them onto the
97
+ * runner's PATH. Rebuilding a captured file changes its blob hash → the
98
+ * environment hash → the tasks that use it re-run. This closes the
99
+ * pre-existing hole where a custom-runner binary resolved from PATH was
100
+ * never part of the cache key, so a rebuild silently served stale outputs.
101
+ *
102
+ * @remarks
103
+ * - `files`: the captured files, sorted by `path` so capture order never
104
+ * affects the environment hash.
105
+ * - `path`: environment-dir-relative POSIX path; v1 writers emit
106
+ * `bin/<basename>` (materialization writes it there and adds `bin` to
107
+ * PATH). Validated at materialization: no absolute paths, no `..`, no
108
+ * empty segments.
109
+ * - `hash`: object hash of the file's bytes. No mode is stored:
110
+ * materialization always applies a fixed mode, so an exec-bit-only
111
+ * change does not alter the environment yet also cannot go stale.
112
+ */
113
+ export const ToolsEnvironmentType = StructType({
114
+ /** Captured files (env-relative path + object hash), sorted by path */
115
+ files: ArrayType(StructType({ path: StringType, hash: StringType })),
116
+ });
117
+ export type ToolsEnvironmentType = typeof ToolsEnvironmentType;
118
+ export type ToolsEnvironment = ValueTypeOf<typeof ToolsEnvironmentType>;
119
+
120
+ /**
121
+ * A Node **workspace-member** environment (npm or pnpm workspaces).
122
+ *
123
+ * Where {@link NodeEnvironmentType} captures one self-contained project,
124
+ * this captures one member of a workspace together with the transitive
125
+ * closure of the local workspace packages it depends on — so editing a
126
+ * member's code re-runs only the environments whose closure contains it.
127
+ * Materialized by reconstructing a minimal workspace of exactly the closure
128
+ * members and running the frozen install against the verbatim root lock.
129
+ *
130
+ * @remarks
131
+ * - `packageJson`: object hash of the workspace **root** `package.json` blob.
132
+ * - `lock`: object hash of the **root** lockfile blob (content-sniffed as
133
+ * today; npm in v1, pnpm once the pnpm capture path ships).
134
+ * - `config`: pnpm only — object hash of the capture-synthesized
135
+ * `pnpm-workspace.yaml` blob; `none` for npm.
136
+ * - `subject`: workspace-relative POSIX path of the environment's own
137
+ * member. Must satisfy `members.some((m) => m.path === subject)` — this is
138
+ * enforced at capture and re-validated at materialization (BEAST2 typed
139
+ * decode is structural only and cannot check it).
140
+ * - `members`: the dependency closure sorted by `path`; each carries its
141
+ * package `name` (read from the member's `package.json` at capture) and
142
+ * the object `hash` of its `npm pack` tarball.
143
+ */
144
+ export const WorkspaceNodeEnvironmentType = StructType({
145
+ /** Object hash of the workspace root package.json blob */
146
+ packageJson: StringType,
147
+ /** Object hash of the root lockfile blob */
148
+ lock: StringType,
149
+ /** pnpm only: object hash of the synthesized pnpm-workspace.yaml; none for npm */
150
+ config: OptionType(StringType),
151
+ /** Workspace-relative POSIX path of this environment's own member */
152
+ subject: StringType,
153
+ /** Dependency closure (path + package name + tarball hash), sorted by path */
154
+ members: ArrayType(StructType({ path: StringType, name: StringType, tarball: StringType })),
155
+ });
156
+ export type WorkspaceNodeEnvironmentType = typeof WorkspaceNodeEnvironmentType;
157
+ export type WorkspaceNodeEnvironment = ValueTypeOf<typeof WorkspaceNodeEnvironmentType>;
158
+
91
159
  /**
92
160
  * An execution environment specification.
93
161
  *
94
162
  * Stored beast2-encoded in the object store; the **environment hash** is the
95
163
  * object hash of the encoded spec. A task/function with no environment
96
164
  * (`none`) runs on the stock runtime image as today.
165
+ *
166
+ * @remarks
167
+ * BEAST2 encodes a variant's tag as the index of its case in the
168
+ * **alphabetically sorted** case list, so the case order is load-bearing: a
169
+ * repo persists specs by that order, and reordering the cases in a later
170
+ * edit would re-tag every case after the insertion point and mis-decode
171
+ * already-stored specs. New cases must therefore be added so the sorted
172
+ * order only grows at the end (`tools` and `workspace_node` sort after the
173
+ * original three). The frozen-order guard test in `environment.spec.ts`
174
+ * turns an accidental reorder into a red test.
97
175
  */
98
176
  export const EnvironmentSpecType = VariantType({
99
177
  /** Python (uv) project environment */
@@ -102,6 +180,10 @@ export const EnvironmentSpecType = VariantType({
102
180
  node: NodeEnvironmentType,
103
181
  /** Custom container image environment */
104
182
  image: ImageEnvironmentType,
183
+ /** Prebuilt-file environment for C / custom runners */
184
+ tools: ToolsEnvironmentType,
185
+ /** Node workspace-member environment (npm/pnpm workspaces) */
186
+ workspace_node: WorkspaceNodeEnvironmentType,
105
187
  });
106
188
  export type EnvironmentSpecType = typeof EnvironmentSpecType;
107
189
  export type EnvironmentSpec = ValueTypeOf<typeof EnvironmentSpecType>;
@@ -123,5 +205,14 @@ export function environmentSpecObjectHashes(spec: EnvironmentSpec): string[] {
123
205
  return [spec.value.packageJson, spec.value.lock, ...spec.value.tarballs];
124
206
  case 'image':
125
207
  return [];
208
+ case 'tools':
209
+ return spec.value.files.map((f) => f.hash);
210
+ case 'workspace_node':
211
+ return [
212
+ spec.value.packageJson,
213
+ spec.value.lock,
214
+ ...(spec.value.config.type === 'some' ? [spec.value.config.value] : []),
215
+ ...spec.value.members.map((m) => m.tarball),
216
+ ];
126
217
  }
127
218
  }
package/src/index.ts CHANGED
@@ -56,6 +56,10 @@ export {
56
56
  type NodeEnvironment,
57
57
  ImageEnvironmentType,
58
58
  type ImageEnvironment,
59
+ ToolsEnvironmentType,
60
+ type ToolsEnvironment,
61
+ WorkspaceNodeEnvironmentType,
62
+ type WorkspaceNodeEnvironment,
59
63
  environmentSpecObjectHashes,
60
64
  } from './environment.js';
61
65
 
@@ -86,6 +90,7 @@ export {
86
90
  RunnerType,
87
91
  type RunnerValue,
88
92
  runnerToArgv,
93
+ withRunnerVerbose,
89
94
  } from './runner.js';
90
95
 
91
96
  // Function objects
@@ -0,0 +1,76 @@
1
+ /**
2
+ * Copyright (c) 2025 Elara AI Pty Ltd
3
+ * Dual-licensed under AGPL-3.0 and commercial license. See LICENSE for details.
4
+ */
5
+
6
+ /**
7
+ * Gating contract for {@link withRunnerVerbose}.
8
+ *
9
+ * `-v` is a pure runtime toggle: it is spliced into an already-built argv just
10
+ * before spawn. These tests pin the two things that make it safe — it reaches
11
+ * the known runtimes (which all accept `-v`) at the right argv position, and it
12
+ * never touches a `custom` runner's user-authored command. Because it only
13
+ * rewrites the argv (never the runner variant or any hash), it is
14
+ * cache-irrelevant by construction.
15
+ */
16
+
17
+ import { describe, it } from 'node:test';
18
+ import * as assert from 'node:assert';
19
+ import { variant } from '@elaraai/east';
20
+ import { runnerToArgv, withRunnerVerbose, type RunnerValue } from './runner.js';
21
+
22
+ /** A realistic fully-built argv: runner prefix + the `-i`/`-o`/`<ir>` suffix. */
23
+ function fullArgv(runner: RunnerValue): string[] {
24
+ return [...runnerToArgv(runner), '-i', 'in.beast2', '-o', 'out.beast2', 'body.beast2'];
25
+ }
26
+
27
+ const KNOWN: Array<[string, RunnerValue, string]> = [
28
+ ['east_node', variant('east_node', { platforms: ['@elaraai/east-node-std'] }), 'east-node'],
29
+ ['east_py', variant('east_py', { platforms: ['east-py-std'] }), 'east-py'],
30
+ ['east_c', variant('east_c', { platforms: ['east-c-std'] }), 'east-c'],
31
+ ];
32
+
33
+ describe('withRunnerVerbose', () => {
34
+ for (const [tag, runner, bin] of KNOWN) {
35
+ it(`inserts -v after the 'run' subcommand for ${tag}`, () => {
36
+ const args = fullArgv(runner);
37
+ const out = withRunnerVerbose(runner, args, true);
38
+ // `[<bin>, 'run', '-v', …rest]` — position 2, ahead of -p/-i/-o and the IR.
39
+ assert.deepStrictEqual(out.slice(0, 3), [bin, 'run', '-v']);
40
+ // Exactly one -v, and the rest of the argv is preserved in order.
41
+ assert.strictEqual(out.filter((a) => a === '-v').length, 1);
42
+ assert.deepStrictEqual(out.slice(3), args.slice(2));
43
+ // The IR path is still last.
44
+ assert.strictEqual(out[out.length - 1], 'body.beast2');
45
+ });
46
+
47
+ it(`leaves the argv untouched when verbose is off for ${tag}`, () => {
48
+ const args = fullArgv(runner);
49
+ assert.deepStrictEqual(withRunnerVerbose(runner, args, false), args);
50
+ assert.deepStrictEqual(withRunnerVerbose(runner, args, undefined), args);
51
+ });
52
+ }
53
+
54
+ it('never splices -v into a custom runner (user-authored argv)', () => {
55
+ const runner: RunnerValue = variant('custom', { command: ['uv', 'run', 'east-py', 'run'] });
56
+ const args = fullArgv(runner);
57
+ // Even with verbose requested, a custom command is passed through verbatim —
58
+ // we cannot know it understands `-v`.
59
+ assert.deepStrictEqual(withRunnerVerbose(runner, args, true), args);
60
+ assert.ok(!withRunnerVerbose(runner, args, true).includes('-v'));
61
+ });
62
+
63
+ it('does not mutate the input argv (returns a new array)', () => {
64
+ const runner = variant('east_node', { platforms: ['@elaraai/east-node-std'] });
65
+ const args = fullArgv(runner);
66
+ const before = [...args];
67
+ withRunnerVerbose(runner, args, true);
68
+ assert.deepStrictEqual(args, before, 'input array must be unchanged');
69
+ });
70
+
71
+ it('is a no-op on a degenerate (too-short) argv rather than throwing', () => {
72
+ const runner = variant('east_node', { platforms: [] });
73
+ assert.deepStrictEqual(withRunnerVerbose(runner, ['east-node'], true), ['east-node']);
74
+ assert.deepStrictEqual(withRunnerVerbose(runner, [], true), []);
75
+ });
76
+ });
package/src/runner.ts CHANGED
@@ -60,3 +60,28 @@ export function runnerToArgv(r: RunnerValue): string[] {
60
60
  case 'custom': return [...r.value.command];
61
61
  }
62
62
  }
63
+
64
+ /**
65
+ * Insert the runner's `-v/--verbose` flag into a fully-built argv, for the
66
+ * known runtimes only.
67
+ *
68
+ * All three known runners (`east-node`/`east-py`/`east-c run`) accept `-v`
69
+ * among their options and print timing/perf detail to stderr; a `custom`
70
+ * runner's argv is user-authored, so a flag is never spliced into it. A
71
+ * known-runtime argv always starts `[<bin>, 'run', …]` (see
72
+ * {@link runnerToArgv} and the SDK's `runnerToCommand`), so `-v` goes at
73
+ * index 2 — ahead of the `-p`/`-i`/`-o` flags and the trailing IR path.
74
+ *
75
+ * This is a pure **runtime** toggle: it is applied to the *evaluated* argv
76
+ * immediately before spawn and never touches the task's `commandIr`, the
77
+ * {@link RunnerType}, or any hash — so it cannot affect caching.
78
+ *
79
+ * @param runner - the runner the argv was built for (gates the injection)
80
+ * @param args - the fully-built argv (runner prefix + `-i`/`-o`/`<ir>` suffix)
81
+ * @param verbose - when true, request the runner's verbose output
82
+ * @returns the argv, with `-v` inserted for known runtimes when verbose
83
+ */
84
+ export function withRunnerVerbose(runner: RunnerValue, args: string[], verbose?: boolean): string[] {
85
+ if (!verbose || runner.type === 'custom' || args.length < 2) return args;
86
+ return [...args.slice(0, 2), '-v', ...args.slice(2)];
87
+ }