@workflow/world-testing 5.0.0-beta.28 → 5.0.0-beta.29

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.
@@ -317,10 +317,10 @@ function mergeDefs2(...defs) {
317
317
  function cloneDef2(schema) {
318
318
  return mergeDefs2(schema._zod.def);
319
319
  }
320
- function getElementAtPath2(obj, path10) {
321
- if (!path10)
320
+ function getElementAtPath2(obj, path11) {
321
+ if (!path11)
322
322
  return obj;
323
- return path10.reduce((acc, key) => acc?.[key], obj);
323
+ return path11.reduce((acc, key) => acc?.[key], obj);
324
324
  }
325
325
  function promiseAllObject2(promisesObj) {
326
326
  const keys = Object.keys(promisesObj);
@@ -632,11 +632,11 @@ function aborted2(x, startIndex = 0) {
632
632
  }
633
633
  return false;
634
634
  }
635
- function prefixIssues2(path10, issues) {
635
+ function prefixIssues2(path11, issues) {
636
636
  return issues.map((iss) => {
637
637
  var _a3;
638
638
  (_a3 = iss).path ?? (_a3.path = []);
639
- iss.path.unshift(path10);
639
+ iss.path.unshift(path11);
640
640
  return iss;
641
641
  });
642
642
  }
@@ -935,7 +935,7 @@ function formatError2(error95, mapper = (issue3) => issue3.message) {
935
935
  }
936
936
  function treeifyError2(error95, mapper = (issue3) => issue3.message) {
937
937
  const result = { errors: [] };
938
- const processError = /* @__PURE__ */ __name((error96, path10 = []) => {
938
+ const processError = /* @__PURE__ */ __name((error96, path11 = []) => {
939
939
  var _a3, _b;
940
940
  for (const issue3 of error96.issues) {
941
941
  if (issue3.code === "invalid_union" && issue3.errors.length) {
@@ -945,7 +945,7 @@ function treeifyError2(error95, mapper = (issue3) => issue3.message) {
945
945
  } else if (issue3.code === "invalid_element") {
946
946
  processError({ issues: issue3.issues }, issue3.path);
947
947
  } else {
948
- const fullpath = [...path10, ...issue3.path];
948
+ const fullpath = [...path11, ...issue3.path];
949
949
  if (fullpath.length === 0) {
950
950
  result.errors.push(mapper(issue3));
951
951
  continue;
@@ -977,8 +977,8 @@ function treeifyError2(error95, mapper = (issue3) => issue3.message) {
977
977
  }
978
978
  function toDotPath2(_path) {
979
979
  const segs = [];
980
- const path10 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
981
- for (const seg of path10) {
980
+ const path11 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
981
+ for (const seg of path11) {
982
982
  if (typeof seg === "number")
983
983
  segs.push(`[${seg}]`);
984
984
  else if (typeof seg === "symbol")
@@ -14033,13 +14033,13 @@ function resolveRef2(ref, ctx) {
14033
14033
  if (!ref.startsWith("#")) {
14034
14034
  throw new Error("External $ref is not supported, only local refs (#/...) are allowed");
14035
14035
  }
14036
- const path10 = ref.slice(1).split("/").filter(Boolean);
14037
- if (path10.length === 0) {
14036
+ const path11 = ref.slice(1).split("/").filter(Boolean);
14037
+ if (path11.length === 0) {
14038
14038
  return ctx.rootSchema;
14039
14039
  }
14040
14040
  const defsKey = ctx.version === "draft-2020-12" ? "$defs" : "definitions";
14041
- if (path10[0] === defsKey) {
14042
- const key = path10[1];
14041
+ if (path11[0] === defsKey) {
14042
+ const key = path11[1];
14043
14043
  if (!key || !ctx.defs[key]) {
14044
14044
  throw new Error(`Reference not found: ${ref}`);
14045
14045
  }
@@ -14952,7 +14952,7 @@ function stripEventDataRefs(event, resolveData) {
14952
14952
  function isTerminalRunEventType(eventType) {
14953
14953
  return TERMINAL_RUN_EVENT_TYPES2.includes(eventType);
14954
14954
  }
14955
- var EVENT_DATA_REF_FIELDS, EventTypeSchema2, TerminalRunEventTypeSchema2, TERMINAL_RUN_EVENT_TYPES2, BaseEventSchema2, StepCompletedEventSchema2, StepFailedEventSchema2, StepRetryingEventSchema2, StepStartedEventSchema2, StepCreatedEventSchema2, HookCreatedEventSchema2, HookReceivedEventSchema2, HookDisposedEventSchema2, HookConflictEventSchema2, WaitCreatedEventSchema2, WaitCompletedEventSchema2, AttributeWriterSchema2, AttrSetEventSchema2, RunCreatedEventSchema2, RunStartedEventSchema2, RunCompletedEventSchema2, RunFailedEventSchema2, RunCancelledEventSchema2, CreateEventSchema2, AllEventsSchema2, EventSchema2;
14955
+ var EVENT_DATA_REF_FIELDS, EventTypeSchema2, TerminalRunEventTypeSchema2, TERMINAL_RUN_EVENT_TYPES2, BaseEventSchema2, stepLatencyTelemetryFields2, StepCompletedEventSchema2, StepFailedEventSchema2, StepRetryingEventSchema2, StepStartedEventSchema2, StepCreatedEventSchema2, HookCreatedEventSchema2, HookReceivedEventSchema2, HookDisposedEventSchema2, HookConflictEventSchema2, WaitCreatedEventSchema2, WaitCompletedEventSchema2, AttributeWriterSchema2, AttrSetEventSchema2, RunCreatedEventSchema2, RunStartedEventSchema2, RunCompletedEventSchema2, RunFailedEventSchema2, RunCancelledEventSchema2, CreateEventSchema2, AllEventsSchema2, EventSchema2;
14956
14956
  var init_events2 = __esm({
14957
14957
  "../world/dist/events.js"() {
14958
14958
  "use strict";
@@ -15008,6 +15008,22 @@ var init_events2 = __esm({
15008
15008
  correlationId: external_exports2.string().optional(),
15009
15009
  specVersion: external_exports2.number().optional()
15010
15010
  });
15011
+ stepLatencyTelemetryFields2 = {
15012
+ // Time-to-first-step: milliseconds from run creation until the run's first
15013
+ // step body began executing, minus time spent committing hook_created
15014
+ // events. Only reported when nothing else (hooks received, waits,
15015
+ // attributes, other steps) happened before the first step.
15016
+ ttfs: external_exports2.number().optional(),
15017
+ // Step-to-step overhead: milliseconds between the previous step's terminal
15018
+ // event and this step's body beginning to execute. Only reported when the
15019
+ // two steps ran back-to-back (the previous event-log entry is a
15020
+ // step_completed/step_failed).
15021
+ stso: external_exports2.number().optional(),
15022
+ // Names of the runtime's optional startup-latency optimizations that were
15023
+ // active for this measurement (e.g. 'turbo', 'lazyStepStart',
15024
+ // 'optimisticStart'), so latency metrics can be segmented by them.
15025
+ optimizations: external_exports2.array(external_exports2.string()).optional()
15026
+ };
15011
15027
  StepCompletedEventSchema2 = BaseEventSchema2.extend({
15012
15028
  eventType: external_exports2.literal("step_completed"),
15013
15029
  correlationId: external_exports2.string(),
@@ -15017,7 +15033,8 @@ var init_events2 = __esm({
15017
15033
  // the key without an extra run lookup on this hot per-step write.
15018
15034
  // Optional: older runtimes omit it and the backend falls back to a read.
15019
15035
  workflowName: external_exports2.string().optional(),
15020
- result: SerializedDataSchema2
15036
+ result: SerializedDataSchema2,
15037
+ ...stepLatencyTelemetryFields2
15021
15038
  })
15022
15039
  });
15023
15040
  StepFailedEventSchema2 = BaseEventSchema2.extend({
@@ -15027,7 +15044,8 @@ var init_events2 = __esm({
15027
15044
  stepName: external_exports2.string().optional(),
15028
15045
  // The thrown value, serialized via the workflow serialization pipeline.
15029
15046
  // Can be any JavaScript value (string, number, object, Error, etc.)
15030
- error: SerializedDataSchema2
15047
+ error: SerializedDataSchema2,
15048
+ ...stepLatencyTelemetryFields2
15031
15049
  })
15032
15050
  });
15033
15051
  StepRetryingEventSchema2 = BaseEventSchema2.extend({
@@ -15174,7 +15192,13 @@ var init_events2 = __esm({
15174
15192
  })
15175
15193
  });
15176
15194
  RunCancelledEventSchema2 = BaseEventSchema2.extend({
15177
- eventType: external_exports2.literal("run_cancelled")
15195
+ eventType: external_exports2.literal("run_cancelled"),
15196
+ eventData: external_exports2.object({
15197
+ // Optional free-text reason for the cancellation. Kept as small
15198
+ // plaintext metadata (like run_failed's errorCode) so it survives
15199
+ // resolveData: 'none' and can be displayed without decryption.
15200
+ cancelReason: external_exports2.string().max(512).optional()
15201
+ }).optional()
15178
15202
  });
15179
15203
  CreateEventSchema2 = external_exports2.discriminatedUnion("eventType", [
15180
15204
  // Run lifecycle events
@@ -20023,14 +20047,14 @@ var require_util = __commonJS({
20023
20047
  }
20024
20048
  const port = url3.port != null ? url3.port : url3.protocol === "https:" ? 443 : 80;
20025
20049
  let origin = url3.origin != null ? url3.origin : `${url3.protocol || ""}//${url3.hostname || ""}:${port}`;
20026
- let path10 = url3.path != null ? url3.path : `${url3.pathname || ""}${url3.search || ""}`;
20050
+ let path11 = url3.path != null ? url3.path : `${url3.pathname || ""}${url3.search || ""}`;
20027
20051
  if (origin[origin.length - 1] === "/") {
20028
20052
  origin = origin.slice(0, origin.length - 1);
20029
20053
  }
20030
- if (path10 && path10[0] !== "/") {
20031
- path10 = `/${path10}`;
20054
+ if (path11 && path11[0] !== "/") {
20055
+ path11 = `/${path11}`;
20032
20056
  }
20033
- return new URL(`${origin}${path10}`);
20057
+ return new URL(`${origin}${path11}`);
20034
20058
  }
20035
20059
  if (!isHttpOrHttpsPrefixed(url3.origin || url3.protocol)) {
20036
20060
  throw new InvalidArgumentError("Invalid URL protocol: the URL must start with `http:` or `https:`.");
@@ -20890,9 +20914,9 @@ var require_diagnostics = __commonJS({
20890
20914
  "undici:client:sendHeaders",
20891
20915
  (evt) => {
20892
20916
  const {
20893
- request: { method, path: path10, origin }
20917
+ request: { method, path: path11, origin }
20894
20918
  } = evt;
20895
- debugLog("sending request to %s %s%s", method, origin, path10);
20919
+ debugLog("sending request to %s %s%s", method, origin, path11);
20896
20920
  }
20897
20921
  );
20898
20922
  }
@@ -20911,14 +20935,14 @@ var require_diagnostics = __commonJS({
20911
20935
  "undici:request:headers",
20912
20936
  (evt) => {
20913
20937
  const {
20914
- request: { method, path: path10, origin },
20938
+ request: { method, path: path11, origin },
20915
20939
  response: { statusCode }
20916
20940
  } = evt;
20917
20941
  debugLog(
20918
20942
  "received response to %s %s%s - HTTP %d",
20919
20943
  method,
20920
20944
  origin,
20921
- path10,
20945
+ path11,
20922
20946
  statusCode
20923
20947
  );
20924
20948
  }
@@ -20927,23 +20951,23 @@ var require_diagnostics = __commonJS({
20927
20951
  "undici:request:trailers",
20928
20952
  (evt) => {
20929
20953
  const {
20930
- request: { method, path: path10, origin }
20954
+ request: { method, path: path11, origin }
20931
20955
  } = evt;
20932
- debugLog("trailers received from %s %s%s", method, origin, path10);
20956
+ debugLog("trailers received from %s %s%s", method, origin, path11);
20933
20957
  }
20934
20958
  );
20935
20959
  diagnosticsChannel.subscribe(
20936
20960
  "undici:request:error",
20937
20961
  (evt) => {
20938
20962
  const {
20939
- request: { method, path: path10, origin },
20963
+ request: { method, path: path11, origin },
20940
20964
  error: error95
20941
20965
  } = evt;
20942
20966
  debugLog(
20943
20967
  "request to %s %s%s errored - %s",
20944
20968
  method,
20945
20969
  origin,
20946
- path10,
20970
+ path11,
20947
20971
  error95.message
20948
20972
  );
20949
20973
  }
@@ -21064,7 +21088,7 @@ var require_request = __commonJS({
21064
21088
  __name(this, "Request");
21065
21089
  }
21066
21090
  constructor(origin, {
21067
- path: path10,
21091
+ path: path11,
21068
21092
  method,
21069
21093
  body,
21070
21094
  headers,
@@ -21081,11 +21105,11 @@ var require_request = __commonJS({
21081
21105
  maxRedirections,
21082
21106
  typeOfService
21083
21107
  }, handler) {
21084
- if (typeof path10 !== "string") {
21108
+ if (typeof path11 !== "string") {
21085
21109
  throw new InvalidArgumentError("path must be a string");
21086
- } else if (path10[0] !== "/" && !(path10.startsWith("http://") || path10.startsWith("https://")) && method !== "CONNECT") {
21110
+ } else if (path11[0] !== "/" && !(path11.startsWith("http://") || path11.startsWith("https://")) && method !== "CONNECT") {
21087
21111
  throw new InvalidArgumentError("path must be an absolute URL or start with a slash");
21088
- } else if (invalidPathRegex.test(path10)) {
21112
+ } else if (invalidPathRegex.test(path11)) {
21089
21113
  throw new InvalidArgumentError("invalid request path");
21090
21114
  }
21091
21115
  if (typeof method !== "string") {
@@ -21160,7 +21184,7 @@ var require_request = __commonJS({
21160
21184
  this.completed = false;
21161
21185
  this.aborted = false;
21162
21186
  this.upgrade = upgrade || null;
21163
- this.path = query ? serializePathWithQuery(path10, query) : path10;
21187
+ this.path = query ? serializePathWithQuery(path11, query) : path11;
21164
21188
  this.origin = origin;
21165
21189
  this.protocol = getProtocolFromUrlString(origin);
21166
21190
  this.idempotent = idempotent == null ? method === "HEAD" || method === "GET" : idempotent;
@@ -26490,7 +26514,7 @@ var require_client_h1 = __commonJS({
26490
26514
  }
26491
26515
  __name(shouldSendContentLength, "shouldSendContentLength");
26492
26516
  function writeH1(client, request) {
26493
- const { method, path: path10, host, upgrade, blocking, reset } = request;
26517
+ const { method, path: path11, host, upgrade, blocking, reset } = request;
26494
26518
  let { body, headers, contentLength } = request;
26495
26519
  const expectsPayload = method === "PUT" || method === "POST" || method === "PATCH" || method === "QUERY" || method === "PROPFIND" || method === "PROPPATCH";
26496
26520
  if (util.isFormDataLike(body)) {
@@ -26560,7 +26584,7 @@ var require_client_h1 = __commonJS({
26560
26584
  if (socket.setTypeOfService) {
26561
26585
  socket.setTypeOfService(request.typeOfService);
26562
26586
  }
26563
- let header = `${method} ${path10} HTTP/1.1\r
26587
+ let header = `${method} ${path11} HTTP/1.1\r
26564
26588
  `;
26565
26589
  if (typeof host === "string") {
26566
26590
  header += `host: ${host}\r
@@ -27239,7 +27263,7 @@ var require_client_h2 = __commonJS({
27239
27263
  function writeH2(client, request) {
27240
27264
  const requestTimeout = request.bodyTimeout ?? client[kBodyTimeout];
27241
27265
  const session = client[kHTTP2Session];
27242
- const { method, path: path10, host, upgrade, expectContinue, signal, protocol, headers: reqHeaders } = request;
27266
+ const { method, path: path11, host, upgrade, expectContinue, signal, protocol, headers: reqHeaders } = request;
27243
27267
  let { body } = request;
27244
27268
  if (upgrade != null && upgrade !== "websocket") {
27245
27269
  util.errorRequest(client, request, new InvalidArgumentError(`Custom upgrade "${upgrade}" not supported over HTTP/2`));
@@ -27307,7 +27331,7 @@ var require_client_h2 = __commonJS({
27307
27331
  }
27308
27332
  headers[HTTP2_HEADER_METHOD] = "CONNECT";
27309
27333
  headers[HTTP2_HEADER_PROTOCOL] = "websocket";
27310
- headers[HTTP2_HEADER_PATH] = path10;
27334
+ headers[HTTP2_HEADER_PATH] = path11;
27311
27335
  if (protocol === "ws:" || protocol === "wss:") {
27312
27336
  headers[HTTP2_HEADER_SCHEME] = protocol === "ws:" ? "http" : "https";
27313
27337
  } else {
@@ -27348,7 +27372,7 @@ var require_client_h2 = __commonJS({
27348
27372
  stream.setTimeout(requestTimeout);
27349
27373
  return true;
27350
27374
  }
27351
- headers[HTTP2_HEADER_PATH] = path10;
27375
+ headers[HTTP2_HEADER_PATH] = path11;
27352
27376
  headers[HTTP2_HEADER_SCHEME] = protocol === "http:" ? "http" : "https";
27353
27377
  const expectsPayload = method === "PUT" || method === "POST" || method === "PATCH";
27354
27378
  if (body && typeof body.read === "function") {
@@ -29752,10 +29776,10 @@ var require_proxy_agent = __commonJS({
29752
29776
  };
29753
29777
  const {
29754
29778
  origin,
29755
- path: path10 = "/",
29779
+ path: path11 = "/",
29756
29780
  headers = {}
29757
29781
  } = opts;
29758
- opts.path = origin + path10;
29782
+ opts.path = origin + path11;
29759
29783
  if (!("host" in headers) && !("Host" in headers)) {
29760
29784
  const { host } = new URL(origin);
29761
29785
  headers.host = host;
@@ -31892,21 +31916,21 @@ var require_mock_utils = __commonJS({
31892
31916
  return normalizedQp;
31893
31917
  }
31894
31918
  __name(normalizeSearchParams, "normalizeSearchParams");
31895
- function safeUrl(path10) {
31896
- if (typeof path10 !== "string") {
31897
- return path10;
31919
+ function safeUrl(path11) {
31920
+ if (typeof path11 !== "string") {
31921
+ return path11;
31898
31922
  }
31899
- const pathSegments = path10.split("?", 3);
31923
+ const pathSegments = path11.split("?", 3);
31900
31924
  if (pathSegments.length !== 2) {
31901
- return path10;
31925
+ return path11;
31902
31926
  }
31903
31927
  const qp = new URLSearchParams(pathSegments.pop());
31904
31928
  qp.sort();
31905
31929
  return [...pathSegments, qp.toString()].join("?");
31906
31930
  }
31907
31931
  __name(safeUrl, "safeUrl");
31908
- function matchKey(mockDispatch2, { path: path10, method, body, headers }) {
31909
- const pathMatch = matchValue(mockDispatch2.path, path10);
31932
+ function matchKey(mockDispatch2, { path: path11, method, body, headers }) {
31933
+ const pathMatch = matchValue(mockDispatch2.path, path11);
31910
31934
  const methodMatch = matchValue(mockDispatch2.method, method);
31911
31935
  const bodyMatch = typeof mockDispatch2.body !== "undefined" ? matchValue(mockDispatch2.body, body) : true;
31912
31936
  const headersMatch = matchHeaders(mockDispatch2, headers);
@@ -31933,8 +31957,8 @@ var require_mock_utils = __commonJS({
31933
31957
  const basePath = key.query ? serializePathWithQuery(key.path, key.query) : key.path;
31934
31958
  const resolvedPath = typeof basePath === "string" ? safeUrl(basePath) : basePath;
31935
31959
  const resolvedPathWithoutTrailingSlash = removeTrailingSlash(resolvedPath);
31936
- let matchedMockDispatches = mockDispatches.filter(({ consumed }) => !consumed).filter(({ path: path10, ignoreTrailingSlash }) => {
31937
- return ignoreTrailingSlash ? matchValue(removeTrailingSlash(safeUrl(path10)), resolvedPathWithoutTrailingSlash) : matchValue(safeUrl(path10), resolvedPath);
31960
+ let matchedMockDispatches = mockDispatches.filter(({ consumed }) => !consumed).filter(({ path: path11, ignoreTrailingSlash }) => {
31961
+ return ignoreTrailingSlash ? matchValue(removeTrailingSlash(safeUrl(path11)), resolvedPathWithoutTrailingSlash) : matchValue(safeUrl(path11), resolvedPath);
31938
31962
  });
31939
31963
  if (matchedMockDispatches.length === 0) {
31940
31964
  throw new MockNotMatchedError(`Mock dispatch not matched for path '${resolvedPath}'`);
@@ -31976,20 +32000,20 @@ var require_mock_utils = __commonJS({
31976
32000
  }
31977
32001
  }
31978
32002
  __name(deleteMockDispatch, "deleteMockDispatch");
31979
- function removeTrailingSlash(path10) {
31980
- while (path10.endsWith("/")) {
31981
- path10 = path10.slice(0, -1);
32003
+ function removeTrailingSlash(path11) {
32004
+ while (path11.endsWith("/")) {
32005
+ path11 = path11.slice(0, -1);
31982
32006
  }
31983
- if (path10.length === 0) {
31984
- path10 = "/";
32007
+ if (path11.length === 0) {
32008
+ path11 = "/";
31985
32009
  }
31986
- return path10;
32010
+ return path11;
31987
32011
  }
31988
32012
  __name(removeTrailingSlash, "removeTrailingSlash");
31989
32013
  function buildKey(opts) {
31990
- const { path: path10, method, body, headers, query } = opts;
32014
+ const { path: path11, method, body, headers, query } = opts;
31991
32015
  return {
31992
- path: path10,
32016
+ path: path11,
31993
32017
  method,
31994
32018
  body,
31995
32019
  headers,
@@ -32716,10 +32740,10 @@ var require_pending_interceptors_formatter = __commonJS({
32716
32740
  }
32717
32741
  format(pendingInterceptors) {
32718
32742
  const withPrettyHeaders = pendingInterceptors.map(
32719
- ({ method, path: path10, data: { statusCode }, persist, times, timesInvoked, origin }) => ({
32743
+ ({ method, path: path11, data: { statusCode }, persist, times, timesInvoked, origin }) => ({
32720
32744
  Method: method,
32721
32745
  Origin: origin,
32722
- Path: path10,
32746
+ Path: path11,
32723
32747
  "Status code": statusCode,
32724
32748
  Persistent: persist ? PERSISTENT : NOT_PERSISTENT,
32725
32749
  Invocations: timesInvoked,
@@ -32804,9 +32828,9 @@ var require_mock_agent = __commonJS({
32804
32828
  const acceptNonStandardSearchParameters = this[kMockAgentAcceptsNonStandardSearchParameters];
32805
32829
  const dispatchOpts = { ...opts };
32806
32830
  if (acceptNonStandardSearchParameters && dispatchOpts.path) {
32807
- const [path10, searchParams] = dispatchOpts.path.split("?");
32831
+ const [path11, searchParams] = dispatchOpts.path.split("?");
32808
32832
  const normalizedSearchParams = normalizeSearchParams(searchParams, acceptNonStandardSearchParameters);
32809
- dispatchOpts.path = `${path10}?${normalizedSearchParams}`;
32833
+ dispatchOpts.path = `${path11}?${normalizedSearchParams}`;
32810
32834
  }
32811
32835
  return this[kAgent].dispatch(dispatchOpts, handler);
32812
32836
  }
@@ -33219,12 +33243,12 @@ var require_snapshot_recorder = __commonJS({
33219
33243
  * @return {Promise<void>} - Resolves when snapshots are loaded
33220
33244
  */
33221
33245
  async loadSnapshots(filePath) {
33222
- const path10 = filePath || this.#snapshotPath;
33223
- if (!path10) {
33246
+ const path11 = filePath || this.#snapshotPath;
33247
+ if (!path11) {
33224
33248
  throw new InvalidArgumentError("Snapshot path is required");
33225
33249
  }
33226
33250
  try {
33227
- const data = await readFile3(resolve2(path10), "utf8");
33251
+ const data = await readFile3(resolve2(path11), "utf8");
33228
33252
  const parsed = JSON.parse(data);
33229
33253
  if (Array.isArray(parsed)) {
33230
33254
  this.#snapshots.clear();
@@ -33238,7 +33262,7 @@ var require_snapshot_recorder = __commonJS({
33238
33262
  if (error95.code === "ENOENT") {
33239
33263
  this.#snapshots.clear();
33240
33264
  } else {
33241
- throw new UndiciError(`Failed to load snapshots from ${path10}`, { cause: error95 });
33265
+ throw new UndiciError(`Failed to load snapshots from ${path11}`, { cause: error95 });
33242
33266
  }
33243
33267
  }
33244
33268
  }
@@ -33249,11 +33273,11 @@ var require_snapshot_recorder = __commonJS({
33249
33273
  * @returns {Promise<void>} - Resolves when snapshots are saved
33250
33274
  */
33251
33275
  async saveSnapshots(filePath) {
33252
- const path10 = filePath || this.#snapshotPath;
33253
- if (!path10) {
33276
+ const path11 = filePath || this.#snapshotPath;
33277
+ if (!path11) {
33254
33278
  throw new InvalidArgumentError("Snapshot path is required");
33255
33279
  }
33256
- const resolvedPath = resolve2(path10);
33280
+ const resolvedPath = resolve2(path11);
33257
33281
  await mkdir2(dirname(resolvedPath), { recursive: true });
33258
33282
  const data = Array.from(this.#snapshots.entries()).map(([hash3, snapshot]) => ({
33259
33283
  hash: hash3,
@@ -33899,15 +33923,15 @@ var require_redirect_handler = __commonJS({
33899
33923
  return;
33900
33924
  }
33901
33925
  const { origin, pathname, search } = util.parseURL(new URL(this.location, this.opts.origin && new URL(this.opts.path, this.opts.origin)));
33902
- const path10 = search ? `${pathname}${search}` : pathname;
33903
- const redirectUrlString = `${origin}${path10}`;
33926
+ const path11 = search ? `${pathname}${search}` : pathname;
33927
+ const redirectUrlString = `${origin}${path11}`;
33904
33928
  for (const historyUrl of this.history) {
33905
33929
  if (historyUrl.toString() === redirectUrlString) {
33906
33930
  throw new InvalidArgumentError(`Redirect loop detected. Cannot redirect to ${origin}. This typically happens when using a Client or Pool with cross-origin redirects. Use an Agent for cross-origin redirects.`);
33907
33931
  }
33908
33932
  }
33909
33933
  this.opts.headers = cleanRequestHeaders(this.opts.headers, statusCode === 303, this.opts.origin !== origin);
33910
- this.opts.path = path10;
33934
+ this.opts.path = path11;
33911
33935
  this.opts.origin = origin;
33912
33936
  this.opts.query = null;
33913
33937
  }
@@ -40241,11 +40265,11 @@ var require_fetch = __commonJS({
40241
40265
  function dispatch({ body }) {
40242
40266
  const url3 = requestCurrentURL(request);
40243
40267
  const agent = fetchParams.controller.dispatcher;
40244
- const path10 = url3.pathname + url3.search;
40268
+ const path11 = url3.pathname + url3.search;
40245
40269
  const hasTrailingQuestionMark = url3.search.length === 0 && url3.href[url3.href.length - url3.hash.length - 1] === "?";
40246
40270
  return new Promise((resolve2, reject) => agent.dispatch(
40247
40271
  {
40248
- path: hasTrailingQuestionMark ? `${path10}?` : path10,
40272
+ path: hasTrailingQuestionMark ? `${path11}?` : path11,
40249
40273
  origin: url3.origin,
40250
40274
  method: request.method,
40251
40275
  body: agent.isMockActive ? request.body && (request.body.source || request.body.stream) : body,
@@ -41205,9 +41229,9 @@ var require_util4 = __commonJS({
41205
41229
  }
41206
41230
  }
41207
41231
  __name(validateCookieValue, "validateCookieValue");
41208
- function validateCookiePath(path10) {
41209
- for (let i = 0; i < path10.length; ++i) {
41210
- const code3 = path10.charCodeAt(i);
41232
+ function validateCookiePath(path11) {
41233
+ for (let i = 0; i < path11.length; ++i) {
41234
+ const code3 = path11.charCodeAt(i);
41211
41235
  if (code3 < 32 || // exclude CTLs (0-31)
41212
41236
  code3 === 127 || // DEL
41213
41237
  code3 === 59) {
@@ -44484,11 +44508,11 @@ var require_undici = __commonJS({
44484
44508
  if (typeof opts.path !== "string") {
44485
44509
  throw new InvalidArgumentError("invalid opts.path");
44486
44510
  }
44487
- let path10 = opts.path;
44511
+ let path11 = opts.path;
44488
44512
  if (!opts.path.startsWith("/")) {
44489
- path10 = `/${path10}`;
44513
+ path11 = `/${path11}`;
44490
44514
  }
44491
- url3 = new URL(util.parseOrigin(url3).origin + path10);
44515
+ url3 = new URL(util.parseOrigin(url3).origin + path11);
44492
44516
  } else {
44493
44517
  if (!opts) {
44494
44518
  opts = typeof url3 === "object" ? url3 : {};
@@ -44988,7 +45012,7 @@ var init_log_format2 = __esm({
44988
45012
  function SemanticConvention3(...names) {
44989
45013
  return (value) => Object.fromEntries(names.map((name) => [name, value]));
44990
45014
  }
44991
- var WorkflowName2, WorkflowOperation2, WorkflowRunId3, WorkflowRunStatus2, WorkflowStartedAt2, WorkflowEventsCount2, WorkflowArgumentsCount2, WorkflowResultType2, WorkflowTracePropagated2, WorkflowTraceMode2, WorkflowTurbo2, WorkflowErrorName2, WorkflowErrorMessage2, WorkflowErrorCode2, WorkflowStepsCreated2, WorkflowHooksCreated2, WorkflowWaitsCreated2, WorkflowRouteType2, WorkflowRouteHandlerCached2, WorkflowRouteInvocationCount2, WorkflowRouteEntrypointAgeMs2, WorkflowRouteModuleBodyInitMs2, StepName2, StepId3, StepAttempt2, StepStatus2, StepMaxRetries2, StepTracePropagated2, StepSkipped2, StepSkipReason2, StepArgumentsCount2, StepResultType2, StepErrorName2, StepErrorMessage2, StepFatalError2, StepRetryExhausted2, StepRetryTimeoutSeconds2, StepRetryWillRetry2, MessagingSystem2, MessagingDestinationName2, MessagingMessageId2, MessagingOperationType2, QueueOverheadMs2, DeploymentId2, HookToken2, HookId2, HookFound2, WebhookHandlersTriggered2, WorkflowSuspensionState2, WorkflowSuspensionHookCount2, WorkflowSuspensionStepCount2, WorkflowSuspensionWaitCount2, HttpRequestMethod2, HttpRoute2, UrlFull2, ServerAddress2, ServerPort2, HttpResponseStatusCode2, ErrorType2, WorldParseFormat2, WorkflowEventsPagesLoaded2, QueueDeserializeTimeMs2, QueueExecutionTimeMs2, QueueSerializeTimeMs2, SerializationOperation2, SerializationCompressed2, SerializationCodec2, SerializationUncompressedBytes2, SerializationStoredBytes2, SerializationCompressionRatio2, PeerService3, RpcSystem3, RpcService3, RpcMethod3, ErrorRetryable2, ErrorCategory2;
45015
+ var WorkflowName2, WorkflowOperation2, WorkflowRunId3, WorkflowRunStatus2, WorkflowStartedAt2, WorkflowEventsCount2, WorkflowArgumentsCount2, WorkflowResultType2, WorkflowTracePropagated2, WorkflowTraceMode2, WorkflowTurbo2, WorkflowErrorName2, WorkflowErrorMessage2, WorkflowErrorCode2, WorkflowStepsCreated2, WorkflowHooksCreated2, WorkflowWaitsCreated2, WorkflowRouteType2, WorkflowRouteHandlerCached2, WorkflowRouteInvocationCount2, WorkflowRouteEntrypointAgeMs2, WorkflowRouteModuleBodyInitMs2, StepName2, StepId3, StepAttempt2, StepStatus2, StepMaxRetries2, StepTracePropagated2, StepTtfsMs2, StepStsoMs2, StepLatencyOptimizations2, StepSkipped2, StepSkipReason2, StepArgumentsCount2, StepResultType2, StepErrorName2, StepErrorMessage2, StepFatalError2, StepRetryExhausted2, StepRetryTimeoutSeconds2, StepRetryWillRetry2, MessagingSystem2, MessagingDestinationName2, MessagingMessageId2, MessagingOperationType2, QueueOverheadMs2, DeploymentId2, HookToken2, HookId2, HookFound2, WebhookHandlersTriggered2, WorkflowSuspensionState2, WorkflowSuspensionHookCount2, WorkflowSuspensionStepCount2, WorkflowSuspensionWaitCount2, HttpRequestMethod2, HttpRoute2, UrlFull2, ServerAddress2, ServerPort2, HttpResponseStatusCode2, ErrorType2, WorldParseFormat2, WorkflowEventsPagesLoaded2, QueueDeserializeTimeMs2, QueueExecutionTimeMs2, QueueSerializeTimeMs2, SerializationOperation2, SerializationCompressed2, SerializationCodec2, SerializationUncompressedBytes2, SerializationStoredBytes2, SerializationCompressionRatio2, PeerService3, RpcSystem3, RpcService3, RpcMethod3, ErrorRetryable2, ErrorCategory2;
44992
45016
  var init_semantic_conventions2 = __esm({
44993
45017
  "../core/dist/telemetry/semantic-conventions.js"() {
44994
45018
  "use strict";
@@ -45021,6 +45045,9 @@ var init_semantic_conventions2 = __esm({
45021
45045
  StepStatus2 = SemanticConvention3("step.status");
45022
45046
  StepMaxRetries2 = SemanticConvention3("step.max_retries");
45023
45047
  StepTracePropagated2 = SemanticConvention3("step.trace.propagated");
45048
+ StepTtfsMs2 = SemanticConvention3("step.ttfs_ms");
45049
+ StepStsoMs2 = SemanticConvention3("step.stso_ms");
45050
+ StepLatencyOptimizations2 = SemanticConvention3("step.latency_optimizations");
45024
45051
  StepSkipped2 = SemanticConvention3("step.skipped");
45025
45052
  StepSkipReason2 = SemanticConvention3("step.skip_reason");
45026
45053
  StepArgumentsCount2 = SemanticConvention3("step.arguments.count");
@@ -45413,7 +45440,7 @@ var version4;
45413
45440
  var init_version3 = __esm({
45414
45441
  "../core/dist/version.js"() {
45415
45442
  "use strict";
45416
- version4 = "5.0.0-beta.28";
45443
+ version4 = "5.0.0-beta.29";
45417
45444
  }
45418
45445
  });
45419
45446
 
@@ -54826,9 +54853,9 @@ function cloneDef(schema) {
54826
54853
  return mergeDefs(schema._zod.def);
54827
54854
  }
54828
54855
  __name(cloneDef, "cloneDef");
54829
- function getElementAtPath(obj, path10) {
54830
- if (!path10) return obj;
54831
- return path10.reduce((acc, key) => acc?.[key], obj);
54856
+ function getElementAtPath(obj, path11) {
54857
+ if (!path11) return obj;
54858
+ return path11.reduce((acc, key) => acc?.[key], obj);
54832
54859
  }
54833
54860
  __name(getElementAtPath, "getElementAtPath");
54834
54861
  function promiseAllObject(promisesObj) {
@@ -55168,11 +55195,11 @@ function aborted(x, startIndex = 0) {
55168
55195
  return false;
55169
55196
  }
55170
55197
  __name(aborted, "aborted");
55171
- function prefixIssues(path10, issues) {
55198
+ function prefixIssues(path11, issues) {
55172
55199
  return issues.map((iss) => {
55173
55200
  var _a22;
55174
55201
  (_a22 = iss).path ?? (_a22.path = []);
55175
- iss.path.unshift(path10);
55202
+ iss.path.unshift(path11);
55176
55203
  return iss;
55177
55204
  });
55178
55205
  }
@@ -55546,7 +55573,7 @@ function treeifyError(error482, mapper = (issue22) => issue22.message) {
55546
55573
  const result = {
55547
55574
  errors: []
55548
55575
  };
55549
- const processError = /* @__PURE__ */ __name2((error492, path10 = []) => {
55576
+ const processError = /* @__PURE__ */ __name2((error492, path11 = []) => {
55550
55577
  var _a22, _b;
55551
55578
  for (const issue22 of error492.issues) {
55552
55579
  if (issue22.code === "invalid_union" && issue22.errors.length) {
@@ -55563,7 +55590,7 @@ function treeifyError(error482, mapper = (issue22) => issue22.message) {
55563
55590
  }, issue22.path);
55564
55591
  } else {
55565
55592
  const fullpath = [
55566
- ...path10,
55593
+ ...path11,
55567
55594
  ...issue22.path
55568
55595
  ];
55569
55596
  if (fullpath.length === 0) {
@@ -55602,8 +55629,8 @@ function treeifyError(error482, mapper = (issue22) => issue22.message) {
55602
55629
  __name(treeifyError, "treeifyError");
55603
55630
  function toDotPath(_path) {
55604
55631
  const segs = [];
55605
- const path10 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
55606
- for (const seg of path10) {
55632
+ const path11 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
55633
+ for (const seg of path11) {
55607
55634
  if (typeof seg === "number") segs.push(`[${seg}]`);
55608
55635
  else if (typeof seg === "symbol") segs.push(`[${JSON.stringify(String(seg))}]`);
55609
55636
  else if (/[^\w$]/.test(seg)) segs.push(`[${JSON.stringify(seg)}]`);
@@ -69957,13 +69984,13 @@ function resolveRef(ref, ctx) {
69957
69984
  if (!ref.startsWith("#")) {
69958
69985
  throw new Error("External $ref is not supported, only local refs (#/...) are allowed");
69959
69986
  }
69960
- const path10 = ref.slice(1).split("/").filter(Boolean);
69961
- if (path10.length === 0) {
69987
+ const path11 = ref.slice(1).split("/").filter(Boolean);
69988
+ if (path11.length === 0) {
69962
69989
  return ctx.rootSchema;
69963
69990
  }
69964
69991
  const defsKey = ctx.version === "draft-2020-12" ? "$defs" : "definitions";
69965
- if (path10[0] === defsKey) {
69966
- const key = path10[1];
69992
+ if (path11[0] === defsKey) {
69993
+ const key = path11[1];
69967
69994
  if (!key || !ctx.defs[key]) {
69968
69995
  throw new Error(`Reference not found: ${ref}`);
69969
69996
  }
@@ -70878,6 +70905,7 @@ var EventTypeSchema;
70878
70905
  var TerminalRunEventTypeSchema;
70879
70906
  var TERMINAL_RUN_EVENT_TYPES;
70880
70907
  var BaseEventSchema;
70908
+ var stepLatencyTelemetryFields;
70881
70909
  var StepCompletedEventSchema;
70882
70910
  var StepFailedEventSchema;
70883
70911
  var StepRetryingEventSchema;
@@ -70940,6 +70968,22 @@ var init_events = __esm2({
70940
70968
  correlationId: external_exports.string().optional(),
70941
70969
  specVersion: external_exports.number().optional()
70942
70970
  });
70971
+ stepLatencyTelemetryFields = {
70972
+ // Time-to-first-step: milliseconds from run creation until the run's first
70973
+ // step body began executing, minus time spent committing hook_created
70974
+ // events. Only reported when nothing else (hooks received, waits,
70975
+ // attributes, other steps) happened before the first step.
70976
+ ttfs: external_exports.number().optional(),
70977
+ // Step-to-step overhead: milliseconds between the previous step's terminal
70978
+ // event and this step's body beginning to execute. Only reported when the
70979
+ // two steps ran back-to-back (the previous event-log entry is a
70980
+ // step_completed/step_failed).
70981
+ stso: external_exports.number().optional(),
70982
+ // Names of the runtime's optional startup-latency optimizations that were
70983
+ // active for this measurement (e.g. 'turbo', 'lazyStepStart',
70984
+ // 'optimisticStart'), so latency metrics can be segmented by them.
70985
+ optimizations: external_exports.array(external_exports.string()).optional()
70986
+ };
70943
70987
  StepCompletedEventSchema = BaseEventSchema.extend({
70944
70988
  eventType: external_exports.literal("step_completed"),
70945
70989
  correlationId: external_exports.string(),
@@ -70949,7 +70993,8 @@ var init_events = __esm2({
70949
70993
  // the key without an extra run lookup on this hot per-step write.
70950
70994
  // Optional: older runtimes omit it and the backend falls back to a read.
70951
70995
  workflowName: external_exports.string().optional(),
70952
- result: SerializedDataSchema
70996
+ result: SerializedDataSchema,
70997
+ ...stepLatencyTelemetryFields
70953
70998
  })
70954
70999
  });
70955
71000
  StepFailedEventSchema = BaseEventSchema.extend({
@@ -70959,7 +71004,8 @@ var init_events = __esm2({
70959
71004
  stepName: external_exports.string().optional(),
70960
71005
  // The thrown value, serialized via the workflow serialization pipeline.
70961
71006
  // Can be any JavaScript value (string, number, object, Error, etc.)
70962
- error: SerializedDataSchema
71007
+ error: SerializedDataSchema,
71008
+ ...stepLatencyTelemetryFields
70963
71009
  })
70964
71010
  });
70965
71011
  StepRetryingEventSchema = BaseEventSchema.extend({
@@ -71106,7 +71152,13 @@ var init_events = __esm2({
71106
71152
  })
71107
71153
  });
71108
71154
  RunCancelledEventSchema = BaseEventSchema.extend({
71109
- eventType: external_exports.literal("run_cancelled")
71155
+ eventType: external_exports.literal("run_cancelled"),
71156
+ eventData: external_exports.object({
71157
+ // Optional free-text reason for the cancellation. Kept as small
71158
+ // plaintext metadata (like run_failed's errorCode) so it survives
71159
+ // resolveData: 'none' and can be displayed without decryption.
71160
+ cancelReason: external_exports.string().max(512).optional()
71161
+ }).optional()
71110
71162
  });
71111
71163
  CreateEventSchema = external_exports.discriminatedUnion("eventType", [
71112
71164
  // Run lifecycle events
@@ -74226,6 +74278,9 @@ var StepAttempt;
74226
74278
  var StepStatus;
74227
74279
  var StepMaxRetries;
74228
74280
  var StepTracePropagated;
74281
+ var StepTtfsMs;
74282
+ var StepStsoMs;
74283
+ var StepLatencyOptimizations;
74229
74284
  var StepSkipped;
74230
74285
  var StepSkipReason;
74231
74286
  var StepArgumentsCount;
@@ -74306,6 +74361,9 @@ var init_semantic_conventions = __esm2({
74306
74361
  StepStatus = SemanticConvention("step.status");
74307
74362
  StepMaxRetries = SemanticConvention("step.max_retries");
74308
74363
  StepTracePropagated = SemanticConvention("step.trace.propagated");
74364
+ StepTtfsMs = SemanticConvention("step.ttfs_ms");
74365
+ StepStsoMs = SemanticConvention("step.stso_ms");
74366
+ StepLatencyOptimizations = SemanticConvention("step.latency_optimizations");
74309
74367
  StepSkipped = SemanticConvention("step.skipped");
74310
74368
  StepSkipReason = SemanticConvention("step.skip_reason");
74311
74369
  StepArgumentsCount = SemanticConvention("step.arguments.count");
@@ -78786,7 +78844,7 @@ var version2;
78786
78844
  var init_version = __esm2({
78787
78845
  "../core/dist/version.js"() {
78788
78846
  "use strict";
78789
- version2 = "5.0.0-beta.28";
78847
+ version2 = "5.0.0-beta.29";
78790
78848
  }
78791
78849
  });
78792
78850
  function getWorkflowQueueName(workflowName, namespace) {
@@ -82103,7 +82161,7 @@ __name2(start, "start");
82103
82161
  value: "start",
82104
82162
  configurable: true
82105
82163
  });
82106
- })(start, "step//@workflow/core/runtime/start@5.0.0-beta.28//start");
82164
+ })(start, "step//@workflow/core/runtime/start@5.0.0-beta.29//start");
82107
82165
  async function wakeUpRun(world, runId, options) {
82108
82166
  try {
82109
82167
  const run22 = await world.runs.get(runId, {
@@ -82273,12 +82331,21 @@ var Run = class _Run {
82273
82331
  }
82274
82332
  /**
82275
82333
  * Cancels the workflow run.
82334
+ *
82335
+ * @param options - Optional cancellation settings. `cancelReason` records a
82336
+ * free-text reason (max 512 chars) on the run_cancelled event, surfaced in
82337
+ * the run detail view.
82276
82338
  */
82277
- async cancel() {
82339
+ async cancel(options) {
82278
82340
  const world = await this.#lazyWorldPromise;
82279
82341
  await world.events.create(this.runId, {
82280
82342
  eventType: "run_cancelled",
82281
- specVersion: SPEC_VERSION_CURRENT
82343
+ specVersion: SPEC_VERSION_CURRENT,
82344
+ ...options?.cancelReason !== void 0 ? {
82345
+ eventData: {
82346
+ cancelReason: options.cancelReason
82347
+ }
82348
+ } : {}
82282
82349
  });
82283
82350
  }
82284
82351
  /**
@@ -82430,7 +82497,7 @@ var Run = class _Run {
82430
82497
  value: "wakeUp",
82431
82498
  configurable: true
82432
82499
  });
82433
- })(Run.prototype["wakeUp"], "step//@workflow/core/runtime/run@5.0.0-beta.28//Run#wakeUp");
82500
+ })(Run.prototype["wakeUp"], "step//@workflow/core/runtime/run@5.0.0-beta.29//Run#wakeUp");
82434
82501
  (function(__wf_fn, __wf_id) {
82435
82502
  var __wf_sym = /* @__PURE__ */ Symbol.for("@workflow/core//registeredSteps"), __wf_reg = globalThis[__wf_sym] || (globalThis[__wf_sym] = /* @__PURE__ */ new Map());
82436
82503
  __wf_reg.set(__wf_id, __wf_fn);
@@ -82439,7 +82506,7 @@ var Run = class _Run {
82439
82506
  value: "cancel",
82440
82507
  configurable: true
82441
82508
  });
82442
- })(Run.prototype["cancel"], "step//@workflow/core/runtime/run@5.0.0-beta.28//Run#cancel");
82509
+ })(Run.prototype["cancel"], "step//@workflow/core/runtime/run@5.0.0-beta.29//Run#cancel");
82443
82510
  (function(__wf_fn, __wf_id) {
82444
82511
  var __wf_sym = /* @__PURE__ */ Symbol.for("@workflow/core//registeredSteps"), __wf_reg = globalThis[__wf_sym] || (globalThis[__wf_sym] = /* @__PURE__ */ new Map());
82445
82512
  __wf_reg.set(__wf_id, __wf_fn);
@@ -82448,7 +82515,7 @@ var Run = class _Run {
82448
82515
  value: "getReadable",
82449
82516
  configurable: true
82450
82517
  });
82451
- })(Run.prototype["getReadable"], "step//@workflow/core/runtime/run@5.0.0-beta.28//Run#getReadable");
82518
+ })(Run.prototype["getReadable"], "step//@workflow/core/runtime/run@5.0.0-beta.29//Run#getReadable");
82452
82519
  (function(__wf_fn, __wf_id) {
82453
82520
  var __wf_sym = /* @__PURE__ */ Symbol.for("@workflow/core//registeredSteps"), __wf_reg = globalThis[__wf_sym] || (globalThis[__wf_sym] = /* @__PURE__ */ new Map());
82454
82521
  __wf_reg.set(__wf_id, __wf_fn);
@@ -82457,7 +82524,7 @@ var Run = class _Run {
82457
82524
  value: "exists",
82458
82525
  configurable: true
82459
82526
  });
82460
- })(Object.getOwnPropertyDescriptor(Run.prototype, "exists").get, "step//@workflow/core/runtime/run@5.0.0-beta.28//Run#exists");
82527
+ })(Object.getOwnPropertyDescriptor(Run.prototype, "exists").get, "step//@workflow/core/runtime/run@5.0.0-beta.29//Run#exists");
82461
82528
  (function(__wf_fn, __wf_id) {
82462
82529
  var __wf_sym = /* @__PURE__ */ Symbol.for("@workflow/core//registeredSteps"), __wf_reg = globalThis[__wf_sym] || (globalThis[__wf_sym] = /* @__PURE__ */ new Map());
82463
82530
  __wf_reg.set(__wf_id, __wf_fn);
@@ -82466,7 +82533,7 @@ var Run = class _Run {
82466
82533
  value: "status",
82467
82534
  configurable: true
82468
82535
  });
82469
- })(Object.getOwnPropertyDescriptor(Run.prototype, "status").get, "step//@workflow/core/runtime/run@5.0.0-beta.28//Run#status");
82536
+ })(Object.getOwnPropertyDescriptor(Run.prototype, "status").get, "step//@workflow/core/runtime/run@5.0.0-beta.29//Run#status");
82470
82537
  (function(__wf_fn, __wf_id) {
82471
82538
  var __wf_sym = /* @__PURE__ */ Symbol.for("@workflow/core//registeredSteps"), __wf_reg = globalThis[__wf_sym] || (globalThis[__wf_sym] = /* @__PURE__ */ new Map());
82472
82539
  __wf_reg.set(__wf_id, __wf_fn);
@@ -82475,7 +82542,7 @@ var Run = class _Run {
82475
82542
  value: "returnValue",
82476
82543
  configurable: true
82477
82544
  });
82478
- })(Object.getOwnPropertyDescriptor(Run.prototype, "returnValue").get, "step//@workflow/core/runtime/run@5.0.0-beta.28//Run#returnValue");
82545
+ })(Object.getOwnPropertyDescriptor(Run.prototype, "returnValue").get, "step//@workflow/core/runtime/run@5.0.0-beta.29//Run#returnValue");
82479
82546
  (function(__wf_fn, __wf_id) {
82480
82547
  var __wf_sym = /* @__PURE__ */ Symbol.for("@workflow/core//registeredSteps"), __wf_reg = globalThis[__wf_sym] || (globalThis[__wf_sym] = /* @__PURE__ */ new Map());
82481
82548
  __wf_reg.set(__wf_id, __wf_fn);
@@ -82484,7 +82551,7 @@ var Run = class _Run {
82484
82551
  value: "workflowName",
82485
82552
  configurable: true
82486
82553
  });
82487
- })(Object.getOwnPropertyDescriptor(Run.prototype, "workflowName").get, "step//@workflow/core/runtime/run@5.0.0-beta.28//Run#workflowName");
82554
+ })(Object.getOwnPropertyDescriptor(Run.prototype, "workflowName").get, "step//@workflow/core/runtime/run@5.0.0-beta.29//Run#workflowName");
82488
82555
  (function(__wf_fn, __wf_id) {
82489
82556
  var __wf_sym = /* @__PURE__ */ Symbol.for("@workflow/core//registeredSteps"), __wf_reg = globalThis[__wf_sym] || (globalThis[__wf_sym] = /* @__PURE__ */ new Map());
82490
82557
  __wf_reg.set(__wf_id, __wf_fn);
@@ -82493,7 +82560,7 @@ var Run = class _Run {
82493
82560
  value: "createdAt",
82494
82561
  configurable: true
82495
82562
  });
82496
- })(Object.getOwnPropertyDescriptor(Run.prototype, "createdAt").get, "step//@workflow/core/runtime/run@5.0.0-beta.28//Run#createdAt");
82563
+ })(Object.getOwnPropertyDescriptor(Run.prototype, "createdAt").get, "step//@workflow/core/runtime/run@5.0.0-beta.29//Run#createdAt");
82497
82564
  (function(__wf_fn, __wf_id) {
82498
82565
  var __wf_sym = /* @__PURE__ */ Symbol.for("@workflow/core//registeredSteps"), __wf_reg = globalThis[__wf_sym] || (globalThis[__wf_sym] = /* @__PURE__ */ new Map());
82499
82566
  __wf_reg.set(__wf_id, __wf_fn);
@@ -82502,7 +82569,7 @@ var Run = class _Run {
82502
82569
  value: "startedAt",
82503
82570
  configurable: true
82504
82571
  });
82505
- })(Object.getOwnPropertyDescriptor(Run.prototype, "startedAt").get, "step//@workflow/core/runtime/run@5.0.0-beta.28//Run#startedAt");
82572
+ })(Object.getOwnPropertyDescriptor(Run.prototype, "startedAt").get, "step//@workflow/core/runtime/run@5.0.0-beta.29//Run#startedAt");
82506
82573
  (function(__wf_fn, __wf_id) {
82507
82574
  var __wf_sym = /* @__PURE__ */ Symbol.for("@workflow/core//registeredSteps"), __wf_reg = globalThis[__wf_sym] || (globalThis[__wf_sym] = /* @__PURE__ */ new Map());
82508
82575
  __wf_reg.set(__wf_id, __wf_fn);
@@ -82511,7 +82578,7 @@ var Run = class _Run {
82511
82578
  value: "completedAt",
82512
82579
  configurable: true
82513
82580
  });
82514
- })(Object.getOwnPropertyDescriptor(Run.prototype, "completedAt").get, "step//@workflow/core/runtime/run@5.0.0-beta.28//Run#completedAt");
82581
+ })(Object.getOwnPropertyDescriptor(Run.prototype, "completedAt").get, "step//@workflow/core/runtime/run@5.0.0-beta.29//Run#completedAt");
82515
82582
  (function(__wf_cls, __wf_id) {
82516
82583
  var __wf_sym = /* @__PURE__ */ Symbol.for("workflow-class-registry"), __wf_reg = globalThis[__wf_sym] || (globalThis[__wf_sym] = /* @__PURE__ */ new Map());
82517
82584
  __wf_reg.set(__wf_id, __wf_cls);
@@ -82521,7 +82588,7 @@ var Run = class _Run {
82521
82588
  enumerable: false,
82522
82589
  configurable: false
82523
82590
  });
82524
- })(Run, "class//@workflow/core/runtime/run@5.0.0-beta.28//Run");
82591
+ })(Run, "class//@workflow/core/runtime/run@5.0.0-beta.29//Run");
82525
82592
  async function fetch2(...args) {
82526
82593
  return globalThis.fetch(...args);
82527
82594
  }
@@ -82737,8 +82804,8 @@ function defineHook({ schema } = {}) {
82737
82804
  }
82738
82805
  if (result.issues) {
82739
82806
  const lines = result.issues.map((issue22) => {
82740
- const path10 = issue22.path?.map((segment) => typeof segment === "object" && segment !== null ? String(segment.key) : String(segment)).join(".");
82741
- return path10 ? ` at "${path10}": ${issue22.message}` : ` ${issue22.message}`;
82807
+ const path11 = issue22.path?.map((segment) => typeof segment === "object" && segment !== null ? String(segment.key) : String(segment)).join(".");
82808
+ return path11 ? ` at "${path11}": ${issue22.message}` : ` ${issue22.message}`;
82742
82809
  });
82743
82810
  throw new Error(`Hook payload did not match the defined schema:
82744
82811
  ${lines.join("\n")}`);
@@ -83007,9 +83074,9 @@ __export(dist_exports2, {
83007
83074
  parseVersion: () => parseVersion
83008
83075
  });
83009
83076
  init_dist5();
83010
- import { promises as fs5 } from "node:fs";
83077
+ import { promises as fs6 } from "node:fs";
83011
83078
  import { rm } from "node:fs/promises";
83012
- import path9 from "node:path";
83079
+ import path10 from "node:path";
83013
83080
 
83014
83081
  // ../world-local/dist/config.js
83015
83082
  init_dist6();
@@ -83620,21 +83687,26 @@ async function paginatedFileSystemQuery(config4) {
83620
83687
  return true;
83621
83688
  });
83622
83689
  }
83690
+ const readConcurrency = 32;
83623
83691
  const validItems = [];
83624
- for (const fileId of candidateFileIds) {
83625
- const filePath = path.join(resolvedDirectory, `${fileId}.json`);
83626
- let item = null;
83627
- try {
83628
- const cachedItem = cachedItems?.get(filePath);
83629
- item = cachedItem === void 0 ? await readJSON(filePath, schema) : structuredClone(cachedItem);
83630
- } catch (error95) {
83631
- if (error95 instanceof external_exports2.ZodError) {
83632
- console.warn(`Skipping item ${fileId} due to malformed JSON: ${error95.message}`);
83633
- continue;
83692
+ for (let batchStart = 0; batchStart < candidateFileIds.length; batchStart += readConcurrency) {
83693
+ const batch = candidateFileIds.slice(batchStart, batchStart + readConcurrency);
83694
+ const loadedBatch = await Promise.all(batch.map(async (fileId) => {
83695
+ const filePath = path.join(resolvedDirectory, `${fileId}.json`);
83696
+ try {
83697
+ const cachedItem = cachedItems?.get(filePath);
83698
+ return cachedItem === void 0 ? await readJSON(filePath, schema) : structuredClone(cachedItem);
83699
+ } catch (error95) {
83700
+ if (error95 instanceof external_exports2.ZodError) {
83701
+ console.warn(`Skipping item ${fileId} due to malformed JSON: ${error95.message}`);
83702
+ return null;
83703
+ }
83704
+ throw error95;
83634
83705
  }
83635
- throw error95;
83636
- }
83637
- if (item) {
83706
+ }));
83707
+ for (const item of loadedBatch) {
83708
+ if (!item)
83709
+ continue;
83638
83710
  if (filter && !filter(item))
83639
83711
  continue;
83640
83712
  if (parsedCursor) {
@@ -84358,28 +84430,241 @@ function hookRecoveryMarkerPath(basedir, token, runId, hookId) {
84358
84430
  }
84359
84431
  __name(hookRecoveryMarkerPath, "hookRecoveryMarkerPath");
84360
84432
  var monotonicUlid = monotonicFactory2(() => Math.random());
84361
- var getObjectCreatedAt = /* @__PURE__ */ __name((idPrefix) => (filename) => {
84362
- const cleanName = stripTag(filename.replace(/\.json$/, "")) + ".json";
84433
+ var getObjectCreatedAt = /* @__PURE__ */ __name((idPrefix) => {
84363
84434
  const replaceRegex = new RegExp(`^${idPrefix}_`, "g");
84364
- const dashIndex = cleanName.indexOf("-");
84365
- if (dashIndex === -1) {
84366
- const ulid9 = cleanName.replace(/\.json$/, "").replace(replaceRegex, "");
84367
- return ulidToDate(ulid9);
84435
+ return (filename) => {
84436
+ const cleanName = stripTag(filename.replace(/\.json$/, "")) + ".json";
84437
+ const dashIndex = cleanName.indexOf("-");
84438
+ if (dashIndex === -1) {
84439
+ const ulid9 = cleanName.replace(/\.json$/, "").replace(replaceRegex, "");
84440
+ return ulidToDate(ulid9);
84441
+ }
84442
+ if (idPrefix === "step") {
84443
+ return null;
84444
+ }
84445
+ const id = cleanName.substring(dashIndex + 1).replace(/\.json$/, "");
84446
+ const ulid8 = id.replace(replaceRegex, "");
84447
+ return ulidToDate(ulid8);
84448
+ };
84449
+ }, "getObjectCreatedAt");
84450
+
84451
+ // ../world-local/dist/storage/hook-index.js
84452
+ init_dist5();
84453
+ init_zod2();
84454
+ import fs3 from "node:fs/promises";
84455
+ import path4 from "node:path";
84456
+ var IndexEntrySchema = external_exports2.object({
84457
+ runId: external_exports2.string()
84458
+ });
84459
+ var ByRunMarkerSchema = external_exports2.object({
84460
+ hookId: external_exports2.string(),
84461
+ tag: external_exports2.string().optional()
84462
+ });
84463
+ var INDEX_COMPLETE_MARKER = ".hook-index-complete";
84464
+ function tokenIndexDir(basedir, token) {
84465
+ return resolveWithinBase(basedir, "hooks", "token-index", hashToken(token));
84466
+ }
84467
+ __name(tokenIndexDir, "tokenIndexDir");
84468
+ function idIndexDir(basedir, hookId) {
84469
+ assertSafeEntityId("hookId", hookId);
84470
+ return resolveWithinBase(basedir, "hooks", "id-index", hookId);
84471
+ }
84472
+ __name(idIndexDir, "idIndexDir");
84473
+ function byRunDir(basedir) {
84474
+ return resolveWithinBase(basedir, "hooks", "by-run");
84475
+ }
84476
+ __name(byRunDir, "byRunDir");
84477
+ function tagOf(fileId) {
84478
+ const stripped = stripTag(fileId);
84479
+ return stripped === fileId ? void 0 : fileId.slice(stripped.length + 1);
84480
+ }
84481
+ __name(tagOf, "tagOf");
84482
+ function isVisibleToTag(fileId, tag) {
84483
+ return tag ? isUntagged(fileId) || hasTag(fileId, tag) : isUntagged(fileId);
84484
+ }
84485
+ __name(isVisibleToTag, "isVisibleToTag");
84486
+ async function readEventLenient(filePath) {
84487
+ try {
84488
+ return await readJSON(filePath, EventSchema2);
84489
+ } catch (error95) {
84490
+ if (error95 instanceof SyntaxError || error95 instanceof external_exports2.ZodError) {
84491
+ return null;
84492
+ }
84493
+ throw error95;
84494
+ }
84495
+ }
84496
+ __name(readEventLenient, "readEventLenient");
84497
+ async function writeHookCreatedIndexEntries(basedir, token, runId, hookId, eventId, tag) {
84498
+ assertSafeEntityId("runId", runId);
84499
+ assertSafeEntityId("eventId", eventId);
84500
+ if (tag !== void 0)
84501
+ assertSafeEntityId("tag", tag);
84502
+ const fileName = tag ? `${eventId}.${tag}.json` : `${eventId}.json`;
84503
+ const content = JSON.stringify({ runId });
84504
+ await Promise.all([
84505
+ writeExclusive(path4.join(tokenIndexDir(basedir, token), fileName), content),
84506
+ writeExclusive(path4.join(idIndexDir(basedir, hookId), fileName), content)
84507
+ ]);
84508
+ }
84509
+ __name(writeHookCreatedIndexEntries, "writeHookCreatedIndexEntries");
84510
+ function hookByRunMarkerPath(basedir, runId, hookId, tag) {
84511
+ return taggedPath(basedir, "hooks/by-run", `${runId}-${hookId}`, tag);
84512
+ }
84513
+ __name(hookByRunMarkerPath, "hookByRunMarkerPath");
84514
+ async function writeHookByRunMarker(basedir, runId, hookId, tag) {
84515
+ await writeExclusive(hookByRunMarkerPath(basedir, runId, hookId, tag), JSON.stringify(tag ? { hookId, tag } : { hookId }));
84516
+ }
84517
+ __name(writeHookByRunMarker, "writeHookByRunMarker");
84518
+ async function deleteHookByRunMarker(basedir, runId, hookId, tag) {
84519
+ await deleteJSON(hookByRunMarkerPath(basedir, runId, hookId, tag));
84520
+ if (tag) {
84521
+ await deleteJSON(hookByRunMarkerPath(basedir, runId, hookId));
84368
84522
  }
84369
- if (idPrefix === "step") {
84523
+ }
84524
+ __name(deleteHookByRunMarker, "deleteHookByRunMarker");
84525
+ async function listHookByRunMarkers(basedir, runId) {
84526
+ assertSafeEntityId("runId", runId);
84527
+ const dir = byRunDir(basedir);
84528
+ const prefix = `${runId}-`;
84529
+ const out = [];
84530
+ for (const fileId of await listJSONFiles(dir)) {
84531
+ if (!fileId.startsWith(prefix))
84532
+ continue;
84533
+ let marker = null;
84534
+ try {
84535
+ marker = await readJSON(path4.join(dir, `${fileId}.json`), ByRunMarkerSchema);
84536
+ } catch (error95) {
84537
+ if (!(error95 instanceof SyntaxError || error95 instanceof external_exports2.ZodError)) {
84538
+ throw error95;
84539
+ }
84540
+ }
84541
+ out.push({
84542
+ fileId,
84543
+ hookId: marker?.hookId ?? null,
84544
+ tag: marker?.tag
84545
+ });
84546
+ }
84547
+ return out;
84548
+ }
84549
+ __name(listHookByRunMarkers, "listHookByRunMarkers");
84550
+ async function deleteHookByRunMarkerFile(basedir, fileId) {
84551
+ await deleteJSON(path4.join(byRunDir(basedir), `${fileId}.json`));
84552
+ }
84553
+ __name(deleteHookByRunMarkerFile, "deleteHookByRunMarkerFile");
84554
+ var ensuredBasedirs = /* @__PURE__ */ new Map();
84555
+ function resetHookIndexEnsureCache() {
84556
+ ensuredBasedirs.clear();
84557
+ }
84558
+ __name(resetHookIndexEnsureCache, "resetHookIndexEnsureCache");
84559
+ async function ensureHookIndexes(basedir) {
84560
+ const key = path4.resolve(basedir);
84561
+ let pending = ensuredBasedirs.get(key);
84562
+ if (!pending) {
84563
+ pending = ensureHookIndexesImpl(key).catch((error95) => {
84564
+ ensuredBasedirs.delete(key);
84565
+ throw error95;
84566
+ });
84567
+ ensuredBasedirs.set(key, pending);
84568
+ }
84569
+ return pending;
84570
+ }
84571
+ __name(ensureHookIndexes, "ensureHookIndexes");
84572
+ async function forEachConcurrent(items, concurrency, fn) {
84573
+ for (let start3 = 0; start3 < items.length; start3 += concurrency) {
84574
+ await Promise.all(items.slice(start3, start3 + concurrency).map(fn));
84575
+ }
84576
+ }
84577
+ __name(forEachConcurrent, "forEachConcurrent");
84578
+ async function ensureHookIndexesImpl(basedir) {
84579
+ const markerPath = path4.join(basedir, "hooks", INDEX_COMPLETE_MARKER);
84580
+ try {
84581
+ await fs3.access(markerPath);
84582
+ return;
84583
+ } catch {
84584
+ }
84585
+ const eventsDir = path4.join(basedir, "events");
84586
+ await forEachConcurrent(await listJSONFiles(eventsDir), 32, async (fileId) => {
84587
+ const event = await readEventLenient(path4.join(eventsDir, `${fileId}.json`));
84588
+ if (!event || event.eventType !== "hook_created")
84589
+ return;
84590
+ if (typeof event.correlationId !== "string")
84591
+ return;
84592
+ const token = event.eventData?.token;
84593
+ if (typeof token !== "string")
84594
+ return;
84595
+ try {
84596
+ await writeHookCreatedIndexEntries(basedir, token, event.runId, event.correlationId, event.eventId, tagOf(fileId));
84597
+ } catch {
84598
+ }
84599
+ });
84600
+ const hooksDir = path4.join(basedir, "hooks");
84601
+ await forEachConcurrent(await listJSONFiles(hooksDir), 32, async (fileId) => {
84602
+ let hook = null;
84603
+ try {
84604
+ hook = await readJSON(path4.join(hooksDir, `${fileId}.json`), HookSchema2);
84605
+ } catch (error95) {
84606
+ if (!(error95 instanceof SyntaxError || error95 instanceof external_exports2.ZodError)) {
84607
+ throw error95;
84608
+ }
84609
+ }
84610
+ if (!hook)
84611
+ return;
84612
+ try {
84613
+ await writeHookByRunMarker(basedir, hook.runId, hook.hookId, tagOf(fileId));
84614
+ } catch {
84615
+ }
84616
+ });
84617
+ await writeExclusive(markerPath, "");
84618
+ }
84619
+ __name(ensureHookIndexesImpl, "ensureHookIndexesImpl");
84620
+ async function findNewestIndexedHookCreatedEvent(basedir, index, matches, tag) {
84621
+ await ensureHookIndexes(basedir);
84622
+ let dir;
84623
+ try {
84624
+ dir = index.kind === "token" ? tokenIndexDir(basedir, index.token) : idIndexDir(basedir, index.hookId);
84625
+ } catch {
84370
84626
  return null;
84371
84627
  }
84372
- const id = cleanName.substring(dashIndex + 1).replace(/\.json$/, "");
84373
- const ulid8 = id.replace(replaceRegex, "");
84374
- return ulidToDate(ulid8);
84375
- }, "getObjectCreatedAt");
84628
+ const entryIds = (await listJSONFiles(dir)).filter((fileId) => isVisibleToTag(fileId, tag)).sort((a, b) => stripTag(b).localeCompare(stripTag(a)));
84629
+ for (const entryId of entryIds) {
84630
+ let entry = null;
84631
+ try {
84632
+ entry = await readJSON(path4.join(dir, `${entryId}.json`), IndexEntrySchema);
84633
+ } catch (error95) {
84634
+ if (!(error95 instanceof SyntaxError || error95 instanceof external_exports2.ZodError)) {
84635
+ throw error95;
84636
+ }
84637
+ }
84638
+ if (!entry)
84639
+ continue;
84640
+ const eventId = stripTag(entryId);
84641
+ let eventPath;
84642
+ try {
84643
+ eventPath = taggedPath(basedir, "events", `${entry.runId}-${eventId}`, tagOf(entryId));
84644
+ } catch {
84645
+ continue;
84646
+ }
84647
+ const event = await readEventLenient(eventPath);
84648
+ if (!event)
84649
+ continue;
84650
+ if (event.eventType !== "hook_created")
84651
+ continue;
84652
+ if (typeof event.correlationId !== "string")
84653
+ continue;
84654
+ if (!matches(event))
84655
+ continue;
84656
+ return event;
84657
+ }
84658
+ return null;
84659
+ }
84660
+ __name(findNewestIndexedHookCreatedEvent, "findNewestIndexedHookCreatedEvent");
84376
84661
 
84377
84662
  // ../world-local/dist/storage/events-storage.js
84378
84663
  init_dist7();
84379
84664
  init_dist5();
84380
84665
  init_zod2();
84381
- import fs3 from "node:fs/promises";
84382
- import path6 from "node:path";
84666
+ import fs4 from "node:fs/promises";
84667
+ import path7 from "node:path";
84383
84668
 
84384
84669
  // ../world-local/dist/storage/filters.js
84385
84670
  init_dist5();
@@ -84418,11 +84703,7 @@ __name(filterHookData, "filterHookData");
84418
84703
  init_dist7();
84419
84704
  init_dist5();
84420
84705
  init_zod2();
84421
- import path4 from "node:path";
84422
- function isVisibleToTag(fileId, tag) {
84423
- return tag ? isUntagged(fileId) || hasTag(fileId, tag) : isUntagged(fileId);
84424
- }
84425
- __name(isVisibleToTag, "isVisibleToTag");
84706
+ import path5 from "node:path";
84426
84707
  function getHookCreatedToken(event) {
84427
84708
  if (event.eventType !== "hook_created")
84428
84709
  return void 0;
@@ -84451,90 +84732,78 @@ function isMatchingHookCreatedEvent(event, matches) {
84451
84732
  return event.eventType === "hook_created" && typeof event.correlationId === "string" && matches(event);
84452
84733
  }
84453
84734
  __name(isMatchingHookCreatedEvent, "isMatchingHookCreatedEvent");
84454
- function closesLiveHook(event, liveEvent) {
84455
- if (event.runId !== liveEvent.runId)
84456
- return false;
84457
- return event.eventType === "hook_disposed" && event.correlationId === liveEvent.correlationId || isTerminalRunEventType(event.eventType);
84458
- }
84459
- __name(closesLiveHook, "closesLiveHook");
84460
- async function readEventForHookScan(filePath) {
84461
- try {
84462
- return await readJSON(filePath, EventSchema2);
84463
- } catch (error95) {
84464
- if (error95 instanceof SyntaxError || error95 instanceof external_exports2.ZodError) {
84465
- return null;
84466
- }
84467
- throw error95;
84468
- }
84469
- }
84470
- __name(readEventForHookScan, "readEventForHookScan");
84471
84735
  async function isTerminalRunCache(basedir, runId, tag) {
84472
84736
  const run3 = await readJSONWithFallback(basedir, "runs", runId, WorkflowRunSchema2, tag);
84473
84737
  return run3 ? isTerminalWorkflowRunStatus(run3.status) : false;
84474
84738
  }
84475
84739
  __name(isTerminalRunCache, "isTerminalRunCache");
84476
- async function findLiveHookCreatedEvent(basedir, matches, tag) {
84477
- const eventsDir = path4.join(basedir, "events");
84478
- const events = [];
84479
- for (const fileId of await listJSONFiles(eventsDir)) {
84480
- if (!isVisibleToTag(fileId, tag))
84481
- continue;
84482
- const event = await readEventForHookScan(path4.join(eventsDir, `${fileId}.json`));
84483
- if (event)
84484
- events.push(event);
84485
- }
84486
- events.sort((a, b) => {
84487
- const byTime = a.createdAt.getTime() - b.createdAt.getTime();
84488
- return byTime === 0 ? a.eventId.localeCompare(b.eventId) : byTime;
84489
- });
84490
- let liveEvent = null;
84491
- for (const event of events) {
84492
- if (isMatchingHookCreatedEvent(event, matches)) {
84493
- liveEvent = event;
84494
- continue;
84495
- }
84496
- if (liveEvent && closesLiveHook(event, liveEvent)) {
84497
- liveEvent = null;
84498
- }
84740
+ async function findLiveHookCreatedEvent(basedir, index, matches, tag) {
84741
+ const newest = await findNewestIndexedHookCreatedEvent(basedir, index, (event) => isMatchingHookCreatedEvent(event, matches), tag);
84742
+ if (!newest || !isMatchingHookCreatedEvent(newest, matches)) {
84743
+ return null;
84499
84744
  }
84500
- if (liveEvent && await isTerminalRunCache(basedir, liveEvent.runId, tag)) {
84745
+ if (await isTerminalRunCache(basedir, newest.runId, tag)) {
84501
84746
  return null;
84502
84747
  }
84503
- if (liveEvent && await isHookDisposalCommitted(basedir, liveEvent.correlationId, tag)) {
84748
+ if (await isHookDisposalCommitted(basedir, newest.correlationId, tag)) {
84504
84749
  return null;
84505
84750
  }
84506
- return liveEvent;
84751
+ return newest;
84507
84752
  }
84508
84753
  __name(findLiveHookCreatedEvent, "findLiveHookCreatedEvent");
84509
84754
  async function restoreHookCachesFromEvent(basedir, event, tag) {
84510
84755
  const hook = hookFromCreatedEvent(event);
84511
- const claimPath = path4.join(basedir, "hooks", "tokens", `${hashToken(hook.token)}.json`);
84756
+ const claimPath = path5.join(basedir, "hooks", "tokens", `${hashToken(hook.token)}.json`);
84512
84757
  await writeExclusive(claimPath, JSON.stringify({
84513
84758
  token: hook.token,
84514
84759
  hookId: hook.hookId,
84515
84760
  runId: hook.runId,
84516
84761
  eventId: event.eventId
84517
84762
  }));
84763
+ await writeHookByRunMarker(basedir, hook.runId, hook.hookId, tag);
84518
84764
  await writeExclusive(taggedPath(basedir, "hooks", hook.hookId, tag), JSON.stringify(hook, jsonReplacer, 2));
84519
84765
  return hook;
84520
84766
  }
84521
84767
  __name(restoreHookCachesFromEvent, "restoreHookCachesFromEvent");
84522
84768
  async function rebuildLiveHookByTokenFromEventLog(basedir, token, tag) {
84523
- const event = await findLiveHookCreatedEvent(basedir, (candidate) => getHookCreatedToken(candidate) === token, tag);
84769
+ const event = await findLiveHookCreatedEvent(basedir, { kind: "token", token }, (candidate) => getHookCreatedToken(candidate) === token, tag);
84524
84770
  return event ? restoreHookCachesFromEvent(basedir, event, tag) : null;
84525
84771
  }
84526
84772
  __name(rebuildLiveHookByTokenFromEventLog, "rebuildLiveHookByTokenFromEventLog");
84527
84773
  async function rebuildLiveHookByIdFromEventLog(basedir, hookId, tag) {
84528
- const event = await findLiveHookCreatedEvent(basedir, (candidate) => candidate.correlationId === hookId, tag);
84774
+ const event = await findLiveHookCreatedEvent(basedir, { kind: "id", hookId }, (candidate) => candidate.correlationId === hookId, tag);
84529
84775
  return event ? restoreHookCachesFromEvent(basedir, event, tag) : null;
84530
84776
  }
84531
84777
  __name(rebuildLiveHookByIdFromEventLog, "rebuildLiveHookByIdFromEventLog");
84532
84778
  function createHooksStorage(basedir, tag) {
84779
+ const TokenClaimPointerSchema = external_exports2.object({
84780
+ hookId: external_exports2.string().optional()
84781
+ });
84533
84782
  async function findHookByToken(token) {
84534
- const hooksDir = path4.join(basedir, "hooks");
84783
+ let claim = null;
84784
+ try {
84785
+ claim = await readJSON(hookTokenClaimPath(basedir, token), TokenClaimPointerSchema);
84786
+ } catch (error95) {
84787
+ if (!(error95 instanceof SyntaxError || error95 instanceof external_exports2.ZodError)) {
84788
+ throw error95;
84789
+ }
84790
+ }
84791
+ if (claim?.hookId) {
84792
+ try {
84793
+ const hook = await readJSONWithFallback(basedir, "hooks", claim.hookId, HookSchema2, tag);
84794
+ if (hook && hook.token === token) {
84795
+ return { ...hook, isWebhook: hook.isWebhook ?? true };
84796
+ }
84797
+ } catch (error95) {
84798
+ if (!UnsafeEntityIdError.is(error95)) {
84799
+ throw error95;
84800
+ }
84801
+ }
84802
+ }
84803
+ const hooksDir = path5.join(basedir, "hooks");
84535
84804
  const files = await listJSONFiles(hooksDir);
84536
84805
  for (const file3 of files) {
84537
- const hookPath = path4.join(hooksDir, `${file3}.json`);
84806
+ const hookPath = path5.join(hooksDir, `${file3}.json`);
84538
84807
  const hook = await readJSON(hookPath, HookSchema2);
84539
84808
  if (hook && hook.token === token) {
84540
84809
  return { ...hook, isWebhook: hook.isWebhook ?? true };
@@ -84567,7 +84836,7 @@ function createHooksStorage(basedir, tag) {
84567
84836
  }
84568
84837
  __name(getByToken, "getByToken");
84569
84838
  async function list(params) {
84570
- const hooksDir = path4.join(basedir, "hooks");
84839
+ const hooksDir = path5.join(basedir, "hooks");
84571
84840
  const resolveData = params.resolveData || DEFAULT_RESOLVE_DATA_OPTION;
84572
84841
  const result = await paginatedFileSystemQuery({
84573
84842
  directory: hooksDir,
@@ -84598,16 +84867,26 @@ function createHooksStorage(basedir, tag) {
84598
84867
  }
84599
84868
  __name(createHooksStorage, "createHooksStorage");
84600
84869
  async function deleteAllHooksForRun(basedir, runId) {
84601
- const hooksDir = path4.join(basedir, "hooks");
84602
- const files = await listJSONFiles(hooksDir);
84603
- for (const file3 of files) {
84604
- const hookPath = path4.join(hooksDir, `${file3}.json`);
84605
- const hook = await readJSON(hookPath, HookSchema2);
84606
- if (hook && hook.runId === runId) {
84607
- await releaseHookTokenClaimIfOwnedBy(basedir, hook.token, hook.runId, hook.hookId);
84608
- await deleteJSON(hookRecoveryMarkerPath(basedir, hook.token, hook.runId, hook.hookId));
84609
- await deleteJSON(hookPath);
84870
+ await ensureHookIndexes(basedir);
84871
+ for (const marker of await listHookByRunMarkers(basedir, runId)) {
84872
+ if (marker.hookId) {
84873
+ let hook = null;
84874
+ let hookPath = null;
84875
+ try {
84876
+ hookPath = taggedPath(basedir, "hooks", marker.hookId, marker.tag);
84877
+ hook = await readJSON(hookPath, HookSchema2);
84878
+ } catch (error95) {
84879
+ if (!UnsafeEntityIdError.is(error95) && !(error95 instanceof SyntaxError || error95 instanceof external_exports2.ZodError)) {
84880
+ throw error95;
84881
+ }
84882
+ }
84883
+ if (hook && hookPath && hook.runId === runId) {
84884
+ await releaseHookTokenClaimIfOwnedBy(basedir, hook.token, hook.runId, hook.hookId);
84885
+ await deleteJSON(hookRecoveryMarkerPath(basedir, hook.token, hook.runId, hook.hookId));
84886
+ await deleteJSON(hookPath);
84887
+ }
84610
84888
  }
84889
+ await deleteHookByRunMarkerFile(basedir, marker.fileId);
84611
84890
  }
84612
84891
  }
84613
84892
  __name(deleteAllHooksForRun, "deleteAllHooksForRun");
@@ -84670,7 +84949,7 @@ __name(handleLegacyEvent, "handleLegacyEvent");
84670
84949
  // ../world-local/dist/storage/runs-storage.js
84671
84950
  init_dist7();
84672
84951
  init_dist5();
84673
- import path5 from "node:path";
84952
+ import path6 from "node:path";
84674
84953
  var runFileLocks = /* @__PURE__ */ new Map();
84675
84954
  function withRunFileLock(key, fn) {
84676
84955
  const prev = runFileLocks.get(key);
@@ -84705,7 +84984,7 @@ function createRunsStorage(basedir, tag) {
84705
84984
  list: /* @__PURE__ */ __name((async (params) => {
84706
84985
  const resolveData = params?.resolveData ?? DEFAULT_RESOLVE_DATA_OPTION;
84707
84986
  const result = await paginatedFileSystemQuery({
84708
- directory: path5.join(basedir, "runs"),
84987
+ directory: path6.join(basedir, "runs"),
84709
84988
  schema: WorkflowRunSchema2,
84710
84989
  fileIdFilter: params?.fileIdFilter,
84711
84990
  filter: /* @__PURE__ */ __name((run3) => {
@@ -84718,7 +84997,10 @@ function createRunsStorage(basedir, tag) {
84718
84997
  return true;
84719
84998
  }, "filter"),
84720
84999
  sortOrder: params?.pagination?.sortOrder ?? "desc",
84721
- limit: params?.pagination?.limit,
85000
+ // Each page pays a full directory scan, so larger default pages
85001
+ // keep unpaginated consumers (e.g. startup recovery) cheap over
85002
+ // large run histories.
85003
+ limit: params?.pagination?.limit ?? 200,
84722
85004
  cursor: params?.pagination?.cursor,
84723
85005
  getCreatedAt: getObjectCreatedAt("wrun"),
84724
85006
  getId: /* @__PURE__ */ __name((run3) => run3.runId, "getId")
@@ -84827,7 +85109,7 @@ async function readHookRecoveryMarker(markerPath) {
84827
85109
  __name(readHookRecoveryMarker, "readHookRecoveryMarker");
84828
85110
  async function findExistingHookCreatedEventId(basedir, runId, correlationId) {
84829
85111
  const result = await paginatedFileSystemQuery({
84830
- directory: path6.join(basedir, "events"),
85112
+ directory: path7.join(basedir, "events"),
84831
85113
  schema: EventSchema2,
84832
85114
  filePrefix: `${runId}-`,
84833
85115
  filter: /* @__PURE__ */ __name((event) => event.eventType === "hook_created" && event.correlationId === correlationId, "filter"),
@@ -84865,6 +85147,8 @@ async function repairHookEntityFromPersistedEvent(basedir, runId, hookId, persis
84865
85147
  isWebhook: eventData.isWebhook ?? true,
84866
85148
  isSystem: eventData.isSystem ?? false
84867
85149
  };
85150
+ await writeHookCreatedIndexEntries(basedir, eventData.token, runId, hookId, persistedEventId, tag);
85151
+ await writeHookByRunMarker(basedir, runId, hookId, tag);
84868
85152
  await writeExclusive(taggedPath(basedir, "hooks", hookId, tag), JSON.stringify(hook, jsonReplacer, 2));
84869
85153
  }
84870
85154
  __name(repairHookEntityFromPersistedEvent, "repairHookEntityFromPersistedEvent");
@@ -84900,11 +85184,11 @@ function withInProcessLock(locks, key, fn) {
84900
85184
  }
84901
85185
  __name(withInProcessLock, "withInProcessLock");
84902
85186
  async function deleteAllWaitsForRun(basedir, runId) {
84903
- const waitsDir = path6.join(basedir, "waits");
85187
+ const waitsDir = path7.join(basedir, "waits");
84904
85188
  const files = await listJSONFiles(waitsDir);
84905
85189
  for (const file3 of files) {
84906
85190
  if (file3.startsWith(`${runId}-`)) {
84907
- const waitPath = path6.join(waitsDir, `${file3}.json`);
85191
+ const waitPath = path7.join(waitsDir, `${file3}.json`);
84908
85192
  await deleteJSON(waitPath);
84909
85193
  }
84910
85194
  }
@@ -85616,6 +85900,7 @@ function createEventsStorage(basedir, tag) {
85616
85900
  isSystem: hookData.isSystem ?? false
85617
85901
  };
85618
85902
  hookEntityWriteOptions = writeHookEntityWithOverwrite ? { overwrite: true } : void 0;
85903
+ await writeHookCreatedIndexEntries(basedir, hookData.token, effectiveRunId, data.correlationId, eventId, tag);
85619
85904
  } else if (data.eventType === "hook_disposed") {
85620
85905
  const lockPath = hookDisposeLockPath(basedir, data.correlationId, tag);
85621
85906
  const claimed = await writeExclusive(lockPath, "");
@@ -85629,6 +85914,7 @@ function createEventsStorage(basedir, tag) {
85629
85914
  await deleteJSON(hookRecoveryMarkerPath(basedir, existingHook.token, existingHook.runId, existingHook.hookId));
85630
85915
  }
85631
85916
  await deleteJSON(hookPath);
85917
+ await deleteHookByRunMarker(basedir, effectiveRunId, data.correlationId, tag);
85632
85918
  } else if (data.eventType === "wait_created" && "eventData" in data) {
85633
85919
  const waitCompositeKey = `${effectiveRunId}-${data.correlationId}`;
85634
85920
  const waitCreatedLockName = tag ? `${waitCompositeKey}.created.${tag}` : `${waitCompositeKey}.created`;
@@ -85659,7 +85945,7 @@ function createEventsStorage(basedir, tag) {
85659
85945
  }
85660
85946
  const existingWait = await readJSONWithFallback(basedir, "waits", waitCompositeKey, WaitSchema2, tag);
85661
85947
  if (!existingWait) {
85662
- await fs3.unlink(lockPath).catch(() => {
85948
+ await fs4.unlink(lockPath).catch(() => {
85663
85949
  });
85664
85950
  throw new WorkflowWorldError2(`Wait "${data.correlationId}" not found`);
85665
85951
  }
@@ -85686,6 +85972,7 @@ function createEventsStorage(basedir, tag) {
85686
85972
  }
85687
85973
  rememberStoredEvent(event, eventPath, serializedEvent);
85688
85974
  if (hook && data.eventType === "hook_created") {
85975
+ await writeHookByRunMarker(basedir, hook.runId, hook.hookId, tag);
85689
85976
  await writeJSON(taggedPath(basedir, "hooks", hook.hookId, tag), hook, hookEntityWriteOptions);
85690
85977
  }
85691
85978
  const resolveData = params?.resolveData ?? DEFAULT_RESOLVE_DATA_OPTION;
@@ -85695,7 +85982,7 @@ function createEventsStorage(basedir, tag) {
85695
85982
  let hasMore;
85696
85983
  if (data.eventType === "run_started" && run3) {
85697
85984
  const allEvents = await paginatedFileSystemQuery({
85698
- directory: path6.join(basedir, "events"),
85985
+ directory: path7.join(basedir, "events"),
85699
85986
  schema: EventSchema2,
85700
85987
  cachedItems: eventCache,
85701
85988
  filePrefix: `${effectiveRunId}-`,
@@ -85710,7 +85997,7 @@ function createEventsStorage(basedir, tag) {
85710
85997
  }
85711
85998
  if ((data.eventType === "step_completed" || data.eventType === "step_failed") && typeof params?.sinceCursor === "string") {
85712
85999
  const delta = await paginatedFileSystemQuery({
85713
- directory: path6.join(basedir, "events"),
86000
+ directory: path7.join(basedir, "events"),
85714
86001
  schema: EventSchema2,
85715
86002
  filePrefix: `${effectiveRunId}-`,
85716
86003
  sortOrder: "asc",
@@ -85752,7 +86039,7 @@ function createEventsStorage(basedir, tag) {
85752
86039
  assertSafeEntityId("runId", runId);
85753
86040
  const resolveData = params.resolveData ?? DEFAULT_RESOLVE_DATA_OPTION;
85754
86041
  const result = await paginatedFileSystemQuery({
85755
- directory: path6.join(basedir, "events"),
86042
+ directory: path7.join(basedir, "events"),
85756
86043
  schema: EventSchema2,
85757
86044
  cachedItems: eventCache,
85758
86045
  filePrefix: `${runId}-`,
@@ -85777,7 +86064,7 @@ function createEventsStorage(basedir, tag) {
85777
86064
  assertSafeEntityId("correlationId", correlationId);
85778
86065
  const resolveData = params.resolveData ?? DEFAULT_RESOLVE_DATA_OPTION;
85779
86066
  const result = await paginatedFileSystemQuery({
85780
- directory: path6.join(basedir, "events"),
86067
+ directory: path7.join(basedir, "events"),
85781
86068
  schema: EventSchema2,
85782
86069
  cachedItems: eventCache,
85783
86070
  // No filePrefix - search all events
@@ -85804,7 +86091,7 @@ __name(createEventsStorage, "createEventsStorage");
85804
86091
 
85805
86092
  // ../world-local/dist/storage/steps-storage.js
85806
86093
  init_dist5();
85807
- import path7 from "node:path";
86094
+ import path8 from "node:path";
85808
86095
  function createStepsStorage(basedir, tag) {
85809
86096
  return {
85810
86097
  get: /* @__PURE__ */ __name((async (runId, stepId, params) => {
@@ -85822,7 +86109,7 @@ function createStepsStorage(basedir, tag) {
85822
86109
  assertSafeEntityId("runId", params.runId);
85823
86110
  const resolveData = params.resolveData ?? DEFAULT_RESOLVE_DATA_OPTION;
85824
86111
  const result = await paginatedFileSystemQuery({
85825
- directory: path7.join(basedir, "steps"),
86112
+ directory: path8.join(basedir, "steps"),
85826
86113
  schema: StepSchema2,
85827
86114
  filePrefix: `${params.runId}-`,
85828
86115
  sortOrder: params.pagination?.sortOrder ?? "desc",
@@ -85867,8 +86154,8 @@ __name(createStorage, "createStorage");
85867
86154
  init_node2();
85868
86155
  init_zod2();
85869
86156
  import { EventEmitter } from "node:events";
85870
- import fs4 from "node:fs/promises";
85871
- import path8 from "node:path";
86157
+ import fs5 from "node:fs/promises";
86158
+ import path9 from "node:path";
85872
86159
  var monotonicUlid2 = monotonicFactory2(() => Math.random());
85873
86160
  var RunStreamsSchema = external_exports2.object({
85874
86161
  streams: external_exports2.array(external_exports2.string())
@@ -85895,7 +86182,7 @@ function deserializeChunk(serialized) {
85895
86182
  __name(deserializeChunk, "deserializeChunk");
85896
86183
  async function listChunkEntries(chunksDir) {
85897
86184
  try {
85898
- return await fs4.readdir(chunksDir);
86185
+ return await fs5.readdir(chunksDir);
85899
86186
  } catch (error95) {
85900
86187
  if (error95.code === "ENOENT")
85901
86188
  return [];
@@ -85915,7 +86202,7 @@ function addChunkFilesByExtension(extMap, entries, sourceExtension, fileExtensio
85915
86202
  __name(addChunkFilesByExtension, "addChunkFilesByExtension");
85916
86203
  function chunkDirForStream(chunksBaseDir, name) {
85917
86204
  assertSafeEntityId("streamName", name);
85918
- return path8.join(chunksBaseDir, name);
86205
+ return path9.join(chunksBaseDir, name);
85919
86206
  }
85920
86207
  __name(chunkDirForStream, "chunkDirForStream");
85921
86208
  async function listChunkFilesForStream(chunksBaseDir, name, tag) {
@@ -85974,7 +86261,7 @@ function createStreamer(basedir, tag) {
85974
86261
  chunk: chunkBuffer,
85975
86262
  eof: false
85976
86263
  });
85977
- const chunkPath = path8.join(chunkDirForStream(path8.join(basedir, "streams", "chunks"), name), `${chunkId}${tagSuffix}.bin`);
86264
+ const chunkPath = path9.join(chunkDirForStream(path9.join(basedir, "streams", "chunks"), name), `${chunkId}${tagSuffix}.bin`);
85978
86265
  await write(chunkPath, serialized);
85979
86266
  const chunkData = Uint8Array.from(chunkBuffer);
85980
86267
  streamEmitter.emit(`chunk:${name}`, {
@@ -85996,7 +86283,7 @@ function createStreamer(basedir, tag) {
85996
86283
  chunk: chunkBuffer,
85997
86284
  eof: false
85998
86285
  });
85999
- const chunkPath = path8.join(chunkDirForStream(path8.join(basedir, "streams", "chunks"), name), `${chunkId}${tagSuffix}.bin`);
86286
+ const chunkPath = path9.join(chunkDirForStream(path9.join(basedir, "streams", "chunks"), name), `${chunkId}${tagSuffix}.bin`);
86000
86287
  await write(chunkPath, serialized);
86001
86288
  return {
86002
86289
  chunkId,
@@ -86016,7 +86303,7 @@ function createStreamer(basedir, tag) {
86016
86303
  const chunkId = `chnk_${monotonicUlid2()}`;
86017
86304
  const runId = await _runId;
86018
86305
  await registerStreamForRun(runId, name);
86019
- const chunkPath = path8.join(chunkDirForStream(path8.join(basedir, "streams", "chunks"), name), `${chunkId}${tagSuffix}.bin`);
86306
+ const chunkPath = path9.join(chunkDirForStream(path9.join(basedir, "streams", "chunks"), name), `${chunkId}${tagSuffix}.bin`);
86020
86307
  await write(chunkPath, serializeChunk({ chunk: Buffer.from([]), eof: true }));
86021
86308
  streamEmitter.emit(`close:${name}`, { streamName: name });
86022
86309
  },
@@ -86027,7 +86314,7 @@ function createStreamer(basedir, tag) {
86027
86314
  },
86028
86315
  async getChunks(_runId, name, options) {
86029
86316
  const limit = options?.limit ?? 100;
86030
- const chunksBaseDir = path8.join(basedir, "streams", "chunks");
86317
+ const chunksBaseDir = path9.join(basedir, "streams", "chunks");
86031
86318
  const { files: chunkFiles, extMap: fileExtMap, dir: chunksDir } = await listChunkFilesForStream(chunksBaseDir, name, tag);
86032
86319
  let startIndex = 0;
86033
86320
  if (options?.cursor) {
@@ -86043,7 +86330,7 @@ function createStreamer(basedir, tag) {
86043
86330
  let dataIndex = 0;
86044
86331
  for (const file3 of chunkFiles) {
86045
86332
  const ext = fileExtMap.get(file3) ?? ".bin";
86046
- const filePath = path8.join(chunksDir, `${file3}${ext}`);
86333
+ const filePath = path9.join(chunksDir, `${file3}${ext}`);
86047
86334
  if (dataIndex < startIndex) {
86048
86335
  if (isEofByte(await readFirstByte(filePath))) {
86049
86336
  streamDone = true;
@@ -86082,13 +86369,13 @@ function createStreamer(basedir, tag) {
86082
86369
  };
86083
86370
  },
86084
86371
  async getInfo(_runId, name) {
86085
- const chunksBaseDir = path8.join(basedir, "streams", "chunks");
86372
+ const chunksBaseDir = path9.join(basedir, "streams", "chunks");
86086
86373
  const { files: chunkFiles, extMap: fileExtMap, dir: chunksDir } = await listChunkFilesForStream(chunksBaseDir, name, tag);
86087
86374
  let streamDone = false;
86088
86375
  let dataCount = 0;
86089
86376
  for (const file3 of chunkFiles) {
86090
86377
  const ext = fileExtMap.get(file3) ?? ".bin";
86091
- if (isEofByte(await readFirstByte(path8.join(chunksDir, `${file3}${ext}`)))) {
86378
+ if (isEofByte(await readFirstByte(path9.join(chunksDir, `${file3}${ext}`)))) {
86092
86379
  streamDone = true;
86093
86380
  break;
86094
86381
  }
@@ -86097,7 +86384,7 @@ function createStreamer(basedir, tag) {
86097
86384
  return { tailIndex: dataCount - 1, done: streamDone };
86098
86385
  },
86099
86386
  async get(_runId, name, startIndex = 0) {
86100
- const chunksBaseDir = path8.join(basedir, "streams", "chunks");
86387
+ const chunksBaseDir = path9.join(basedir, "streams", "chunks");
86101
86388
  let teardown = /* @__PURE__ */ __name(() => {
86102
86389
  }, "teardown");
86103
86390
  let pollInterval = null;
@@ -86151,7 +86438,7 @@ function createStreamer(basedir, tag) {
86151
86438
  if (typeof startIndex === "number" && startIndex < 0 && chunkFiles.length > 0) {
86152
86439
  const lastFile = chunkFiles[chunkFiles.length - 1];
86153
86440
  const lastExt = fileExtMap.get(lastFile) ?? ".bin";
86154
- if (isEofByte(await readFirstByte(path8.join(chunksDir, `${lastFile}${lastExt}`)))) {
86441
+ if (isEofByte(await readFirstByte(path9.join(chunksDir, `${lastFile}${lastExt}`)))) {
86155
86442
  dataChunkCount--;
86156
86443
  }
86157
86444
  }
@@ -86164,7 +86451,7 @@ function createStreamer(basedir, tag) {
86164
86451
  continue;
86165
86452
  }
86166
86453
  const ext = fileExtMap.get(file3) ?? ".bin";
86167
- const chunk = deserializeChunk(await readBuffer(path8.join(chunksDir, `${file3}${ext}`)));
86454
+ const chunk = deserializeChunk(await readBuffer(path9.join(chunksDir, `${file3}${ext}`)));
86168
86455
  if (chunk?.eof === true) {
86169
86456
  isComplete = true;
86170
86457
  break;
@@ -86217,7 +86504,7 @@ function createStreamer(basedir, tag) {
86217
86504
  continue;
86218
86505
  deliveredChunkIds.add(chunkId);
86219
86506
  const ext = currentExtMap.get(file3) ?? ".bin";
86220
- const chunk = deserializeChunk(await readBuffer(path8.join(chunksDir, `${file3}${ext}`)));
86507
+ const chunk = deserializeChunk(await readBuffer(path9.join(chunksDir, `${file3}${ext}`)));
86221
86508
  if (chunk?.eof === true) {
86222
86509
  streamClosed = true;
86223
86510
  teardown();
@@ -86294,13 +86581,13 @@ function createWorld(args) {
86294
86581
  clearStorageCache();
86295
86582
  if (tag) {
86296
86583
  const basedir = mergedConfig.dataDir;
86297
- const hooksDir = path9.join(basedir, "hooks");
86584
+ const hooksDir = path10.join(basedir, "hooks");
86298
86585
  const taggedHookFiles = await listTaggedFiles(hooksDir, tag);
86299
86586
  const { HookSchema: HookSchema3 } = await Promise.resolve().then(() => (init_dist5(), dist_exports));
86300
86587
  await Promise.all(taggedHookFiles.map(async (hookFile) => {
86301
- const hook = await readJSON(path9.join(hooksDir, hookFile), HookSchema3);
86588
+ const hook = await readJSON(path10.join(hooksDir, hookFile), HookSchema3);
86302
86589
  if (hook?.token) {
86303
- await deleteJSON(path9.join(hooksDir, "tokens", `${hashToken(hook.token)}.json`));
86590
+ await deleteJSON(path10.join(hooksDir, "tokens", `${hashToken(hook.token)}.json`));
86304
86591
  await deleteJSON(hookRecoveryMarkerPath(basedir, hook.token, hook.runId, hook.hookId));
86305
86592
  }
86306
86593
  }));
@@ -86309,34 +86596,52 @@ function createWorld(args) {
86309
86596
  "steps",
86310
86597
  "events",
86311
86598
  "hooks",
86599
+ "hooks/by-run",
86312
86600
  "waits",
86313
86601
  "streams/runs"
86314
86602
  ];
86315
86603
  await Promise.all(entityDirs.map(async (dir) => {
86316
- const fullDir = path9.join(basedir, dir);
86604
+ const fullDir = path10.join(basedir, dir);
86317
86605
  const files = await listTaggedFiles(fullDir, tag);
86318
- await Promise.all(files.map((f) => deleteJSON(path9.join(fullDir, f))));
86606
+ await Promise.all(files.map((f) => deleteJSON(path10.join(fullDir, f))));
86319
86607
  }));
86320
- await fs5.rm(path9.join(basedir, ".locks"), { recursive: true, force: true }).catch(() => {
86608
+ for (const indexDir of ["token-index", "id-index"]) {
86609
+ const fullIndexDir = path10.join(basedir, "hooks", indexDir);
86610
+ let keyDirEntries;
86611
+ try {
86612
+ keyDirEntries = await fs6.readdir(fullIndexDir, {
86613
+ withFileTypes: true
86614
+ });
86615
+ } catch {
86616
+ keyDirEntries = [];
86617
+ }
86618
+ await Promise.all(keyDirEntries.filter((entry) => entry.isDirectory()).map(async (entry) => {
86619
+ const keyDir = path10.join(fullIndexDir, entry.name);
86620
+ const taggedEntryFiles = await listTaggedFiles(keyDir, tag);
86621
+ await Promise.all(taggedEntryFiles.map((f) => deleteJSON(path10.join(keyDir, f))));
86622
+ }));
86623
+ }
86624
+ await fs6.rm(path10.join(basedir, ".locks"), { recursive: true, force: true }).catch(() => {
86321
86625
  });
86322
- const chunksDir = path9.join(basedir, "streams", "chunks");
86626
+ const chunksDir = path10.join(basedir, "streams", "chunks");
86323
86627
  let streamDirEntries;
86324
86628
  try {
86325
- streamDirEntries = await fs5.readdir(chunksDir, {
86629
+ streamDirEntries = await fs6.readdir(chunksDir, {
86326
86630
  withFileTypes: true
86327
86631
  });
86328
86632
  } catch {
86329
86633
  streamDirEntries = [];
86330
86634
  }
86331
86635
  await Promise.all(streamDirEntries.filter((entry) => entry.isDirectory()).map(async (entry) => {
86332
- const streamChunkDir = path9.join(chunksDir, entry.name);
86636
+ const streamChunkDir = path10.join(chunksDir, entry.name);
86333
86637
  const taggedBinFiles = await listTaggedFilesByExtension(streamChunkDir, tag, ".bin");
86334
- await Promise.all(taggedBinFiles.map((f) => fs5.unlink(path9.join(streamChunkDir, f)).catch(() => {
86638
+ await Promise.all(taggedBinFiles.map((f) => fs6.unlink(path10.join(streamChunkDir, f)).catch(() => {
86335
86639
  })));
86336
86640
  }));
86337
86641
  clearCreatedFilesCache();
86338
86642
  } else {
86339
86643
  clearCreatedFilesCache();
86644
+ resetHookIndexEnsureCache();
86340
86645
  await rm(mergedConfig.dataDir, { recursive: true, force: true });
86341
86646
  await initDataDir(mergedConfig.dataDir);
86342
86647
  }
@@ -86991,6 +87296,19 @@ async function handleReplayBudgetExhausted(args) {
86991
87296
  }
86992
87297
  __name(handleReplayBudgetExhausted, "handleReplayBudgetExhausted");
86993
87298
 
87299
+ // ../core/dist/runtime/run-id-time.js
87300
+ init_node2();
87301
+ var RUN_ID_PREFIX = "wrun_";
87302
+ function runIdCreatedAt(runId) {
87303
+ const ulidPart = runId.startsWith(RUN_ID_PREFIX) ? runId.slice(RUN_ID_PREFIX.length) : runId;
87304
+ try {
87305
+ return decodeTime(ulidPart);
87306
+ } catch {
87307
+ return void 0;
87308
+ }
87309
+ }
87310
+ __name(runIdCreatedAt, "runIdCreatedAt");
87311
+
86994
87312
  // ../core/dist/runtime/step-executor.js
86995
87313
  init_dist7();
86996
87314
  init_dist6();
@@ -87128,6 +87446,82 @@ __name(getPortLazy, "getPortLazy");
87128
87446
 
87129
87447
  // ../core/dist/runtime/step-executor.js
87130
87448
  init_helpers2();
87449
+
87450
+ // ../core/dist/runtime/step-latency.js
87451
+ var TTFS_DISQUALIFYING_EVENT_TYPES = /* @__PURE__ */ new Set([
87452
+ "step_created",
87453
+ "step_started",
87454
+ "step_completed",
87455
+ "step_failed",
87456
+ "step_retrying",
87457
+ "hook_received",
87458
+ "wait_created",
87459
+ "wait_completed"
87460
+ ]);
87461
+ function computeStepLatencyTracking(params) {
87462
+ const { events } = params;
87463
+ let ttfsEligible = params.invocationStartedClean && params.runCreatedAtMs !== void 0 && !params.suspensionHasWaits;
87464
+ let preStepAttrStartMs;
87465
+ if (ttfsEligible) {
87466
+ for (const event of events) {
87467
+ if (TTFS_DISQUALIFYING_EVENT_TYPES.has(event.eventType)) {
87468
+ ttfsEligible = false;
87469
+ break;
87470
+ }
87471
+ if (event.eventType === "attr_set") {
87472
+ const attrStartMs = +(event.occurredAt ?? event.createdAt);
87473
+ preStepAttrStartMs = preStepAttrStartMs === void 0 ? attrStartMs : Math.min(preStepAttrStartMs, attrStartMs);
87474
+ }
87475
+ }
87476
+ }
87477
+ let prevStepEndMs;
87478
+ const lastEvent = events[events.length - 1];
87479
+ if (!params.suspensionHasWaits && !params.suspensionCreatedHooks && lastEvent && (lastEvent.eventType === "step_completed" || lastEvent.eventType === "step_failed")) {
87480
+ prevStepEndMs = +(lastEvent.occurredAt ?? lastEvent.createdAt);
87481
+ }
87482
+ if (!ttfsEligible && prevStepEndMs === void 0) {
87483
+ return void 0;
87484
+ }
87485
+ return {
87486
+ ...ttfsEligible ? {
87487
+ ttfsAnchorMs: params.runCreatedAtMs,
87488
+ // When the measurement ends at the first attr write, only hook
87489
+ // time from before that point is inside the measured window.
87490
+ preStepBlockingMs: preStepAttrStartMs !== void 0 ? params.preStepBlockingBeforeAttrMs ?? 0 : params.preStepBlockingMs,
87491
+ ...preStepAttrStartMs !== void 0 ? { preStepAttrStartMs } : {}
87492
+ } : {},
87493
+ ...prevStepEndMs !== void 0 ? { prevStepEndMs } : {},
87494
+ turbo: params.turbo
87495
+ };
87496
+ }
87497
+ __name(computeStepLatencyTracking, "computeStepLatencyTracking");
87498
+ function computeStepLatencyEventData(params) {
87499
+ const { tracking } = params;
87500
+ if (!tracking || params.attempt !== 1) {
87501
+ return void 0;
87502
+ }
87503
+ const ttfsEndMs = tracking.preStepAttrStartMs ?? params.stepCodeStartedAtMs;
87504
+ const ttfs = tracking.ttfsAnchorMs !== void 0 ? Math.max(0, ttfsEndMs - tracking.ttfsAnchorMs - (tracking.preStepBlockingMs ?? 0)) : void 0;
87505
+ const stso = tracking.prevStepEndMs !== void 0 ? Math.max(0, params.stepCodeStartedAtMs - tracking.prevStepEndMs) : void 0;
87506
+ if (ttfs === void 0 && stso === void 0) {
87507
+ return void 0;
87508
+ }
87509
+ const optimizations = [];
87510
+ if (tracking.turbo)
87511
+ optimizations.push("turbo");
87512
+ if (params.lazyStepStart)
87513
+ optimizations.push("lazyStepStart");
87514
+ if (params.optimisticStart)
87515
+ optimizations.push("optimisticStart");
87516
+ return {
87517
+ ...ttfs !== void 0 ? { ttfs } : {},
87518
+ ...stso !== void 0 ? { stso } : {},
87519
+ optimizations
87520
+ };
87521
+ }
87522
+ __name(computeStepLatencyEventData, "computeStepLatencyEventData");
87523
+
87524
+ // ../core/dist/runtime/step-executor.js
87131
87525
  init_wait_until2();
87132
87526
  var DEFAULT_STEP_MAX_RETRIES = 3;
87133
87527
  function extractInlineDelta(result, requested) {
@@ -87356,6 +87750,7 @@ async function executeStep(params) {
87356
87750
  const preCompletionOps = [];
87357
87751
  const ops = [];
87358
87752
  let opsSettled = true;
87753
+ let latencyEventData;
87359
87754
  try {
87360
87755
  const attempt = step.attempt;
87361
87756
  if (!step.startedAt) {
@@ -87379,6 +87774,20 @@ async function executeStep(params) {
87379
87774
  let userCodeError;
87380
87775
  let userCodeFailed = false;
87381
87776
  const executionStartTime = Date.now();
87777
+ latencyEventData = computeStepLatencyEventData({
87778
+ tracking: params.latencyTracking,
87779
+ stepCodeStartedAtMs: executionStartTime,
87780
+ attempt,
87781
+ lazyStepStart: params.lazyStepInput !== void 0,
87782
+ optimisticStart
87783
+ });
87784
+ if (latencyEventData) {
87785
+ span?.setAttributes({
87786
+ ...latencyEventData.ttfs !== void 0 ? StepTtfsMs2(latencyEventData.ttfs) : {},
87787
+ ...latencyEventData.stso !== void 0 ? StepStsoMs2(latencyEventData.stso) : {},
87788
+ ...StepLatencyOptimizations2(latencyEventData.optimizations ?? [])
87789
+ });
87790
+ }
87382
87791
  try {
87383
87792
  result = await trace4("step.execute", {}, async () => {
87384
87793
  return await contextStorage2.run({
@@ -87514,7 +87923,8 @@ async function executeStep(params) {
87514
87923
  correlationId: stepId,
87515
87924
  eventData: {
87516
87925
  stepName,
87517
- error: await dehydrateStepError(effectiveErr, workflowRunId, await getEncryptionKey(), [], globalThis, compression)
87926
+ error: await dehydrateStepError(effectiveErr, workflowRunId, await getEncryptionKey(), [], globalThis, compression),
87927
+ ...latencyEventData
87518
87928
  }
87519
87929
  });
87520
87930
  } catch (stepFailErr) {
@@ -87561,7 +87971,8 @@ async function executeStep(params) {
87561
87971
  correlationId: stepId,
87562
87972
  eventData: {
87563
87973
  stepName,
87564
- error: await dehydrateStepError(wrappedError, workflowRunId, await getEncryptionKey(), [], globalThis, compression)
87974
+ error: await dehydrateStepError(wrappedError, workflowRunId, await getEncryptionKey(), [], globalThis, compression),
87975
+ ...latencyEventData
87565
87976
  }
87566
87977
  });
87567
87978
  } catch (stepFailErr) {
@@ -87639,7 +88050,8 @@ async function executeStep(params) {
87639
88050
  eventData: {
87640
88051
  stepName,
87641
88052
  workflowName,
87642
- result
88053
+ result,
88054
+ ...latencyEventData
87643
88055
  }
87644
88056
  }, params.inlineDeltaSinceCursor !== void 0 ? { sinceCursor: params.inlineDeltaSinceCursor } : void 0);
87645
88057
  } catch (err) {
@@ -87795,7 +88207,9 @@ async function handleSuspension({ suspension, world, run: run3, span, requestId,
87795
88207
  __name(disposeHook, "disposeHook");
87796
88208
  let hasHookConflict = false;
87797
88209
  let hasAwaitedHookCreation = false;
88210
+ let hookCreationMs = 0;
87798
88211
  if (hookItemsByToken.size > 0) {
88212
+ const hookPhaseStart = Date.now();
87799
88213
  await ensureRunReady();
87800
88214
  await Promise.all([...hookItemsByToken.values()].map(async (items) => {
87801
88215
  for (const queueItem of items) {
@@ -87829,6 +88243,7 @@ async function handleSuspension({ suspension, world, run: run3, span, requestId,
87829
88243
  }
87830
88244
  }
87831
88245
  }));
88246
+ hookCreationMs = Date.now() - hookPhaseStart;
87832
88247
  }
87833
88248
  const hooksNeedingAbort = allHookItems.filter((item) => item.abortRequested && !item.disposed);
87834
88249
  if (hooksNeedingAbort.length > 0) {
@@ -88012,7 +88427,8 @@ async function handleSuspension({ suspension, world, run: run3, span, requestId,
88012
88427
  hasHookConflict,
88013
88428
  hasAwaitedHookCreation,
88014
88429
  hasAttributeEvents: attributeItems.length > 0,
88015
- hasHookEvents: hooksNeedingCreation.length > 0
88430
+ hasHookEvents: hooksNeedingCreation.length > 0,
88431
+ hookCreationMs
88016
88432
  };
88017
88433
  }
88018
88434
  __name(handleSuspension, "handleSuspension");
@@ -88190,17 +88606,17 @@ function parseAbsoluteUrl(input) {
88190
88606
  __name(parseAbsoluteUrl, "parseAbsoluteUrl");
88191
88607
  function parseFileUrl(input) {
88192
88608
  const match = fileRegex.exec(input);
88193
- const path10 = match[2];
88194
- return makeUrl("file:", "", match[1] || "", "", isAbsolutePath(path10) ? path10 : "/" + path10, match[3] || "", match[4] || "");
88609
+ const path11 = match[2];
88610
+ return makeUrl("file:", "", match[1] || "", "", isAbsolutePath(path11) ? path11 : "/" + path11, match[3] || "", match[4] || "");
88195
88611
  }
88196
88612
  __name(parseFileUrl, "parseFileUrl");
88197
- function makeUrl(scheme, user, host, port, path10, query, hash3) {
88613
+ function makeUrl(scheme, user, host, port, path11, query, hash3) {
88198
88614
  return {
88199
88615
  scheme,
88200
88616
  user,
88201
88617
  host,
88202
88618
  port,
88203
- path: path10,
88619
+ path: path11,
88204
88620
  query,
88205
88621
  hash: hash3,
88206
88622
  type: 7
@@ -88232,11 +88648,11 @@ function parseUrl(input) {
88232
88648
  return url3;
88233
88649
  }
88234
88650
  __name(parseUrl, "parseUrl");
88235
- function stripPathFilename(path10) {
88236
- if (path10.endsWith("/.."))
88237
- return path10;
88238
- const index = path10.lastIndexOf("/");
88239
- return path10.slice(0, index + 1);
88651
+ function stripPathFilename(path11) {
88652
+ if (path11.endsWith("/.."))
88653
+ return path11;
88654
+ const index = path11.lastIndexOf("/");
88655
+ return path11.slice(0, index + 1);
88240
88656
  }
88241
88657
  __name(stripPathFilename, "stripPathFilename");
88242
88658
  function mergePaths(url3, base) {
@@ -88276,14 +88692,14 @@ function normalizePath(url3, type) {
88276
88692
  pieces[pointer++] = piece;
88277
88693
  positive++;
88278
88694
  }
88279
- let path10 = "";
88695
+ let path11 = "";
88280
88696
  for (let i = 1; i < pointer; i++) {
88281
- path10 += "/" + pieces[i];
88697
+ path11 += "/" + pieces[i];
88282
88698
  }
88283
- if (!path10 || addTrailingSlash && !path10.endsWith("/..")) {
88284
- path10 += "/";
88699
+ if (!path11 || addTrailingSlash && !path11.endsWith("/..")) {
88700
+ path11 += "/";
88285
88701
  }
88286
- url3.path = path10;
88702
+ url3.path = path11;
88287
88703
  }
88288
88704
  __name(normalizePath, "normalizePath");
88289
88705
  function resolve(input, base) {
@@ -88325,13 +88741,13 @@ function resolve(input, base) {
88325
88741
  case 3:
88326
88742
  return queryHash;
88327
88743
  case 4: {
88328
- const path10 = url3.path.slice(1);
88329
- if (!path10)
88744
+ const path11 = url3.path.slice(1);
88745
+ if (!path11)
88330
88746
  return queryHash || ".";
88331
- if (isRelative(base || input) && !isRelative(path10)) {
88332
- return "./" + path10 + queryHash;
88747
+ if (isRelative(base || input) && !isRelative(path11)) {
88748
+ return "./" + path11 + queryHash;
88333
88749
  }
88334
- return path10 + queryHash;
88750
+ return path11 + queryHash;
88335
88751
  }
88336
88752
  case 5:
88337
88753
  return url3.path + queryHash;
@@ -88342,10 +88758,10 @@ function resolve(input, base) {
88342
88758
  __name(resolve, "resolve");
88343
88759
 
88344
88760
  // ../../node_modules/.pnpm/@jridgewell+trace-mapping@0.3.31/node_modules/@jridgewell/trace-mapping/dist/trace-mapping.mjs
88345
- function stripFilename(path10) {
88346
- if (!path10) return "";
88347
- const index = path10.lastIndexOf("/");
88348
- return path10.slice(0, index + 1);
88761
+ function stripFilename(path11) {
88762
+ if (!path11) return "";
88763
+ const index = path11.lastIndexOf("/");
88764
+ return path11.slice(0, index + 1);
88349
88765
  }
88350
88766
  __name(stripFilename, "stripFilename");
88351
88767
  function resolver(mapUrl, sourceRoot) {
@@ -88729,21 +89145,6 @@ init_node2();
88729
89145
  init_events_consumer2();
88730
89146
  init_global2();
88731
89147
  init_logger2();
88732
-
88733
- // ../core/dist/runtime/run-id-time.js
88734
- init_node2();
88735
- var RUN_ID_PREFIX = "wrun_";
88736
- function runIdCreatedAt(runId) {
88737
- const ulidPart = runId.startsWith(RUN_ID_PREFIX) ? runId.slice(RUN_ID_PREFIX.length) : runId;
88738
- try {
88739
- return decodeTime(ulidPart);
88740
- } catch {
88741
- return void 0;
88742
- }
88743
- }
88744
- __name(runIdCreatedAt, "runIdCreatedAt");
88745
-
88746
- // ../core/dist/workflow.js
88747
89148
  init_serialization4();
88748
89149
 
88749
89150
  // ../core/dist/step.js
@@ -90581,13 +90982,18 @@ var Run2 = class _Run2 {
90581
90982
  }
90582
90983
  /**
90583
90984
  * Cancels the workflow run.
90985
+ *
90986
+ * @param options - Optional cancellation settings. `cancelReason` records a
90987
+ * free-text reason (max 512 chars) on the run_cancelled event, surfaced in
90988
+ * the run detail view.
90584
90989
  */
90585
- async cancel() {
90990
+ async cancel(options) {
90586
90991
  "use step";
90587
90992
  const world = await this.#lazyWorldPromise;
90588
90993
  await world.events.create(this.runId, {
90589
90994
  eventType: "run_cancelled",
90590
- specVersion: SPEC_VERSION_CURRENT2
90995
+ specVersion: SPEC_VERSION_CURRENT2,
90996
+ ...options?.cancelReason !== void 0 ? { eventData: { cancelReason: options.cancelReason } } : {}
90591
90997
  });
90592
90998
  }
90593
90999
  /**
@@ -90892,6 +91298,9 @@ function workflowEntrypoint(workflowCode2, options) {
90892
91298
  let workflowStartedAt = -1;
90893
91299
  let preloadedEvents;
90894
91300
  let preloadedEventsCursor;
91301
+ let invocationStartedClean;
91302
+ let preStepBlockingMs = 0;
91303
+ let preStepBlockingBeforeAttrMs;
90895
91304
  const turbo = isTurboEnabled() && runInput !== void 0 && metadata.attempt === 1 && incomingStepId === void 0 && !replayDivergence;
90896
91305
  span?.setAttributes(WorkflowTurbo2(turbo));
90897
91306
  let runReadyBarrier;
@@ -91262,6 +91671,7 @@ function workflowEntrypoint(workflowCode2, options) {
91262
91671
  return;
91263
91672
  }
91264
91673
  cachedEvents = events;
91674
+ invocationStartedClean ??= events.every((e) => e.eventType === "run_created" || e.eventType === "run_started" || e.eventType === "attr_set");
91265
91675
  preInlineWriteCursor = eventsCursor;
91266
91676
  runtimeLogger2.debug("Starting workflow replay", {
91267
91677
  workflowRunId: runId,
@@ -91369,6 +91779,10 @@ function workflowEntrypoint(workflowCode2, options) {
91369
91779
  });
91370
91780
  return;
91371
91781
  }
91782
+ preStepBlockingMs += suspensionResult.hookCreationMs;
91783
+ if (suspensionResult.hasAttributeEvents && preStepBlockingBeforeAttrMs === void 0) {
91784
+ preStepBlockingBeforeAttrMs = preStepBlockingMs;
91785
+ }
91372
91786
  runtimeLogger2.debug("Suspension handled", {
91373
91787
  workflowRunId: runId,
91374
91788
  suspensionMs: Date.now() - suspensionStart,
@@ -91382,7 +91796,7 @@ function workflowEntrypoint(workflowCode2, options) {
91382
91796
  return await reinvoke(0);
91383
91797
  }
91384
91798
  if (suspensionResult.hasAttributeEvents) {
91385
- return await reinvoke(0);
91799
+ continue;
91386
91800
  }
91387
91801
  const pendingSteps = suspensionResult.pendingSteps;
91388
91802
  const lazyInlineSteps = suspensionResult.lazyInlineSteps;
@@ -91419,10 +91833,22 @@ function workflowEntrypoint(workflowCode2, options) {
91419
91833
  }
91420
91834
  const requestInlineDelta = typeof preInlineWriteCursor === "string" && err.stepCount === 1 && err.hookCount === 0 && err.waitCount === 0 && pendingSteps.length === 1 && lazyInlineSteps.length === 1 && !suspensionResult.waitTimeout && !hasOpenHookOrWait(cachedEvents ?? []);
91421
91835
  const forceOptimisticStart = turbo && !suspensionResult.waitTimeout && !suspensionResult.hasHookEvents && !suspensionResult.hasAttributeEvents && !suspensionResult.hasAwaitedHookCreation && !hasOpenHookOrWait(cachedEvents ?? []);
91836
+ const latencyTracking = computeStepLatencyTracking({
91837
+ events: cachedEvents ?? [],
91838
+ invocationStartedClean: invocationStartedClean === true,
91839
+ runCreatedAtMs: runIdCreatedAt(runId) ?? (turbo ? void 0 : +workflowRun.createdAt),
91840
+ preStepBlockingMs,
91841
+ preStepBlockingBeforeAttrMs,
91842
+ // This suspension's own hook/wait writes are not in
91843
+ // cachedEvents yet, so report them explicitly.
91844
+ suspensionHasWaits: err.waitCount > 0 || suspensionResult.waitTimeout !== void 0,
91845
+ suspensionCreatedHooks: err.hookCount > 0 || suspensionResult.hasHookEvents,
91846
+ turbo
91847
+ });
91422
91848
  replayBudget.pause();
91423
91849
  let stepResults;
91424
91850
  try {
91425
- stepResults = await Promise.all(lazyInlineSteps.map((s) => executeStep({
91851
+ stepResults = await Promise.all(lazyInlineSteps.map((s, stepIndex) => executeStep({
91426
91852
  world,
91427
91853
  workflowRunId: runId,
91428
91854
  workflowDeploymentId: workflowRun.deploymentId,
@@ -91441,6 +91867,7 @@ function workflowEntrypoint(workflowCode2, options) {
91441
91867
  // are undefined/false outside turbo.
91442
91868
  forceOptimisticStart,
91443
91869
  runReadyBarrier,
91870
+ ...stepIndex === 0 && latencyTracking ? { latencyTracking } : {},
91444
91871
  ...requestInlineDelta && preInlineWriteCursor ? {
91445
91872
  inlineDeltaSinceCursor: preInlineWriteCursor
91446
91873
  } : {}
@@ -107366,6 +107793,22 @@ var BaseEventSchema = external_exports.object({
107366
107793
  correlationId: external_exports.string().optional(),
107367
107794
  specVersion: external_exports.number().optional()
107368
107795
  });
107796
+ var stepLatencyTelemetryFields = {
107797
+ // Time-to-first-step: milliseconds from run creation until the run's first
107798
+ // step body began executing, minus time spent committing hook_created
107799
+ // events. Only reported when nothing else (hooks received, waits,
107800
+ // attributes, other steps) happened before the first step.
107801
+ ttfs: external_exports.number().optional(),
107802
+ // Step-to-step overhead: milliseconds between the previous step's terminal
107803
+ // event and this step's body beginning to execute. Only reported when the
107804
+ // two steps ran back-to-back (the previous event-log entry is a
107805
+ // step_completed/step_failed).
107806
+ stso: external_exports.number().optional(),
107807
+ // Names of the runtime's optional startup-latency optimizations that were
107808
+ // active for this measurement (e.g. 'turbo', 'lazyStepStart',
107809
+ // 'optimisticStart'), so latency metrics can be segmented by them.
107810
+ optimizations: external_exports.array(external_exports.string()).optional()
107811
+ };
107369
107812
  var StepCompletedEventSchema = BaseEventSchema.extend({
107370
107813
  eventType: external_exports.literal("step_completed"),
107371
107814
  correlationId: external_exports.string(),
@@ -107375,7 +107818,8 @@ var StepCompletedEventSchema = BaseEventSchema.extend({
107375
107818
  // the key without an extra run lookup on this hot per-step write.
107376
107819
  // Optional: older runtimes omit it and the backend falls back to a read.
107377
107820
  workflowName: external_exports.string().optional(),
107378
- result: SerializedDataSchema
107821
+ result: SerializedDataSchema,
107822
+ ...stepLatencyTelemetryFields
107379
107823
  })
107380
107824
  });
107381
107825
  var StepFailedEventSchema = BaseEventSchema.extend({
@@ -107385,7 +107829,8 @@ var StepFailedEventSchema = BaseEventSchema.extend({
107385
107829
  stepName: external_exports.string().optional(),
107386
107830
  // The thrown value, serialized via the workflow serialization pipeline.
107387
107831
  // Can be any JavaScript value (string, number, object, Error, etc.)
107388
- error: SerializedDataSchema
107832
+ error: SerializedDataSchema,
107833
+ ...stepLatencyTelemetryFields
107389
107834
  })
107390
107835
  });
107391
107836
  var StepRetryingEventSchema = BaseEventSchema.extend({
@@ -107532,7 +107977,13 @@ var RunFailedEventSchema = BaseEventSchema.extend({
107532
107977
  })
107533
107978
  });
107534
107979
  var RunCancelledEventSchema = BaseEventSchema.extend({
107535
- eventType: external_exports.literal("run_cancelled")
107980
+ eventType: external_exports.literal("run_cancelled"),
107981
+ eventData: external_exports.object({
107982
+ // Optional free-text reason for the cancellation. Kept as small
107983
+ // plaintext metadata (like run_failed's errorCode) so it survives
107984
+ // resolveData: 'none' and can be displayed without decryption.
107985
+ cancelReason: external_exports.string().max(512).optional()
107986
+ }).optional()
107536
107987
  });
107537
107988
  var CreateEventSchema = external_exports.discriminatedUnion("eventType", [
107538
107989
  // Run lifecycle events
@@ -108052,10 +108503,10 @@ var Run = class _Run {
108052
108503
  return this.getReadable();
108053
108504
  }
108054
108505
  };
108055
- Run.prototype["wakeUp"] = globalThis[/* @__PURE__ */ Symbol.for("WORKFLOW_USE_STEP")]("step//@workflow/core/runtime/run@5.0.0-beta.28//Run#wakeUp");
108056
- Run.prototype["cancel"] = globalThis[/* @__PURE__ */ Symbol.for("WORKFLOW_USE_STEP")]("step//@workflow/core/runtime/run@5.0.0-beta.28//Run#cancel");
108057
- Run.prototype["getReadable"] = globalThis[/* @__PURE__ */ Symbol.for("WORKFLOW_USE_STEP")]("step//@workflow/core/runtime/run@5.0.0-beta.28//Run#getReadable");
108058
- var __step_Run$exists = globalThis[/* @__PURE__ */ Symbol.for("WORKFLOW_USE_STEP")]("step//@workflow/core/runtime/run@5.0.0-beta.28//Run#exists");
108506
+ Run.prototype["wakeUp"] = globalThis[/* @__PURE__ */ Symbol.for("WORKFLOW_USE_STEP")]("step//@workflow/core/runtime/run@5.0.0-beta.29//Run#wakeUp");
108507
+ Run.prototype["cancel"] = globalThis[/* @__PURE__ */ Symbol.for("WORKFLOW_USE_STEP")]("step//@workflow/core/runtime/run@5.0.0-beta.29//Run#cancel");
108508
+ Run.prototype["getReadable"] = globalThis[/* @__PURE__ */ Symbol.for("WORKFLOW_USE_STEP")]("step//@workflow/core/runtime/run@5.0.0-beta.29//Run#getReadable");
108509
+ var __step_Run$exists = globalThis[/* @__PURE__ */ Symbol.for("WORKFLOW_USE_STEP")]("step//@workflow/core/runtime/run@5.0.0-beta.29//Run#exists");
108059
108510
  Object.defineProperty(Run.prototype, "exists", {
108060
108511
  get() {
108061
108512
  return __step_Run$exists.call(this);
@@ -108063,7 +108514,7 @@ Object.defineProperty(Run.prototype, "exists", {
108063
108514
  configurable: true,
108064
108515
  enumerable: false
108065
108516
  });
108066
- var __step_Run$status = globalThis[/* @__PURE__ */ Symbol.for("WORKFLOW_USE_STEP")]("step//@workflow/core/runtime/run@5.0.0-beta.28//Run#status");
108517
+ var __step_Run$status = globalThis[/* @__PURE__ */ Symbol.for("WORKFLOW_USE_STEP")]("step//@workflow/core/runtime/run@5.0.0-beta.29//Run#status");
108067
108518
  Object.defineProperty(Run.prototype, "status", {
108068
108519
  get() {
108069
108520
  return __step_Run$status.call(this);
@@ -108071,7 +108522,7 @@ Object.defineProperty(Run.prototype, "status", {
108071
108522
  configurable: true,
108072
108523
  enumerable: false
108073
108524
  });
108074
- var __step_Run$returnValue = globalThis[/* @__PURE__ */ Symbol.for("WORKFLOW_USE_STEP")]("step//@workflow/core/runtime/run@5.0.0-beta.28//Run#returnValue");
108525
+ var __step_Run$returnValue = globalThis[/* @__PURE__ */ Symbol.for("WORKFLOW_USE_STEP")]("step//@workflow/core/runtime/run@5.0.0-beta.29//Run#returnValue");
108075
108526
  Object.defineProperty(Run.prototype, "returnValue", {
108076
108527
  get() {
108077
108528
  return __step_Run$returnValue.call(this);
@@ -108079,7 +108530,7 @@ Object.defineProperty(Run.prototype, "returnValue", {
108079
108530
  configurable: true,
108080
108531
  enumerable: false
108081
108532
  });
108082
- var __step_Run$workflowName = globalThis[/* @__PURE__ */ Symbol.for("WORKFLOW_USE_STEP")]("step//@workflow/core/runtime/run@5.0.0-beta.28//Run#workflowName");
108533
+ var __step_Run$workflowName = globalThis[/* @__PURE__ */ Symbol.for("WORKFLOW_USE_STEP")]("step//@workflow/core/runtime/run@5.0.0-beta.29//Run#workflowName");
108083
108534
  Object.defineProperty(Run.prototype, "workflowName", {
108084
108535
  get() {
108085
108536
  return __step_Run$workflowName.call(this);
@@ -108087,7 +108538,7 @@ Object.defineProperty(Run.prototype, "workflowName", {
108087
108538
  configurable: true,
108088
108539
  enumerable: false
108089
108540
  });
108090
- var __step_Run$createdAt = globalThis[/* @__PURE__ */ Symbol.for("WORKFLOW_USE_STEP")]("step//@workflow/core/runtime/run@5.0.0-beta.28//Run#createdAt");
108541
+ var __step_Run$createdAt = globalThis[/* @__PURE__ */ Symbol.for("WORKFLOW_USE_STEP")]("step//@workflow/core/runtime/run@5.0.0-beta.29//Run#createdAt");
108091
108542
  Object.defineProperty(Run.prototype, "createdAt", {
108092
108543
  get() {
108093
108544
  return __step_Run$createdAt.call(this);
@@ -108095,7 +108546,7 @@ Object.defineProperty(Run.prototype, "createdAt", {
108095
108546
  configurable: true,
108096
108547
  enumerable: false
108097
108548
  });
108098
- var __step_Run$startedAt = globalThis[/* @__PURE__ */ Symbol.for("WORKFLOW_USE_STEP")]("step//@workflow/core/runtime/run@5.0.0-beta.28//Run#startedAt");
108549
+ var __step_Run$startedAt = globalThis[/* @__PURE__ */ Symbol.for("WORKFLOW_USE_STEP")]("step//@workflow/core/runtime/run@5.0.0-beta.29//Run#startedAt");
108099
108550
  Object.defineProperty(Run.prototype, "startedAt", {
108100
108551
  get() {
108101
108552
  return __step_Run$startedAt.call(this);
@@ -108103,7 +108554,7 @@ Object.defineProperty(Run.prototype, "startedAt", {
108103
108554
  configurable: true,
108104
108555
  enumerable: false
108105
108556
  });
108106
- var __step_Run$completedAt = globalThis[/* @__PURE__ */ Symbol.for("WORKFLOW_USE_STEP")]("step//@workflow/core/runtime/run@5.0.0-beta.28//Run#completedAt");
108557
+ var __step_Run$completedAt = globalThis[/* @__PURE__ */ Symbol.for("WORKFLOW_USE_STEP")]("step//@workflow/core/runtime/run@5.0.0-beta.29//Run#completedAt");
108107
108558
  Object.defineProperty(Run.prototype, "completedAt", {
108108
108559
  get() {
108109
108560
  return __step_Run$completedAt.call(this);
@@ -108120,7 +108571,7 @@ Object.defineProperty(Run.prototype, "completedAt", {
108120
108571
  enumerable: false,
108121
108572
  configurable: false
108122
108573
  });
108123
- })(Run, "class//@workflow/core/runtime/run@5.0.0-beta.28//Run");
108574
+ })(Run, "class//@workflow/core/runtime/run@5.0.0-beta.29//Run");
108124
108575
 
108125
108576
  // ../core/dist/workflow/create-hook.js
108126
108577
  aliasSerializationClass(RUN_CLASS_ID, Run);