@runcofactor/cli 0.13.0 → 0.15.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (149) hide show
  1. package/dist/account-62I7FG5G.js +255 -0
  2. package/dist/account-62I7FG5G.js.map +1 -0
  3. package/dist/{api-catalog-7HLEN7C2.js → api-catalog-CAJUASVC.js} +5 -5
  4. package/dist/{attachment-OVNQD6Z2.js → attachment-RL4AZUJE.js} +5 -5
  5. package/dist/augmentor-GAF3MFY6.js +198 -0
  6. package/dist/augmentor-GAF3MFY6.js.map +1 -0
  7. package/dist/{auth-VUHL74FH.js → auth-DURHUZDW.js} +3 -3
  8. package/dist/{chunk-YN763NWQ.js → chunk-26U3DGUM.js} +10 -4
  9. package/dist/chunk-26U3DGUM.js.map +1 -0
  10. package/dist/{chunk-JZMJUPZP.js → chunk-32P26BZT.js} +3 -3
  11. package/dist/chunk-32P26BZT.js.map +1 -0
  12. package/dist/{chunk-QQVWGWPI.js → chunk-5R4HMSNX.js} +8561 -1511
  13. package/dist/chunk-5R4HMSNX.js.map +1 -0
  14. package/dist/{chunk-VGTKUOYS.js → chunk-AQPJQ5AE.js} +2 -2
  15. package/dist/{chunk-CQE46HSM.js → chunk-CFJXYPTF.js} +14 -8
  16. package/dist/chunk-CFJXYPTF.js.map +1 -0
  17. package/dist/{chunk-NL7CVG56.js → chunk-CJEKEW7R.js} +57 -10
  18. package/dist/chunk-CJEKEW7R.js.map +1 -0
  19. package/dist/{chunk-Z5LUTUDN.js → chunk-G5SXUXSU.js} +3 -3
  20. package/dist/{chunk-ZTOE3ND3.js → chunk-HKQ5XQAQ.js} +4 -4
  21. package/dist/{chunk-PZ4LCN6K.js → chunk-IGHDIWZU.js} +2 -2
  22. package/dist/{chunk-QGI4UCJX.js → chunk-IWKJQZJQ.js} +124 -74
  23. package/dist/chunk-IWKJQZJQ.js.map +1 -0
  24. package/dist/{chunk-ZD3KHESI.js → chunk-KRWRUU6R.js} +27 -7
  25. package/dist/chunk-KRWRUU6R.js.map +1 -0
  26. package/dist/{chunk-CRHPDPRS.js → chunk-PXFDH6YL.js} +63 -8
  27. package/dist/{chunk-CRHPDPRS.js.map → chunk-PXFDH6YL.js.map} +1 -1
  28. package/dist/{chunk-EJ4U242G.js → chunk-UZ2ZA5A6.js} +2 -2
  29. package/dist/{chunk-EEN2TZUQ.js → chunk-VKBTI5EF.js} +3 -3
  30. package/dist/{chunk-ENDHMYEJ.js → chunk-ZXRVFFCY.js} +3 -3
  31. package/dist/{credential-LO2SEEHU.js → credential-JGVSEGVH.js} +5 -5
  32. package/dist/{credential-template-ZN7W7734.js → credential-template-CWWMOKB2.js} +5 -5
  33. package/dist/{debug-workflow-R3RYYAXK.js → debug-workflow-BXRU72YZ.js} +5 -5
  34. package/dist/{docs-DIAFBDXQ.js → docs-PVBXPTGR.js} +95 -11
  35. package/dist/docs-PVBXPTGR.js.map +1 -0
  36. package/dist/{doctor-NZPUSCRE.js → doctor-RHMKD4W5.js} +3 -3
  37. package/dist/{environment-RQVU4P5M.js → environment-WZKIO3R3.js} +5 -5
  38. package/dist/{feature-flag-XG26RURR.js → feature-flag-K5REGGDY.js} +98 -12
  39. package/dist/feature-flag-K5REGGDY.js.map +1 -0
  40. package/dist/index.js +107 -51
  41. package/dist/index.js.map +1 -1
  42. package/dist/{init-EDNLKGPT.js → init-FFUZO5D7.js} +5 -5
  43. package/dist/{install-FYZ3HNZK.js → install-XRKEQAFZ.js} +5 -5
  44. package/dist/{issues-NNRVTJ4L.js → issues-I3V6GEXU.js} +5 -5
  45. package/dist/{knobs-A2BOBH22.js → knobs-6WLJMB44.js} +7 -6
  46. package/dist/knobs-6WLJMB44.js.map +1 -0
  47. package/dist/{list-F33VZ4BJ.js → list-PHC7VYNS.js} +5 -5
  48. package/dist/{local-DQDTM3XA.js → local-VGYRSW22.js} +7 -7
  49. package/dist/{login-BUMVIB36.js → login-QPU2BKG2.js} +5 -5
  50. package/dist/{mcp-B5Y5CDMQ.js → mcp-LA452TOA.js} +9 -9
  51. package/dist/{mcp-B5Y5CDMQ.js.map → mcp-LA452TOA.js.map} +1 -1
  52. package/dist/{pdf-extract-ABWV3L5X.js → pdf-extract-YHE54XU4.js} +2 -2
  53. package/dist/product-RSZV5HMB.js +346 -0
  54. package/dist/product-RSZV5HMB.js.map +1 -0
  55. package/dist/{property-NJ4SRXQG.js → property-YP4GHQAR.js} +5 -5
  56. package/dist/{psql-VBZFCMNR.js → psql-XGLBI6T7.js} +3 -3
  57. package/dist/{record-WAO36O7G.js → record-KWKHP2ZY.js} +6 -6
  58. package/dist/{redis-DHZXHL4S.js → redis-VJGCUJPV.js} +3 -3
  59. package/dist/redis-VJGCUJPV.js.map +1 -0
  60. package/dist/{release-STJKUKTE.js → release-NDRHPW6V.js} +5 -5
  61. package/dist/{sandbox-DWSGLY7B.js → sandbox-OOCANWOG.js} +51 -7
  62. package/dist/sandbox-OOCANWOG.js.map +1 -0
  63. package/dist/{scenarios-HCIDY725.js → scenarios-2HRLCGFY.js} +5 -5
  64. package/dist/{session-Y5RHU54D.js → session-M4ULYDYP.js} +8 -9
  65. package/dist/session-M4ULYDYP.js.map +1 -0
  66. package/dist/{skill-23WAHUOB.js → skill-4DGPRDUC.js} +10 -10
  67. package/dist/{skill-23WAHUOB.js.map → skill-4DGPRDUC.js.map} +1 -1
  68. package/dist/skills/debug-run/SKILL.md +7 -1
  69. package/dist/skills/debug-run/history/1.3.1.md +279 -0
  70. package/dist/skills/debug-run/version.json +1 -1
  71. package/dist/skills/optimize-cache/SKILL.md +41 -4
  72. package/dist/{spec-LM5XHOQ5.js → spec-XZ2TKUFZ.js} +5 -5
  73. package/dist/{src-BGDRMOKC.js → src-2FK3JHGW.js} +315 -104
  74. package/dist/src-2FK3JHGW.js.map +1 -0
  75. package/dist/{src-NCJPUAE6.js → src-CV57ZD6I.js} +10 -8
  76. package/dist/{src-22RI5VP2.js → src-HL7HEJIW.js} +2 -2
  77. package/dist/{src-Y3K7UJEF.js → src-OU7544PM.js} +6 -4
  78. package/dist/{start-SWY55CZX.js → start-IYKF3C3X.js} +5 -5
  79. package/dist/{tag-YSU2XXPI.js → tag-T45MMSCH.js} +6 -6
  80. package/dist/{task-NLBKLD7D.js → task-MCUHAVTD.js} +5 -5
  81. package/dist/{test-suite-QCPWZ2LS.js → test-suite-BICBRSBP.js} +10 -8
  82. package/dist/{test-suite-QCPWZ2LS.js.map → test-suite-BICBRSBP.js.map} +1 -1
  83. package/dist/trace-2BAPMYAS.js +16 -0
  84. package/dist/{triage-TT4BMDBU.js → triage-M3RZ2ASB.js} +6 -6
  85. package/dist/{upgrade-6ZUFETKX.js → upgrade-4QCRAUHP.js} +3 -3
  86. package/dist/{workflow-2CX3ZNOQ.js → workflow-4J23FV7K.js} +86 -15
  87. package/dist/workflow-4J23FV7K.js.map +1 -0
  88. package/dist/{workflow-cache-GXNE6SU2.js → workflow-cache-XPSK6KC7.js} +26 -13
  89. package/dist/workflow-cache-XPSK6KC7.js.map +1 -0
  90. package/dist/{workflow-debug-PRX3DWGD.js → workflow-debug-W4USZH35.js} +9 -9
  91. package/dist/{workflow-proposals-BW327WGL.js → workflow-proposals-5E3DTYZB.js} +5 -7
  92. package/dist/workflow-proposals-5E3DTYZB.js.map +1 -0
  93. package/package.json +5 -1
  94. package/dist/chunk-CQE46HSM.js.map +0 -1
  95. package/dist/chunk-JZMJUPZP.js.map +0 -1
  96. package/dist/chunk-NL7CVG56.js.map +0 -1
  97. package/dist/chunk-QGI4UCJX.js.map +0 -1
  98. package/dist/chunk-QQVWGWPI.js.map +0 -1
  99. package/dist/chunk-YN763NWQ.js.map +0 -1
  100. package/dist/chunk-ZD3KHESI.js.map +0 -1
  101. package/dist/docs-DIAFBDXQ.js.map +0 -1
  102. package/dist/feature-flag-XG26RURR.js.map +0 -1
  103. package/dist/knobs-A2BOBH22.js.map +0 -1
  104. package/dist/redis-DHZXHL4S.js.map +0 -1
  105. package/dist/sandbox-DWSGLY7B.js.map +0 -1
  106. package/dist/session-Y5RHU54D.js.map +0 -1
  107. package/dist/src-BGDRMOKC.js.map +0 -1
  108. package/dist/trace-A3ZY6K26.js +0 -16
  109. package/dist/workflow-2CX3ZNOQ.js.map +0 -1
  110. package/dist/workflow-cache-GXNE6SU2.js.map +0 -1
  111. package/dist/workflow-proposals-BW327WGL.js.map +0 -1
  112. /package/dist/{api-catalog-7HLEN7C2.js.map → api-catalog-CAJUASVC.js.map} +0 -0
  113. /package/dist/{attachment-OVNQD6Z2.js.map → attachment-RL4AZUJE.js.map} +0 -0
  114. /package/dist/{auth-VUHL74FH.js.map → auth-DURHUZDW.js.map} +0 -0
  115. /package/dist/{chunk-VGTKUOYS.js.map → chunk-AQPJQ5AE.js.map} +0 -0
  116. /package/dist/{chunk-Z5LUTUDN.js.map → chunk-G5SXUXSU.js.map} +0 -0
  117. /package/dist/{chunk-ZTOE3ND3.js.map → chunk-HKQ5XQAQ.js.map} +0 -0
  118. /package/dist/{chunk-PZ4LCN6K.js.map → chunk-IGHDIWZU.js.map} +0 -0
  119. /package/dist/{chunk-EJ4U242G.js.map → chunk-UZ2ZA5A6.js.map} +0 -0
  120. /package/dist/{chunk-EEN2TZUQ.js.map → chunk-VKBTI5EF.js.map} +0 -0
  121. /package/dist/{chunk-ENDHMYEJ.js.map → chunk-ZXRVFFCY.js.map} +0 -0
  122. /package/dist/{credential-LO2SEEHU.js.map → credential-JGVSEGVH.js.map} +0 -0
  123. /package/dist/{credential-template-ZN7W7734.js.map → credential-template-CWWMOKB2.js.map} +0 -0
  124. /package/dist/{debug-workflow-R3RYYAXK.js.map → debug-workflow-BXRU72YZ.js.map} +0 -0
  125. /package/dist/{doctor-NZPUSCRE.js.map → doctor-RHMKD4W5.js.map} +0 -0
  126. /package/dist/{environment-RQVU4P5M.js.map → environment-WZKIO3R3.js.map} +0 -0
  127. /package/dist/{init-EDNLKGPT.js.map → init-FFUZO5D7.js.map} +0 -0
  128. /package/dist/{install-FYZ3HNZK.js.map → install-XRKEQAFZ.js.map} +0 -0
  129. /package/dist/{issues-NNRVTJ4L.js.map → issues-I3V6GEXU.js.map} +0 -0
  130. /package/dist/{list-F33VZ4BJ.js.map → list-PHC7VYNS.js.map} +0 -0
  131. /package/dist/{local-DQDTM3XA.js.map → local-VGYRSW22.js.map} +0 -0
  132. /package/dist/{login-BUMVIB36.js.map → login-QPU2BKG2.js.map} +0 -0
  133. /package/dist/{pdf-extract-ABWV3L5X.js.map → pdf-extract-YHE54XU4.js.map} +0 -0
  134. /package/dist/{property-NJ4SRXQG.js.map → property-YP4GHQAR.js.map} +0 -0
  135. /package/dist/{psql-VBZFCMNR.js.map → psql-XGLBI6T7.js.map} +0 -0
  136. /package/dist/{record-WAO36O7G.js.map → record-KWKHP2ZY.js.map} +0 -0
  137. /package/dist/{release-STJKUKTE.js.map → release-NDRHPW6V.js.map} +0 -0
  138. /package/dist/{scenarios-HCIDY725.js.map → scenarios-2HRLCGFY.js.map} +0 -0
  139. /package/dist/{spec-LM5XHOQ5.js.map → spec-XZ2TKUFZ.js.map} +0 -0
  140. /package/dist/{src-NCJPUAE6.js.map → src-CV57ZD6I.js.map} +0 -0
  141. /package/dist/{src-22RI5VP2.js.map → src-HL7HEJIW.js.map} +0 -0
  142. /package/dist/{src-Y3K7UJEF.js.map → src-OU7544PM.js.map} +0 -0
  143. /package/dist/{start-SWY55CZX.js.map → start-IYKF3C3X.js.map} +0 -0
  144. /package/dist/{tag-YSU2XXPI.js.map → tag-T45MMSCH.js.map} +0 -0
  145. /package/dist/{task-NLBKLD7D.js.map → task-MCUHAVTD.js.map} +0 -0
  146. /package/dist/{trace-A3ZY6K26.js.map → trace-2BAPMYAS.js.map} +0 -0
  147. /package/dist/{triage-TT4BMDBU.js.map → triage-M3RZ2ASB.js.map} +0 -0
  148. /package/dist/{upgrade-6ZUFETKX.js.map → upgrade-4QCRAUHP.js.map} +0 -0
  149. /package/dist/{workflow-debug-PRX3DWGD.js.map → workflow-debug-W4USZH35.js.map} +0 -0
@@ -1,30 +1,34 @@
1
1
  import { createRequire as __cr } from "module"; const require = __cr(import.meta.url);
2
2
  import {
3
- reconstructSnapshots
4
- } from "./chunk-CRHPDPRS.js";
3
+ parseTraceActions,
4
+ reconstructSnapshots,
5
+ toMutationIndex
6
+ } from "./chunk-PXFDH6YL.js";
5
7
  import {
6
8
  buildLocatorString
7
9
  } from "./chunk-5GD47G2D.js";
8
10
  import {
9
- captureSubstrateV2
10
- } from "./chunk-QQVWGWPI.js";
11
+ applyCustomAugmentors,
12
+ captureSubstrateV2,
13
+ parseSnapshot
14
+ } from "./chunk-5R4HMSNX.js";
11
15
  import "./chunk-JWHYXEA2.js";
12
16
  import {
13
17
  MACRO_PATTERN,
14
18
  isVolatileIdentifier,
15
19
  stableAttrSelector,
16
20
  stableIdentifierPrefix
17
- } from "./chunk-QGI4UCJX.js";
21
+ } from "./chunk-IWKJQZJQ.js";
18
22
  import "./chunk-6LEZCKKV.js";
19
23
  import {
20
24
  consoleLogger
21
- } from "./chunk-ZD3KHESI.js";
25
+ } from "./chunk-KRWRUU6R.js";
22
26
  import "./chunk-VKVL7WBN.js";
23
27
 
24
28
  // ../workflow-cache/src/logger.ts
25
29
  var activeLogger = consoleLogger;
26
- function setWorkflowCacheLogger(logger3) {
27
- activeLogger = logger3;
30
+ function setWorkflowCacheLogger(logger4) {
31
+ activeLogger = logger4;
28
32
  }
29
33
  function createLogger(bindings) {
30
34
  if (!bindings || Object.keys(bindings).length === 0) {
@@ -53,8 +57,8 @@ function sortObjectKeys(obj) {
53
57
  }
54
58
  if (obj !== null && typeof obj === "object") {
55
59
  const sorted = Object.keys(obj).sort().reduce(
56
- (acc, key) => {
57
- acc[key] = sortObjectKeys(obj[key]);
60
+ (acc, key2) => {
61
+ acc[key2] = sortObjectKeys(obj[key2]);
58
62
  return acc;
59
63
  },
60
64
  {}
@@ -64,10 +68,26 @@ function sortObjectKeys(obj) {
64
68
  return obj;
65
69
  }
66
70
  function generateNodeHash(input) {
71
+ return hashWithPrefix(input, HASH_VERSION);
72
+ }
73
+ function generateNodeHashV3(input) {
74
+ const { playbookSteps: _playbookSteps, inlineAssertions, ...identity } = input;
75
+ const v3Input = {
76
+ ...identity,
77
+ ...inlineAssertions ? {
78
+ inlineAssertions: inlineAssertions.map(({ condition, agentic }) => ({
79
+ condition,
80
+ ...agentic !== void 0 ? { agentic } : {}
81
+ }))
82
+ } : {}
83
+ };
84
+ return hashWithPrefix(v3Input, "v3");
85
+ }
86
+ function hashWithPrefix(input, version) {
67
87
  const sortedInput = sortObjectKeys(input);
68
88
  const stableJson = JSON.stringify(sortedInput);
69
89
  const hash = createHash("sha256").update(stableJson).digest("hex").slice(0, 16);
70
- return `${HASH_VERSION}:${hash}`;
90
+ return `${version}:${hash}`;
71
91
  }
72
92
 
73
93
  // ../workflow-cache/src/build-locator.ts
@@ -95,6 +115,15 @@ function buildLocator(snapshot, ref, variableValues = {}) {
95
115
  const frameContext = frameContextFor(target.el);
96
116
  const baseDynamicText = buildDynamicText(target);
97
117
  const ancestors = ancestorChain(target);
118
+ const augmentorAnchor = target.el.augmentorAnchor;
119
+ if (augmentorAnchor) {
120
+ return {
121
+ selectors: applyContexts({ css: augmentorAnchor }, frameContext, baseDynamicText),
122
+ predicate: "augmentorAnchor",
123
+ bindings: allBindings,
124
+ irreducible: false
125
+ };
126
+ }
98
127
  const uniqueTestId = pickUniqueTestId(target, flat);
99
128
  if (uniqueTestId) {
100
129
  return {
@@ -366,12 +395,12 @@ function buildRowScopedOrdinalLocator(args) {
366
395
  const buttonRefs = collectRoleRefs(anchor.el, "button");
367
396
  const ordinal = buttonRefs.indexOf(args.target.el.ref);
368
397
  if (ordinal < 0) continue;
369
- const [key, value] = match;
398
+ const [key2, value] = match;
370
399
  return {
371
- locator: `getByRole('${escapeLocatorString(anchor.el.role)}').filter({ hasText: '{{var.${key}}}' }).getByRole('button').nth(${ordinal})`,
400
+ locator: `getByRole('${escapeLocatorString(anchor.el.role)}').filter({ hasText: '{{var.${key2}}}' }).getByRole('button').nth(${ordinal})`,
372
401
  anchor,
373
402
  innerAncestors: args.ancestors.slice(i + 1),
374
- key,
403
+ key: key2,
375
404
  value
376
405
  };
377
406
  }
@@ -392,8 +421,8 @@ function escapeLocatorString(value) {
392
421
  var MIN_TEMPLATING_LENGTH = 3;
393
422
  function templateAll(flat, variableValues) {
394
423
  const summary = /* @__PURE__ */ new Map();
395
- const compiled = Object.entries(variableValues).filter(([, v]) => typeof v === "string" && v.length >= MIN_TEMPLATING_LENGTH).map(([key, value]) => ({
396
- key,
424
+ const compiled = Object.entries(variableValues).filter(([, v]) => typeof v === "string" && v.length >= MIN_TEMPLATING_LENGTH).map(([key2, value]) => ({
425
+ key: key2,
397
426
  value,
398
427
  regex: new RegExp(`(^|\\W)${escapeRegex(value)}(?=\\W|$)`, "g")
399
428
  }));
@@ -870,12 +899,12 @@ function findRowVariableScope(args) {
870
899
  continue;
871
900
  }
872
901
  const anchorText = collectSubtreeText(anchor.el);
873
- for (const [key, value] of entries) {
902
+ for (const [key2, value] of entries) {
874
903
  if (!textContainsValue(anchorText, value)) continue;
875
904
  return {
876
905
  anchor,
877
906
  innerAncestors: args.ancestors.slice(i + 1),
878
- key,
907
+ key: key2,
879
908
  value
880
909
  };
881
910
  }
@@ -977,9 +1006,9 @@ function parseLine(line) {
977
1006
  if (cleanContent.startsWith("/")) {
978
1007
  const colonIdx = cleanContent.indexOf(":");
979
1008
  if (colonIdx !== -1) {
980
- const key = cleanContent.slice(1, colonIdx).trim();
1009
+ const key2 = cleanContent.slice(1, colonIdx).trim();
981
1010
  const value = cleanContent.slice(colonIdx + 1).trim();
982
- return { indent, role: "_property", attributes: { [key]: value } };
1011
+ return { indent, role: "_property", attributes: { [key2]: value } };
983
1012
  }
984
1013
  }
985
1014
  if (withoutBrackets.startsWith('"') && withoutBrackets.endsWith('"')) {
@@ -1005,9 +1034,9 @@ function parseLine(line) {
1005
1034
  const attributes = {};
1006
1035
  const attrMatches = cleanContent.matchAll(/\[(\w+)=([^\]]+)\]/g);
1007
1036
  for (const match of attrMatches) {
1008
- const [, key, value] = match;
1009
- if (key !== "ref") {
1010
- attributes[key] = value;
1037
+ const [, key2, value] = match;
1038
+ if (key2 !== "ref") {
1039
+ attributes[key2] = value;
1011
1040
  }
1012
1041
  }
1013
1042
  return {
@@ -1414,11 +1443,11 @@ function escapeForLocatorString(value) {
1414
1443
  return value.replace(/\\/g, "\\\\").replace(/'/g, "\\'");
1415
1444
  }
1416
1445
  function hydrateLocatorVariables(locatorStr, variableValues) {
1417
- return locatorStr.replace(/\{\{var\.([a-zA-Z0-9_]+)\}\}/g, (_match, key) => {
1418
- const value = variableValues[key];
1446
+ return locatorStr.replace(/\{\{var\.([a-zA-Z0-9_]+)\}\}/g, (_match, key2) => {
1447
+ const value = variableValues[key2];
1419
1448
  if (value === void 0) {
1420
- getLogger().warn("[LocatorParser] Variable placeholder not found in values", { key });
1421
- return `{{var.${key}}}`;
1449
+ getLogger().warn("[LocatorParser] Variable placeholder not found in values", { key: key2 });
1450
+ return `{{var.${key2}}}`;
1422
1451
  }
1423
1452
  return escapeForLocatorString(value);
1424
1453
  });
@@ -1585,7 +1614,7 @@ function parseObjectArg(input) {
1585
1614
  for (const pair of pairs) {
1586
1615
  const colonIdx = pair.indexOf(":");
1587
1616
  if (colonIdx === -1) continue;
1588
- const key = pair.slice(0, colonIdx).trim().replace(/^['"]|['"]$/g, "");
1617
+ const key2 = pair.slice(0, colonIdx).trim().replace(/^['"]|['"]$/g, "");
1589
1618
  const rawValue = pair.slice(colonIdx + 1).trim();
1590
1619
  if (rawValue.startsWith("'") || rawValue.startsWith('"')) {
1591
1620
  const q = rawValue[0];
@@ -1594,20 +1623,20 @@ function parseObjectArg(input) {
1594
1623
  if (rawValue[end] === "\\") end++;
1595
1624
  end++;
1596
1625
  }
1597
- obj[key] = rawValue.slice(1, end).replace(/\\'/g, "'").replace(/\\"/g, '"');
1626
+ obj[key2] = rawValue.slice(1, end).replace(/\\'/g, "'").replace(/\\"/g, '"');
1598
1627
  } else if (rawValue.startsWith("/")) {
1599
1628
  const regexMatch = rawValue.match(/^\/([^/]+)\/([gimsuy]*)/);
1600
1629
  if (regexMatch) {
1601
- obj[key] = new RegExp(regexMatch[1], regexMatch[2]);
1630
+ obj[key2] = new RegExp(regexMatch[1], regexMatch[2]);
1602
1631
  }
1603
1632
  } else if (rawValue === "true") {
1604
- obj[key] = true;
1633
+ obj[key2] = true;
1605
1634
  } else if (rawValue === "false") {
1606
- obj[key] = false;
1635
+ obj[key2] = false;
1607
1636
  } else if (/^-?\d+$/.test(rawValue)) {
1608
- obj[key] = parseInt(rawValue, 10);
1637
+ obj[key2] = parseInt(rawValue, 10);
1609
1638
  } else {
1610
- obj[key] = rawValue;
1639
+ obj[key2] = rawValue;
1611
1640
  }
1612
1641
  }
1613
1642
  return { value: obj, rest };
@@ -3368,8 +3397,8 @@ async function resolveElement(page, selectors, _timeoutMs, options) {
3368
3397
  errors.push(`CSS selector ("${selectors.css}") found no matches`);
3369
3398
  }
3370
3399
  if (selectors.dynamicText && options?.variableValues && selectors.role && !requireSelect && !skipHeuristicFallbacks) {
3371
- const { key } = selectors.dynamicText;
3372
- const currentValue = options.variableValues[key];
3400
+ const { key: key2 } = selectors.dynamicText;
3401
+ const currentValue = options.variableValues[key2];
3373
3402
  if (currentValue) {
3374
3403
  logger().debug("[ElementResolver] Trying structural fallback for dynamic text", {
3375
3404
  role: selectors.role.role,
@@ -3585,15 +3614,15 @@ function deriveSelectorsFromElementInfo(elementInfo) {
3585
3614
  }
3586
3615
  function sanitizeArgsForCache(args) {
3587
3616
  const sanitized = {};
3588
- for (const [key, value] of Object.entries(args)) {
3589
- if (key === "ref" || key === "startRef" || key === "endRef") {
3617
+ for (const [key2, value] of Object.entries(args)) {
3618
+ if (key2 === "ref" || key2 === "startRef" || key2 === "endRef") {
3590
3619
  continue;
3591
3620
  }
3592
- if (key === "signal" || key === "timeoutMs") {
3621
+ if (key2 === "signal" || key2 === "timeoutMs") {
3593
3622
  continue;
3594
3623
  }
3595
3624
  if (Array.isArray(value)) {
3596
- sanitized[key] = value.map((item) => {
3625
+ sanitized[key2] = value.map((item) => {
3597
3626
  if (typeof item === "object" && item !== null) {
3598
3627
  return sanitizeArgsForCache(item);
3599
3628
  }
@@ -3601,7 +3630,7 @@ function sanitizeArgsForCache(args) {
3601
3630
  });
3602
3631
  continue;
3603
3632
  }
3604
- sanitized[key] = value;
3633
+ sanitized[key2] = value;
3605
3634
  }
3606
3635
  return sanitized;
3607
3636
  }
@@ -3754,12 +3783,12 @@ async function findRowAnchor(originalLocator, timeoutMs) {
3754
3783
  const t = raw.trim();
3755
3784
  if (t.length < 3) return;
3756
3785
  if (t.length > 120) return;
3757
- const key = t.toLowerCase();
3758
- if (key === targetText) return;
3759
- if (targetText.length > 0 && key.includes(targetText)) return;
3760
- if (targetText.length > 0 && targetText.includes(key)) return;
3761
- if (seen.has(key)) return;
3762
- seen.add(key);
3786
+ const key2 = t.toLowerCase();
3787
+ if (key2 === targetText) return;
3788
+ if (targetText.length > 0 && key2.includes(targetText)) return;
3789
+ if (targetText.length > 0 && targetText.includes(key2)) return;
3790
+ if (seen.has(key2)) return;
3791
+ seen.add(key2);
3763
3792
  texts.push(t);
3764
3793
  };
3765
3794
  if (ariaLabel) pushText(ariaLabel);
@@ -3814,7 +3843,7 @@ async function findRowAnchor(originalLocator, timeoutMs) {
3814
3843
  }
3815
3844
  async function discoverParentContext(page, selectors, selectorType, originalLocator, options) {
3816
3845
  const { timeoutMs, maxParentDepth } = options;
3817
- const logger3 = getLogger2();
3846
+ const logger4 = getLogger2();
3818
3847
  const context = selectors.frameContext?.selector ? page.frameLocator(selectors.frameContext.selector) : page;
3819
3848
  try {
3820
3849
  const rowCandidate = await findRowAnchor(originalLocator, timeoutMs);
@@ -3833,7 +3862,7 @@ async function discoverParentContext(page, selectors, selectorType, originalLoca
3833
3862
  if (!resolved) continue;
3834
3863
  const isSame = await isSameDOMElement(page, originalLocator, resolved, timeoutMs);
3835
3864
  if (!isSame) continue;
3836
- logger3.debug("[SelectorDerivation] Found unique row anchor", {
3865
+ logger4.debug("[SelectorDerivation] Found unique row anchor", {
3837
3866
  selectorType,
3838
3867
  parentContext: candidateParent
3839
3868
  });
@@ -3844,7 +3873,7 @@ async function discoverParentContext(page, selectors, selectorType, originalLoca
3844
3873
  }
3845
3874
  }
3846
3875
  } catch (err) {
3847
- logger3.debug("[SelectorDerivation] Row-anchor strategy error", {
3876
+ logger4.debug("[SelectorDerivation] Row-anchor strategy error", {
3848
3877
  error: err instanceof Error ? err.message : String(err)
3849
3878
  });
3850
3879
  }
@@ -3937,7 +3966,7 @@ async function discoverParentContext(page, selectors, selectorType, originalLoca
3937
3966
  if (resolved) {
3938
3967
  const isSame = await isSameDOMElement(page, originalLocator, resolved, timeoutMs);
3939
3968
  if (!isSame) {
3940
- logger3.debug(
3969
+ logger4.debug(
3941
3970
  "[SelectorDerivation] Parent-scoped selector resolved to wrong element, skipping",
3942
3971
  {
3943
3972
  selectorType,
@@ -3946,7 +3975,7 @@ async function discoverParentContext(page, selectors, selectorType, originalLoca
3946
3975
  );
3947
3976
  continue;
3948
3977
  }
3949
- logger3.debug("[SelectorDerivation] Found unique parent via simple scoping", {
3978
+ logger4.debug("[SelectorDerivation] Found unique parent via simple scoping", {
3950
3979
  selectorType,
3951
3980
  parentContext: candidateParent
3952
3981
  });
@@ -3958,7 +3987,7 @@ async function discoverParentContext(page, selectors, selectorType, originalLoca
3958
3987
  }
3959
3988
  }
3960
3989
  } catch (err) {
3961
- logger3.debug("[SelectorDerivation] Error in simple parent scoping", {
3990
+ logger4.debug("[SelectorDerivation] Error in simple parent scoping", {
3962
3991
  error: err instanceof Error ? err.message : String(err)
3963
3992
  });
3964
3993
  }
@@ -4079,7 +4108,7 @@ async function discoverParentContext(page, selectors, selectorType, originalLoca
4079
4108
  }
4080
4109
  const targetEl = elementAncestries.find((e) => e.isTarget);
4081
4110
  if (!targetEl) {
4082
- logger3.warn("[SelectorDerivation] Target not found by DOM identity in ancestry search");
4111
+ logger4.warn("[SelectorDerivation] Target not found by DOM identity in ancestry search");
4083
4112
  return null;
4084
4113
  }
4085
4114
  for (let depth = 0; depth < maxParentDepth; depth++) {
@@ -4098,7 +4127,7 @@ async function discoverParentContext(page, selectors, selectorType, originalLoca
4098
4127
  try {
4099
4128
  const resolved = await resolveElement(page, strategyWithChain, timeoutMs, { mode: "verify" });
4100
4129
  if (resolved) {
4101
- logger3.debug("[SelectorDerivation] Found unique parent chain via recursive search", {
4130
+ logger4.debug("[SelectorDerivation] Found unique parent chain via recursive search", {
4102
4131
  depth,
4103
4132
  parentChain
4104
4133
  });
@@ -4108,7 +4137,7 @@ async function discoverParentContext(page, selectors, selectorType, originalLoca
4108
4137
  continue;
4109
4138
  }
4110
4139
  }
4111
- logger3.warn("[SelectorDerivation] No unique parent found, using matchIndex fallback", {
4140
+ logger4.warn("[SelectorDerivation] No unique parent found, using matchIndex fallback", {
4112
4141
  targetIndex: targetEl.index,
4113
4142
  matchCount: count
4114
4143
  });
@@ -4117,7 +4146,7 @@ async function discoverParentContext(page, selectors, selectorType, originalLoca
4117
4146
  };
4118
4147
  }
4119
4148
  async function probeChildIconCSS(page, originalLocator, role) {
4120
- const logger3 = getLogger2();
4149
+ const logger4 = getLogger2();
4121
4150
  const iconAttr = await originalLocator.evaluate((el) => {
4122
4151
  const svg = el.querySelector("svg[data-icon]");
4123
4152
  return svg?.getAttribute("data-icon") ?? null;
@@ -4127,7 +4156,7 @@ async function probeChildIconCSS(page, originalLocator, role) {
4127
4156
  try {
4128
4157
  const count = await page.locator(baseSelector).count();
4129
4158
  if (count === 1) {
4130
- logger3.debug("[SelectorDerivation] probeChildIconCSS found unique selector", {
4159
+ logger4.debug("[SelectorDerivation] probeChildIconCSS found unique selector", {
4131
4160
  css: baseSelector
4132
4161
  });
4133
4162
  return baseSelector;
@@ -4141,7 +4170,7 @@ async function probeChildIconCSS(page, originalLocator, role) {
4141
4170
  const hasMarker = await matches.nth(i).evaluate((el, attr) => el.hasAttribute(attr), MARKER);
4142
4171
  if (hasMarker) {
4143
4172
  const nthSelector = `${baseSelector} >> nth=${i}`;
4144
- logger3.debug("[SelectorDerivation] probeChildIconCSS disambiguated via nth", {
4173
+ logger4.debug("[SelectorDerivation] probeChildIconCSS disambiguated via nth", {
4145
4174
  css: nthSelector,
4146
4175
  matchCount: count,
4147
4176
  index: i
@@ -4154,7 +4183,7 @@ async function probeChildIconCSS(page, originalLocator, role) {
4154
4183
  });
4155
4184
  }
4156
4185
  }
4157
- logger3.debug("[SelectorDerivation] probeChildIconCSS could not disambiguate", {
4186
+ logger4.debug("[SelectorDerivation] probeChildIconCSS could not disambiguate", {
4158
4187
  css: baseSelector,
4159
4188
  count
4160
4189
  });
@@ -4164,7 +4193,7 @@ async function probeChildIconCSS(page, originalLocator, role) {
4164
4193
  }
4165
4194
  }
4166
4195
  async function probeElementIdCSS(page, originalLocator) {
4167
- const logger3 = getLogger2();
4196
+ const logger4 = getLogger2();
4168
4197
  const elementId = await originalLocator.evaluate((el) => {
4169
4198
  if (el.id) return el.id;
4170
4199
  const child = el.querySelector("[id]");
@@ -4175,7 +4204,7 @@ async function probeElementIdCSS(page, originalLocator) {
4175
4204
  try {
4176
4205
  const count = await page.locator(baseSelector).count();
4177
4206
  if (count === 1) {
4178
- logger3.debug("[SelectorDerivation] probeElementIdCSS found unique selector", {
4207
+ logger4.debug("[SelectorDerivation] probeElementIdCSS found unique selector", {
4179
4208
  css: baseSelector
4180
4209
  });
4181
4210
  return baseSelector;
@@ -4198,7 +4227,7 @@ async function probeElementIdCSS(page, originalLocator) {
4198
4227
  }
4199
4228
  }
4200
4229
  if (visibleCount === 1 && targetIsOnlyVisible) {
4201
- logger3.debug("[SelectorDerivation] probeElementIdCSS: single visible among duplicates", {
4230
+ logger4.debug("[SelectorDerivation] probeElementIdCSS: single visible among duplicates", {
4202
4231
  css: baseSelector,
4203
4232
  matchCount: count
4204
4233
  });
@@ -4212,7 +4241,7 @@ async function probeElementIdCSS(page, originalLocator) {
4212
4241
  const hasMarker = await matches.nth(i).evaluate((el, attr) => el.hasAttribute(attr), MARKER);
4213
4242
  if (hasMarker) {
4214
4243
  const nthSelector = `${baseSelector} >> nth=${i}`;
4215
- logger3.debug("[SelectorDerivation] probeElementIdCSS disambiguated via nth", {
4244
+ logger4.debug("[SelectorDerivation] probeElementIdCSS disambiguated via nth", {
4216
4245
  css: nthSelector,
4217
4246
  matchCount: count,
4218
4247
  index: i
@@ -4225,7 +4254,7 @@ async function probeElementIdCSS(page, originalLocator) {
4225
4254
  });
4226
4255
  }
4227
4256
  }
4228
- logger3.debug("[SelectorDerivation] probeElementIdCSS could not disambiguate", {
4257
+ logger4.debug("[SelectorDerivation] probeElementIdCSS could not disambiguate", {
4229
4258
  css: baseSelector,
4230
4259
  count
4231
4260
  });
@@ -4235,14 +4264,14 @@ async function probeElementIdCSS(page, originalLocator) {
4235
4264
  }
4236
4265
  }
4237
4266
  async function probeTitleCSS(page, originalLocator) {
4238
- const logger3 = getLogger2();
4267
+ const logger4 = getLogger2();
4239
4268
  const titleAttr = await originalLocator.evaluate((el) => el.getAttribute("title")).catch(() => null);
4240
4269
  if (!titleAttr) return void 0;
4241
4270
  const baseSelector = `[title="${titleAttr}"]`;
4242
4271
  try {
4243
4272
  const count = await page.locator(baseSelector).count();
4244
4273
  if (count === 1) {
4245
- logger3.debug("[SelectorDerivation] probeTitleCSS found unique selector", {
4274
+ logger4.debug("[SelectorDerivation] probeTitleCSS found unique selector", {
4246
4275
  css: baseSelector
4247
4276
  });
4248
4277
  return baseSelector;
@@ -4256,7 +4285,7 @@ async function probeTitleCSS(page, originalLocator) {
4256
4285
  const hasMarker = await matches.nth(i).evaluate((el, attr) => el.hasAttribute(attr), MARKER);
4257
4286
  if (hasMarker) {
4258
4287
  const nthSelector = `${baseSelector} >> nth=${i}`;
4259
- logger3.debug("[SelectorDerivation] probeTitleCSS disambiguated via nth", {
4288
+ logger4.debug("[SelectorDerivation] probeTitleCSS disambiguated via nth", {
4260
4289
  css: nthSelector,
4261
4290
  matchCount: count,
4262
4291
  index: i
@@ -4269,7 +4298,7 @@ async function probeTitleCSS(page, originalLocator) {
4269
4298
  });
4270
4299
  }
4271
4300
  }
4272
- logger3.debug("[SelectorDerivation] probeTitleCSS could not disambiguate", {
4301
+ logger4.debug("[SelectorDerivation] probeTitleCSS could not disambiguate", {
4273
4302
  css: baseSelector,
4274
4303
  count
4275
4304
  });
@@ -4375,7 +4404,7 @@ async function probeAncestorRowIndex(elementLocator, timeoutMs = 3e3) {
4375
4404
  }
4376
4405
  async function verifySingleSelector(page, selectors, selectorType, originalLocator, options) {
4377
4406
  const { timeoutMs } = options;
4378
- const logger3 = getLogger2();
4407
+ const logger4 = getLogger2();
4379
4408
  const result = {
4380
4409
  selectorType,
4381
4410
  verified: false,
@@ -4395,11 +4424,11 @@ async function verifySingleSelector(page, selectors, selectorType, originalLocat
4395
4424
  result.verified = true;
4396
4425
  return result;
4397
4426
  }
4398
- logger3.debug("[SelectorDerivation] Initial resolution failed, trying parent disambiguation", {
4427
+ logger4.debug("[SelectorDerivation] Initial resolution failed, trying parent disambiguation", {
4399
4428
  selectorType
4400
4429
  });
4401
4430
  if (selectors.itemIndex !== void 0 || selectors.rowIndex !== void 0) {
4402
- logger3.debug("[SelectorDerivation] Data attributes present but did not disambiguate", {
4431
+ logger4.debug("[SelectorDerivation] Data attributes present but did not disambiguate", {
4403
4432
  selectorType,
4404
4433
  itemIndex: selectors.itemIndex,
4405
4434
  rowIndex: selectors.rowIndex
@@ -4552,9 +4581,9 @@ var DYNAMIC_TEXT_MIN_RATIO = 0.4;
4552
4581
  var DYNAMIC_TEXT_DISTINCTIVE_LENGTH = 8;
4553
4582
  function buildDynamicValueEntries(variableValues) {
4554
4583
  const entries = [];
4555
- for (const [key, value] of Object.entries(variableValues)) {
4584
+ for (const [key2, value] of Object.entries(variableValues)) {
4556
4585
  if (typeof value !== "string" || value.length < DYNAMIC_TEXT_MIN_LENGTH) continue;
4557
- entries.push({ source: "inputValue", key, value });
4586
+ entries.push({ source: "inputValue", key: key2, value });
4558
4587
  }
4559
4588
  entries.sort((a, b) => b.value.length - a.value.length);
4560
4589
  return entries;
@@ -4709,9 +4738,9 @@ function hydrateDynamicSelectors(selectors, variableValues) {
4709
4738
  }
4710
4739
  const dynamicText = hydrated.dynamicText;
4711
4740
  if (!dynamicText) return hydrated;
4712
- const { key, originalText } = dynamicText;
4741
+ const { key: key2, originalText } = dynamicText;
4713
4742
  selectors = hydrated;
4714
- const currentValue = variableValues[key];
4743
+ const currentValue = variableValues[key2];
4715
4744
  if (!currentValue || currentValue === originalText) {
4716
4745
  return selectors;
4717
4746
  }
@@ -4720,7 +4749,7 @@ function hydrateDynamicSelectors(selectors, variableValues) {
4720
4749
  getLogger2().warn(
4721
4750
  "[SelectorDerivation] Full-field replacement triggered due to stale surrounding text",
4722
4751
  {
4723
- key,
4752
+ key: key2,
4724
4753
  originalText,
4725
4754
  currentValue,
4726
4755
  roleName: selectors.role?.name,
@@ -4736,8 +4765,8 @@ function hydrateDynamicSelectors(selectors, variableValues) {
4736
4765
  return nextSelectors;
4737
4766
  }
4738
4767
  function hydratePlaywrightLocatorVariables(locator, variableValues) {
4739
- return locator.replace(/\{\{var\.([a-zA-Z0-9_]+)\}\}/g, (match, key) => {
4740
- const value = variableValues[key];
4768
+ return locator.replace(/\{\{var\.([a-zA-Z0-9_]+)\}\}/g, (match, key2) => {
4769
+ const value = variableValues[key2];
4741
4770
  if (value === void 0) return match;
4742
4771
  return value.replace(/\\/g, "\\\\").replace(/'/g, "\\'");
4743
4772
  });
@@ -4827,9 +4856,9 @@ var escapeRegex3 = (s) => s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
4827
4856
  var STRING_LITERAL = /'(?:\\.|[^'\\])*'|"(?:\\.|[^"\\])*"/g;
4828
4857
  function replaceVariableValuesInString(input, sortedEntries) {
4829
4858
  let out = input;
4830
- for (const [key, value] of sortedEntries) {
4859
+ for (const [key2, value] of sortedEntries) {
4831
4860
  if (!value || out.indexOf(value) === -1) continue;
4832
- out = out.replace(new RegExp(escapeRegex3(value), "g"), `$var.${key}`);
4861
+ out = out.replace(new RegExp(escapeRegex3(value), "g"), `$var.${key2}`);
4833
4862
  }
4834
4863
  return out;
4835
4864
  }
@@ -4846,21 +4875,21 @@ function endsWithOddBackslashes(s) {
4846
4875
  return count % 2 === 1;
4847
4876
  }
4848
4877
  function rewriteStringLiteralInner(inner, quote, sortedEntries) {
4849
- for (const [key, value] of sortedEntries) {
4878
+ for (const [key2, value] of sortedEntries) {
4850
4879
  if (!value || inner.indexOf(value) === -1) continue;
4851
- if (inner === value) return `$var.${key}`;
4880
+ if (inner === value) return `$var.${key2}`;
4852
4881
  const parts = inner.split(value);
4853
4882
  if (parts.some((p) => p.length > 0 && endsWithOddBackslashes(p))) continue;
4854
4883
  const pieces = [];
4855
4884
  for (let i = 0; i < parts.length; i++) {
4856
4885
  const segment = parts[i];
4857
4886
  if (segment.length > 0) pieces.push(`${quote}${segment}${quote}`);
4858
- if (i < parts.length - 1) pieces.push(`$var.${key}`);
4887
+ if (i < parts.length - 1) pieces.push(`$var.${key2}`);
4859
4888
  }
4860
4889
  const rebuilt = pieces.join(" + ");
4861
4890
  return replaceVariableValuesInJsExpression(
4862
4891
  rebuilt,
4863
- sortedEntries.filter(([k]) => k !== key)
4892
+ sortedEntries.filter(([k]) => k !== key2)
4864
4893
  );
4865
4894
  }
4866
4895
  return `${quote}${inner}${quote}`;
@@ -5103,7 +5132,7 @@ var HeadlessDomSession = class {
5103
5132
 
5104
5133
  // ../workflow-cache/src/optimizer/trace-node-segmenter.ts
5105
5134
  var STEP_GROUP = /^Step (\d+): (.*)$/;
5106
- var CACHE_REPLAY_GROUP = /^Cache Replay: (.*)$/;
5135
+ var CACHE_REPLAY_GROUP = /^Cache Replay(?: (\d+))?: (.*)$/;
5107
5136
  var INTERNAL_GROUP_PREFIX = "Canary Internal:";
5108
5137
  function segmentTraceByNode(groups, actions) {
5109
5138
  const nodeGroups = groups.filter(
@@ -5114,10 +5143,11 @@ function segmentTraceByNode(groups, actions) {
5114
5143
  const stepMatch = STEP_GROUP.exec(g.name);
5115
5144
  const replayMatch = CACHE_REPLAY_GROUP.exec(g.name);
5116
5145
  const effectiveEnd = g.endTime ?? sorted[idx + 1]?.startTime;
5146
+ const stepNumberRaw = stepMatch ? stepMatch[1] : replayMatch?.[1];
5117
5147
  return {
5118
5148
  kind: stepMatch ? "agent-step" : "cache-replay",
5119
- stepNumber: stepMatch ? Number(stepMatch[1]) : void 0,
5120
- label: stepMatch ? stepMatch[2] : replayMatch[1],
5149
+ stepNumber: stepNumberRaw !== void 0 ? Number(stepNumberRaw) : void 0,
5150
+ label: stepMatch ? stepMatch[2] : replayMatch[2],
5121
5151
  groupCallId: g.callId,
5122
5152
  startTime: g.startTime,
5123
5153
  endTime: effectiveEnd,
@@ -5150,10 +5180,28 @@ function segmentTraceByNode(groups, actions) {
5150
5180
  }
5151
5181
  return segments;
5152
5182
  }
5183
+ function resolveSegmentNodeIds(segments, steps) {
5184
+ let cursor = 0;
5185
+ return segments.map((segment) => {
5186
+ if (segment.stepNumber !== void 0) {
5187
+ const idx = segment.stepNumber - 1;
5188
+ cursor = Math.max(cursor, idx + 1);
5189
+ return steps[idx]?.nodeId ?? null;
5190
+ }
5191
+ for (let j = cursor; j < steps.length; j++) {
5192
+ if (steps[j].label === segment.label) {
5193
+ cursor = j + 1;
5194
+ return steps[j].nodeId;
5195
+ }
5196
+ }
5197
+ return null;
5198
+ });
5199
+ }
5153
5200
 
5154
5201
  // ../workflow-cache/src/optimizer/substrate-materializer.ts
5155
5202
  import { mkdir, writeFile } from "fs/promises";
5156
5203
  import path from "path";
5204
+ import { pathToFileURL } from "url";
5157
5205
  var logger2 = createLogger({ module: "SubstrateMaterializer" });
5158
5206
  var SubstrateMaterializer = class {
5159
5207
  constructor(opts) {
@@ -5165,22 +5213,35 @@ var SubstrateMaterializer = class {
5165
5213
  cache = /* @__PURE__ */ new Map();
5166
5214
  session;
5167
5215
  ownsSession;
5216
+ /** Parsed trace actions in `actions.jsonl` order — lazy, parsed once. */
5217
+ allActions = null;
5168
5218
  /**
5169
5219
  * Reconstruct one action's snapshot and capture substrate-v2 over it.
5170
5220
  * `phase: 'before'` is the page state the action targeted (locator input);
5171
5221
  * `'after'` is its result (the next action's context).
5222
+ *
5223
+ * `actionIndex` is the action's position in `parseTraceActions` order — the
5224
+ * SAME index space as the workspace's `browser/actions.jsonl` and
5225
+ * `optimizer/segments.json` actionIndices. The mutation-filtered index the
5226
+ * snapshot reconstructor uses internally is remapped here; observation
5227
+ * actions (screenshots) are rejected with a self-correcting error.
5172
5228
  */
5173
5229
  async materialize(actionIndex, phase = "before") {
5174
- const key = `${actionIndex}:${phase}`;
5175
- const hit = this.cache.get(key);
5230
+ const key2 = `${actionIndex}:${phase}`;
5231
+ const hit = this.cache.get(key2);
5176
5232
  if (hit) return hit;
5233
+ this.allActions ??= parseTraceActions(this.opts.traceZipPath);
5234
+ const resolved = toMutationIndex(this.allActions, actionIndex);
5235
+ if (!resolved.ok) {
5236
+ throw new Error(resolved.reason);
5237
+ }
5177
5238
  const results = await reconstructSnapshots({
5178
5239
  traceZipPath: this.opts.traceZipPath,
5179
5240
  includeScreenshots: false,
5180
5241
  includeHtml: true,
5181
5242
  filter: phase,
5182
5243
  raw: false,
5183
- actionIndex
5244
+ actionIndex: resolved.mutationIndex
5184
5245
  });
5185
5246
  const snapshot = results.find((r) => r.phase === phase && r.html);
5186
5247
  if (!snapshot?.html) {
@@ -5189,14 +5250,14 @@ var SubstrateMaterializer = class {
5189
5250
  );
5190
5251
  }
5191
5252
  await mkdir(this.opts.outDir, { recursive: true });
5192
- const domPath = path.join(this.opts.outDir, `${actionIndex}.${phase}.dom.html`);
5253
+ const domPath = path.resolve(this.opts.outDir, `${actionIndex}.${phase}.dom.html`);
5193
5254
  await writeFile(domPath, snapshot.html, "utf-8");
5194
5255
  const page = await this.session.page();
5195
5256
  try {
5196
- await page.goto(`file://${domPath}`, { waitUntil: "load" });
5257
+ await page.goto(pathToFileURL(domPath).href, { waitUntil: "load" });
5197
5258
  await waitForTraceDomHydration(page);
5198
5259
  const substrateYaml = await captureSubstrateV2(page, this.opts.logger ?? logger2);
5199
- const substratePath = path.join(this.opts.outDir, `${actionIndex}.${phase}.substrate.v2.yaml`);
5260
+ const substratePath = path.resolve(this.opts.outDir, `${actionIndex}.${phase}.substrate.v2.yaml`);
5200
5261
  await writeFile(substratePath, substrateYaml, "utf-8");
5201
5262
  const out = {
5202
5263
  substrateYaml,
@@ -5205,7 +5266,7 @@ var SubstrateMaterializer = class {
5205
5266
  actionIndex,
5206
5267
  phase
5207
5268
  };
5208
- this.cache.set(key, out);
5269
+ this.cache.set(key2, out);
5209
5270
  return out;
5210
5271
  } finally {
5211
5272
  await page.close().catch(() => void 0);
@@ -5224,6 +5285,8 @@ async function waitForTraceDomHydration(page) {
5224
5285
  }
5225
5286
 
5226
5287
  // ../workflow-cache/src/optimizer/locator-verifier.ts
5288
+ import path2 from "path";
5289
+ import { pathToFileURL as pathToFileURL2 } from "url";
5227
5290
  var RESOLVE_TIMEOUT_MS2 = 5e3;
5228
5291
  function identifyingTokens(strategy) {
5229
5292
  const tokens = [];
@@ -5259,7 +5322,7 @@ var LocatorVerifier = class {
5259
5322
  const tokenPass = classifyStrategyTokens(opts.strategy);
5260
5323
  const page = await this.session.page();
5261
5324
  try {
5262
- await page.goto(`file://${opts.domPath}`, { waitUntil: "load" });
5325
+ await page.goto(pathToFileURL2(path2.resolve(opts.domPath)).href, { waitUntil: "load" });
5263
5326
  await waitForTraceDomHydration(page);
5264
5327
  await page.ariaSnapshot({ mode: "ai" });
5265
5328
  const truth = page.locator(`aria-ref=${opts.targetRef}`);
@@ -5317,6 +5380,148 @@ var LocatorVerifier = class {
5317
5380
  }
5318
5381
  };
5319
5382
 
5383
+ // ../workflow-cache/src/optimizer/augmentor-verifier.ts
5384
+ import path3 from "path";
5385
+ import { pathToFileURL as pathToFileURL3 } from "url";
5386
+ var logger3 = createLogger({ module: "AugmentorVerifier" });
5387
+ function flatten2(roots) {
5388
+ const out = [];
5389
+ const walk = (n) => {
5390
+ out.push(n);
5391
+ for (const c of n.children) walk(c);
5392
+ };
5393
+ for (const r of roots) walk(r);
5394
+ return out;
5395
+ }
5396
+ var key = (role, name) => `${role}\0${name ?? ""}`;
5397
+ var AugmentorVerifier = class {
5398
+ session;
5399
+ ownsSession;
5400
+ constructor(opts) {
5401
+ this.session = opts?.session ?? new HeadlessDomSession();
5402
+ this.ownsSession = !opts?.session;
5403
+ }
5404
+ async verify(opts) {
5405
+ const { domPath, augmentor } = opts;
5406
+ const issues = [];
5407
+ const page = await this.session.page();
5408
+ try {
5409
+ await page.goto(pathToFileURL3(path3.resolve(domPath)).href, { waitUntil: "load" });
5410
+ await waitForTraceDomHydration(page);
5411
+ const baselineYaml = await captureSubstrateV2(page, logger3);
5412
+ const baselineKeys = new Set(flatten2(parseSnapshot(baselineYaml)).map((e) => key(e.role, e.text)));
5413
+ const pass = await applyCustomAugmentors(page, [augmentor], logger3);
5414
+ const exec = pass.executions[0];
5415
+ const elementsAnnotated = exec?.elementsAnnotated ?? 0;
5416
+ const errored = exec?.errored ?? false;
5417
+ const invariantPassed = exec?.invariantPassed ?? false;
5418
+ const durationMs = exec?.durationMs ?? 0;
5419
+ if (errored) {
5420
+ issues.push(`collector errored in page: ${exec?.errorMessage ?? "unknown"}`);
5421
+ }
5422
+ if (elementsAnnotated === 0) {
5423
+ issues.push("collector annotated 0 elements \u2014 matchSelector found nothing, or every descriptor was rejected");
5424
+ }
5425
+ const augmentedYaml = await captureSubstrateV2(page, logger3);
5426
+ const augmentedEls = flatten2(parseSnapshot(augmentedYaml));
5427
+ const annotatedKeys = new Set(pass.annotations.map((a) => key(a.role, a.name)));
5428
+ const newEls = augmentedEls.filter(
5429
+ (e) => annotatedKeys.has(key(e.role, e.text)) && !baselineKeys.has(key(e.role, e.text))
5430
+ );
5431
+ const baselineAbsent = pass.annotations.length > 0 && newEls.length > 0;
5432
+ if (!baselineAbsent && pass.annotations.length > 0) {
5433
+ issues.push(
5434
+ "annotated (role,name) pairs were already present in the un-augmented snapshot \u2014 this augmentor heals nothing (or the names are not distinctive)"
5435
+ );
5436
+ }
5437
+ const sampleRefs = newEls.slice(0, 8).map((e) => e.ref);
5438
+ const targeting = await Promise.all(
5439
+ sampleRefs.map(async (ref) => {
5440
+ try {
5441
+ const handle = await page.$(`aria-ref=${ref}`);
5442
+ const augId = handle ? await handle.getAttribute("data-augmentor-id").catch(() => null) : null;
5443
+ await handle?.dispose();
5444
+ if (augId !== augmentor.id) {
5445
+ return `ref ${ref} did not resolve to an augmentor-annotated element`;
5446
+ }
5447
+ return null;
5448
+ } catch (err) {
5449
+ return `ref ${ref} could not be resolved: ${err instanceof Error ? err.message : String(err)}`;
5450
+ }
5451
+ })
5452
+ );
5453
+ const targetingIssues = targeting.filter((i) => i !== null);
5454
+ for (const i of targetingIssues) issues.push(i);
5455
+ const refsResolveToTargets = sampleRefs.length > 0 && targetingIssues.length === 0;
5456
+ const cacheCheck = await page.evaluate(() => {
5457
+ const els = Array.from(document.querySelectorAll("[data-augmentor-id]"));
5458
+ let anchorless = 0;
5459
+ const failures = [];
5460
+ els.forEach((el, i) => el.setAttribute("data-aug-verify-idx", String(i)));
5461
+ const anchors = els.map((el) => el.getAttribute("data-augmentor-anchor"));
5462
+ for (const el of els) {
5463
+ el.removeAttribute("role");
5464
+ el.removeAttribute("aria-label");
5465
+ el.removeAttribute("aria-disabled");
5466
+ el.removeAttribute("data-augmentor-id");
5467
+ el.removeAttribute("data-augmentor-anchor");
5468
+ }
5469
+ els.forEach((el, i) => {
5470
+ const anchor = anchors[i];
5471
+ if (!anchor) {
5472
+ anchorless++;
5473
+ return;
5474
+ }
5475
+ if (anchor.length > 500) {
5476
+ failures.push(`stableAnchor #${i} exceeds 500 chars \u2014 too complex to be durable: ${anchor.slice(0, 80)}\u2026`);
5477
+ return;
5478
+ }
5479
+ let matches = [];
5480
+ try {
5481
+ matches = Array.from(document.querySelectorAll(anchor));
5482
+ } catch {
5483
+ failures.push(`stableAnchor #${i} is not a valid selector: ${anchor}`);
5484
+ return;
5485
+ }
5486
+ if (matches.length !== 1) {
5487
+ failures.push(`stableAnchor #${i} matched ${matches.length} elements (want exactly 1): ${anchor}`);
5488
+ } else if (matches[0]?.getAttribute("data-aug-verify-idx") !== String(i)) {
5489
+ failures.push(`stableAnchor #${i} resolved to a different element than its target: ${anchor}`);
5490
+ }
5491
+ });
5492
+ return { anchorless, failures };
5493
+ });
5494
+ for (const f of cacheCheck.failures) issues.push(f);
5495
+ const cacheSafe = cacheCheck.failures.length === 0;
5496
+ if (cacheCheck.anchorless > 0) {
5497
+ issues.push(
5498
+ `${cacheCheck.anchorless} annotated element(s) declared no stableAnchor \u2014 they will be visible to the agent but their locators stay irreducible (workflow-variable / L3 disambiguation)`
5499
+ );
5500
+ }
5501
+ const verified = baselineAbsent && !errored && invariantPassed && elementsAnnotated > 0 && refsResolveToTargets && cacheSafe;
5502
+ return {
5503
+ verified,
5504
+ baselineAbsent,
5505
+ elementsAnnotated,
5506
+ invariantPassed,
5507
+ errored,
5508
+ errorMessage: exec?.errorMessage,
5509
+ sampleRefs,
5510
+ refsResolveToTargets,
5511
+ cacheSafe,
5512
+ anchorlessCount: cacheCheck.anchorless,
5513
+ durationMs,
5514
+ issues
5515
+ };
5516
+ } finally {
5517
+ await page.close().catch(() => void 0);
5518
+ }
5519
+ }
5520
+ async close() {
5521
+ if (this.ownsSession) await this.session.close();
5522
+ }
5523
+ };
5524
+
5320
5525
  // ../workflow-cache/src/optimizer/action-synthesizer.ts
5321
5526
  var ELEMENT_TARGET_ACTION_TYPES = /* @__PURE__ */ new Set([
5322
5527
  "click",
@@ -5426,8 +5631,11 @@ function buildCacheRecipe(opts) {
5426
5631
  const bindingKeys = /* @__PURE__ */ new Set();
5427
5632
  for (const a of actionsJson) {
5428
5633
  if (a.variableKey) bindingKeys.add(`$var.${a.variableKey}`);
5429
- for (const key of Object.values(a.variableBindings ?? {})) bindingKeys.add(`$var.${key}`);
5634
+ for (const key2 of Object.values(a.variableBindings ?? {})) bindingKeys.add(`$var.${key2}`);
5430
5635
  for (const expr of Object.values(a.macroBindings ?? {})) bindingKeys.add(expr);
5636
+ if (a.actionType === "capture" && typeof a.args?.saveAs === "string" && a.args.saveAs) {
5637
+ bindingKeys.add(`$var.${a.args.saveAs}`);
5638
+ }
5431
5639
  }
5432
5640
  const missing = opts.requiredTokens.filter((t) => !present.has(t) && !bindingKeys.has(t));
5433
5641
  if (missing.length > 0) {
@@ -5655,13 +5863,13 @@ function resolveMacros(value, ctx) {
5655
5863
  function resolveMacrosInRecord(values, ctx) {
5656
5864
  const resolved = {};
5657
5865
  const log = /* @__PURE__ */ new Map();
5658
- for (const [key, value] of Object.entries(values)) {
5866
+ for (const [key2, value] of Object.entries(values)) {
5659
5867
  if (containsMacro(value)) {
5660
5868
  const resolvedValue = resolveMacros(value, ctx);
5661
- resolved[key] = resolvedValue;
5662
- log.set(key, { expression: value, resolved: resolvedValue });
5869
+ resolved[key2] = resolvedValue;
5870
+ log.set(key2, { expression: value, resolved: resolvedValue });
5663
5871
  } else {
5664
- resolved[key] = value;
5872
+ resolved[key2] = value;
5665
5873
  }
5666
5874
  }
5667
5875
  return { resolved, log };
@@ -5671,12 +5879,13 @@ function resolveNodeInputMacros(inputValues, ctx, workflowState) {
5671
5879
  const hasMacros = Object.values(inputValues).some((v) => containsMacro(v));
5672
5880
  if (!hasMacros) return { resolvedValues: inputValues, macroResolutionLog: void 0 };
5673
5881
  const { resolved, log } = resolveMacrosInRecord(inputValues, ctx);
5674
- for (const [key, { resolved: val }] of log.entries()) {
5675
- workflowState[`macro:${key}`] = val;
5882
+ for (const [key2, { resolved: val }] of log.entries()) {
5883
+ workflowState[`macro:${key2}`] = val;
5676
5884
  }
5677
5885
  return { resolvedValues: resolved, macroResolutionLog: log };
5678
5886
  }
5679
5887
  export {
5888
+ AugmentorVerifier,
5680
5889
  CACHE_COMPILER_VERSION,
5681
5890
  HeadlessDomSession,
5682
5891
  LocatorVerifier,
@@ -5708,6 +5917,7 @@ export {
5708
5917
  findElementWithAncestors,
5709
5918
  findFirstVisibleElement,
5710
5919
  generateNodeHash,
5920
+ generateNodeHashV3,
5711
5921
  getFrameLocators,
5712
5922
  getMacro,
5713
5923
  getMacroNames,
@@ -5732,6 +5942,7 @@ export {
5732
5942
  resolveMacros,
5733
5943
  resolveMacrosInRecord,
5734
5944
  resolveNodeInputMacros,
5945
+ resolveSegmentNodeIds,
5735
5946
  resolveSpecificIframeSelector,
5736
5947
  sanitizeArgsForCache,
5737
5948
  segmentTraceByNode,
@@ -5745,4 +5956,4 @@ export {
5745
5956
  verifySelectorAgainstRef,
5746
5957
  waitForTraceDomHydration
5747
5958
  };
5748
- //# sourceMappingURL=src-BGDRMOKC.js.map
5959
+ //# sourceMappingURL=src-2FK3JHGW.js.map