sela-core 1.0.2 → 1.0.4

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 (34) hide show
  1. package/dist/cli/commands/showReport.d.ts +3 -0
  2. package/dist/cli/commands/showReport.d.ts.map +1 -0
  3. package/dist/cli/commands/showReport.js +80 -0
  4. package/dist/cli/index.js +4 -1
  5. package/dist/config/SelaConfig.d.ts +57 -11
  6. package/dist/config/SelaConfig.d.ts.map +1 -1
  7. package/dist/config/SelaConfig.js +37 -7
  8. package/dist/engine/SelaEngine.d.ts +29 -0
  9. package/dist/engine/SelaEngine.d.ts.map +1 -0
  10. package/dist/engine/SelaEngine.js +682 -0
  11. package/dist/engine/singleton.d.ts +2 -2
  12. package/dist/engine/singleton.d.ts.map +1 -1
  13. package/dist/engine/singleton.js +2 -2
  14. package/dist/fixtures/expectProxy.d.ts +2 -2
  15. package/dist/fixtures/expectProxy.d.ts.map +1 -1
  16. package/dist/fixtures/expectProxy.js +2 -2
  17. package/dist/fixtures/index.d.ts.map +1 -1
  18. package/dist/fixtures/index.js +21 -15
  19. package/dist/fixtures/moduleExpect.d.ts.map +1 -1
  20. package/dist/fixtures/moduleExpect.js +13 -6
  21. package/dist/services/ASTSourceUpdater.d.ts.map +1 -1
  22. package/dist/services/ASTSourceUpdater.js +10 -1
  23. package/dist/services/HealReportService.d.ts +110 -0
  24. package/dist/services/HealReportService.d.ts.map +1 -0
  25. package/dist/services/HealReportService.js +1195 -0
  26. package/dist/services/PRAutomationService.d.ts +30 -0
  27. package/dist/services/PRAutomationService.d.ts.map +1 -0
  28. package/dist/services/PRAutomationService.js +464 -0
  29. package/dist/services/SnapshotService.d.ts.map +1 -1
  30. package/dist/services/SnapshotService.js +7 -8
  31. package/dist/services/SourceUpdater.d.ts.map +1 -1
  32. package/dist/services/SourceUpdater.js +13 -2
  33. package/dist/storage/SnapshotManager.js +1 -1
  34. package/package.json +2 -2
@@ -1,3 +1,3 @@
1
- import { FixwrightEngine } from './FixwrightEngine.js';
2
- export declare const sharedEngine: FixwrightEngine;
1
+ import { SelaEngine } from "./SelaEngine.js";
2
+ export declare const sharedEngine: SelaEngine;
3
3
  //# sourceMappingURL=singleton.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"singleton.d.ts","sourceRoot":"","sources":["../../src/engine/singleton.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAEvD,eAAO,MAAM,YAAY,iBAAwB,CAAC"}
1
+ {"version":3,"file":"singleton.d.ts","sourceRoot":"","sources":["../../src/engine/singleton.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAE7C,eAAO,MAAM,YAAY,YAAmB,CAAC"}
@@ -1,5 +1,5 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.sharedEngine = void 0;
4
- const FixwrightEngine_js_1 = require("./FixwrightEngine.js");
5
- exports.sharedEngine = new FixwrightEngine_js_1.FixwrightEngine();
4
+ const SelaEngine_js_1 = require("./SelaEngine.js");
5
+ exports.sharedEngine = new SelaEngine_js_1.SelaEngine();
@@ -1,5 +1,5 @@
1
1
  import { Locator } from "@playwright/test";
2
- import { FixwrightEngine } from "../engine/FixwrightEngine";
2
+ import { SelaEngine } from "../engine/SelaEngine";
3
3
  /**
4
4
  * createHealingExpect — drop-in replacement for Playwright's expect().
5
5
  *
@@ -7,6 +7,6 @@ import { FixwrightEngine } from "../engine/FixwrightEngine";
7
7
  * to its current live Locator. Supplied by
8
8
  * fixtures/index.ts which owns proxyToActiveLocator.
9
9
  */
10
- export declare function createHealingExpect(engine: FixwrightEngine, page: import("@playwright/test").Page, filePath: string, initialLine: number, // השורה מהפיקסצ'ר (לרוב תהיה לא מדויקת או 0)
10
+ export declare function createHealingExpect(engine: SelaEngine, page: import("@playwright/test").Page, filePath: string, initialLine: number, // השורה מהפיקסצ'ר (לרוב תהיה לא מדויקת או 0)
11
11
  resolveProxy?: (value: unknown) => Locator | null): (locatorOrValue: unknown) => any;
12
12
  //# sourceMappingURL=expectProxy.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"expectProxy.d.ts","sourceRoot":"","sources":["../../src/fixtures/expectProxy.ts"],"names":[],"mappings":"AAEA,OAAO,EAEL,OAAO,EAER,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAgO5D;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,eAAe,EACvB,IAAI,EAAE,OAAO,kBAAkB,EAAE,IAAI,EACrC,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM,EAAE,6CAA6C;AAClE,YAAY,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,OAAO,GAAG,IAAI,GAChD,CAAC,cAAc,EAAE,OAAO,KAAK,GAAG,CAiElC"}
1
+ {"version":3,"file":"expectProxy.d.ts","sourceRoot":"","sources":["../../src/fixtures/expectProxy.ts"],"names":[],"mappings":"AAEA,OAAO,EAEL,OAAO,EAER,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAgOlD;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,UAAU,EAClB,IAAI,EAAE,OAAO,kBAAkB,EAAE,IAAI,EACrC,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM,EAAE,6CAA6C;AAClE,YAAY,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,OAAO,GAAG,IAAI,GAChD,CAAC,cAAc,EAAE,OAAO,KAAK,GAAG,CAiElC"}
@@ -126,7 +126,7 @@ function wrapMatcher(matcher, locator, matcherName, engine, page, ctx) {
126
126
  const rawSelector = extractSelectorFromLocator(locator);
127
127
  if (!rawSelector)
128
128
  throw err;
129
- console.log(`[Fixwright-Expect] ⚠️ Assertion failed for "${rawSelector}", attempting heal…`);
129
+ console.log(`[Sela] ⚠️ Assertion failed for "${rawSelector}", attempting heal…`);
130
130
  // Fast path — already healed in this test via registry
131
131
  const resolved = HealingRegistry_1.HealingRegistry.getInstance().resolveSelector(rawSelector, ctx);
132
132
  let healedSelector = resolved;
@@ -162,7 +162,7 @@ function wrapMatcher(matcher, locator, matcherName, engine, page, ctx) {
162
162
  const retryMatcher = newExpectation[matcherName];
163
163
  if (typeof retryMatcher !== "function")
164
164
  throw err;
165
- console.log(`[Fixwright-Expect] ♻️ Retrying assertion with healed selector: "${healedSelector}"`);
165
+ console.log(`[Sela] ♻️ Retrying assertion with healed selector: "${healedSelector}"`);
166
166
  return await retryMatcher.apply(newExpectation, args);
167
167
  }
168
168
  });
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/fixtures/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,OAAO,EAER,MAAM,kBAAkB,CAAC;AAI1B,OAAO,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AAWpD,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,GAAG,IAAI,CAIpE;AA02BD,eAAO,MAAM,IAAI;YACP,UAAU,CAAC,OAAO,mBAAmB,CAAC;wGA+F9C,CAAC;AAGH,OAAO,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/fixtures/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,OAAO,EAAQ,MAAM,kBAAkB,CAAC;AAI/D,OAAO,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AAWpD,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,GAAG,IAAI,CAIpE;AAi3BD,eAAO,MAAM,IAAI;YACP,UAAU,CAAC,OAAO,mBAAmB,CAAC;wGA+F9C,CAAC;AAGH,OAAO,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC"}
@@ -230,14 +230,14 @@ function buildHealedArgs(prop, args, timeout = 8000) {
230
230
  const opts = args[0] && typeof args[0] === "object" ? args[0] : {};
231
231
  return [{ ...opts, timeout }];
232
232
  }
233
- console.warn(`[Fixwright] buildHealedArgs: unknown prop "${prop}", passing as-is`);
233
+ console.warn(`[Sela] buildHealedArgs: unknown prop "${prop}", passing as-is`);
234
234
  return args;
235
235
  }
236
236
  // ─────────────────────────────────────────────────────────────────
237
237
  // runWithHealArgument (unchanged from original)
238
238
  // ─────────────────────────────────────────────────────────────────
239
239
  async function runWithHealArgument(rawPage, prop, args, fullSelector, stableId, callerInfo, originalError) {
240
- console.log(`[Fixwright-Heal] 💡 Element visible, action '${prop}' failed — healing argument…`);
240
+ console.log(`[Sela] 💡 Element visible, action '${prop}' failed — healing argument…`);
241
241
  const oldArgument = typeof args[0] === "string" ? args[0] : JSON.stringify(args[0]);
242
242
  const newArgument = await singleton_1.sharedEngine.healArgument(rawPage, fullSelector, prop, oldArgument, stableId, callerInfo.filePath, callerInfo.line);
243
243
  if (!newArgument)
@@ -259,7 +259,7 @@ async function runWithHeal(rawPage, prop, args, fullSelector, elementSelectorOnl
259
259
  const preResolved = registry.resolveSelector(fullSelector);
260
260
  const effectiveSelector = preResolved !== fullSelector ? preResolved : fullSelector;
261
261
  if (effectiveSelector !== fullSelector) {
262
- console.log(`[Fixwright] ⚡ Pre-flight swap: "${fullSelector}" → "${effectiveSelector}"`);
262
+ console.log(`[Sela] ⚡ Pre-flight swap: "${fullSelector}" → "${effectiveSelector}"`);
263
263
  }
264
264
  const initialLocator = buildLiveLocator(rawPage, effectiveSelector);
265
265
  try {
@@ -272,7 +272,7 @@ async function runWithHeal(rawPage, prop, args, fullSelector, elementSelectorOnl
272
272
  };
273
273
  }
274
274
  catch (firstError) {
275
- console.warn(`[Fixwright-Heal] ⚠️ '${prop}' failed on: "${effectiveSelector}"`);
275
+ console.warn(`[Sela] ⚠️ '${prop}' failed on: "${effectiveSelector}"`);
276
276
  const isVisible = await initialLocator
277
277
  .isVisible({ timeout: 1500 })
278
278
  .catch(() => false);
@@ -298,7 +298,7 @@ async function runWithHeal(rawPage, prop, args, fullSelector, elementSelectorOnl
298
298
  // The Proxy listener fires automatically before this function returns.
299
299
  // ─────────────────────────────────────────────────────────────────
300
300
  async function runWithHealSelector(rawPage, prop, args, fullSelector, elementSelectorOnly, stableId, callerInfo, originalError) {
301
- console.log(`[Fixwright-Heal] 🔧 Healing selector…`);
301
+ console.log(`[Sela] 🔧 Healing selector…`);
302
302
  const newFullSelector = await singleton_1.sharedEngine.heal(rawPage, fullSelector, elementSelectorOnly, stableId, callerInfo.filePath, callerInfo.line);
303
303
  if (!newFullSelector)
304
304
  throw originalError;
@@ -356,7 +356,7 @@ function extractDragToTargetFromSource(rawFilePath, line) {
356
356
  }
357
357
  }
358
358
  async function runWithHealDragTo(rawPage, args, fullSelector, elementSelectorOnly, stableId, callerInfo, originalError, buildFreshLocator) {
359
- console.log(`[Fixwright-Heal] 🎯 dragTo Double Healing initiated`);
359
+ console.log(`[Sela] 🎯 dragTo Double Healing initiated`);
360
360
  const targetSelectorFromSource = extractDragToTargetFromSource(callerInfo.filePath, callerInfo.line);
361
361
  const sourceLocator = buildFreshLocator(fullSelector);
362
362
  const isSourceVisible = await sourceLocator
@@ -368,12 +368,12 @@ async function runWithHealDragTo(rawPage, args, fullSelector, elementSelectorOnl
368
368
  try {
369
369
  healedSourceSelector = await singleton_1.sharedEngine.heal(rawPage, fullSelector, elementSelectorOnly, stableId, callerInfo.filePath, callerInfo.line);
370
370
  // broadcast already fired inside engine.heal() via ASTSourceUpdater
371
- console.log(`[Fixwright-Heal] 💡 Source healed: "${healedSourceSelector}"`);
371
+ console.log(`[Sela] 💡 Source healed: "${healedSourceSelector}"`);
372
372
  }
373
373
  catch (e) {
374
374
  if (e instanceof Error && e.message.includes("[SafetyGuard]"))
375
375
  throw e;
376
- console.warn(`[Fixwright-Heal] ⚠️ Source healing failed, using original`);
376
+ console.warn(`[Sela] ⚠️ Source healing failed, using original`);
377
377
  }
378
378
  }
379
379
  const healedSourceLocator = buildFreshLocator(healedSourceSelector);
@@ -391,7 +391,7 @@ async function runWithHealDragTo(rawPage, args, fullSelector, elementSelectorOnl
391
391
  }
392
392
  }
393
393
  catch (e) {
394
- console.warn(`[Fixwright-Heal] ⚠️ Target healing failed: ${e.message}`);
394
+ console.warn(`[Sela] ⚠️ Target healing failed: ${e.message}`);
395
395
  }
396
396
  }
397
397
  else {
@@ -428,7 +428,7 @@ async function runWithHealDragTo(rawPage, args, fullSelector, elementSelectorOnl
428
428
  ...options,
429
429
  timeout: 8000,
430
430
  });
431
- console.log(`[Fixwright-Heal] ✅ dragTo double heal successful`);
431
+ console.log(`[Sela] ✅ dragTo double heal successful`);
432
432
  return {
433
433
  result,
434
434
  finalSelector: healedSourceSelector,
@@ -474,7 +474,9 @@ function createLocatorProxy(rawLocator, selector, rawPage, testTitle, actionCoun
474
474
  // Defensive: Proxy ctor throws "Cannot create proxy with a non-object as target"
475
475
  // when downstream callers (e.g. chained traps) pass a non-Locator return value.
476
476
  // Returning the raw value lets the caller see it unchanged instead of crashing.
477
- if (rawLocator === null || rawLocator === undefined || typeof rawLocator !== "object") {
477
+ if (rawLocator === null ||
478
+ rawLocator === undefined ||
479
+ typeof rawLocator !== "object") {
478
480
  return rawLocator;
479
481
  }
480
482
  // ── Resolve immediately (handles post-heal proxy creation) ────
@@ -507,7 +509,7 @@ function createLocatorProxy(rawLocator, selector, rawPage, testTitle, actionCoun
507
509
  }
508
510
  if (nextSelector === currentFullSelector)
509
511
  return;
510
- console.log(`[Fixwright] ♻️ proxy swap (Smart Clean): "${currentFullSelector}" → "${nextSelector}"`);
512
+ console.log(`[Sela] ♻️ proxy swap (Smart Clean): "${currentFullSelector}" → "${nextSelector}"`);
511
513
  currentFullSelector = nextSelector;
512
514
  currentElementSelector = nextSelector.split(" >> ").pop() ?? nextSelector;
513
515
  // בנייה מחדש של הלוקטור האמיתי מהמחרוזת הנקייה
@@ -534,7 +536,9 @@ function createLocatorProxy(rawLocator, selector, rawPage, testTitle, actionCoun
534
536
  if (prop in GET_BY_METHODS) {
535
537
  return (...args) => {
536
538
  const nextLocator = activeLocator[prop](...args);
537
- if (nextLocator === null || nextLocator === undefined || typeof nextLocator !== "object") {
539
+ if (nextLocator === null ||
540
+ nextLocator === undefined ||
541
+ typeof nextLocator !== "object") {
538
542
  return nextLocator;
539
543
  }
540
544
  const semanticSelector = GET_BY_METHODS[prop](args);
@@ -547,7 +551,9 @@ function createLocatorProxy(rawLocator, selector, rawPage, testTitle, actionCoun
547
551
  if (chainables.includes(prop)) {
548
552
  return (...args) => {
549
553
  const nextLocator = activeLocator[prop](...args);
550
- if (nextLocator === null || nextLocator === undefined || typeof nextLocator !== "object") {
554
+ if (nextLocator === null ||
555
+ nextLocator === undefined ||
556
+ typeof nextLocator !== "object") {
551
557
  return nextLocator;
552
558
  }
553
559
  let nextFull = currentFullSelector;
@@ -613,7 +619,7 @@ function createLocatorProxy(rawLocator, selector, rawPage, testTitle, actionCoun
613
619
  return await activeLocator[prop](...args);
614
620
  }
615
621
  catch {
616
- console.debug(`[Fixwright] 🔇 Silent heal for getter '${prop}'`);
622
+ console.debug(`[Sela] 🔇 Silent heal for getter '${prop}'`);
617
623
  try {
618
624
  actionCounter.value++;
619
625
  const stableId = StackUtils_1.StackUtils.getActionKey(testTitle, prop, actionCounter.value);
@@ -1 +1 @@
1
- {"version":3,"file":"moduleExpect.d.ts","sourceRoot":"","sources":["../../src/fixtures/moduleExpect.ts"],"names":[],"mappings":"AAuCA,wBAAgB,MAAM,CAAC,KAAK,EAAE,OAAO,GAAG,GAAG,CAa1C"}
1
+ {"version":3,"file":"moduleExpect.d.ts","sourceRoot":"","sources":["../../src/fixtures/moduleExpect.ts"],"names":[],"mappings":"AA8CA,wBAAgB,MAAM,CAAC,KAAK,EAAE,OAAO,GAAG,GAAG,CAa1C"}
@@ -28,12 +28,19 @@ function extractPage(value) {
28
28
  }
29
29
  function getCallerFile() {
30
30
  const lines = new Error().stack?.split('\n') ?? [];
31
- for (let i = 3; i < lines.length; i++) {
32
- if (/\.(spec|test)\.[jt]sx?/.test(lines[i])) {
33
- const m = lines[i].match(/\((.+?):\d+:\d+\)/);
34
- if (m)
35
- return m[1];
36
- }
31
+ // Match BOTH frame shapes V8 emits:
32
+ // " at fnName (D:\\path\\file.spec.ts:17:20)"
33
+ // " at D:\\path\\file.spec.ts:17:20"
34
+ // The path may include Windows drive letters (colon after C/D/...).
35
+ const FRAME_WITH_PARENS = /\(([^()]+?):\d+:\d+\)\s*$/;
36
+ const FRAME_BARE = /\s+at\s+(.+?):\d+:\d+\s*$/;
37
+ for (let i = 1; i < lines.length; i++) {
38
+ const line = lines[i];
39
+ if (!/\.(spec|test)\.[jt]sx?/.test(line))
40
+ continue;
41
+ const m = line.match(FRAME_WITH_PARENS) ?? line.match(FRAME_BARE);
42
+ if (m && m[1])
43
+ return m[1].trim();
37
44
  }
38
45
  return '';
39
46
  }
@@ -1 +1 @@
1
- {"version":3,"file":"ASTSourceUpdater.d.ts","sourceRoot":"","sources":["../../src/services/ASTSourceUpdater.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAQ/C,OAAO,EAAE,cAAc,EAAgB,MAAM,mBAAmB,CAAC;AAOjE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAMtD,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,kGAAkG;IAClG,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,wEAAwE;IACxE,cAAc,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IAChD,gFAAgF;IAChF,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,UAAU,aAAa;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;CACd;AAg5DD,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,OAAO,CAAU;IACzB,QAAQ,CAAC,cAAc,iBAAwB;IAE/C,eAAe,IAAI,IAAI;;IAiBvB,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAcjC;IAEH,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CA8B9B;IAEH,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAuB/B;IAMH,MAAM,CACJ,MAAM,EAAE,aAAa,EACrB,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,MAAM,EACnB,UAAU,CAAC,EAAE,eAAe,EAAE,EAC9B,mBAAmB,CAAC,EAAE,MAAM,EAC5B,aAAa,CAAC,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,EACpD,kBAAkB,CAAC,EAAE,iBAAiB,EAAE,EACxC,iBAAiB,CAAC,EAAE,iBAAiB,EAAE,GACtC,eAAe;IA8PlB,OAAO,CAAC,kBAAkB;IAsM1B,OAAO,CAAC,uBAAuB;IA6F/B,OAAO,CAAC,qBAAqB;IAyF7B,OAAO,CAAC,YAAY;IAkDpB,OAAO,CAAC,qBAAqB;IA0G7B,OAAO,CAAC,4BAA4B;IAoRpC,OAAO,CAAC,yBAAyB;IAsGjC,OAAO,CAAC,uBAAuB;IA4E/B,OAAO,CAAC,4BAA4B;IA4EpC,OAAO,CAAC,qBAAqB;IA6B7B,OAAO,CAAC,oBAAoB;IAwB5B,OAAO,CAAC,gBAAgB;IAwBxB;;;;;OAKG;IACH,OAAO,CAAC,MAAM,CAAC,iBAAiB;IAUhC,OAAO,CAAC,mBAAmB;IAuC3B,OAAO,CAAC,kBAAkB;IA2B1B,OAAO,CAAC,kBAAkB;IAuB1B,OAAO,CAAC,2BAA2B;IAsCnC,OAAO,CAAC,yBAAyB;IAqCjC,OAAO,CAAC,yBAAyB;IA+CjC,OAAO,CAAC,qBAAqB;IAQ7B,OAAO,CAAC,cAAc;IAYtB,OAAO,CAAC,0BAA0B;IAmBlC,OAAO,CAAC,sBAAsB;IA2B9B,OAAO,CAAC,2BAA2B;IAoCnC,OAAO,CAAC,oBAAoB;IA2B5B,OAAO,CAAC,YAAY;IAUpB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAa3C,OAAO,CAAC,gBAAgB;IAkExB,OAAO,CAAC,mBAAmB;IAiF3B,OAAO,CAAC,uBAAuB;IAiF/B,OAAO,CAAC,wBAAwB;IAkFhC,OAAO,CAAC,mBAAmB;IA8C3B,OAAO,CAAC,uBAAuB;IAoF/B,OAAO,CAAC,kBAAkB;IAwB1B,OAAO,CAAC,kBAAkB;CAgB3B"}
1
+ {"version":3,"file":"ASTSourceUpdater.d.ts","sourceRoot":"","sources":["../../src/services/ASTSourceUpdater.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAQ/C,OAAO,EAAE,cAAc,EAAgB,MAAM,mBAAmB,CAAC;AAOjE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAMtD,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,kGAAkG;IAClG,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,wEAAwE;IACxE,cAAc,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IAChD,gFAAgF;IAChF,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,UAAU,aAAa;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;CACd;AAg5DD,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,OAAO,CAAU;IACzB,QAAQ,CAAC,cAAc,iBAAwB;IAE/C,eAAe,IAAI,IAAI;;IAiBvB,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAcjC;IAEH,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CA8B9B;IAEH,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAuB/B;IAMH,MAAM,CACJ,MAAM,EAAE,aAAa,EACrB,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,MAAM,EACnB,UAAU,CAAC,EAAE,eAAe,EAAE,EAC9B,mBAAmB,CAAC,EAAE,MAAM,EAC5B,aAAa,CAAC,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,EACpD,kBAAkB,CAAC,EAAE,iBAAiB,EAAE,EACxC,iBAAiB,CAAC,EAAE,iBAAiB,EAAE,GACtC,eAAe;IA8PlB,OAAO,CAAC,kBAAkB;IAsM1B,OAAO,CAAC,uBAAuB;IA6F/B,OAAO,CAAC,qBAAqB;IAyF7B,OAAO,CAAC,YAAY;IAkDpB,OAAO,CAAC,qBAAqB;IA0G7B,OAAO,CAAC,4BAA4B;IAoRpC,OAAO,CAAC,yBAAyB;IAsGjC,OAAO,CAAC,uBAAuB;IA4E/B,OAAO,CAAC,4BAA4B;IA4EpC,OAAO,CAAC,qBAAqB;IA6B7B,OAAO,CAAC,oBAAoB;IAwB5B,OAAO,CAAC,gBAAgB;IAwBxB;;;;;OAKG;IACH,OAAO,CAAC,MAAM,CAAC,iBAAiB;IAUhC,OAAO,CAAC,mBAAmB;IAuC3B,OAAO,CAAC,kBAAkB;IA2B1B,OAAO,CAAC,kBAAkB;IAuB1B,OAAO,CAAC,2BAA2B;IAsCnC,OAAO,CAAC,yBAAyB;IAqCjC,OAAO,CAAC,yBAAyB;IA+CjC,OAAO,CAAC,qBAAqB;IAQ7B,OAAO,CAAC,cAAc;IAYtB,OAAO,CAAC,0BAA0B;IAmBlC,OAAO,CAAC,sBAAsB;IA2B9B,OAAO,CAAC,2BAA2B;IAoCnC,OAAO,CAAC,oBAAoB;IA2B5B,OAAO,CAAC,YAAY;IAUpB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAkB3C,OAAO,CAAC,gBAAgB;IAkExB,OAAO,CAAC,mBAAmB;IAiF3B,OAAO,CAAC,uBAAuB;IAiF/B,OAAO,CAAC,wBAAwB;IAkFhC,OAAO,CAAC,mBAAmB;IA8C3B,OAAO,CAAC,uBAAuB;IAoF/B,OAAO,CAAC,kBAAkB;IAwB1B,OAAO,CAAC,kBAAkB;CAgB3B"}
@@ -2791,13 +2791,22 @@ class ASTSourceUpdater {
2791
2791
  return offset;
2792
2792
  }
2793
2793
  resolveFilePath(raw) {
2794
+ if (!raw || typeof raw !== "string")
2795
+ return null;
2794
2796
  let clean = raw
2795
2797
  .replace(/^.*?at\s+/, "")
2796
2798
  .replace(/:\d+:\d+.*$/, "")
2797
2799
  .trim();
2800
+ if (!clean)
2801
+ return null;
2798
2802
  if (!path.isAbsolute(clean))
2799
2803
  clean = path.resolve(process.cwd(), clean);
2800
- return fs.existsSync(clean) ? clean : null;
2804
+ if (!fs.existsSync(clean))
2805
+ return null;
2806
+ const stat = fs.statSync(clean);
2807
+ if (!stat.isFile())
2808
+ return null;
2809
+ return clean;
2801
2810
  }
2802
2811
  // ═══════════════════════════════════════════════════════════════════
2803
2812
  // T-10 / T-11: Semantic Dispatch Gate + handlers
@@ -0,0 +1,110 @@
1
+ import type { AuditVerdict, AuditVerdictValue } from "./IntentAuditor";
2
+ import type { ElementSnapshotV2 } from "../types";
3
+ export type HealEventKind = "HEALED" | "FAILED" | "PROTECTED";
4
+ export interface DnaSummary {
5
+ tagName: string;
6
+ text: string | null;
7
+ role: string | null;
8
+ classes: string[];
9
+ attributes: Record<string, string>;
10
+ ancestry: string[];
11
+ closestLabel: string | null;
12
+ rowAnchor: string | null;
13
+ isGhost: boolean;
14
+ ghostReason: string | null;
15
+ isOccluded: boolean;
16
+ isInShadowDom: boolean;
17
+ }
18
+ export interface AuditorBlock {
19
+ verdict: AuditVerdictValue;
20
+ confidence: number;
21
+ reason: string;
22
+ inversionType: AuditVerdict["inversionType"];
23
+ rawConfidence?: number;
24
+ penalty?: number;
25
+ bonus?: number;
26
+ }
27
+ interface HealEventBase {
28
+ kind: HealEventKind;
29
+ stableId: string;
30
+ sourceFile: string;
31
+ sourceLine: number;
32
+ testTitle?: string;
33
+ timestamp: string;
34
+ framePath: string[];
35
+ inIframe: boolean;
36
+ inShadowDom: boolean;
37
+ }
38
+ export interface HealedEvent extends HealEventBase {
39
+ kind: "HEALED";
40
+ oldSelector: string;
41
+ newSelector: string;
42
+ oldCodeLine: string;
43
+ newCodeLine: string;
44
+ newLineNumber: number;
45
+ aiConfidence: number;
46
+ aiExplanation: string;
47
+ aiAlternatives: string[];
48
+ reasoningSteps: string[];
49
+ auditor: AuditorBlock | null;
50
+ dnaBefore: DnaSummary;
51
+ dnaAfter: DnaSummary | null;
52
+ diffStrategy: string;
53
+ blastRadius?: number;
54
+ definitionSite?: {
55
+ file: string;
56
+ line: number;
57
+ };
58
+ contentChange?: {
59
+ oldText: string;
60
+ newText: string;
61
+ };
62
+ }
63
+ export interface FailedEvent extends HealEventBase {
64
+ kind: "FAILED";
65
+ oldSelector: string;
66
+ reason: string;
67
+ aiConfidence?: number;
68
+ aiExplanation?: string;
69
+ dnaBefore: DnaSummary | null;
70
+ }
71
+ export interface ProtectedEvent extends HealEventBase {
72
+ kind: "PROTECTED";
73
+ oldSelector: string;
74
+ candidateNewSelector?: string;
75
+ reason: string;
76
+ safetyLevel: string;
77
+ auditor: AuditorBlock | null;
78
+ aiConfidence: number;
79
+ aiExplanation: string;
80
+ dnaBefore: DnaSummary | null;
81
+ dnaAfter: DnaSummary | null;
82
+ contentChange?: {
83
+ oldText: string;
84
+ newText: string;
85
+ };
86
+ }
87
+ export type HealEvent = HealedEvent | FailedEvent | ProtectedEvent;
88
+ export declare function summariseSnapshot(s: ElementSnapshotV2 | null | undefined): DnaSummary | null;
89
+ export declare class HealReportService {
90
+ private events;
91
+ private startedAt;
92
+ record(event: HealEvent): void;
93
+ size(): number;
94
+ clear(): void;
95
+ hasContent(): boolean;
96
+ /** All HEALED events accumulated in this session. */
97
+ getHealedEvents(): HealedEvent[];
98
+ /** All PROTECTED events (SafetyGuard blocks) accumulated in this session. */
99
+ getProtectedEvents(): ProtectedEvent[];
100
+ /**
101
+ * Write `sela-report.html` (+ `sela-report.json` debug dump) to cwd.
102
+ * Returns the absolute path of the HTML report, or null if nothing to write.
103
+ */
104
+ flushToDisk(targetDir?: string): string | null;
105
+ private renderHtml;
106
+ private computeStats;
107
+ }
108
+ export declare const sharedHealReport: HealReportService;
109
+ export {};
110
+ //# sourceMappingURL=HealReportService.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"HealReportService.d.ts","sourceRoot":"","sources":["../../src/services/HealReportService.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACvE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAMlD,MAAM,MAAM,aAAa,GAAG,QAAQ,GAAG,QAAQ,GAAG,WAAW,CAAC;AAE9D,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,OAAO,EAAE,OAAO,CAAC;IACjB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,UAAU,EAAE,OAAO,CAAC;IACpB,aAAa,EAAE,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,iBAAiB,CAAC;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,aAAa,EAAE,YAAY,CAAC,eAAe,CAAC,CAAC;IAC7C,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,UAAU,aAAa;IACrB,IAAI,EAAE,aAAa,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,QAAQ,EAAE,OAAO,CAAC;IAClB,WAAW,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,WAAY,SAAQ,aAAa;IAChD,IAAI,EAAE,QAAQ,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,OAAO,EAAE,YAAY,GAAG,IAAI,CAAC;IAC7B,SAAS,EAAE,UAAU,CAAC;IACtB,QAAQ,EAAE,UAAU,GAAG,IAAI,CAAC;IAC5B,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,cAAc,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IAChD,aAAa,CAAC,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;CACtD;AAED,MAAM,WAAW,WAAY,SAAQ,aAAa;IAChD,IAAI,EAAE,QAAQ,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE,UAAU,GAAG,IAAI,CAAC;CAC9B;AAED,MAAM,WAAW,cAAe,SAAQ,aAAa;IACnD,IAAI,EAAE,WAAW,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,YAAY,GAAG,IAAI,CAAC;IAC7B,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,UAAU,GAAG,IAAI,CAAC;IAC7B,QAAQ,EAAE,UAAU,GAAG,IAAI,CAAC;IAC5B,aAAa,CAAC,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;CACtD;AAED,MAAM,MAAM,SAAS,GAAG,WAAW,GAAG,WAAW,GAAG,cAAc,CAAC;AAWnE,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,iBAAiB,GAAG,IAAI,GAAG,SAAS,GAAG,UAAU,GAAG,IAAI,CAgB5F;AAMD,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,MAAM,CAAmB;IACjC,OAAO,CAAC,SAAS,CAAoC;IAErD,MAAM,CAAC,KAAK,EAAE,SAAS,GAAG,IAAI;IAI9B,IAAI,IAAI,MAAM;IAId,KAAK,IAAI,IAAI;IAKb,UAAU,IAAI,OAAO;IAIrB,qDAAqD;IACrD,eAAe,IAAI,WAAW,EAAE;IAIhC,6EAA6E;IAC7E,kBAAkB,IAAI,cAAc,EAAE;IAItC;;;OAGG;IACH,WAAW,CAAC,SAAS,GAAE,MAAsB,GAAG,MAAM,GAAG,IAAI;IAyB7D,OAAO,CAAC,UAAU;IAWlB,OAAO,CAAC,YAAY;CAwBrB;AAMD,eAAO,MAAM,gBAAgB,mBAA0B,CAAC"}