@omni-oss/task-bench 0.0.0-beta.1 → 0.0.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.
@@ -3,8 +3,7 @@ import { Stats } from './stats';
3
3
  export interface RunSample {
4
4
  durationMs: number;
5
5
  exitCode: number;
6
- stdout: string;
7
- stderr: string;
6
+ stdoutBytes: number;
8
7
  /** Number of tasks that actually executed (0 == a full cache hit). */
9
8
  executed: number;
10
9
  ok: boolean;
@@ -51,10 +50,6 @@ export type BenchEvent = {
51
50
  kind: "tool-error";
52
51
  tool: Tool;
53
52
  error: string;
54
- } | {
55
- kind: "tool-unsuccessful";
56
- tool: Tool;
57
- sample: RunSample;
58
53
  };
59
54
  export interface RunBenchmarkOptions {
60
55
  tools?: Tool[] | undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/bench/index.ts"],"names":[],"mappings":"AAMA,OAAO,EAAuB,KAAK,IAAI,EAAE,MAAM,WAAW,CAAC;AAG3D,OAAO,EAAgB,KAAK,KAAK,EAAE,MAAM,SAAS,CAAC;AAEnD,MAAM,WAAW,SAAS;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,sEAAsE;IACtE,QAAQ,EAAE,MAAM,CAAC;IACjB,EAAE,EAAE,OAAO,CAAC;CACf;AAED,MAAM,WAAW,cAAc;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,KAAK,CAAC;IACb,qEAAqE;IACrE,cAAc,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,UAAU;IACvB,IAAI,EAAE,IAAI,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,2EAA2E;IAC3E,aAAa,EAAE,MAAM,CAAC;IACtB,IAAI,EAAE,cAAc,CAAC;IACrB,IAAI,EAAE,cAAc,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,eAAe;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,eAAe,EAAE,MAAM,CAAC;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,OAAO,CAAC;IAChB,qEAAqE;IACrE,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC,CAAC;IACxC,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,UAAU,EAAE,CAAC;CACvB;AAED,MAAM,MAAM,UAAU,GAChB;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,IAAI,EAAE,IAAI,CAAA;CAAE,GAClC;IACI,IAAI,EAAE,UAAU,CAAC;IACjB,IAAI,EAAE,IAAI,CAAC;IACX,QAAQ,EAAE,MAAM,GAAG,MAAM,CAAC;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,SAAS,CAAC;CACrB,GACD;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,IAAI,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GACjD;IACI,IAAI,EAAE,mBAAmB,CAAC;IAC1B,IAAI,EAAE,IAAI,CAAC;IACX,MAAM,EAAE,SAAS,CAAC;CACrB,CAAC;AAER,MAAM,WAAW,mBAAmB;IAChC,KAAK,CAAC,EAAE,IAAI,EAAE,GAAG,SAAS,CAAC;IAC3B,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACjC,0DAA0D;IAC1D,MAAM,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAC7B,OAAO,CAAC,EAAE,CAAC,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;CACvD;AAuED;;;;;;;;;;;GAWG;AACH,wBAAsB,YAAY,CAC9B,OAAO,EAAE,MAAM,EACf,OAAO,GAAE,mBAAwB,GAClC,OAAO,CAAC,eAAe,CAAC,CA8J1B"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/bench/index.ts"],"names":[],"mappings":"AAMA,OAAO,EAAuB,KAAK,IAAI,EAAE,MAAM,WAAW,CAAC;AAG3D,OAAO,EAAgB,KAAK,KAAK,EAAE,MAAM,SAAS,CAAC;AAEnD,MAAM,WAAW,SAAS;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,sEAAsE;IACtE,QAAQ,EAAE,MAAM,CAAC;IACjB,EAAE,EAAE,OAAO,CAAC;CACf;AAED,MAAM,WAAW,cAAc;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,KAAK,CAAC;IACb,qEAAqE;IACrE,cAAc,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,UAAU;IACvB,IAAI,EAAE,IAAI,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,2EAA2E;IAC3E,aAAa,EAAE,MAAM,CAAC;IACtB,IAAI,EAAE,cAAc,CAAC;IACrB,IAAI,EAAE,cAAc,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,eAAe;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,eAAe,EAAE,MAAM,CAAC;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,OAAO,CAAC;IAChB,qEAAqE;IACrE,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC,CAAC;IACxC,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,UAAU,EAAE,CAAC;CACvB;AAED,MAAM,MAAM,UAAU,GAChB;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,IAAI,EAAE,IAAI,CAAA;CAAE,GAClC;IACI,IAAI,EAAE,UAAU,CAAC;IACjB,IAAI,EAAE,IAAI,CAAC;IACX,QAAQ,EAAE,MAAM,GAAG,MAAM,CAAC;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,SAAS,CAAC;CACrB,GACD;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,IAAI,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAExD,MAAM,WAAW,mBAAmB;IAChC,KAAK,CAAC,EAAE,IAAI,EAAE,GAAG,SAAS,CAAC;IAC3B,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACjC,0DAA0D;IAC1D,MAAM,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAC7B,OAAO,CAAC,EAAE,CAAC,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;CACvD;AAoED;;;;;;;;;;;GAWG;AACH,wBAAsB,YAAY,CAC9B,OAAO,EAAE,MAAM,EACf,OAAO,GAAE,mBAAwB,GAClC,OAAO,CAAC,eAAe,CAAC,CAgJ1B"}
package/dist/index.mjs CHANGED
@@ -1,2 +1,2 @@
1
- import { A as e, C as t, D as n, E as r, M as i, N as a, O as o, S as s, T as c, _ as l, a as u, b as d, c as f, d as p, f as m, g as h, h as g, i as _, j as v, k as y, l as b, m as x, n as S, o as C, p as w, r as T, s as E, t as D, u as O, v as k, w as A, x as j, y as M } from "./src-D3XyMXAu.mjs";
1
+ import { A as e, C as t, D as n, E as r, M as i, N as a, O as o, S as s, T as c, _ as l, a as u, b as d, c as f, d as p, f as m, g as h, h as g, i as _, j as v, k as y, l as b, m as x, n as S, o as C, p as w, r as T, s as E, t as D, u as O, v as k, w as A, x as j, y as M } from "./src-DOsUAz2Z.mjs";
2
2
  export { T as BUILTIN_PRESETS, c as DEPENDENCY_STRATEGIES, r as DependencyConfigSchema, n as DependencyStrategySchema, o as HarnessConfigSchema, _ as RunOptionsSchema, u as ScenarioSchema, C as SuiteSchema, y as TOOLS, e as TaskConfigSchema, v as ToolSchema, i as VersionsConfigSchema, k as assertSupportedVersion, s as buildGraph, h as computeStats, E as deepMerge, l as formatMs, w as formatReport, D as formatSuiteMarkdown, m as generateWorkspace, M as getAdapter, d as getAdapters, f as getPreset, x as installWorkspace, b as listPresets, O as parseSuite, t as projectName, a as resolveConfig, p as resolveScenario, j as resolveToolVersions, g as runBenchmark, S as runSuite, A as taskNames };
@@ -7,46 +7,46 @@ import { execa as f } from "execa";
7
7
  import { z as p } from "zod";
8
8
  import { satisfies as m } from "semver";
9
9
  import { stringify as h } from "yaml";
10
- //#region package.json
11
- var g = "@omni-oss/task-bench", _ = "Generate configurable test workspaces and benchmark omni/turbo/nx task execution performance", v = "0.0.0-beta.1", y = [
10
+ //#region src/config.ts
11
+ var g = [
12
12
  "isolated",
13
13
  "chain",
14
14
  "fan-out",
15
15
  "layered",
16
16
  "random"
17
- ], b = p.enum(y), x = [
17
+ ], _ = p.enum(g), v = [
18
18
  "omni",
19
19
  "turbo",
20
20
  "nx",
21
21
  "moon"
22
- ], S = p.enum(x), C = p.object({
23
- strategy: b.default("layered").describe("Shape of the inter-project dependency graph."),
22
+ ], y = p.enum(v), b = p.object({
23
+ strategy: _.default("layered").describe("Shape of the inter-project dependency graph."),
24
24
  layers: p.number().int().positive().default(5).describe("Number of layers for the `layered` strategy."),
25
25
  fanout: p.number().int().nonnegative().default(3).describe("Maximum number of upstream dependencies per project (cap for `layered`/`random`)."),
26
26
  edgeProbability: p.number().min(0).max(1).default(.35).describe("Edge inclusion probability for the `random` strategy.")
27
- }).prefault({}), w = p.object({
27
+ }).prefault({}), x = p.object({
28
28
  logLines: p.number().int().nonnegative().default(25).describe("How many log lines each task prints to stdout."),
29
29
  workIterations: p.number().int().nonnegative().default(15e4).describe("Iterations of cheap CPU work per task. Keep small so caching dominates."),
30
30
  outputFiles: p.number().int().positive().default(1).describe("Number of output files each task writes into dist/."),
31
31
  chainWithinProject: p.boolean().default(!0).describe("Whether task `tN` depends on `t(N-1)` within a project."),
32
32
  fanUpstream: p.boolean().default(!0).describe("Whether task `tN` depends on `tN` of upstream projects (^tN).")
33
- }).prefault({}), T = p.object({
33
+ }).prefault({}), S = p.object({
34
34
  turbo: p.string().default("2.10.3"),
35
35
  nx: p.string().default("23.0.1"),
36
36
  moon: p.string().default("2.3.5"),
37
37
  bun: p.string().default("1.3.14")
38
- }).prefault({}), E = p.object({
38
+ }).prefault({}), C = p.object({
39
39
  seed: p.number().int().nonnegative().default(1).describe("Seed for deterministic graph generation."),
40
40
  projectPrefix: p.string().regex(/^[a-z][a-z0-9-]*$/).default("bench-p").describe("Prefix used for generated package names."),
41
41
  projects: p.number().int().positive().default(50).describe("Number of projects to generate."),
42
42
  tasksPerProject: p.number().int().positive().default(3).describe("Number of tasks (t0..tN-1) per project."),
43
- dependency: C,
44
- task: w,
45
- tools: p.array(S).min(1).default([...x]).describe("Which runners to configure and benchmark."),
46
- versions: T
43
+ dependency: b,
44
+ task: x,
45
+ tools: p.array(y).min(1).default([...v]).describe("Which runners to configure and benchmark."),
46
+ versions: S
47
47
  });
48
- function D(e) {
49
- return E.parse(e ?? {});
48
+ function w(e) {
49
+ return C.parse(e ?? {});
50
50
  }
51
51
  //#endregion
52
52
  //#region src/graph.ts
@@ -61,7 +61,7 @@ function ee(e) {
61
61
  function te(e) {
62
62
  return Math.max(4, String(e - 1).length);
63
63
  }
64
- function O(e, t) {
64
+ function T(e, t) {
65
65
  let n = te(e.projects);
66
66
  return `${e.projectPrefix}${String(t).padStart(n, "0")}`;
67
67
  }
@@ -95,10 +95,10 @@ function re(e, t, n) {
95
95
  default: return [];
96
96
  }
97
97
  }
98
- function k(e) {
98
+ function E(e) {
99
99
  let t = ee(e.seed), n = [];
100
100
  for (let r = 0; r < e.projects; r++) {
101
- let i = O(e, r);
101
+ let i = T(e, r);
102
102
  n.push({
103
103
  index: r,
104
104
  name: i,
@@ -108,48 +108,48 @@ function k(e) {
108
108
  }
109
109
  return n;
110
110
  }
111
- function A(e) {
111
+ function D(e) {
112
112
  return Array.from({ length: e.tasksPerProject }, (e, t) => `t${t}`);
113
113
  }
114
114
  //#endregion
115
115
  //#region src/tools/types.ts
116
- function j(t, n) {
116
+ function O(t, n) {
117
117
  let r = o(t, "node_modules", ".bin", n);
118
118
  return e(r) ? r : n;
119
119
  }
120
- async function M(e) {
120
+ async function k(e) {
121
121
  await Promise.all(e.projectDirs.map((t) => l(o(e.rootDir, t, "dist"), {
122
122
  recursive: !0,
123
123
  force: !0
124
124
  })));
125
125
  }
126
- function N(e, t) {
126
+ function A(e, t) {
127
127
  let n = [];
128
128
  return e.task.chainWithinProject && t > 0 && n.push(`t${t - 1}`), e.task.fanUpstream && n.push(`^t${t}`), n;
129
129
  }
130
- function ie(e, t) {
130
+ function j(e, t) {
131
131
  return e.dependencies.map((e) => t[e]?.name ?? "");
132
132
  }
133
133
  //#endregion
134
134
  //#region src/tools/moon.ts
135
- var ae = "https://moonrepo.dev/schemas/workspace.json", oe = "https://moonrepo.dev/schemas/toolchain.json", se = "https://moonrepo.dev/schemas/project.json";
136
- function ce(e, t) {
135
+ var ie = "https://moonrepo.dev/schemas/workspace.json", ae = "https://moonrepo.dev/schemas/toolchain.json", oe = "https://moonrepo.dev/schemas/project.json";
136
+ function se(e, t) {
137
137
  let n = [];
138
138
  return e.task.chainWithinProject && t > 0 && n.push(`~:t${t - 1}`), e.task.fanUpstream && n.push(`^:t${t}`), n;
139
139
  }
140
- function le() {
140
+ function ce() {
141
141
  return h({
142
- $schema: ae,
142
+ $schema: ie,
143
143
  projects: ["packages/*"]
144
144
  });
145
145
  }
146
- function ue() {
147
- return h({ $schema: oe });
146
+ function le() {
147
+ return h({ $schema: ae });
148
148
  }
149
- function de(e, t, n) {
149
+ function ue(e, t, n) {
150
150
  let r = {};
151
- return A(e).forEach((t, n) => {
152
- let i = ce(e, n);
151
+ return D(e).forEach((t, n) => {
152
+ let i = se(e, n);
153
153
  r[t] = {
154
154
  command: `node ./task.mjs ${t}`,
155
155
  ...i.length ? { deps: i } : {},
@@ -161,26 +161,26 @@ function de(e, t, n) {
161
161
  outputs: [`dist/${t}.*`]
162
162
  };
163
163
  }), h({
164
- $schema: se,
164
+ $schema: oe,
165
165
  id: t.name,
166
166
  layer: "library",
167
167
  language: "javascript",
168
- ...t.dependencies.length ? { dependsOn: ie(t, n) } : {},
168
+ ...t.dependencies.length ? { dependsOn: j(t, n) } : {},
169
169
  tasks: r
170
170
  });
171
171
  }
172
- var fe = {
172
+ var de = {
173
173
  tool: "moon",
174
174
  hasDaemon: !1,
175
175
  supportedVersions: ["^2.0.0"],
176
176
  pinnedVersion: (e) => e.versions.moon,
177
177
  devDependencies: (e) => ({ "@moonrepo/cli": e.versions.moon }),
178
178
  setup: async (e) => {
179
- await e.write(".moon/workspace.yml", le()), await e.write(".moon/toolchain.yml", ue());
180
- for (let t of e.projects) await e.write(`${t.dir}/moon.yml`, de(e.config, t, e.projects));
179
+ await e.write(".moon/workspace.yml", ce()), await e.write(".moon/toolchain.yml", le());
180
+ for (let t of e.projects) await e.write(`${t.dir}/moon.yml`, ue(e.config, t, e.projects));
181
181
  },
182
182
  run: (e, t) => ({
183
- file: j(t.rootDir, "moon"),
183
+ file: O(t.rootDir, "moon"),
184
184
  args: [
185
185
  "run",
186
186
  `:${e}`,
@@ -190,7 +190,7 @@ var fe = {
190
190
  }),
191
191
  env: () => ({}),
192
192
  clearCaches: async (e) => {
193
- await M(e), await l(o(e.rootDir, ".moon", "cache"), {
193
+ await k(e), await l(o(e.rootDir, ".moon", "cache"), {
194
194
  recursive: !0,
195
195
  force: !0
196
196
  });
@@ -199,11 +199,11 @@ var fe = {
199
199
  };
200
200
  //#endregion
201
201
  //#region src/tools/nx.ts
202
- function pe(e) {
202
+ function fe(e) {
203
203
  let t = {};
204
- return A(e).forEach((n, r) => {
204
+ return D(e).forEach((n, r) => {
205
205
  t[n] = {
206
- dependsOn: N(e, r),
206
+ dependsOn: A(e, r),
207
207
  cache: !0,
208
208
  outputs: [`{projectRoot}/dist/${n}.*`],
209
209
  inputs: [
@@ -217,9 +217,9 @@ function pe(e) {
217
217
  targetDefaults: t
218
218
  }, null, 2)}\n`;
219
219
  }
220
- function me(e, t) {
220
+ function pe(e, t) {
221
221
  let n = {};
222
- for (let r of A(e)) n[r] = {
222
+ for (let r of D(e)) n[r] = {
223
223
  executor: "nx:run-commands",
224
224
  options: {
225
225
  command: `node ./task.mjs ${r}`,
@@ -232,18 +232,18 @@ function me(e, t) {
232
232
  targets: n
233
233
  }, null, 2)}\n`;
234
234
  }
235
- var he = {
235
+ var me = {
236
236
  tool: "nx",
237
237
  hasDaemon: !0,
238
238
  supportedVersions: [">=21.0.0 <24.0.0"],
239
239
  pinnedVersion: (e) => e.versions.nx,
240
240
  devDependencies: (e) => ({ nx: e.versions.nx }),
241
241
  setup: async (e) => {
242
- await e.write("nx.json", pe(e.config));
243
- for (let t of e.projects) await e.write(`${t.dir}/project.json`, me(e.config, t));
242
+ await e.write("nx.json", fe(e.config));
243
+ for (let t of e.projects) await e.write(`${t.dir}/project.json`, pe(e.config, t));
244
244
  },
245
245
  run: (e, t) => ({
246
- file: j(t.rootDir, "nx"),
246
+ file: O(t.rootDir, "nx"),
247
247
  args: [
248
248
  "run-many",
249
249
  "-t",
@@ -256,7 +256,7 @@ var he = {
256
256
  NX_TUI: "false"
257
257
  }),
258
258
  clearCaches: async (e) => {
259
- await M(e), await f(j(e.rootDir, "nx"), ["reset"], {
259
+ await k(e), await f(O(e.rootDir, "nx"), ["reset"], {
260
260
  cwd: e.rootDir,
261
261
  reject: !1,
262
262
  stdio: "ignore",
@@ -267,32 +267,32 @@ var he = {
267
267
  });
268
268
  },
269
269
  stopDaemon: async (e) => {
270
- await f(j(e.rootDir, "nx"), ["reset"], {
270
+ await f(O(e.rootDir, "nx"), ["reset"], {
271
271
  cwd: e.rootDir,
272
272
  reject: !1,
273
273
  stdio: "ignore",
274
274
  env: { NX_DAEMON: "false" }
275
275
  });
276
276
  }
277
- }, ge = "# yaml-language-server: $schema=https://raw.githubusercontent.com/omni-oss/json-schemas/refs/heads/main/project.json", _e = "# yaml-language-server: $schema=https://raw.githubusercontent.com/omni-oss/json-schemas/refs/heads/main/workspace.json";
278
- function ve() {
279
- return `${_e}\n${h({
277
+ }, he = "# yaml-language-server: $schema=https://raw.githubusercontent.com/omni-oss/json-schemas/refs/heads/main/project.json", ge = "# yaml-language-server: $schema=https://raw.githubusercontent.com/omni-oss/json-schemas/refs/heads/main/workspace.json";
278
+ function _e() {
279
+ return `${ge}\n${h({
280
280
  ui: "stream",
281
281
  projects: ["packages/*"]
282
282
  })}`;
283
283
  }
284
- function ye(e, t, n) {
284
+ function ve(e, t, n) {
285
285
  let r = {};
286
- return A(e).forEach((t, n) => {
287
- let i = N(e, n);
286
+ return D(e).forEach((t, n) => {
287
+ let i = A(e, n);
288
288
  r[t] = {
289
289
  exec: `node ./task.mjs ${t}`,
290
290
  ...i.length ? { dependencies: i } : {},
291
291
  cache: { output: { files: [`dist/${t}.*`] } }
292
292
  };
293
- }), `${ge}\n${h({
293
+ }), `${he}\n${h({
294
294
  name: t.name,
295
- ...t.dependencies.length ? { dependencies: ie(t, n) } : {},
295
+ ...t.dependencies.length ? { dependencies: j(t, n) } : {},
296
296
  cache: { key: { files: [
297
297
  "package.json",
298
298
  "task.mjs",
@@ -301,7 +301,7 @@ function ye(e, t, n) {
301
301
  tasks: r
302
302
  })}`;
303
303
  }
304
- var be = {
304
+ var ye = {
305
305
  tool: "omni",
306
306
  hasDaemon: !1,
307
307
  supportedVersions: [">=0.16.0"],
@@ -315,8 +315,8 @@ var be = {
315
315
  },
316
316
  devDependencies: () => ({}),
317
317
  setup: async (e) => {
318
- await e.write("workspace.omni.yaml", ve());
319
- for (let t of e.projects) await e.write(`${t.dir}/project.omni.yaml`, ye(e.config, t, e.projects));
318
+ await e.write("workspace.omni.yaml", _e());
319
+ for (let t of e.projects) await e.write(`${t.dir}/project.omni.yaml`, ve(e.config, t, e.projects));
320
320
  },
321
321
  run: (e, t) => ({
322
322
  file: "omni",
@@ -331,7 +331,7 @@ var be = {
331
331
  }),
332
332
  env: () => ({}),
333
333
  clearCaches: async (e) => {
334
- await M(e), await l(o(e.rootDir, ".omni", "cache"), {
334
+ await k(e), await l(o(e.rootDir, ".omni", "cache"), {
335
335
  recursive: !0,
336
336
  force: !0
337
337
  });
@@ -340,11 +340,11 @@ var be = {
340
340
  };
341
341
  //#endregion
342
342
  //#region src/tools/turbo.ts
343
- function xe(e) {
343
+ function be(e) {
344
344
  let t = {};
345
- return A(e).forEach((n, r) => {
345
+ return D(e).forEach((n, r) => {
346
346
  t[n] = {
347
- dependsOn: N(e, r),
347
+ dependsOn: A(e, r),
348
348
  outputs: [`dist/${n}.*`],
349
349
  inputs: [
350
350
  "package.json",
@@ -360,8 +360,8 @@ function xe(e) {
360
360
  }
361
361
  //#endregion
362
362
  //#region src/tools/index.ts
363
- var Se = {
364
- omni: be,
363
+ var xe = {
364
+ omni: ye,
365
365
  turbo: {
366
366
  tool: "turbo",
367
367
  hasDaemon: !0,
@@ -369,10 +369,10 @@ var Se = {
369
369
  pinnedVersion: (e) => e.versions.turbo,
370
370
  devDependencies: (e) => ({ turbo: e.versions.turbo }),
371
371
  setup: async (e) => {
372
- await e.write("turbo.json", xe(e.config));
372
+ await e.write("turbo.json", be(e.config));
373
373
  },
374
374
  run: (e, t) => ({
375
- file: j(t.rootDir, "turbo"),
375
+ file: O(t.rootDir, "turbo"),
376
376
  args: [
377
377
  "run",
378
378
  e,
@@ -383,7 +383,7 @@ var Se = {
383
383
  }),
384
384
  env: () => ({}),
385
385
  clearCaches: async (e) => {
386
- await M(e), await l(o(e.rootDir, ".turbo"), {
386
+ await k(e), await l(o(e.rootDir, ".turbo"), {
387
387
  recursive: !0,
388
388
  force: !0
389
389
  }), await l(o(e.rootDir, "node_modules", ".cache", "turbo"), {
@@ -392,39 +392,39 @@ var Se = {
392
392
  });
393
393
  },
394
394
  stopDaemon: async (e) => {
395
- await f(j(e.rootDir, "turbo"), ["daemon", "stop"], {
395
+ await f(O(e.rootDir, "turbo"), ["daemon", "stop"], {
396
396
  cwd: e.rootDir,
397
397
  reject: !1,
398
398
  stdio: "ignore"
399
399
  });
400
400
  }
401
401
  },
402
- nx: he,
403
- moon: fe
402
+ nx: me,
403
+ moon: de
404
404
  };
405
- function P(e) {
406
- return Se[e];
405
+ function M(e) {
406
+ return xe[e];
407
407
  }
408
- function F(e) {
409
- return e.map(P);
408
+ function N(e) {
409
+ return e.map(M);
410
410
  }
411
- function I(e, t) {
411
+ function P(e, t) {
412
412
  if (!e.supportedVersions.some((e) => m(t, e, {
413
413
  includePrerelease: !0,
414
414
  loose: !0
415
415
  }))) throw Error(`${e.tool} version "${t}" is not supported by task-bench (supported: ${e.supportedVersions.join(" || ")}). Adjust versions.${e.tool} in your config or upgrade/downgrade the tool.`);
416
416
  }
417
- async function L(e, t, n = e.tools) {
417
+ async function F(e, t, n = e.tools) {
418
418
  let r = /* @__PURE__ */ new Map();
419
419
  for (let i of n) {
420
- let n = P(i), a = n.pinnedVersion(e);
421
- a === null && n.detectVersion && (a = await n.detectVersion(t)), a !== null && I(n, a), r.set(i, a);
420
+ let n = M(i), a = n.pinnedVersion(e);
421
+ a === null && n.detectVersion && (a = await n.detectVersion(t)), a !== null && P(n, a), r.set(i, a);
422
422
  }
423
423
  return r;
424
424
  }
425
425
  //#endregion
426
426
  //#region src/bench/stats.ts
427
- function R(e) {
427
+ function I(e) {
428
428
  if (e.length === 0) return {
429
429
  samples: e,
430
430
  min: 0,
@@ -443,17 +443,17 @@ function R(e) {
443
443
  stddev: Math.sqrt(a)
444
444
  };
445
445
  }
446
- function z(e) {
446
+ function L(e) {
447
447
  return e >= 1e3 ? `${(e / 1e3).toFixed(2)}s` : `${e.toFixed(0)}ms`;
448
448
  }
449
449
  //#endregion
450
450
  //#region src/bench/index.ts
451
- function Ce(e) {
451
+ function Se(e) {
452
452
  if (e.length === 0) return 0;
453
453
  let t = [...e].sort((e, t) => e - t), n = Math.floor(t.length / 2);
454
454
  return t.length % 2 == 0 ? ((t[n - 1] ?? 0) + (t[n] ?? 0)) / 2 : t[n] ?? 0;
455
455
  }
456
- function we(e) {
456
+ function Ce(e) {
457
457
  try {
458
458
  let n = t(e, "utf8");
459
459
  if (n.length === 0) return 0;
@@ -464,7 +464,7 @@ function we(e) {
464
464
  return 0;
465
465
  }
466
466
  }
467
- async function B(e, t, r, i, a) {
467
+ async function R(e, t, r, i, a) {
468
468
  n(i, "");
469
469
  let o = d.now(), s = await f(e, t, {
470
470
  cwd: r,
@@ -477,31 +477,30 @@ async function B(e, t, r, i, a) {
477
477
  TASK_BENCH_EXEC_LOG: i,
478
478
  ...a
479
479
  }
480
- }), c = d.now() - o, l = typeof s.stdout == "string" ? s.stdout : "", u = typeof s.stderr == "string" ? s.stderr : "";
480
+ }), c = d.now() - o, l = typeof s.stdout == "string" ? s.stdout : "";
481
481
  return {
482
482
  durationMs: c,
483
483
  exitCode: s.exitCode ?? -1,
484
- stdout: l,
485
- stderr: u,
486
- executed: we(i),
484
+ stdoutBytes: Buffer.byteLength(l),
485
+ executed: Ce(i),
487
486
  ok: s.exitCode === 0
488
487
  };
489
488
  }
490
- function V(e) {
489
+ function z(e) {
491
490
  return {
492
491
  runs: e.length,
493
492
  failures: e.filter((e) => !e.ok).length,
494
- stats: R(e.map((e) => e.durationMs)),
495
- executedMedian: Ce(e.map((e) => e.executed))
493
+ stats: I(e.map((e) => e.durationMs)),
494
+ executedMedian: Se(e.map((e) => e.executed))
496
495
  };
497
496
  }
498
- async function H(e, t = {}) {
499
- let n = JSON.parse(await c(o(e, "bench.config.json"), "utf8")), a = E.parse(n), s = k(a), l = A(a), u = t.tools ?? a.tools, d = t.task ?? l[l.length - 1] ?? "t0", f = t.coldRuns ?? 3, p = t.warmRuns ?? 5, m = t.concurrency ?? Math.max(1, r().length), h = t.daemon ?? !0, g = t.onEvent ?? (() => {}), _ = o(i(), `task-bench-exec-${process.pid}-${Date.now()}.log`), v = {
497
+ async function B(e, t = {}) {
498
+ let n = JSON.parse(await c(o(e, "bench.config.json"), "utf8")), a = C.parse(n), s = E(a), l = D(a), u = t.tools ?? a.tools, d = t.task ?? l[l.length - 1] ?? "t0", f = t.coldRuns ?? 3, p = t.warmRuns ?? 5, m = t.concurrency ?? Math.max(1, r().length), h = t.daemon ?? !0, g = t.onEvent ?? (() => {}), _ = o(i(), `task-bench-exec-${process.pid}-${Date.now()}.log`), v = {
500
499
  rootDir: e,
501
500
  projectDirs: s.map((e) => e.dir),
502
501
  concurrency: m,
503
502
  daemon: h
504
- }, y = await L(a, e, u), b = {};
503
+ }, y = await F(a, e, u), b = {};
505
504
  for (let [e, t] of y) b[e] = t;
506
505
  let x = [];
507
506
  for (let t of u) {
@@ -509,13 +508,13 @@ async function H(e, t = {}) {
509
508
  kind: "tool-start",
510
509
  tool: t
511
510
  });
512
- let n = P(t), r = n.run(d, v), i = n.env(v);
511
+ let n = M(t), r = n.run(d, v), i = n.env(v);
513
512
  try {
514
513
  !h && n.hasDaemon && await n.stopDaemon(v);
515
514
  let a = [];
516
515
  for (let o = 1; o <= f; o++) {
517
516
  await n.clearCaches(v), h && n.hasDaemon && await n.stopDaemon(v);
518
- let s = await B(r.file, r.args, e, _, i);
517
+ let s = await R(r.file, r.args, e, _, i);
519
518
  a.push(s), g({
520
519
  kind: "scenario",
521
520
  tool: t,
@@ -523,16 +522,12 @@ async function H(e, t = {}) {
523
522
  run: o,
524
523
  total: f,
525
524
  sample: s
526
- }), s.exitCode !== 0 && g({
527
- kind: "tool-unsuccessful",
528
- tool: t,
529
- sample: s
530
525
  });
531
526
  }
532
- await B(r.file, r.args, e, _, i);
527
+ await R(r.file, r.args, e, _, i);
533
528
  let o = [];
534
529
  for (let n = 1; n <= p; n++) {
535
- let a = await B(r.file, r.args, e, _, i);
530
+ let a = await R(r.file, r.args, e, _, i);
536
531
  o.push(a), g({
537
532
  kind: "scenario",
538
533
  tool: t,
@@ -540,10 +535,6 @@ async function H(e, t = {}) {
540
535
  run: n,
541
536
  total: p,
542
537
  sample: a
543
- }), a.exitCode !== 0 && g({
544
- kind: "tool-unsuccessful",
545
- tool: t,
546
- sample: a
547
538
  });
548
539
  }
549
540
  let s = Math.max(0, ...a.map((e) => e.executed), ...o.map((e) => e.executed));
@@ -551,8 +542,8 @@ async function H(e, t = {}) {
551
542
  tool: t,
552
543
  task: d,
553
544
  taskGraphSize: s,
554
- cold: V(a),
555
- warm: V(o)
545
+ cold: z(a),
546
+ warm: z(o)
556
547
  });
557
548
  } catch (e) {
558
549
  let n = e instanceof Error ? e.message : String(e);
@@ -564,8 +555,8 @@ async function H(e, t = {}) {
564
555
  tool: t,
565
556
  task: d,
566
557
  taskGraphSize: 0,
567
- cold: V([]),
568
- warm: V([]),
558
+ cold: z([]),
559
+ warm: z([]),
569
560
  error: n
570
561
  });
571
562
  } finally {
@@ -586,7 +577,7 @@ async function H(e, t = {}) {
586
577
  }
587
578
  //#endregion
588
579
  //#region src/bench/install.ts
589
- async function U(e, t = {}) {
580
+ async function V(e, t = {}) {
590
581
  await f("bun", ["install"], {
591
582
  cwd: e,
592
583
  stdio: t.quiet ? "ignore" : "inherit"
@@ -594,24 +585,24 @@ async function U(e, t = {}) {
594
585
  }
595
586
  //#endregion
596
587
  //#region src/bench/report.ts
597
- function Te(e, t) {
588
+ function we(e, t) {
598
589
  return e.length >= t ? e : e + " ".repeat(t - e.length);
599
590
  }
600
- function W(e, t) {
591
+ function H(e, t) {
601
592
  if (e.samples.length === 0) return "—";
602
- let n = `${z(e.median)} ±${z(e.stddev)}`;
593
+ let n = `${L(e.median)} ±${L(e.stddev)}`;
603
594
  return t > 0 ? `${n} ⚠${t}` : n;
604
595
  }
605
- function G(e) {
596
+ function U(e) {
606
597
  return e.taskGraphSize <= 0 || e.warm.stats.samples.length === 0 ? null : (e.taskGraphSize - e.warm.executedMedian) / e.taskGraphSize * 100;
607
598
  }
608
- function K(e) {
609
- let t = G(e);
599
+ function Te(e) {
600
+ let t = U(e);
610
601
  return t === null ? "—" : `${t.toFixed(0)}%`;
611
602
  }
612
- function Ee(e) {
603
+ function W(e) {
613
604
  let t = [], n = Math.max(0, ...e.tools.map((e) => e.taskGraphSize));
614
- t.push(""), t.push(`task-bench: ${e.projects} projects × ${e.tasksPerProject} tasks (${n} task-graph nodes), running "${e.task}" at concurrency ${e.concurrency} (daemons ${e.daemon ? "on" : "off"})`), t.push(De(e)), t.push("");
605
+ t.push(""), t.push(`task-bench: ${e.projects} projects × ${e.tasksPerProject} tasks (${n} task-graph nodes), running "${e.task}" at concurrency ${e.concurrency} (daemons ${e.daemon ? "on" : "off"})`), t.push(Ee(e)), t.push("");
615
606
  let r = [
616
607
  "tool",
617
608
  "cold (median)",
@@ -622,42 +613,42 @@ function Ee(e) {
622
613
  let t = e.error ? `error: ${(e.error.split("\n")[0] ?? "").slice(0, 40)}` : "";
623
614
  return [
624
615
  e.tool,
625
- W(e.cold.stats, e.cold.failures),
626
- W(e.warm.stats, e.warm.failures),
627
- K(e),
616
+ H(e.cold.stats, e.cold.failures),
617
+ H(e.warm.stats, e.warm.failures),
618
+ Te(e),
628
619
  t
629
620
  ];
630
- }), a = r.map((e, t) => Math.max(e.length, ...i.map((e) => (e[t] ?? "").length))), o = (e) => `| ${e.map((e, t) => Te(e, a[t] ?? 0)).join(" | ")} |`;
621
+ }), a = r.map((e, t) => Math.max(e.length, ...i.map((e) => (e[t] ?? "").length))), o = (e) => `| ${e.map((e, t) => we(e, a[t] ?? 0)).join(" | ")} |`;
631
622
  t.push(o(r)), t.push(`| ${a.map((e) => "-".repeat(e)).join(" | ")} |`);
632
623
  for (let e of i) t.push(o(e));
633
624
  t.push("");
634
625
  let s = e.tools.filter((e) => {
635
- let t = G(e);
626
+ let t = U(e);
636
627
  return t !== null && t < 99.5;
637
628
  });
638
- for (let e of s) t.push(`⚠ ${e.tool}: warm runs were not fully cached (${K(e)} hit, ${e.warm.executedMedian}/${e.taskGraphSize} tasks re-ran) — treat its warm number with caution.`);
629
+ for (let e of s) t.push(`⚠ ${e.tool}: warm runs were not fully cached (${Te(e)} hit, ${e.warm.executedMedian}/${e.taskGraphSize} tasks re-ran) — treat its warm number with caution.`);
639
630
  s.length && t.push("");
640
631
  let c = e.tools.filter((e) => {
641
- let t = G(e);
632
+ let t = U(e);
642
633
  return !e.error && t !== null && t >= 99.5;
643
634
  }).sort((e, t) => e.warm.stats.median - t.warm.stats.median), l = c[0], u = c[c.length - 1];
644
635
  if (c.length > 1 && l && u) {
645
636
  let e = u.warm.stats.median / l.warm.stats.median;
646
- t.push(`Warm-cache overhead: ${l.tool} is fastest (${z(l.warm.stats.median)}), ${e.toFixed(2)}× faster than ${u.tool} (${z(u.warm.stats.median)}).\n`);
637
+ t.push(`Warm-cache overhead: ${l.tool} is fastest (${L(l.warm.stats.median)}), ${e.toFixed(2)}× faster than ${u.tool} (${L(u.warm.stats.median)}).\n`);
647
638
  }
648
639
  let d = e.tools.filter((e) => !e.error && e.cold.stats.samples.length > 0).sort((e, t) => e.cold.stats.median - t.cold.stats.median), f = d[0], p = d[d.length - 1];
649
640
  if (d.length > 1 && f && p) {
650
641
  let e = p.cold.stats.median / f.cold.stats.median;
651
- t.push(`Cold-run overhead: ${f.tool} is fastest (${z(f.cold.stats.median)}), ${e.toFixed(2)}× faster than ${p.tool} (${z(p.cold.stats.median)}).`);
642
+ t.push(`Cold-run overhead: ${f.tool} is fastest (${L(f.cold.stats.median)}), ${e.toFixed(2)}× faster than ${p.tool} (${L(p.cold.stats.median)}).`);
652
643
  }
653
644
  return (c.length > 1 || d.length > 1) && t.push(""), t.join("\n");
654
645
  }
655
- function De(e) {
646
+ function Ee(e) {
656
647
  return `versions: ${e.tools.map((t) => `\`${t.tool} ${e.versions[t.tool] ?? "?"}\``).join(", ")}`;
657
648
  }
658
649
  //#endregion
659
650
  //#region src/generate/templates.ts
660
- function Oe(e) {
651
+ function De(e) {
661
652
  return [
662
653
  `// Auto-generated source for ${e.name}.`,
663
654
  "// Edit the harness config, not this file.",
@@ -667,7 +658,7 @@ function Oe(e) {
667
658
  ""
668
659
  ].join("\n");
669
660
  }
670
- function ke(e, t) {
661
+ function Oe(e, t) {
671
662
  let { logLines: n, workIterations: r, outputFiles: i } = e.task;
672
663
  return `#!/usr/bin/env node
673
664
  import { createHash } from "node:crypto";
@@ -724,11 +715,11 @@ console.log(\`[\${PROJECT}] \${task}: complete (\${OUTPUT_FILES} output file(s))
724
715
  }
725
716
  //#endregion
726
717
  //#region src/generate/index.ts
727
- async function q(e, t, n, r) {
718
+ async function G(e, t, n, r) {
728
719
  let i = o(e, t);
729
720
  await s(a(i), { recursive: !0 }), await u(i, n), r.push(t);
730
721
  }
731
- function Ae(e, t) {
722
+ function ke(e, t) {
732
723
  let n = {};
733
724
  for (let r of t) Object.assign(n, r.devDependencies(e));
734
725
  return `${JSON.stringify({
@@ -739,9 +730,9 @@ function Ae(e, t) {
739
730
  ...Object.keys(n).length ? { devDependencies: n } : {}
740
731
  }, null, 2)}\n`;
741
732
  }
742
- function je(e, t, n) {
733
+ function Ae(e, t, n) {
743
734
  let r = {};
744
- for (let t of A(e)) r[t] = `node ./task.mjs ${t}`;
735
+ for (let t of D(e)) r[t] = `node ./task.mjs ${t}`;
745
736
  let i = {};
746
737
  for (let e of t.dependencies) {
747
738
  let t = n[e];
@@ -755,7 +746,7 @@ function je(e, t, n) {
755
746
  ...Object.keys(i).length ? { dependencies: i } : {}
756
747
  }, null, 2)}\n`;
757
748
  }
758
- function Me() {
749
+ function je() {
759
750
  return [
760
751
  "node_modules",
761
752
  "dist",
@@ -767,7 +758,7 @@ function Me() {
767
758
  ""
768
759
  ].join("\n");
769
760
  }
770
- function Ne(e) {
761
+ function Me(e) {
771
762
  return [
772
763
  "# task-bench harness",
773
764
  "",
@@ -783,7 +774,7 @@ function Ne(e) {
783
774
  ""
784
775
  ].join("\n");
785
776
  }
786
- async function Pe(e) {
777
+ async function Ne(e) {
787
778
  let t = {
788
779
  cwd: e,
789
780
  reject: !1,
@@ -799,19 +790,19 @@ async function Pe(e) {
799
790
  "generated benchmark workspace"
800
791
  ], t);
801
792
  }
802
- async function Fe(e, t) {
803
- let n = D(t), r = k(n), i = [], a = F(n.tools);
793
+ async function K(e, t) {
794
+ let n = w(t), r = E(n), i = [], a = N(n.tools);
804
795
  await l(e, {
805
796
  recursive: !0,
806
797
  force: !0
807
798
  }), await s(e, { recursive: !0 });
808
- let o = await L(n, e);
809
- await q(e, "package.json", Ae(n, a), i), await q(e, ".gitignore", Me(), i), await q(e, "README.md", Ne(n), i), await q(e, "bench.config.json", `${JSON.stringify(n, null, 2)}\n`, i);
799
+ let o = await F(n, e);
800
+ await G(e, "package.json", ke(n, a), i), await G(e, ".gitignore", je(), i), await G(e, "README.md", Me(n), i), await G(e, "bench.config.json", `${JSON.stringify(n, null, 2)}\n`, i);
810
801
  for (let t of r) {
811
802
  let a = t.dir;
812
- await q(e, `${a}/package.json`, je(n, t, r), i), await q(e, `${a}/src/index.js`, Oe(t), i), await q(e, `${a}/task.mjs`, ke(n, t), i);
803
+ await G(e, `${a}/package.json`, Ae(n, t, r), i), await G(e, `${a}/src/index.js`, De(t), i), await G(e, `${a}/task.mjs`, Oe(n, t), i);
813
804
  }
814
- let c = (t, n) => q(e, t, n, i);
805
+ let c = (t, n) => G(e, t, n, i);
815
806
  for (let t of a) await t.setup({
816
807
  rootDir: e,
817
808
  config: n,
@@ -819,7 +810,7 @@ async function Fe(e, t) {
819
810
  version: o.get(t.tool) ?? null,
820
811
  write: c
821
812
  });
822
- return await Pe(e), {
813
+ return await Ne(e), {
823
814
  rootDir: e,
824
815
  config: n,
825
816
  projects: r,
@@ -828,39 +819,39 @@ async function Fe(e, t) {
828
819
  }
829
820
  //#endregion
830
821
  //#region src/suite/preset.ts
831
- var J = p.object({
832
- tools: p.array(S).optional(),
822
+ var q = p.object({
823
+ tools: p.array(y).optional(),
833
824
  task: p.string().optional(),
834
825
  coldRuns: p.number().int().nonnegative().optional(),
835
826
  warmRuns: p.number().int().nonnegative().optional(),
836
827
  concurrency: p.number().int().positive().optional(),
837
828
  daemon: p.boolean().optional()
838
- }).default({}), Ie = p.record(p.string(), p.unknown()).default({}), Le = p.object({
829
+ }).default({}), J = p.record(p.string(), p.unknown()).default({}), Pe = p.object({
839
830
  name: p.string().regex(/^[a-zA-Z0-9._-]+$/, "scenario name must be filesystem-safe (letters, digits, . _ -)"),
840
831
  description: p.string().optional(),
841
- config: Ie,
842
- run: J
832
+ config: J,
833
+ run: q
843
834
  }), Y = p.object({
844
835
  name: p.string().default("task-bench suite"),
845
836
  description: p.string().optional(),
846
837
  defaults: p.object({
847
- config: Ie,
848
- run: J
838
+ config: J,
839
+ run: q
849
840
  }).prefault({}),
850
- scenarios: p.array(Le).min(1)
841
+ scenarios: p.array(Pe).min(1)
851
842
  });
852
- function Re(e) {
843
+ function Fe(e) {
853
844
  return typeof e == "object" && !!e && !Array.isArray(e);
854
845
  }
855
846
  function X(e, t) {
856
847
  let n = { ...e };
857
848
  for (let [e, r] of Object.entries(t)) {
858
849
  let t = n[e];
859
- n[e] = Re(t) && Re(r) ? X(t, r) : r;
850
+ n[e] = Fe(t) && Fe(r) ? X(t, r) : r;
860
851
  }
861
852
  return n;
862
853
  }
863
- function ze(e, t) {
854
+ function Ie(e, t) {
864
855
  let n = X(e.defaults.config, t.config), r = {
865
856
  ...e.defaults.run,
866
857
  ...t.run
@@ -868,7 +859,7 @@ function ze(e, t) {
868
859
  return {
869
860
  name: t.name,
870
861
  description: t.description,
871
- config: D(n),
862
+ config: w(n),
872
863
  run: r
873
864
  };
874
865
  }
@@ -1040,25 +1031,25 @@ var Z = [
1040
1031
  ]
1041
1032
  }
1042
1033
  };
1043
- function Be() {
1034
+ function Le() {
1044
1035
  return Object.keys(Q);
1045
1036
  }
1046
- function Ve(e) {
1037
+ function Re(e) {
1047
1038
  let t = Q[e];
1048
- if (!t) throw Error(`unknown preset "${e}" (available: ${Be().join(", ")})`);
1039
+ if (!t) throw Error(`unknown preset "${e}" (available: ${Le().join(", ")})`);
1049
1040
  return Y.parse(t);
1050
1041
  }
1051
- function He(e) {
1042
+ function ze(e) {
1052
1043
  return Y.parse(e);
1053
1044
  }
1054
1045
  //#endregion
1055
1046
  //#region src/suite/index.ts
1056
- async function Ue(e, t) {
1047
+ async function Be(e, t) {
1057
1048
  let n = t.onEvent ?? (() => {}), r = [], i = e.scenarios.length;
1058
1049
  for (let a = 0; a < i; a++) {
1059
1050
  let s = e.scenarios[a];
1060
1051
  if (!s) continue;
1061
- let c = ze(e, s), { config: u, run: d } = c, f = t.overrides?.tools ?? d.tools ?? u.tools;
1052
+ let c = Ie(e, s), { config: u, run: d } = c, f = t.overrides?.tools ?? d.tools ?? u.tools;
1062
1053
  u.tools = f;
1063
1054
  let p = o(t.workdir, c.name);
1064
1055
  n({
@@ -1066,8 +1057,8 @@ async function Ue(e, t) {
1066
1057
  name: c.name,
1067
1058
  index: a,
1068
1059
  total: i
1069
- }), await Fe(p, u), t.install !== !1 && await U(p, { quiet: !0 });
1070
- let m = await H(p, {
1060
+ }), await K(p, u), t.install !== !1 && await V(p, { quiet: !0 });
1061
+ let m = await B(p, {
1071
1062
  tools: f,
1072
1063
  task: t.overrides?.task ?? d.task,
1073
1064
  coldRuns: t.overrides?.coldRuns ?? d.coldRuns,
@@ -1100,29 +1091,28 @@ async function Ue(e, t) {
1100
1091
  name: e.name,
1101
1092
  description: e.description,
1102
1093
  generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
1103
- scenarios: r,
1104
- taskBenchVersion: v
1094
+ scenarios: r
1105
1095
  };
1106
1096
  }
1107
1097
  //#endregion
1108
1098
  //#region src/suite/report.ts
1109
- function We(e) {
1099
+ function Ve(e) {
1110
1100
  let t = /* @__PURE__ */ new Set();
1111
1101
  for (let n of e.scenarios) for (let e of n.result.tools) t.add(e.tool);
1112
- return x.filter((e) => t.has(e));
1102
+ return v.filter((e) => t.has(e));
1113
1103
  }
1114
- function Ge(e, t) {
1104
+ function He(e, t) {
1115
1105
  return `Tool versions:\n\n${t.map((t) => `\`${t} ${e.scenarios.map((e) => e.result.versions[t]).find((e) => e != null) ?? "?"}\``).join("\n\n")}`;
1116
1106
  }
1117
- function Ke(e, t) {
1107
+ function Ue(e, t) {
1118
1108
  let n = e.result.tools.find((e) => e.tool === t);
1119
1109
  if (!n || n.error) return n?.error ? "err" : "—";
1120
- let r = n.taskGraphSize > 0 ? (n.taskGraphSize - n.warm.executedMedian) / n.taskGraphSize : 1, i = z(n.warm.stats.median);
1110
+ let r = n.taskGraphSize > 0 ? (n.taskGraphSize - n.warm.executedMedian) / n.taskGraphSize : 1, i = L(n.warm.stats.median);
1121
1111
  return r < .995 ? `${i}⚠` : i;
1122
1112
  }
1123
- function qe(e, t) {
1113
+ function We(e, t) {
1124
1114
  let n = e.result.tools.find((e) => e.tool === t);
1125
- return !n || n.error ? n?.error ? "err" : "—" : z(n.cold.stats.median);
1115
+ return !n || n.error ? n?.error ? "err" : "—" : L(n.cold.stats.median);
1126
1116
  }
1127
1117
  function $(e, t) {
1128
1118
  let n = e.map((e, n) => Math.max(e.length, ...t.map((e) => (e[n] ?? "").length))), r = (e, t) => e.padEnd(t), i = (e) => `| ${e.map((e, t) => r(e, n[t] ?? 0)).join(" | ")} |`;
@@ -1132,9 +1122,9 @@ function $(e, t) {
1132
1122
  ...t.map(i)
1133
1123
  ];
1134
1124
  }
1135
- function Je(e) {
1136
- let t = We(e), n = [];
1137
- n.push(`# ${e.name}`), n.push(""), n.push(`TaskBench v${e.taskBenchVersion}`), n.push(""), e.description && (n.push(e.description), n.push("")), n.push(`Generated ${e.generatedAt} · ${e.scenarios.length} scenario(s).`), n.push(""), n.push(Ge(e, t)), n.push(""), n.push("`warm` = median wall time with a verified 100% cache hit (discovery + cache-restore overhead). `⚠` marks a scenario whose warm runs were not fully cached. Absolute times are hardware-dependent — read the ratios."), n.push(""), n.push("## Summary — warm median"), n.push(""), n.push(...$([
1125
+ function Ge(e) {
1126
+ let t = Ve(e), n = [];
1127
+ n.push(`# ${e.name}`), n.push(""), e.description && (n.push(e.description), n.push("")), n.push(`Generated ${e.generatedAt} · ${e.scenarios.length} scenario(s).`), n.push(""), n.push(He(e, t)), n.push(""), n.push("`warm` = median wall time with a verified 100% cache hit (discovery + cache-restore overhead). `⚠` marks a scenario whose warm runs were not fully cached. Absolute times are hardware-dependent — read the ratios."), n.push(""), n.push("## Summary — warm median"), n.push(""), n.push(...$([
1138
1128
  "scenario",
1139
1129
  "nodes",
1140
1130
  "conc",
@@ -1145,7 +1135,7 @@ function Je(e) {
1145
1135
  String(e.result.tools[0]?.taskGraphSize ?? 0),
1146
1136
  String(e.result.concurrency),
1147
1137
  e.result.daemon ? "on" : "off",
1148
- ...t.map((t) => Ke(e, t))
1138
+ ...t.map((t) => Ue(e, t))
1149
1139
  ]))), n.push(""), n.push("## Summary — cold median"), n.push(""), n.push(...$([
1150
1140
  "scenario",
1151
1141
  "nodes",
@@ -1155,13 +1145,13 @@ function Je(e) {
1155
1145
  e.name,
1156
1146
  String(e.result.tools[0]?.taskGraphSize ?? 0),
1157
1147
  String(e.result.concurrency),
1158
- ...t.map((t) => qe(e, t))
1148
+ ...t.map((t) => We(e, t))
1159
1149
  ]))), n.push(""), n.push("## Details"), n.push("");
1160
1150
  for (let t of e.scenarios) {
1161
1151
  let e = t.description ? `${t.name} — ${t.description}` : t.name;
1162
- n.push(`### ${e}`), n.push(`Config: ${t.config.projects} projects × ${t.config.tasksPerProject} tasks, strategy \`${t.config.dependency.strategy}\`.`), n.push(Ee(t.result).trimEnd()), n.push("");
1152
+ n.push(`### ${e}`), n.push(`Config: ${t.config.projects} projects × ${t.config.tasksPerProject} tasks, strategy \`${t.config.dependency.strategy}\`.`), n.push(W(t.result).trimEnd()), n.push("");
1163
1153
  }
1164
1154
  return n.join("\n");
1165
1155
  }
1166
1156
  //#endregion
1167
- export { w as A, O as C, b as D, C as E, g as F, v as I, T as M, D as N, E as O, _ as P, k as S, y as T, z as _, Le as a, F as b, Ve as c, ze as d, Fe as f, R as g, H as h, J as i, S as j, x as k, Be as l, U as m, Ue as n, Y as o, Ee as p, Q as r, X as s, Je as t, He as u, I as v, A as w, L as x, P as y };
1157
+ export { x as A, T as C, _ as D, b as E, S as M, w as N, C as O, E as S, g as T, L as _, Pe as a, N as b, Re as c, Ie as d, K as f, I as g, B as h, q as i, y as j, v as k, Le as l, V as m, Be as n, Y as o, W as p, Q as r, X as s, Ge as t, ze as u, P as v, D as w, F as x, M as y };
@@ -13,7 +13,6 @@ export interface SuiteResult {
13
13
  description?: string | undefined;
14
14
  generatedAt: string;
15
15
  scenarios: SuiteScenarioResult[];
16
- taskBenchVersion: string;
17
16
  }
18
17
  export type SuiteEvent = {
19
18
  kind: "scenario-start";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/suite/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,UAAU,EAAE,KAAK,eAAe,EAAgB,MAAM,UAAU,CAAC;AAE/E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAE/C,OAAO,EAAE,KAAK,UAAU,EAAmB,KAAK,WAAW,EAAE,MAAM,UAAU,CAAC;AAE9E,MAAM,WAAW,mBAAmB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACjC,MAAM,EAAE,aAAa,CAAC;IACtB,GAAG,EAAE,UAAU,CAAC;IAChB,MAAM,EAAE,eAAe,CAAC;CAC3B;AAED,MAAM,WAAW,WAAW;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACjC,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,mBAAmB,EAAE,CAAC;IACjC,gBAAgB,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,MAAM,UAAU,GAChB;IAAE,IAAI,EAAE,gBAAgB,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GACtE;IAAE,IAAI,EAAE,eAAe,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GACrE;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,UAAU,CAAA;CAAE,CAAC;AAEzD,MAAM,WAAW,eAAe;IAC5B,uEAAuE;IACvE,OAAO,EAAE,MAAM,CAAC;IAChB,oEAAoE;IACpE,OAAO,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAC9B,kFAAkF;IAClF,IAAI,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAC3B,6DAA6D;IAC7D,SAAS,CAAC,EAAE,OAAO,CAAC,UAAU,CAAC,GAAG,SAAS,CAAC;IAC5C,OAAO,CAAC,EAAE,CAAC,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;CACvD;AAED;;;GAGG;AACH,wBAAsB,QAAQ,CAC1B,KAAK,EAAE,WAAW,EAClB,OAAO,EAAE,eAAe,GACzB,OAAO,CAAC,WAAW,CAAC,CA+DtB"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/suite/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,UAAU,EAAE,KAAK,eAAe,EAAgB,MAAM,UAAU,CAAC;AAE/E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAE/C,OAAO,EAAE,KAAK,UAAU,EAAmB,KAAK,WAAW,EAAE,MAAM,UAAU,CAAC;AAE9E,MAAM,WAAW,mBAAmB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACjC,MAAM,EAAE,aAAa,CAAC;IACtB,GAAG,EAAE,UAAU,CAAC;IAChB,MAAM,EAAE,eAAe,CAAC;CAC3B;AAED,MAAM,WAAW,WAAW;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACjC,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,mBAAmB,EAAE,CAAC;CACpC;AAED,MAAM,MAAM,UAAU,GAChB;IAAE,IAAI,EAAE,gBAAgB,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GACtE;IAAE,IAAI,EAAE,eAAe,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GACrE;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,UAAU,CAAA;CAAE,CAAC;AAEzD,MAAM,WAAW,eAAe;IAC5B,uEAAuE;IACvE,OAAO,EAAE,MAAM,CAAC;IAChB,oEAAoE;IACpE,OAAO,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAC9B,kFAAkF;IAClF,IAAI,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAC3B,6DAA6D;IAC7D,SAAS,CAAC,EAAE,OAAO,CAAC,UAAU,CAAC,GAAG,SAAS,CAAC;IAC5C,OAAO,CAAC,EAAE,CAAC,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;CACvD;AAED;;;GAGG;AACH,wBAAsB,QAAQ,CAC1B,KAAK,EAAE,WAAW,EAClB,OAAO,EAAE,eAAe,GACzB,OAAO,CAAC,WAAW,CAAC,CA8DtB"}
@@ -1 +1 @@
1
- {"version":3,"file":"report.d.ts","sourceRoot":"","sources":["../../src/suite/report.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAuB,MAAM,SAAS,CAAC;AAqDhE;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,WAAW,GAAG,MAAM,CA0E9D"}
1
+ {"version":3,"file":"report.d.ts","sourceRoot":"","sources":["../../src/suite/report.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAuB,MAAM,SAAS,CAAC;AAqDhE;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,WAAW,GAAG,MAAM,CAwE9D"}
@@ -1,12 +1,12 @@
1
1
  #!/usr/bin/env node
2
- import { F as e, I as t, N as n, P as r, T as i, _ as a, c as o, f as s, h as c, k as l, l as u, m as d, n as f, p, t as m, u as h } from "./src-D3XyMXAu.mjs";
3
- import { readFileSync as g, writeFileSync as _ } from "node:fs";
4
- import { tmpdir as v } from "node:os";
5
- import { join as y, resolve as b } from "node:path";
6
- import { Command as x, Option as S } from "@commander-js/extra-typings";
7
- //#region src/cli/index.ts
8
- var C = new x();
9
- C.name(e).version(t).description(r);
2
+ import { N as e, T as t, _ as n, c as r, f as i, h as a, k as o, l as s, m as c, n as l, p as u, t as d, u as f } from "./src-DOsUAz2Z.mjs";
3
+ import { readFileSync as p, writeFileSync as m } from "node:fs";
4
+ import { tmpdir as h } from "node:os";
5
+ import { join as g, resolve as _ } from "node:path";
6
+ import { Command as v, Option as y } from "@commander-js/extra-typings";
7
+ //#region package.json
8
+ var b = "@omni-oss/task-bench", x = "Generate configurable test workspaces and benchmark omni/turbo/nx task execution performance", S = "0.0.0", C = new v();
9
+ C.name(b).version(S).description(x);
10
10
  var w = (e) => {
11
11
  let t = Number.parseInt(e, 10);
12
12
  if (Number.isNaN(t)) throw Error(`expected an integer, got "${e}"`);
@@ -17,11 +17,11 @@ var w = (e) => {
17
17
  return t;
18
18
  }, E = (e) => e.split(",").map((e) => {
19
19
  let t = e.trim();
20
- if (!l.includes(t)) throw Error(`unknown tool "${t}" (allowed: ${l.join(", ")})`);
20
+ if (!o.includes(t)) throw Error(`unknown tool "${t}" (allowed: ${o.join(", ")})`);
21
21
  return t;
22
22
  });
23
23
  function D(e) {
24
- let t = e.config ? JSON.parse(g(e.config, "utf8")) : {}, n = { ...t };
24
+ let t = e.config ? JSON.parse(p(e.config, "utf8")) : {}, n = { ...t };
25
25
  e.seed !== void 0 && (n.seed = e.seed), e.projects !== void 0 && (n.projects = e.projects), e.tasks !== void 0 && (n.tasksPerProject = e.tasks), e.tools !== void 0 && (n.tools = e.tools);
26
26
  let r = { ...t.dependency ?? {} };
27
27
  e.strategy !== void 0 && (r.strategy = e.strategy), e.layers !== void 0 && (r.layers = e.layers), e.fanout !== void 0 && (r.fanout = e.fanout), e.edgeProbability !== void 0 && (r.edgeProbability = e.edgeProbability), Object.keys(r).length && (n.dependency = r);
@@ -31,27 +31,26 @@ function D(e) {
31
31
  return e.turboVersion !== void 0 && (a.turbo = e.turboVersion), e.nxVersion !== void 0 && (a.nx = e.nxVersion), e.moonVersion !== void 0 && (a.moon = e.moonVersion), e.bunVersion !== void 0 && (a.bun = e.bunVersion), Object.keys(a).length && (n.versions = a), n;
32
32
  }
33
33
  function O(e) {
34
- return e.option("--config <file>", "Base config JSON file to extend.").option("--seed <n>", "Deterministic graph seed.", w).option("--projects <n>", "Number of projects.", w).option("--tasks <n>", "Tasks per project.", w).addOption(new S("--strategy <name>", "Dependency graph strategy.").choices(i)).option("--layers <n>", "Layers for the `layered` strategy.", w).option("--fanout <n>", "Max upstream deps per project.", w).option("--edge-probability <p>", "Edge probability for `random`.", T).option("--log-lines <n>", "Log lines printed per task.", w).option("--work <n>", "CPU work iterations per task.", w).option("--output-files <n>", "Output files per task.", w).option("--tools <list>", "Comma-separated tools (omni,turbo,nx,moon).", E).option("--turbo-version <semver>", "Turbo version to install.").option("--nx-version <semver>", "Nx version to install.").option("--moon-version <semver>", "moon (@moonrepo/cli) version to install.").option("--bun-version <semver>", "bun version for packageManager.").option("--no-chain", "Disable intra-project task chaining.").option("--no-fan-upstream", "Disable upstream (^) task dependencies.");
34
+ return e.option("--config <file>", "Base config JSON file to extend.").option("--seed <n>", "Deterministic graph seed.", w).option("--projects <n>", "Number of projects.", w).option("--tasks <n>", "Tasks per project.", w).addOption(new y("--strategy <name>", "Dependency graph strategy.").choices(t)).option("--layers <n>", "Layers for the `layered` strategy.", w).option("--fanout <n>", "Max upstream deps per project.", w).option("--edge-probability <p>", "Edge probability for `random`.", T).option("--log-lines <n>", "Log lines printed per task.", w).option("--work <n>", "CPU work iterations per task.", w).option("--output-files <n>", "Output files per task.", w).option("--tools <list>", "Comma-separated tools (omni,turbo,nx,moon).", E).option("--turbo-version <semver>", "Turbo version to install.").option("--nx-version <semver>", "Nx version to install.").option("--moon-version <semver>", "moon (@moonrepo/cli) version to install.").option("--bun-version <semver>", "bun version for packageManager.").option("--no-chain", "Disable intra-project task chaining.").option("--no-fan-upstream", "Disable upstream (^) task dependencies.");
35
35
  }
36
36
  function k() {
37
37
  return (e) => {
38
38
  if (e.kind === "tool-start") process.stderr.write(`\n▶ ${e.tool}\n`);
39
39
  else if (e.kind === "tool-error") process.stderr.write(` ✖ ${e.tool}: ${e.error}\n`);
40
- else if (e.kind === "tool-unsuccessful") process.stderr.write(` ✖ ${e.tool}: exit ${e.sample.exitCode}\n`), e.sample.stdout && process.stderr.write(` === stdout ===\n${e.sample.stdout}\n`), e.sample.stderr && process.stderr.write(` === stderr ===\n${e.sample.stderr}\n`);
41
40
  else {
42
41
  let t = e.sample.ok ? "ok" : `exit ${e.sample.exitCode}`;
43
- process.stderr.write(` ${e.scenario} ${e.run}/${e.total}: ${a(e.sample.durationMs)} (ran ${e.sample.executed} tasks, ${t})\n`);
42
+ process.stderr.write(` ${e.scenario} ${e.run}/${e.total}: ${n(e.sample.durationMs)} (ran ${e.sample.executed} tasks, ${t})\n`);
44
43
  }
45
44
  };
46
45
  }
47
46
  function A(e, t) {
48
- e && (_(e, `${JSON.stringify(t, null, 2)}\n`), process.stderr.write(`\nWrote results to ${e}\n`));
47
+ e && (m(e, `${JSON.stringify(t, null, 2)}\n`), process.stderr.write(`\nWrote results to ${e}\n`));
49
48
  }
50
49
  O(C.command("generate").alias("gen").description("Generate a benchmark workspace at the given root dir.").requiredOption("-o, --out <dir>", "Root dir to generate the workspace into.")).action(async (e) => {
51
- let t = b(e.out), n = await s(t, D(e));
50
+ let t = _(e.out), n = await i(t, D(e));
52
51
  process.stderr.write(`Generated ${n.projects.length} projects (${n.files.length} files) at ${t}\nTools: ${n.config.tools.join(", ")}\n`);
53
52
  }), C.command("run").description("Benchmark an already-generated workspace.").requiredOption("-d, --dir <dir>", "Root dir of a generated workspace.").option("--tools <list>", "Comma-separated tools to benchmark.", E).option("--task <name>", "Task to run (defaults to the last task).").option("--cold-runs <n>", "Cold (uncached) runs per tool.", w, 3).option("--warm-runs <n>", "Warm (cached) runs per tool.", w, 5).option("--concurrency <n>", "Max parallel tasks, applied identically to all tools (default: CPU count).", w).option("--no-daemon", "Disable each tool's persistent daemon (turbo, nx).").option("--json <file>", "Write full results as JSON to this file.").action(async (e) => {
54
- let t = await c(b(e.dir), {
53
+ let t = await a(_(e.dir), {
55
54
  tools: e.tools,
56
55
  task: e.task,
57
56
  concurrency: e.concurrency,
@@ -60,11 +59,11 @@ O(C.command("generate").alias("gen").description("Generate a benchmark workspace
60
59
  warmRuns: e.warmRuns,
61
60
  onEvent: k()
62
61
  });
63
- process.stdout.write(p(t)), A(e.json, t);
62
+ process.stdout.write(u(t)), A(e.json, t);
64
63
  }), O(C.command("bench").description("Generate, install, and benchmark in one step.").requiredOption("-o, --out <dir>", "Root dir to generate the workspace into.").option("--no-install", "Skip `bun install` in the generated workspace.").option("--task <name>", "Task to run (defaults to the last task).").option("--cold-runs <n>", "Cold (uncached) runs per tool.", w, 3).option("--warm-runs <n>", "Warm (cached) runs per tool.", w, 5).option("--concurrency <n>", "Max parallel tasks, applied identically to all tools (default: CPU count).", w).option("--no-daemon", "Disable each tool's persistent daemon (turbo, nx).").option("--json <file>", "Write full results as JSON to this file.")).action(async (e) => {
65
- let t = b(e.out), n = await s(t, D(e));
66
- process.stderr.write(`Generated ${n.projects.length} projects at ${t}\n`), e.install !== !1 && (process.stderr.write("Installing dependencies (bun install)...\n"), await d(t));
67
- let r = await c(t, {
64
+ let t = _(e.out), n = await i(t, D(e));
65
+ process.stderr.write(`Generated ${n.projects.length} projects at ${t}\n`), e.install !== !1 && (process.stderr.write("Installing dependencies (bun install)...\n"), await c(t));
66
+ let r = await a(t, {
68
67
  task: e.task,
69
68
  coldRuns: e.coldRuns,
70
69
  warmRuns: e.warmRuns,
@@ -72,10 +71,10 @@ O(C.command("generate").alias("gen").description("Generate a benchmark workspace
72
71
  daemon: e.daemon,
73
72
  onEvent: k()
74
73
  });
75
- process.stdout.write(p(r)), A(e.json, r);
76
- }), O(C.command("inspect").description("Resolve a config and print the derived graph summary.")).action((e) => {
77
- let t = n(D(e));
78
- process.stdout.write(`${JSON.stringify(t, null, 2)}\n`);
74
+ process.stdout.write(u(r)), A(e.json, r);
75
+ }), O(C.command("inspect").description("Resolve a config and print the derived graph summary.")).action((t) => {
76
+ let n = e(D(t));
77
+ process.stdout.write(`${JSON.stringify(n, null, 2)}\n`);
79
78
  });
80
79
  function j() {
81
80
  let e = k();
@@ -85,23 +84,23 @@ function j() {
85
84
  }
86
85
  C.command("suite").description("Run a preset (or JSON file) of benchmark scenarios and summarize them.").option("-p, --preset <name>", "Built-in preset name.").option("-f, --file <path>", "Path to a JSON suite preset file.").option("-o, --out <dir>", "Working dir for generated workspaces.").option("--json <file>", "Write aggregated results as JSON to this file.").option("--md <file>", "Write a human-readable Markdown report to this file.").option("--tools <list>", "Override tools for every scenario.", E).option("--cold-runs <n>", "Override cold runs for every scenario.", w).option("--warm-runs <n>", "Override warm runs for every scenario.", w).option("--concurrency <n>", "Override concurrency for every scenario.", w).option("--no-install", "Skip `bun install` in generated workspaces.").option("--keep", "Keep generated workspaces instead of removing them.").option("--list", "List the built-in presets and exit.").action(async (e) => {
87
86
  if (e.list) {
88
- process.stdout.write(`Available presets:\n${u().map((e) => ` - ${e}`).join("\n")}\n`);
87
+ process.stdout.write(`Available presets:\n${s().map((e) => ` - ${e}`).join("\n")}\n`);
89
88
  return;
90
89
  }
91
- let t = e.file ? h(JSON.parse(g(e.file, "utf8"))) : o(e.preset ?? "quick"), n = b(e.out ?? y(v(), "task-bench-suite"));
90
+ let t = e.file ? f(JSON.parse(p(e.file, "utf8"))) : r(e.preset ?? "quick"), n = _(e.out ?? g(h(), "task-bench-suite"));
92
91
  process.stderr.write(`Running suite "${t.name}" (${t.scenarios.length} scenarios) in ${n}\n`);
93
- let r = {
92
+ let i = {
94
93
  ...e.tools ? { tools: e.tools } : {},
95
94
  ...e.coldRuns === void 0 ? {} : { coldRuns: e.coldRuns },
96
95
  ...e.warmRuns === void 0 ? {} : { warmRuns: e.warmRuns },
97
96
  ...e.concurrency === void 0 ? {} : { concurrency: e.concurrency }
98
- }, i = await f(t, {
97
+ }, a = await l(t, {
99
98
  workdir: n,
100
99
  install: e.install,
101
100
  keep: e.keep,
102
- overrides: r,
101
+ overrides: i,
103
102
  onEvent: j()
104
- }), a = m(i);
105
- process.stdout.write(`\n${a}\n`), e.md && (_(e.md, `${a}\n`), process.stderr.write(`\nWrote Markdown report to ${e.md}\n`)), e.json && (_(e.json, `${JSON.stringify(i, null, 2)}\n`), process.stderr.write(`Wrote JSON results to ${e.json}\n`));
103
+ }), o = d(a);
104
+ process.stdout.write(`\n${o}\n`), e.md && (m(e.md, `${o}\n`), process.stderr.write(`\nWrote Markdown report to ${e.md}\n`)), e.json && (m(e.json, `${JSON.stringify(a, null, 2)}\n`), process.stderr.write(`Wrote JSON results to ${e.json}\n`));
106
105
  }), C.parseAsync();
107
106
  //#endregion
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@omni-oss/task-bench",
3
3
  "description": "Generate configurable test workspaces and benchmark omni/turbo/nx task execution performance",
4
- "version": "0.0.0-beta.1",
4
+ "version": "0.0.0",
5
5
  "bin": "./dist/task-bench-cli.mjs",
6
6
  "publishConfig": {
7
7
  "access": "public"
@@ -12,8 +12,7 @@ import { computeStats, type Stats } from "./stats";
12
12
  export interface RunSample {
13
13
  durationMs: number;
14
14
  exitCode: number;
15
- stdout: string;
16
- stderr: string;
15
+ stdoutBytes: number;
17
16
  /** Number of tasks that actually executed (0 == a full cache hit). */
18
17
  executed: number;
19
18
  ok: boolean;
@@ -60,12 +59,7 @@ export type BenchEvent =
60
59
  total: number;
61
60
  sample: RunSample;
62
61
  }
63
- | { kind: "tool-error"; tool: Tool; error: string }
64
- | {
65
- kind: "tool-unsuccessful";
66
- tool: Tool;
67
- sample: RunSample;
68
- };
62
+ | { kind: "tool-error"; tool: Tool; error: string };
69
63
 
70
64
  export interface RunBenchmarkOptions {
71
65
  tools?: Tool[] | undefined;
@@ -124,15 +118,12 @@ async function timeRun(
124
118
  ...extraEnv,
125
119
  },
126
120
  });
127
-
128
121
  const durationMs = performance.now() - start;
129
122
  const stdout = typeof result.stdout === "string" ? result.stdout : "";
130
- const stderr = typeof result.stderr === "string" ? result.stderr : "";
131
123
  return {
132
124
  durationMs,
133
125
  exitCode: result.exitCode ?? -1,
134
- stdout,
135
- stderr,
126
+ stdoutBytes: Buffer.byteLength(stdout),
136
127
  executed: countLines(execLog),
137
128
  ok: result.exitCode === 0,
138
129
  };
@@ -233,13 +224,6 @@ export async function runBenchmark(
233
224
  total: coldRuns,
234
225
  sample,
235
226
  });
236
- if (sample.exitCode !== 0) {
237
- emit({
238
- kind: "tool-unsuccessful",
239
- tool,
240
- sample,
241
- });
242
- }
243
227
  }
244
228
 
245
229
  // Warm scenario: prime once (unmeasured, also warms the daemon),
@@ -269,13 +253,6 @@ export async function runBenchmark(
269
253
  total: warmRuns,
270
254
  sample,
271
255
  });
272
- if (sample.exitCode !== 0) {
273
- emit({
274
- kind: "tool-unsuccessful",
275
- tool,
276
- sample,
277
- });
278
- }
279
256
  }
280
257
 
281
258
  const taskGraphSize = Math.max(
package/src/cli/index.ts CHANGED
@@ -170,20 +170,6 @@ function progressHandler(): (event: BenchEvent) => void {
170
170
  process.stderr.write(`\n▶ ${event.tool}\n`);
171
171
  } else if (event.kind === "tool-error") {
172
172
  process.stderr.write(` ✖ ${event.tool}: ${event.error}\n`);
173
- } else if (event.kind === "tool-unsuccessful") {
174
- process.stderr.write(
175
- ` ✖ ${event.tool}: exit ${event.sample.exitCode}\n`,
176
- );
177
- if (event.sample.stdout) {
178
- process.stderr.write(
179
- ` === stdout ===\n${event.sample.stdout}\n`,
180
- );
181
- }
182
- if (event.sample.stderr) {
183
- process.stderr.write(
184
- ` === stderr ===\n${event.sample.stderr}\n`,
185
- );
186
- }
187
173
  } else {
188
174
  const status = event.sample.ok
189
175
  ? "ok"
@@ -1,6 +1,5 @@
1
1
  import { rm } from "node:fs/promises";
2
2
  import { join } from "node:path";
3
- import { version } from "../../package.json";
4
3
  import { type BenchEvent, type BenchmarkResult, runBenchmark } from "../bench";
5
4
  import { installWorkspace } from "../bench/install";
6
5
  import type { HarnessConfig } from "../config";
@@ -20,7 +19,6 @@ export interface SuiteResult {
20
19
  description?: string | undefined;
21
20
  generatedAt: string;
22
21
  scenarios: SuiteScenarioResult[];
23
- taskBenchVersion: string;
24
22
  }
25
23
 
26
24
  export type SuiteEvent =
@@ -108,6 +106,5 @@ export async function runSuite(
108
106
  description: suite.description,
109
107
  generatedAt: new Date().toISOString(),
110
108
  scenarios,
111
- taskBenchVersion: version,
112
109
  };
113
110
  }
@@ -64,8 +64,6 @@ export function formatSuiteMarkdown(suite: SuiteResult): string {
64
64
 
65
65
  lines.push(`# ${suite.name}`);
66
66
  lines.push("");
67
- lines.push(`TaskBench v${suite.taskBenchVersion}`);
68
- lines.push("");
69
67
  if (suite.description) {
70
68
  lines.push(suite.description);
71
69
  lines.push("");