sela-core 0.1.0-alpha.39 → 0.1.0-alpha.41

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 (97) hide show
  1. package/dist/boot/bootImpl.d.ts +14 -0
  2. package/dist/boot/bootImpl.d.ts.map +1 -0
  3. package/dist/boot/bootImpl.js +68 -0
  4. package/dist/boot/register.cjs +45 -0
  5. package/dist/boot/register.d.cts +2 -0
  6. package/dist/boot/register.d.cts.map +1 -0
  7. package/dist/boot/register.d.mts +2 -0
  8. package/dist/boot/register.d.mts.map +1 -0
  9. package/dist/boot/register.mjs +10 -0
  10. package/dist/cli/commands/init.js +48 -16
  11. package/dist/cli/commands/merge.d.ts.map +1 -1
  12. package/dist/cli/commands/merge.js +5 -0
  13. package/dist/cli/commands/shadowRegression.js +1 -1
  14. package/dist/config/ConfigLoader.d.ts.map +1 -1
  15. package/dist/config/ConfigLoader.js +33 -12
  16. package/dist/config/SelaConfig.d.ts +59 -0
  17. package/dist/config/SelaConfig.d.ts.map +1 -1
  18. package/dist/config/SelaConfig.js +36 -0
  19. package/dist/engine/SelaEngine.d.ts +3 -1
  20. package/dist/engine/SelaEngine.d.ts.map +1 -1
  21. package/dist/engine/SelaEngine.js +193 -3
  22. package/dist/errors/SelaError.d.ts +7 -0
  23. package/dist/errors/SelaError.d.ts.map +1 -1
  24. package/dist/errors/SelaError.js +7 -1
  25. package/dist/fixtures/index.d.ts.map +1 -1
  26. package/dist/fixtures/index.js +5 -4
  27. package/dist/providers/AnthropicProvider.d.ts +9 -0
  28. package/dist/providers/AnthropicProvider.d.ts.map +1 -0
  29. package/dist/providers/AnthropicProvider.js +33 -0
  30. package/dist/providers/LLMProvider.d.ts +13 -0
  31. package/dist/providers/LLMProvider.d.ts.map +1 -0
  32. package/dist/providers/LLMProvider.js +7 -0
  33. package/dist/providers/OpenAICompatibleProvider.d.ts +8 -0
  34. package/dist/providers/OpenAICompatibleProvider.d.ts.map +1 -0
  35. package/dist/providers/OpenAICompatibleProvider.js +48 -0
  36. package/dist/providers/ProviderFactory.d.ts +4 -0
  37. package/dist/providers/ProviderFactory.d.ts.map +1 -0
  38. package/dist/providers/ProviderFactory.js +50 -0
  39. package/dist/providers/SanitizingProvider.d.ts +8 -0
  40. package/dist/providers/SanitizingProvider.d.ts.map +1 -0
  41. package/dist/providers/SanitizingProvider.js +27 -0
  42. package/dist/services/ASTSourceUpdater.d.ts.map +1 -1
  43. package/dist/services/ASTSourceUpdater.js +39 -5
  44. package/dist/services/CrossFileHealer.d.ts +7 -1
  45. package/dist/services/CrossFileHealer.d.ts.map +1 -1
  46. package/dist/services/CrossFileHealer.js +243 -9
  47. package/dist/services/DefinitionTracer.d.ts +1 -0
  48. package/dist/services/DefinitionTracer.d.ts.map +1 -1
  49. package/dist/services/DefinitionTracer.js +59 -36
  50. package/dist/services/HealReportService.d.ts +32 -0
  51. package/dist/services/HealReportService.d.ts.map +1 -1
  52. package/dist/services/HealReportService.js +111 -18
  53. package/dist/services/IntentAuditor.d.ts +9 -7
  54. package/dist/services/IntentAuditor.d.ts.map +1 -1
  55. package/dist/services/IntentAuditor.js +21 -16
  56. package/dist/services/LLMService.d.ts +10 -7
  57. package/dist/services/LLMService.d.ts.map +1 -1
  58. package/dist/services/LLMService.js +76 -10
  59. package/dist/services/PRAutomationService.d.ts +7 -2
  60. package/dist/services/PRAutomationService.d.ts.map +1 -1
  61. package/dist/services/PRAutomationService.js +144 -133
  62. package/dist/services/RegressionManifestService.d.ts +8 -0
  63. package/dist/services/RegressionManifestService.d.ts.map +1 -1
  64. package/dist/services/RegressionManifestService.js +8 -0
  65. package/dist/services/RegressionReclassifier.d.ts +25 -0
  66. package/dist/services/RegressionReclassifier.d.ts.map +1 -0
  67. package/dist/services/RegressionReclassifier.js +195 -0
  68. package/dist/services/ReportMergeService.d.ts +9 -0
  69. package/dist/services/ReportMergeService.d.ts.map +1 -1
  70. package/dist/services/ReportMergeService.js +28 -0
  71. package/dist/services/SmartDOMPruner.d.ts +154 -0
  72. package/dist/services/SmartDOMPruner.d.ts.map +1 -0
  73. package/dist/services/SmartDOMPruner.js +678 -0
  74. package/dist/services/TraceBackEngine.d.ts +23 -6
  75. package/dist/services/TraceBackEngine.d.ts.map +1 -1
  76. package/dist/services/TraceBackEngine.js +51 -13
  77. package/dist/services/VisualSnapshotService.d.ts +54 -0
  78. package/dist/services/VisualSnapshotService.d.ts.map +1 -0
  79. package/dist/services/VisualSnapshotService.js +279 -0
  80. package/dist/services/vcs/GitHubProvider.d.ts +17 -0
  81. package/dist/services/vcs/GitHubProvider.d.ts.map +1 -0
  82. package/dist/services/vcs/GitHubProvider.js +162 -0
  83. package/dist/services/vcs/GitLabProvider.d.ts +17 -0
  84. package/dist/services/vcs/GitLabProvider.d.ts.map +1 -0
  85. package/dist/services/vcs/GitLabProvider.js +175 -0
  86. package/dist/services/vcs/VCSProvider.d.ts +100 -0
  87. package/dist/services/vcs/VCSProvider.d.ts.map +1 -0
  88. package/dist/services/vcs/VCSProvider.js +7 -0
  89. package/dist/services/vcs/VCSProviderFactory.d.ts +7 -0
  90. package/dist/services/vcs/VCSProviderFactory.d.ts.map +1 -0
  91. package/dist/services/vcs/VCSProviderFactory.js +42 -0
  92. package/dist/types/index.d.ts +7 -0
  93. package/dist/types/index.d.ts.map +1 -1
  94. package/dist/utils/shell.d.ts +7 -0
  95. package/dist/utils/shell.d.ts.map +1 -0
  96. package/dist/utils/shell.js +32 -0
  97. package/package.json +7 -1
@@ -1992,9 +1992,40 @@ class ASTSourceUpdater {
1992
1992
  // and prevents dead variables (CLAUDE.md §5, Rules A–C).
1993
1993
  if (input.apply && input.newSelector) {
1994
1994
  const healFields = (0, HealFieldParser_1.parseHealFields)(input.newSelector);
1995
- const argTargets = (0, TraceBackEngine_1.resolveArgTargets)(trace.target.targetNode, healFields);
1995
+ const argResult = (0, TraceBackEngine_1.resolveArgTargetsEx)(trace.target.targetNode, healFields);
1996
+ const argTargets = argResult.targets;
1996
1997
  const hasSymbolic = argTargets.some((t) => !t.isCallSiteLiteral);
1998
+ // Guard: unresolvable symbolic arg (screenplay this.target.selector, dynamic
1999
+ // template factories) → abort immediately, no disk mutation.
2000
+ if (argResult.hasBlockingArg && argTargets.length === 0) {
2001
+ return {
2002
+ kind: "abort",
2003
+ trace: {
2004
+ status: "abort",
2005
+ severity: "hard",
2006
+ code: "UNSUPPORTED",
2007
+ reason: "locator argument is an unresolvable runtime-injected symbolic expression",
2008
+ },
2009
+ };
2010
+ }
1997
2011
  if (argTargets.length > 0 && hasSymbolic) {
2012
+ // Cross-file arg targets (factory or alias dict) — delegate to CrossFileHealer.
2013
+ const crossFileArgTargets = argTargets.filter((t) => t.crossFileRef);
2014
+ if (crossFileArgTargets.length > 0) {
2015
+ const cfTarget = crossFileArgTargets[0];
2016
+ const crossHealResult = ASTSourceUpdater.tryCrossFileHeal(input, cfTarget.crossFileRef, trace);
2017
+ if (crossHealResult !== null)
2018
+ return crossHealResult;
2019
+ return {
2020
+ kind: "abort",
2021
+ trace: {
2022
+ status: "abort",
2023
+ severity: "soft",
2024
+ code: "CROSS_FILE",
2025
+ reason: `cross-file arg heal failed for ${cfTarget.crossFileRef.kind}`,
2026
+ },
2027
+ };
2028
+ }
1998
2029
  const argDecision = (0, DecisionEngine_1.decideArgs)({
1999
2030
  argTargets,
2000
2031
  failingCallSite: failingNode,
@@ -2005,7 +2036,7 @@ class ASTSourceUpdater {
2005
2036
  });
2006
2037
  if (argDecision) {
2007
2038
  const batch = ASTSourceUpdater.decisionToBatch(input.filePath, argDecision);
2008
- const argResult = {
2039
+ const argDecResult = {
2009
2040
  kind: "decision",
2010
2041
  trace,
2011
2042
  decision: argDecision,
@@ -2013,9 +2044,9 @@ class ASTSourceUpdater {
2013
2044
  writtenLine: trace.target.targetNode.getStartLineNumber(),
2014
2045
  };
2015
2046
  if (batch.edits.length > 0) {
2016
- argResult.outcome = await MutationApplier_1.MutationApplier.applyFileBatchAsync(batch, input.applyOptions ?? {});
2047
+ argDecResult.outcome = await MutationApplier_1.MutationApplier.applyFileBatchAsync(batch, input.applyOptions ?? {});
2017
2048
  }
2018
- return argResult;
2049
+ return argDecResult;
2019
2050
  }
2020
2051
  }
2021
2052
  }
@@ -2159,7 +2190,10 @@ class ASTSourceUpdater {
2159
2190
  });
2160
2191
  let crossResult;
2161
2192
  if (crossFileRef.kind === "variable") {
2162
- crossResult = CrossFileHealer_1.CrossFileHealer.heal(crossFileRef.modulePath, crossFileRef.symbolName, input.newSelector, input.filePath, fsProject);
2193
+ crossResult = CrossFileHealer_1.CrossFileHealer.heal(crossFileRef.modulePath, crossFileRef.symbolName, input.newSelector, input.filePath, fsProject, 0, crossFileRef.propertyPath);
2194
+ }
2195
+ else if (crossFileRef.kind === "factory") {
2196
+ crossResult = CrossFileHealer_1.CrossFileHealer.healFactory(crossFileRef.modulePath, crossFileRef.symbolName, input.newSelector, input.filePath, fsProject);
2163
2197
  }
2164
2198
  else {
2165
2199
  crossResult = CrossFileHealer_1.CrossFileHealer.healPomProperty(crossFileRef.modulePath, crossFileRef.symbolName, crossFileRef.propName, input.newSelector, input.filePath, fsProject);
@@ -1,7 +1,13 @@
1
1
  import { Project } from "ts-morph";
2
2
  import type { ASTUpdateResult } from "./ASTSourceUpdater.js";
3
3
  export declare class CrossFileHealer {
4
- static heal(modulePath: string, symbolName: string, newValue: string, callerFilePath: string, project: Project, depth?: number): ASTUpdateResult;
4
+ static heal(modulePath: string, symbolName: string, newValue: string, callerFilePath: string, project: Project, depth?: number, propertyPath?: string[]): ASTUpdateResult;
5
+ /**
6
+ * Heal the return literal of an exported factory function.
7
+ * Handles: `const fn = () => "#selector"` and `function fn() { return "#selector"; }`.
8
+ * Returns failure when the return is a dynamic TemplateExpression (Rule D).
9
+ */
10
+ static healFactory(modulePath: string, functionName: string, newValue: string, callerFilePath: string, project: Project): ASTUpdateResult;
5
11
  /**
6
12
  * Heal a property on a POM class: finds the class by name in the module,
7
13
  * locates the string literal argument of a locator stored in `propName`
@@ -1 +1 @@
1
- {"version":3,"file":"CrossFileHealer.d.ts","sourceRoot":"","sources":["../../src/services/CrossFileHealer.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,OAAO,EAMR,MAAM,UAAU,CAAC;AAGlB,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAuC7D,qBAAa,eAAe;IAC1B,MAAM,CAAC,IAAI,CACT,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,EAChB,cAAc,EAAE,MAAM,EACtB,OAAO,EAAE,OAAO,EAChB,KAAK,SAAI,GACR,eAAe;IA6FlB;;;;;;;;;;;OAWG;IACH,MAAM,CAAC,eAAe,CACpB,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,cAAc,EAAE,MAAM,EACtB,OAAO,EAAE,OAAO,GACf,eAAe;CAoEnB;AAMD,wBAAgB,iBAAiB,CAC/B,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,GACf,MAAM,GAAG,IAAI,CAQf"}
1
+ {"version":3,"file":"CrossFileHealer.d.ts","sourceRoot":"","sources":["../../src/services/CrossFileHealer.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,OAAO,EAOR,MAAM,UAAU,CAAC;AAGlB,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAuC7D,qBAAa,eAAe;IAC1B,MAAM,CAAC,IAAI,CACT,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,EAChB,cAAc,EAAE,MAAM,EACtB,OAAO,EAAE,OAAO,EAChB,KAAK,SAAI,EACT,YAAY,CAAC,EAAE,MAAM,EAAE,GACtB,eAAe;IA+HlB;;;;OAIG;IACH,MAAM,CAAC,WAAW,CAChB,UAAU,EAAE,MAAM,EAClB,YAAY,EAAE,MAAM,EACpB,QAAQ,EAAE,MAAM,EAChB,cAAc,EAAE,MAAM,EACtB,OAAO,EAAE,OAAO,GACf,eAAe;IA2ElB;;;;;;;;;;;OAWG;IACH,MAAM,CAAC,eAAe,CACpB,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,cAAc,EAAE,MAAM,EACtB,OAAO,EAAE,OAAO,GACf,eAAe;CAoEnB;AAMD,wBAAgB,iBAAiB,CAC/B,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,GACf,MAAM,GAAG,IAAI,CAgCf"}
@@ -69,7 +69,7 @@ function captureDefinitionDiff(before, externalSf, externalPath) {
69
69
  // ═══════════════════════════════════════════════════════════════════
70
70
  const DEPTH_GUARD = 3;
71
71
  class CrossFileHealer {
72
- static heal(modulePath, symbolName, newValue, callerFilePath, project, depth = 0) {
72
+ static heal(modulePath, symbolName, newValue, callerFilePath, project, depth = 0, propertyPath) {
73
73
  if (depth >= DEPTH_GUARD) {
74
74
  return {
75
75
  success: false,
@@ -107,7 +107,7 @@ class CrossFileHealer {
107
107
  // Follow re-export chains (barrel files).
108
108
  if (traceResult.crossFile) {
109
109
  logger_1.logger.debug(`CrossFileHealer "${symbolName}" re-exported from "${traceResult.modulePath}" - following chain`);
110
- return CrossFileHealer.heal(traceResult.modulePath, traceResult.symbolName, newValue, externalPath, project, depth + 1);
110
+ return CrossFileHealer.heal(traceResult.modulePath, traceResult.symbolName, newValue, externalPath, project, depth + 1, propertyPath);
111
111
  }
112
112
  return {
113
113
  success: false,
@@ -115,16 +115,48 @@ class CrossFileHealer {
115
115
  strategy: "semantic-cross-file",
116
116
  };
117
117
  }
118
+ // Navigate into nested object properties when a path is provided.
119
+ // e.g. symbolName="Selectors", propertyPath=["Auth","LoginBtn"] resolves
120
+ // the StringLiteral inside `Selectors.Auth.LoginBtn`.
121
+ let targetNode = traceResult.targetNode;
122
+ if (propertyPath && propertyPath.length > 0) {
123
+ for (const key of propertyPath) {
124
+ if (!ts_morph_1.Node.isObjectLiteralExpression(targetNode)) {
125
+ return {
126
+ success: false,
127
+ reason: `CrossFileHealer: "${key}" not reachable — "${symbolName}" is not an ObjectLiteralExpression at this level`,
128
+ strategy: "semantic-cross-file",
129
+ };
130
+ }
131
+ const prop = targetNode.getProperty(key);
132
+ if (!prop || !ts_morph_1.Node.isPropertyAssignment(prop)) {
133
+ return {
134
+ success: false,
135
+ reason: `CrossFileHealer: property "${key}" not found in "${symbolName}"`,
136
+ strategy: "semantic-cross-file",
137
+ };
138
+ }
139
+ const init = prop.getInitializer();
140
+ if (!init) {
141
+ return {
142
+ success: false,
143
+ reason: `CrossFileHealer: property "${key}" in "${symbolName}" has no initializer`,
144
+ strategy: "semantic-cross-file",
145
+ };
146
+ }
147
+ targetNode = init;
148
+ }
149
+ }
118
150
  const before = traceResult.targetFile.getFullText();
119
- const result = InitializerUpdater_js_1.InitializerUpdater.apply(traceResult.targetNode, traceResult.targetFile, newValue);
151
+ const result = InitializerUpdater_js_1.InitializerUpdater.apply(targetNode, traceResult.targetFile, newValue);
120
152
  if (!result) {
121
153
  return {
122
154
  success: false,
123
- reason: `CrossFileHealer: InitializerUpdater rejected node type ${traceResult.targetNode.getKindName()}`,
155
+ reason: `CrossFileHealer: InitializerUpdater rejected node type ${targetNode.getKindName()}`,
124
156
  strategy: "semantic-cross-file",
125
157
  };
126
158
  }
127
- logger_1.logger.debug(`CrossFileHealer healed "${symbolName}" in ${path.basename(externalPath)} ` +
159
+ logger_1.logger.debug(`CrossFileHealer healed "${symbolName}${propertyPath ? "." + propertyPath.join(".") : ""}" in ${path.basename(externalPath)} ` +
128
160
  `@ line ${result.lineUpdated + 1}`);
129
161
  return {
130
162
  success: true,
@@ -136,6 +168,78 @@ class CrossFileHealer {
136
168
  unifiedDiff: captureDefinitionDiff(before, traceResult.targetFile, externalPath),
137
169
  };
138
170
  }
171
+ /**
172
+ * Heal the return literal of an exported factory function.
173
+ * Handles: `const fn = () => "#selector"` and `function fn() { return "#selector"; }`.
174
+ * Returns failure when the return is a dynamic TemplateExpression (Rule D).
175
+ */
176
+ static healFactory(modulePath, functionName, newValue, callerFilePath, project) {
177
+ const externalPath = resolveModulePath(modulePath, callerFilePath);
178
+ if (!externalPath) {
179
+ return {
180
+ success: false,
181
+ reason: `CrossFileHealer.healFactory: module "${modulePath}" not found relative to "${path.basename(callerFilePath)}"`,
182
+ strategy: "semantic-cross-file",
183
+ };
184
+ }
185
+ let externalSf = project.getSourceFile(externalPath);
186
+ if (externalSf) {
187
+ externalSf.refreshFromFileSystemSync();
188
+ }
189
+ else {
190
+ try {
191
+ externalSf = project.addSourceFileAtPath(externalPath);
192
+ }
193
+ catch (e) {
194
+ return {
195
+ success: false,
196
+ reason: `CrossFileHealer.healFactory: failed to load "${path.basename(externalPath)}": ${e.message}`,
197
+ strategy: "semantic-cross-file",
198
+ };
199
+ }
200
+ }
201
+ const factoryReturn = findFactoryReturnNode(externalSf, functionName);
202
+ if (!factoryReturn) {
203
+ return {
204
+ success: false,
205
+ reason: `CrossFileHealer.healFactory: "${functionName}" not found or has no analyzable return in ${path.basename(externalPath)}`,
206
+ strategy: "semantic-cross-file",
207
+ };
208
+ }
209
+ if (factoryReturn.kind === "interpolated") {
210
+ return {
211
+ success: false,
212
+ reason: `CrossFileHealer.healFactory: "${functionName}" returns a dynamic TemplateExpression (Rule D — cannot mutate)`,
213
+ strategy: "semantic-cross-file",
214
+ };
215
+ }
216
+ if (factoryReturn.kind === "complex") {
217
+ return {
218
+ success: false,
219
+ reason: `CrossFileHealer.healFactory: "${functionName}" return is not a directly mutable literal — ${factoryReturn.reason}`,
220
+ strategy: "semantic-cross-file",
221
+ };
222
+ }
223
+ const before = externalSf.getFullText();
224
+ const result = InitializerUpdater_js_1.InitializerUpdater.apply(factoryReturn.node, externalSf, newValue);
225
+ if (!result) {
226
+ return {
227
+ success: false,
228
+ reason: `CrossFileHealer.healFactory: InitializerUpdater rejected ${factoryReturn.node.getKindName()} for "${functionName}"`,
229
+ strategy: "semantic-cross-file",
230
+ };
231
+ }
232
+ logger_1.logger.debug(`CrossFileHealer.healFactory healed "${functionName}" return in ${path.basename(externalPath)} @ line ${result.lineUpdated + 1}`);
233
+ return {
234
+ success: true,
235
+ reason: `factory return heal in ${path.basename(externalPath)}`,
236
+ strategy: "semantic-cross-file",
237
+ lineUpdated: result.lineUpdated,
238
+ healedLocatorString: newValue,
239
+ definitionSite: { file: externalPath, line: result.lineUpdated + 1 },
240
+ unifiedDiff: captureDefinitionDiff(before, externalSf, externalPath),
241
+ };
242
+ }
139
243
  /**
140
244
  * Heal a property on a POM class: finds the class by name in the module,
141
245
  * locates the string literal argument of a locator stored in `propName`
@@ -217,13 +321,95 @@ exports.CrossFileHealer = CrossFileHealer;
217
321
  // ─────────────────────────────────────────────────────────────────
218
322
  function resolveModulePath(modulePath, fromFile) {
219
323
  const base = path.dirname(path.resolve(fromFile));
220
- const resolved = path.resolve(base, modulePath);
221
- for (const candidate of [resolved, resolved + ".ts", resolved + ".js"]) {
222
- if (fs.existsSync(candidate))
223
- return candidate;
324
+ // Absolute path passed directly (e.g., test harnesses passing a real temp file path).
325
+ if (path.isAbsolute(modulePath)) {
326
+ for (const candidate of [modulePath, modulePath + ".ts", modulePath + ".js"]) {
327
+ if (fs.existsSync(candidate))
328
+ return candidate;
329
+ }
330
+ return null;
331
+ }
332
+ // Relative imports — resolve directly.
333
+ if (modulePath.startsWith(".")) {
334
+ const resolved = path.resolve(base, modulePath);
335
+ for (const candidate of [resolved, resolved + ".ts", resolved + ".js"]) {
336
+ if (fs.existsSync(candidate))
337
+ return candidate;
338
+ }
339
+ return null;
340
+ }
341
+ // Non-relative — try TS path alias resolution via nearest tsconfig.json.
342
+ const tsconfig = findTsConfig(base);
343
+ if (tsconfig) {
344
+ const aliased = resolvePathAlias(modulePath, tsconfig);
345
+ if (aliased) {
346
+ for (const candidate of [aliased, aliased + ".ts", aliased + ".js"]) {
347
+ if (fs.existsSync(candidate))
348
+ return candidate;
349
+ }
350
+ }
351
+ }
352
+ return null;
353
+ }
354
+ function findTsConfig(startDir) {
355
+ let dir = path.resolve(startDir);
356
+ const root = path.parse(dir).root;
357
+ while (dir !== root) {
358
+ const candidate = path.join(dir, "tsconfig.json");
359
+ if (fs.existsSync(candidate)) {
360
+ try {
361
+ const raw = JSON.parse(fs.readFileSync(candidate, "utf-8"));
362
+ const co = raw.compilerOptions ?? {};
363
+ return {
364
+ configDir: dir,
365
+ baseUrl: co.baseUrl,
366
+ paths: co.paths ?? {},
367
+ };
368
+ }
369
+ catch {
370
+ return null;
371
+ }
372
+ }
373
+ dir = path.dirname(dir);
374
+ }
375
+ return null;
376
+ }
377
+ function resolvePathAlias(modulePath, tsconfig) {
378
+ const { configDir, baseUrl, paths } = tsconfig;
379
+ const baseDir = baseUrl ? path.resolve(configDir, baseUrl) : configDir;
380
+ for (const [pattern, replacements] of Object.entries(paths)) {
381
+ const matched = matchPattern(pattern, modulePath);
382
+ if (matched !== null) {
383
+ for (const replacement of replacements) {
384
+ // Replace `*` in replacement with the captured wildcard portion.
385
+ const expanded = replacement.includes("*")
386
+ ? replacement.replace("*", matched)
387
+ : replacement;
388
+ return path.resolve(baseDir, expanded);
389
+ }
390
+ }
224
391
  }
225
392
  return null;
226
393
  }
394
+ /**
395
+ * Returns the captured wildcard string if `modulePath` matches `pattern`,
396
+ * or null if it does not match.
397
+ * e.g. pattern="@shared-selectors/*", modulePath="@shared-selectors/auth" → "auth"
398
+ */
399
+ function matchPattern(pattern, modulePath) {
400
+ const starIdx = pattern.indexOf("*");
401
+ if (starIdx === -1) {
402
+ return pattern === modulePath ? "" : null;
403
+ }
404
+ const prefix = pattern.slice(0, starIdx);
405
+ const suffix = pattern.slice(starIdx + 1);
406
+ if (!modulePath.startsWith(prefix))
407
+ return null;
408
+ const afterPrefix = modulePath.slice(prefix.length);
409
+ if (suffix && !afterPrefix.endsWith(suffix))
410
+ return null;
411
+ return suffix ? afterPrefix.slice(0, afterPrefix.length - suffix.length) : afterPrefix;
412
+ }
227
413
  /**
228
414
  * Locate the first mutable string literal used as a locator selector inside
229
415
  * a class property. Checks property declarations first, then constructor
@@ -283,3 +469,51 @@ function findFirstStringArg(node) {
283
469
  }
284
470
  return null;
285
471
  }
472
+ /**
473
+ * Find the first `return` value of an exported function/arrow named `funcName`
474
+ * and classify it.
475
+ */
476
+ function findFactoryReturnNode(sf, funcName) {
477
+ // Arrow const: `export const fn = (x) => expr`
478
+ const varDecl = sf.getVariableDeclaration(funcName);
479
+ if (varDecl) {
480
+ const init = varDecl.getInitializer();
481
+ if (init && ts_morph_1.Node.isArrowFunction(init)) {
482
+ const body = init.getBody();
483
+ // Concise body: `() => "#selector"`
484
+ if (!ts_morph_1.Node.isBlock(body)) {
485
+ return classifyReturnExpr(body);
486
+ }
487
+ // Block body: `() => { return "#selector"; }`
488
+ return getFirstReturnExpr(body);
489
+ }
490
+ return { kind: "complex", reason: `"${funcName}" initializer is not an ArrowFunction` };
491
+ }
492
+ // Named function declaration: `export function fn(x) { return "..."; }`
493
+ const fnDecl = sf.getFunction(funcName);
494
+ if (fnDecl) {
495
+ const body = fnDecl.getBody();
496
+ if (!body)
497
+ return { kind: "complex", reason: `"${funcName}" function has no body` };
498
+ return getFirstReturnExpr(body);
499
+ }
500
+ return null;
501
+ }
502
+ function getFirstReturnExpr(block) {
503
+ for (const ret of block.getDescendantsOfKind(ts_morph_1.SyntaxKind.ReturnStatement)) {
504
+ const expr = ret.getExpression();
505
+ if (expr)
506
+ return classifyReturnExpr(expr);
507
+ }
508
+ return { kind: "complex", reason: "no return statement found" };
509
+ }
510
+ function classifyReturnExpr(expr) {
511
+ if (ts_morph_1.Node.isStringLiteral(expr) || ts_morph_1.Node.isNoSubstitutionTemplateLiteral(expr)) {
512
+ return { kind: "literal", node: expr };
513
+ }
514
+ if (ts_morph_1.Node.isTemplateExpression(expr)) {
515
+ // TemplateExpression always has interpolations → Rule D.
516
+ return { kind: "interpolated" };
517
+ }
518
+ return { kind: "complex", reason: `return is ${expr.getKindName()} — not a static literal` };
519
+ }
@@ -10,6 +10,7 @@ export type TraceResult = {
10
10
  crossFile: true;
11
11
  modulePath: string;
12
12
  symbolName: string;
13
+ propertyPath?: string[];
13
14
  } | {
14
15
  found: false;
15
16
  crossFile: false;
@@ -1 +1 @@
1
- {"version":3,"file":"DefinitionTracer.d.ts","sourceRoot":"","sources":["../../src/services/DefinitionTracer.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,IAAI,EACJ,UAAU,EAKV,aAAa,EACb,6BAA6B,EAC7B,kBAAkB,EAGnB,MAAM,UAAU,CAAC;AAOlB,MAAM,MAAM,WAAW,GACnB;IACE,KAAK,EAAE,IAAI,CAAC;IACZ,UAAU,EAAE,IAAI,CAAC;IACjB,UAAU,EAAE,UAAU,CAAC;IACvB,6FAA6F;IAC7F,eAAe,CAAC,EAAE,IAAI,CAAC;CACxB,GACD;IAAE,KAAK,EAAE,KAAK,CAAC;IAAC,SAAS,EAAE,IAAI,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,GACzE;IAAE,KAAK,EAAE,KAAK,CAAC;IAAC,SAAS,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAEvD,MAAM,MAAM,kBAAkB,GAC1B;IACE,IAAI,EAAE,UAAU,CAAC;IACjB,YAAY,EAAE,kBAAkB,CAAC;IACjC,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9B,YAAY,EAAE,UAAU,CAAC;IACzB,YAAY,EAAE,MAAM,CAAC;CACtB,GACD;IACE,IAAI,EAAE,SAAS,CAAC;IAChB,WAAW,EAAE,aAAa,GAAG,6BAA6B,CAAC;IAC3D,YAAY,EAAE,UAAU,CAAC;IACzB,YAAY,EAAE,MAAM,CAAC;CACtB,GACD;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAcxC,qBAAa,gBAAgB;IAK3B,MAAM,CAAC,eAAe,CACpB,cAAc,EAAE,IAAI,EACpB,UAAU,EAAE,UAAU,EACtB,UAAU,EAAE,MAAM,EAClB,KAAK,SAAI,GACR,WAAW;IA0Fd,MAAM,CAAC,mBAAmB,CACxB,cAAc,EAAE,IAAI,EACpB,UAAU,EAAE,UAAU,EACtB,UAAU,EAAE,MAAM,GACjB,WAAW;IA+Ed,MAAM,CAAC,WAAW,CAAC,UAAU,EAAE,MAAM,EAAE,UAAU,EAAE,UAAU,GAAG,WAAW;CAkC5E;AASD,qBAAa,wBAAwB;IACnC,MAAM,CAAC,OAAO,CAAC,QAAQ,EAAE,IAAI,EAAE,UAAU,EAAE,UAAU,GAAG,kBAAkB;CAmF3E"}
1
+ {"version":3,"file":"DefinitionTracer.d.ts","sourceRoot":"","sources":["../../src/services/DefinitionTracer.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,IAAI,EACJ,UAAU,EAKV,aAAa,EACb,6BAA6B,EAC7B,kBAAkB,EAGnB,MAAM,UAAU,CAAC;AAOlB,MAAM,MAAM,WAAW,GACnB;IACE,KAAK,EAAE,IAAI,CAAC;IACZ,UAAU,EAAE,IAAI,CAAC;IACjB,UAAU,EAAE,UAAU,CAAC;IACvB,6FAA6F;IAC7F,eAAe,CAAC,EAAE,IAAI,CAAC;CACxB,GACD;IAAE,KAAK,EAAE,KAAK,CAAC;IAAC,SAAS,EAAE,IAAI,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,YAAY,CAAC,EAAE,MAAM,EAAE,CAAA;CAAE,GAClG;IAAE,KAAK,EAAE,KAAK,CAAC;IAAC,SAAS,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAEvD,MAAM,MAAM,kBAAkB,GAC1B;IACE,IAAI,EAAE,UAAU,CAAC;IACjB,YAAY,EAAE,kBAAkB,CAAC;IACjC,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9B,YAAY,EAAE,UAAU,CAAC;IACzB,YAAY,EAAE,MAAM,CAAC;CACtB,GACD;IACE,IAAI,EAAE,SAAS,CAAC;IAChB,WAAW,EAAE,aAAa,GAAG,6BAA6B,CAAC;IAC3D,YAAY,EAAE,UAAU,CAAC;IACzB,YAAY,EAAE,MAAM,CAAC;CACtB,GACD;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAcxC,qBAAa,gBAAgB;IAK3B,MAAM,CAAC,eAAe,CACpB,cAAc,EAAE,IAAI,EACpB,UAAU,EAAE,UAAU,EACtB,UAAU,EAAE,MAAM,EAClB,KAAK,SAAI,GACR,WAAW;IA0Fd,MAAM,CAAC,mBAAmB,CACxB,cAAc,EAAE,IAAI,EACpB,UAAU,EAAE,UAAU,EACtB,UAAU,EAAE,MAAM,GACjB,WAAW;IAwGd,MAAM,CAAC,WAAW,CAAC,UAAU,EAAE,MAAM,EAAE,UAAU,EAAE,UAAU,GAAG,WAAW;CAkC5E;AASD,qBAAa,wBAAwB;IACnC,MAAM,CAAC,OAAO,CAAC,QAAQ,EAAE,IAAI,EAAE,UAAU,EAAE,UAAU,GAAG,kBAAkB;CAmF3E"}
@@ -96,56 +96,79 @@ class DefinitionTracer {
96
96
  reason: "node is not a PropertyAccessExpression",
97
97
  };
98
98
  }
99
- const expr = propAccessNode;
100
- const objectName = expr.getExpression().getText().trim();
101
- const propName = expr.getName();
102
- // Find the object's VariableDeclaration.
103
- const objDecl = findVarDeclInFile(sourceFile, objectName, callerLine);
104
- if (!objDecl) {
105
- const imported = findImportedSymbol(sourceFile, objectName);
106
- if (imported) {
107
- logger_1.logger.debug(`tracePropertyAccess: "${objectName}" comes from "${imported.modulePath}" (cross-file)`);
108
- return { found: false, crossFile: true, ...imported };
109
- }
110
- return {
111
- found: false,
112
- crossFile: false,
113
- reason: `object "${objectName}" not found in file or imports`,
114
- };
99
+ // Walk the full chain to extract root identifier + ordered property path.
100
+ // e.g. Selectors.Auth.LoginBtn → root="Selectors", path=["Auth","LoginBtn"]
101
+ const propChain = [];
102
+ let cursor = propAccessNode;
103
+ while (ts_morph_1.Node.isPropertyAccessExpression(cursor)) {
104
+ propChain.unshift(cursor.getName());
105
+ cursor = cursor.getExpression();
115
106
  }
116
- const init = objDecl.getInitializer();
117
- if (!init || !ts_morph_1.Node.isObjectLiteralExpression(init)) {
107
+ if (!ts_morph_1.Node.isIdentifier(cursor)) {
118
108
  return {
119
109
  found: false,
120
110
  crossFile: false,
121
- reason: `"${objectName}" initializer is not an ObjectLiteralExpression (got ${init?.getKindName() ?? "none"})`,
111
+ reason: `property chain root is ${cursor.getKindName()}, not an Identifier`,
122
112
  };
123
113
  }
124
- // ts-morph getProperty(name) - returns the first matching property.
125
- const prop = init.getProperty(propName);
126
- if (!prop || !ts_morph_1.Node.isPropertyAssignment(prop)) {
114
+ const rootName = cursor.getText().trim();
115
+ // ── In-file resolution ───────────────────────────────────────────
116
+ const objDecl = findVarDeclInFile(sourceFile, rootName, callerLine);
117
+ if (objDecl) {
118
+ let currentNode = objDecl.getInitializer();
119
+ let lastPropNode = undefined;
120
+ for (const key of propChain) {
121
+ if (!currentNode || !ts_morph_1.Node.isObjectLiteralExpression(currentNode)) {
122
+ return {
123
+ found: false,
124
+ crossFile: false,
125
+ reason: `"${key}" not reachable — "${rootName}" is not an ObjectLiteralExpression at this level`,
126
+ };
127
+ }
128
+ const prop = currentNode.getProperty(key);
129
+ if (!prop || !ts_morph_1.Node.isPropertyAssignment(prop)) {
130
+ return {
131
+ found: false,
132
+ crossFile: false,
133
+ reason: `property "${key}" not found in "${rootName}"`,
134
+ };
135
+ }
136
+ lastPropNode = prop;
137
+ currentNode = prop.getInitializer();
138
+ }
139
+ if (!currentNode) {
140
+ return {
141
+ found: false,
142
+ crossFile: false,
143
+ reason: `"${rootName}.${propChain.join(".")}" chain resolved to undefined`,
144
+ };
145
+ }
146
+ logger_1.logger.debug(`tracePropertyAccess: "${rootName}.${propChain.join(".")}" → ` +
147
+ `${currentNode.getKindName()} "${currentNode.getText().slice(0, 60)}" ` +
148
+ `@ ${sourceFile.getBaseName()}:${currentNode.getStartLineNumber()}`);
127
149
  return {
128
- found: false,
129
- crossFile: false,
130
- reason: `property "${propName}" not found on "${objectName}"`,
150
+ found: true,
151
+ targetNode: currentNode,
152
+ targetFile: sourceFile,
153
+ declarationNode: lastPropNode,
131
154
  };
132
155
  }
133
- const valueNode = prop.getInitializer();
134
- if (!valueNode) {
156
+ // ── Cross-file resolution ────────────────────────────────────────
157
+ const imported = findImportedSymbol(sourceFile, rootName);
158
+ if (imported) {
159
+ logger_1.logger.debug(`tracePropertyAccess: "${rootName}" comes from "${imported.modulePath}" (cross-file), path=[${propChain.join(",")}]`);
135
160
  return {
136
161
  found: false,
137
- crossFile: false,
138
- reason: `property "${propName}" on "${objectName}" has no initializer`,
162
+ crossFile: true,
163
+ modulePath: imported.modulePath,
164
+ symbolName: imported.symbolName,
165
+ propertyPath: propChain,
139
166
  };
140
167
  }
141
- logger_1.logger.debug(`tracePropertyAccess: "${objectName}.${propName}" → ` +
142
- `${valueNode.getKindName()} "${valueNode.getText()}" ` +
143
- `@ ${sourceFile.getBaseName()}:${valueNode.getStartLineNumber()}`);
144
168
  return {
145
- found: true,
146
- targetNode: valueNode,
147
- targetFile: sourceFile,
148
- declarationNode: prop,
169
+ found: false,
170
+ crossFile: false,
171
+ reason: `"${rootName}" not found in file or imports`,
149
172
  };
150
173
  }
151
174
  // ─────────────────────────────────────────────────────────────────
@@ -1,6 +1,7 @@
1
1
  import type { AuditVerdict, AuditVerdictValue } from "./IntentAuditor";
2
2
  import type { ElementSnapshotV2 } from "../types";
3
3
  import { type ReportData, type RegressionState, type RegressionResult } from "./ReportGenerator";
4
+ import type { RegressionManifestRecord } from "./RegressionManifestService";
4
5
  import type { ConfidenceVectors } from "./confidence/types";
5
6
  export type HealEventKind = "HEALED" | "FAILED" | "PROTECTED" | "BYPASSED";
6
7
  export interface DnaSummary {
@@ -38,12 +39,32 @@ interface HealEventBase {
38
39
  framePath: string[];
39
40
  inIframe: boolean;
40
41
  inShadowDom: boolean;
42
+ /** True when this event originated as a BYPASSED fix later resolved by Job 2. */
43
+ wasBypassed?: boolean;
44
+ /** Per-fix blast-radius verdict attached by shadow-regression. */
45
+ regressionState?: RegressionState;
46
+ /** Human-readable note surfaced on the card (passed / why it failed). */
47
+ regressionNote?: string;
48
+ /** The downstream tests that ran for THIS fix — scoped, not the whole run. */
49
+ regressionTests?: RegressionResult[];
41
50
  }
42
51
  /**
43
52
  * Compute a stable, run-independent key for an event.
44
53
  * Based solely on immutable facts: normalized file path, line number, and original (broken) selector.
45
54
  */
46
55
  export declare function computeEventDeterministicKey(sourceFile: string, sourceLine: number, oldSelector: string): string;
56
+ export interface VisualDiff {
57
+ /** cwd-relative path to the committed DNA baseline PNG, or null on first heal. */
58
+ dnaSnapshotPath: string | null;
59
+ /** cwd-relative path to the live element screenshot captured during this heal. */
60
+ liveSnapshotPath: string | null;
61
+ /** ISO timestamp from the DNA JSON's visualSnapshot.capturedAt field. */
62
+ dnaSnapshotCapturedAt: string | null;
63
+ /** ISO timestamp of the live capture taken during this heal event. */
64
+ liveSnapshotCapturedAt: string | null;
65
+ /** False when the element could not be resolved for screenshotting. */
66
+ elementFound: boolean;
67
+ }
47
68
  export interface HealedEvent extends HealEventBase {
48
69
  kind: "HEALED";
49
70
  dryRun?: boolean;
@@ -72,6 +93,8 @@ export interface HealedEvent extends HealEventBase {
72
93
  };
73
94
  /** Four-vector confidence breakdown from ConfidenceVectorRule. Optional for backward compat. */
74
95
  confidenceVectors?: ConfidenceVectors;
96
+ /** Side-by-side visual baseline vs. live element screenshots. */
97
+ visualDiff?: VisualDiff;
75
98
  }
76
99
  export interface FailedEvent extends HealEventBase {
77
100
  kind: "FAILED";
@@ -218,10 +241,19 @@ export declare const REPORT_JSON_FILE = "sela-report.json";
218
241
  * Merge a regression verdict into the report at `targetDir` and rewrite
219
242
  * `sela-report.html` + `sela-report.json`. Returns the HTML path.
220
243
  * Throws when no base report exists (Job 2 must run after Job 1).
244
+ *
245
+ * When `regression.records` (the manifest) is supplied, each BYPASSED event is
246
+ * reclassified against its OWN blast-radius verdict (see
247
+ * {@link reclassifyBypassEvents}): a fix whose downstream tests all passed is
248
+ * promoted to HEALED, one whose tests broke is demoted to FAILED. Stats + ROI
249
+ * are recomputed from the reclassified stream so the donut, KPIs and filters
250
+ * reflect the post-regression truth — history is left untouched (Job 1 owns it).
221
251
  */
222
252
  export declare function mergeRegressionIntoReport(targetDir: string, regression: {
223
253
  regressionState: RegressionState;
224
254
  regressionTests: RegressionResult[];
255
+ /** Manifest records that drive per-fix bypass reclassification. */
256
+ records?: RegressionManifestRecord[];
225
257
  }, opts?: {
226
258
  reportJsonPath?: string;
227
259
  }): string;
@@ -1 +1 @@
1
- {"version":3,"file":"HealReportService.d.ts","sourceRoot":"","sources":["../../src/services/HealReportService.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"HealReportService.d.ts","sourceRoot":"","sources":["../../src/services/HealReportService.ts"],"names":[],"mappings":"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"}