sela-core 1.0.7 → 1.0.8

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 (114) hide show
  1. package/dist/cli/ErrorHandler.d.ts +1 -1
  2. package/dist/cli/ErrorHandler.js +14 -14
  3. package/dist/cli/commands/bulk.d.ts +1 -1
  4. package/dist/cli/commands/bulk.d.ts.map +1 -1
  5. package/dist/cli/commands/bulk.js +51 -33
  6. package/dist/cli/commands/init.d.ts +1 -1
  7. package/dist/cli/commands/init.d.ts.map +1 -1
  8. package/dist/cli/commands/init.js +26 -18
  9. package/dist/cli/commands/showReport.d.ts +1 -1
  10. package/dist/cli/commands/showReport.d.ts.map +1 -1
  11. package/dist/cli/commands/showReport.js +12 -10
  12. package/dist/cli/commands/status.d.ts +1 -1
  13. package/dist/cli/commands/status.d.ts.map +1 -1
  14. package/dist/cli/commands/status.js +8 -8
  15. package/dist/cli/commands/sync.d.ts +1 -1
  16. package/dist/cli/commands/sync.d.ts.map +1 -1
  17. package/dist/cli/commands/sync.js +38 -30
  18. package/dist/cli/index.js +9 -9
  19. package/dist/cli/ui/DnaTable.d.ts +1 -1
  20. package/dist/cli/ui/DnaTable.d.ts.map +1 -1
  21. package/dist/cli/ui/DnaTable.js +23 -16
  22. package/dist/cli/ui/RefactorWizard.d.ts +3 -3
  23. package/dist/cli/ui/RefactorWizard.d.ts.map +1 -1
  24. package/dist/cli/ui/RefactorWizard.js +108 -82
  25. package/dist/config/ConfigLoader.d.ts +2 -2
  26. package/dist/config/ConfigLoader.d.ts.map +1 -1
  27. package/dist/config/ConfigLoader.js +15 -15
  28. package/dist/config/DryRunGuard.d.ts +1 -1
  29. package/dist/config/DryRunGuard.js +7 -7
  30. package/dist/config/SelaConfig.d.ts +12 -16
  31. package/dist/config/SelaConfig.d.ts.map +1 -1
  32. package/dist/config/SelaConfig.js +32 -26
  33. package/dist/engine/HealingRegistry.d.ts +1 -1
  34. package/dist/engine/HealingRegistry.js +3 -3
  35. package/dist/engine/SelaEngine.d.ts +1 -1
  36. package/dist/engine/SelaEngine.d.ts.map +1 -1
  37. package/dist/engine/SelaEngine.js +63 -49
  38. package/dist/errors/SelaError.d.ts +0 -1
  39. package/dist/errors/SelaError.d.ts.map +1 -1
  40. package/dist/errors/SelaError.js +6 -7
  41. package/dist/fixtures/expectProxy.d.ts +1 -1
  42. package/dist/fixtures/expectProxy.js +11 -11
  43. package/dist/fixtures/index.js +14 -14
  44. package/dist/fixtures/proxyTag.d.ts +1 -1
  45. package/dist/fixtures/proxyTag.js +3 -3
  46. package/dist/index.d.ts +8 -8
  47. package/dist/index.d.ts.map +1 -1
  48. package/dist/index.js +4 -4
  49. package/dist/reporter/SelaReporter.d.ts +45 -12
  50. package/dist/reporter/SelaReporter.d.ts.map +1 -1
  51. package/dist/reporter/SelaReporter.js +139 -39
  52. package/dist/services/ASTSourceUpdater.d.ts +3 -3
  53. package/dist/services/ASTSourceUpdater.d.ts.map +1 -1
  54. package/dist/services/ASTSourceUpdater.js +92 -68
  55. package/dist/services/ArgumentTypeAnalyzer.js +7 -7
  56. package/dist/services/BlastRadiusAnalyzer.d.ts.map +1 -1
  57. package/dist/services/BlastRadiusAnalyzer.js +5 -2
  58. package/dist/services/ChainValidator.js +22 -22
  59. package/dist/services/CrossFileHealer.js +7 -7
  60. package/dist/services/DefinitionTracer.d.ts +1 -1
  61. package/dist/services/DefinitionTracer.d.ts.map +1 -1
  62. package/dist/services/DefinitionTracer.js +28 -13
  63. package/dist/services/DnaEditorService.d.ts +2 -2
  64. package/dist/services/DnaEditorService.d.ts.map +1 -1
  65. package/dist/services/DnaEditorService.js +81 -62
  66. package/dist/services/DnaIndexService.d.ts +1 -1
  67. package/dist/services/DnaIndexService.d.ts.map +1 -1
  68. package/dist/services/DnaIndexService.js +14 -14
  69. package/dist/services/HealReportService.d.ts +6 -6
  70. package/dist/services/HealReportService.d.ts.map +1 -1
  71. package/dist/services/HealReportService.js +33 -29
  72. package/dist/services/HealingAdvisory.js +1 -1
  73. package/dist/services/HealingCacheService.d.ts +8 -8
  74. package/dist/services/HealingCacheService.d.ts.map +1 -1
  75. package/dist/services/HealingCacheService.js +24 -24
  76. package/dist/services/HealthReportService.d.ts +1 -1
  77. package/dist/services/HealthReportService.d.ts.map +1 -1
  78. package/dist/services/HealthReportService.js +25 -25
  79. package/dist/services/InitializerUpdater.js +2 -2
  80. package/dist/services/IntentAuditor.d.ts.map +1 -1
  81. package/dist/services/IntentAuditor.js +32 -21
  82. package/dist/services/InteractiveReview.d.ts +8 -17
  83. package/dist/services/InteractiveReview.d.ts.map +1 -1
  84. package/dist/services/InteractiveReview.js +31 -124
  85. package/dist/services/LLMService.d.ts +1 -1
  86. package/dist/services/LLMService.js +16 -16
  87. package/dist/services/PRAutomationService.d.ts +2 -2
  88. package/dist/services/PRAutomationService.d.ts.map +1 -1
  89. package/dist/services/PRAutomationService.js +43 -39
  90. package/dist/services/PendingPromptLedger.d.ts +2 -2
  91. package/dist/services/PendingPromptLedger.js +6 -6
  92. package/dist/services/ReportGenerator.d.ts +2 -2
  93. package/dist/services/ReportGenerator.d.ts.map +1 -1
  94. package/dist/services/ReportGenerator.js +5 -5
  95. package/dist/services/SafetyGuard.d.ts +3 -6
  96. package/dist/services/SafetyGuard.d.ts.map +1 -1
  97. package/dist/services/SafetyGuard.js +29 -106
  98. package/dist/services/SnapshotService.js +5 -5
  99. package/dist/services/SourceLinkService.d.ts +2 -2
  100. package/dist/services/SourceLinkService.d.ts.map +1 -1
  101. package/dist/services/SourceLinkService.js +31 -22
  102. package/dist/services/SourceUpdater.d.ts +1 -1
  103. package/dist/services/SourceUpdater.d.ts.map +1 -1
  104. package/dist/services/SourceUpdater.js +27 -26
  105. package/dist/services/TemplateDiffService.d.ts.map +1 -1
  106. package/dist/services/TemplateDiffService.js +18 -15
  107. package/dist/services/WorkspaceSnapshotService.d.ts +6 -6
  108. package/dist/services/WorkspaceSnapshotService.d.ts.map +1 -1
  109. package/dist/services/WorkspaceSnapshotService.js +10 -12
  110. package/dist/types/index.d.ts +1 -1
  111. package/dist/utils/IsolatedDiff.d.ts +2 -2
  112. package/dist/utils/IsolatedDiff.d.ts.map +1 -1
  113. package/dist/utils/IsolatedDiff.js +13 -10
  114. package/package.json +2 -2
@@ -41,7 +41,7 @@ const ASTSourceUpdater_1 = require("./ASTSourceUpdater");
41
41
  const DryRunGuard_1 = require("../config/DryRunGuard");
42
42
  const WorkspaceSnapshotService_1 = require("./WorkspaceSnapshotService");
43
43
  const SelaError_1 = require("../errors/SelaError");
44
- // Centralised write gate every disk-mutating `fs.writeFileSync` call in
44
+ // Centralised write gate - every disk-mutating `fs.writeFileSync` call in
45
45
  // this module routes through `persistFile` so the SELA_DRY_RUN bypass is
46
46
  // enforced in one place, and the Clean-Room WorkspaceSnapshotService
47
47
  // records contentBefore/contentAfter for isolated in-memory diffing.
@@ -310,19 +310,19 @@ function updateTemplateLiteralPreservingVars(line, oldSelector, newSelector, dom
310
310
  // GIT HELPER (used by branch strategy and autoCommit)
311
311
  //
312
312
  // Design goals:
313
- // • Lean no stash, no branch-switching, no complex state management.
314
- // • Commit-based write first (inPlace), then commit. If git fails,
313
+ // • Lean - no stash, no branch-switching, no complex state management.
314
+ // • Commit-based - write first (inPlace), then commit. If git fails,
315
315
  // the fix is still on disk (silent inPlace fallback).
316
- // • Detached HEAD aware skips silently in CI environments that check
316
+ // • Detached HEAD aware - skips silently in CI environments that check
317
317
  // out a specific SHA without a branch ref.
318
318
  // ─────────────────────────────────────────────────────────────────
319
319
  function runGitOperations(absoluteFilePath, createBranch, relativeFilePath) {
320
320
  const filename = path.basename(relativeFilePath);
321
- // Dry-run gate suppress branch creation, `git add`, and auto-commit.
321
+ // Dry-run gate - suppress branch creation, `git add`, and auto-commit.
322
322
  // Mirrors the persistFile() skip so a dry run is fully observable in CI
323
323
  // without ever producing a commit.
324
324
  if (DryRunGuard_1.DryRunGuard.active()) {
325
- console.log(`[SourceUpdater] 🌵 Dry Run skip git operations for ${filename}`);
325
+ console.log(`[SourceUpdater] 🌵 Dry Run - skip git operations for ${filename}`);
326
326
  return;
327
327
  }
328
328
  try {
@@ -331,7 +331,7 @@ function runGitOperations(absoluteFilePath, createBranch, relativeFilePath) {
331
331
  (0, child_process_1.execSync)("git symbolic-ref HEAD", { stdio: "pipe" });
332
332
  }
333
333
  catch {
334
- console.warn(`[SourceUpdater] ⚠️ Detached HEAD git operations skipped (fix is saved to disk)`);
334
+ console.warn(`[SourceUpdater] ⚠️ Detached HEAD - git operations skipped (fix is saved to disk)`);
335
335
  return;
336
336
  }
337
337
  if (createBranch) {
@@ -346,7 +346,7 @@ function runGitOperations(absoluteFilePath, createBranch, relativeFilePath) {
346
346
  console.log(`[SourceUpdater] ✅ Auto-committed fix in: ${filename}`);
347
347
  }
348
348
  catch (err) {
349
- console.warn(`[SourceUpdater] ⚠️ Git operation failed: ${err.message} fix written to disk (inPlace fallback)`);
349
+ console.warn(`[SourceUpdater] ⚠️ Git operation failed: ${err.message} - fix written to disk (inPlace fallback)`);
350
350
  }
351
351
  }
352
352
  class SourceUpdater {
@@ -376,7 +376,7 @@ class SourceUpdater {
376
376
  return result;
377
377
  }
378
378
  // ─────────────────────────────────────────────────────────────
379
- // commentOnly helper inserts a TODO comment above the failing
379
+ // commentOnly helper - inserts a TODO comment above the failing
380
380
  // call site and returns success:false so the engine knows the
381
381
  // source was NOT rewritten (no retry suppression needed).
382
382
  // ─────────────────────────────────────────────────────────────
@@ -402,12 +402,12 @@ class SourceUpdater {
402
402
  catch (err) {
403
403
  return {
404
404
  success: false,
405
- reason: `COMMENT_ONLY: write failed ${err.message}`,
405
+ reason: `COMMENT_ONLY: write failed - ${err.message}`,
406
406
  };
407
407
  }
408
408
  }
409
409
  // ─────────────────────────────────────────────────────────────
410
- // CORE UPDATE Layered Healing (AST primary, Regex fallback)
410
+ // CORE UPDATE - Layered Healing (AST primary, Regex fallback)
411
411
  // Called by update(); never call directly from outside the class.
412
412
  // ─────────────────────────────────────────────────────────────
413
413
  static _coreUpdate(caller, oldSelector, newSelector, domContext, dnaAttrHint, fullSelectorContext, aiSegments, contentChange, smartChainSegments, originalChainHint) {
@@ -442,7 +442,7 @@ class SourceUpdater {
442
442
  if (astResult.success) {
443
443
  console.log(`[SourceUpdater] ✅ AST Strategy ${astResult.strategy} SUCCESS` +
444
444
  (astResult.lineUpdated !== undefined
445
- ? ` line ${astResult.lineUpdated + 1}`
445
+ ? ` - line ${astResult.lineUpdated + 1}`
446
446
  : ""));
447
447
  return {
448
448
  success: true,
@@ -458,18 +458,19 @@ class SourceUpdater {
458
458
  // PROPERTY_ACCESS / TEMPLATE_LITERAL) but could not safely resolve the new
459
459
  // value. Regex cannot do better and will corrupt the definition site.
460
460
  if (astResult.strategy === "semantic-guard") {
461
- console.warn(`[SourceUpdater] 🛑 Regex blocked semantic guard fired. ` +
461
+ console.warn(`[SourceUpdater] 🛑 Regex blocked - semantic guard fired. ` +
462
462
  `Source unchanged. Reason: ${astResult.reason}`);
463
463
  return { success: false, reason: astResult.reason };
464
464
  }
465
465
  console.log(`[SourceUpdater] ⚠️ AST engine exhausted (${astResult.reason}), falling back to Regex`);
466
466
  }
467
467
  catch (astError) {
468
- // Developer pinned the failing statement with `// sela-fail-fast`
468
+ // Developer pinned the failing statement with `// sela-fail-fast` -
469
469
  // propagate the directive instead of swallowing into the Regex
470
470
  // fallback chain (which would defeat the whole point of the gate).
471
471
  if ((0, SelaError_1.isSelaErrorFrom)(astError, "ASTUpdater") &&
472
- astError.code === SelaError_1.AST_UPDATER_CODES.HEAL_DISABLED_BY_DIRECTIVE) {
472
+ astError.code ===
473
+ SelaError_1.AST_UPDATER_CODES.HEAL_DISABLED_BY_DIRECTIVE) {
473
474
  throw astError;
474
475
  }
475
476
  console.warn(`[SourceUpdater] ⚠️ AST engine error: ${astError.message}. Falling back to Regex`);
@@ -479,7 +480,7 @@ class SourceUpdater {
479
480
  const raw = fs.readFileSync(filePath, "utf8");
480
481
  const lines = raw.split(/\r?\n/);
481
482
  if (caller.line <= 0) {
482
- console.log(`[SourceUpdater] ⚠️ line ${caller.line} invalid running Regex Strategy G only`);
483
+ console.log(`[SourceUpdater] ⚠️ line ${caller.line} invalid - running Regex Strategy G only`);
483
484
  if (contentChange) {
484
485
  const assertResult = SourceUpdater.strategyAssertionHealing(lines, 1, contentChange, true);
485
486
  if (assertResult.success) {
@@ -511,7 +512,7 @@ class SourceUpdater {
511
512
  if (layeredResult.success) {
512
513
  tryAssertionHealing();
513
514
  persistFile(filePath, lines.join("\n"));
514
- console.log(`[SourceUpdater] ✅ Strategy 0 (Layered Healing) SUCCESS line ${layeredResult.lineUpdated + 1}`);
515
+ console.log(`[SourceUpdater] ✅ Strategy 0 (Layered Healing) SUCCESS - line ${layeredResult.lineUpdated + 1}`);
515
516
  return layeredResult;
516
517
  }
517
518
  }
@@ -587,7 +588,7 @@ class SourceUpdater {
587
588
  };
588
589
  }
589
590
  // ─────────────────────────────────────────────────────────────
590
- // STRATEGY F (Regex) Full Chain Collapsing
591
+ // STRATEGY F (Regex) - Full Chain Collapsing
591
592
  // ─────────────────────────────────────────────────────────────
592
593
  static strategyChainCollapse_Regex(lines, callerLine, oldSelector, newSelector) {
593
594
  console.log(`[Strategy-F] ⛓️ Starting Regex Chain Collapse...`);
@@ -638,7 +639,7 @@ class SourceUpdater {
638
639
  return { success: false, reason: "chain detected but could not replace" };
639
640
  }
640
641
  // ─────────────────────────────────────────────────────────────
641
- // STRATEGY G (Regex) Assertion Healing
642
+ // STRATEGY G (Regex) - Assertion Healing
642
643
  // ─────────────────────────────────────────────────────────────
643
644
  static strategyAssertionHealing(lines, callerLine, contentChange, wholeFile = false) {
644
645
  const { oldText, newText } = contentChange;
@@ -693,7 +694,7 @@ class SourceUpdater {
693
694
  return { success: false, reason: "no assertions to heal" };
694
695
  }
695
696
  // ─────────────────────────────────────────────────────────────
696
- // STRATEGY 0 Layered Healing (Upstream Variable Tracing)
697
+ // STRATEGY 0 - Layered Healing (Upstream Variable Tracing)
697
698
  // ─────────────────────────────────────────────────────────────
698
699
  static strategyLayeredHealing(lines, callerLine, oldElementSelector, aiSegments, fullSelectorContext) {
699
700
  console.log(`[SourceUpdater] 🧠 Strategy 0: Starting Layered Healing...`);
@@ -746,7 +747,7 @@ class SourceUpdater {
746
747
  return null;
747
748
  }
748
749
  // ─────────────────────────────────────────────────────────────
749
- // STRATEGY 1 Chain Collapse (leaf-only precision replacement)
750
+ // STRATEGY 1 - Chain Collapse (leaf-only precision replacement)
750
751
  // ─────────────────────────────────────────────────────────────
751
752
  static strategyChainCollapse(lines, callerLine, oldSelector, newSelector) {
752
753
  const oldLeaf = oldSelector
@@ -788,7 +789,7 @@ class SourceUpdater {
788
789
  };
789
790
  }
790
791
  // ─────────────────────────────────────────────────────────────
791
- // STRATEGY 2 Direct Literal
792
+ // STRATEGY 2 - Direct Literal
792
793
  // ─────────────────────────────────────────────────────────────
793
794
  static strategyDirectLiteral(lines, callerLine, oldSelector, newSelector) {
794
795
  const windowSize = 10;
@@ -821,7 +822,7 @@ class SourceUpdater {
821
822
  return { success: false, reason: "no direct literal" };
822
823
  }
823
824
  // ─────────────────────────────────────────────────────────────
824
- // STRATEGY 3 Upstream Variable/Const
825
+ // STRATEGY 3 - Upstream Variable/Const
825
826
  // ─────────────────────────────────────────────────────────────
826
827
  static strategyUpstreamVariable(lines, callerLine, oldSelector, newSelector) {
827
828
  const callBlock = lines
@@ -858,7 +859,7 @@ class SourceUpdater {
858
859
  return { success: false, reason: "no upstream variable" };
859
860
  }
860
861
  // ─────────────────────────────────────────────────────────────
861
- // STRATEGY 4 Chained Locator Dedup
862
+ // STRATEGY 4 - Chained Locator Dedup
862
863
  // ─────────────────────────────────────────────────────────────
863
864
  static strategyChainedLocator(lines, callerLine, oldSelector, newSelector) {
864
865
  const blockStart = Math.max(0, callerLine - 10);
@@ -885,7 +886,7 @@ class SourceUpdater {
885
886
  return { success: false, reason: "dedup found but literal not replaced" };
886
887
  }
887
888
  // ─────────────────────────────────────────────────────────────
888
- // STRATEGY 5 Function/Template with Variable Preservation
889
+ // STRATEGY 5 - Function/Template with Variable Preservation
889
890
  // ─────────────────────────────────────────────────────────────
890
891
  static strategyFunctionReturn(lines, callerLine, oldSelector, newSelector, domContext, dnaAttrHint) {
891
892
  const callBlock = lines
@@ -970,7 +971,7 @@ class SourceUpdater {
970
971
  return { success: false, reason: "function strategy exhausted" };
971
972
  }
972
973
  // ─────────────────────────────────────────────────────────────
973
- // STRATEGY 6 Global Scan
974
+ // STRATEGY 6 - Global Scan
974
975
  // ─────────────────────────────────────────────────────────────
975
976
  static strategyGlobalScan(lines, oldSelector, newSelector) {
976
977
  const lastOldPart = oldSelector.split(">>").pop().trim();
@@ -1 +1 @@
1
- {"version":3,"file":"TemplateDiffService.d.ts","sourceRoot":"","sources":["../../src/services/TemplateDiffService.ts"],"names":[],"mappings":"AAAA,OAAO,EAAQ,kBAAkB,EAAc,MAAM,UAAU,CAAC;AAMhE,MAAM,MAAM,eAAe,GACvB;IACE,EAAE,EAAE,IAAI,CAAC;IACT,mFAAmF;IACnF,eAAe,EAAE,MAAM,CAAC;IACxB,0DAA0D;IAC1D,qBAAqB,EAAE,MAAM,EAAE,CAAC;CACjC,GACD;IACE,EAAE,EAAE,KAAK,CAAC;IACV,MAAM,EAAE,MAAM,CAAC;IACf;;;;OAIG;IACH,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;CAC1B,CAAC;AA6BN,qBAAa,mBAAmB;IAW9B,MAAM,CAAC,YAAY,CACjB,YAAY,EAAE,MAAM,EACpB,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,MAAM,GAClB,eAAe;IA6GlB,MAAM,CAAC,gBAAgB,CACrB,YAAY,EAAE,kBAAkB,EAChC,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,MAAM,GAClB,eAAe;IAoFlB,MAAM,CAAC,qBAAqB,CAC1B,YAAY,EAAE,kBAAkB,EAChC,QAAQ,EAAE,MAAM,GACf,MAAM,EAAE,GAAG,IAAI;CASnB;AAgJD,6DAA6D;AAC7D,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAKtD"}
1
+ {"version":3,"file":"TemplateDiffService.d.ts","sourceRoot":"","sources":["../../src/services/TemplateDiffService.ts"],"names":[],"mappings":"AAAA,OAAO,EAAQ,kBAAkB,EAAc,MAAM,UAAU,CAAC;AAMhE,MAAM,MAAM,eAAe,GACvB;IACE,EAAE,EAAE,IAAI,CAAC;IACT,mFAAmF;IACnF,eAAe,EAAE,MAAM,CAAC;IACxB,0DAA0D;IAC1D,qBAAqB,EAAE,MAAM,EAAE,CAAC;CACjC,GACD;IACE,EAAE,EAAE,KAAK,CAAC;IACV,MAAM,EAAE,MAAM,CAAC;IACf;;;;OAIG;IACH,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;CAC1B,CAAC;AA6BN,qBAAa,mBAAmB;IAW9B,MAAM,CAAC,YAAY,CACjB,YAAY,EAAE,MAAM,EACpB,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,MAAM,GAClB,eAAe;IAiHlB,MAAM,CAAC,gBAAgB,CACrB,YAAY,EAAE,kBAAkB,EAChC,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,MAAM,GAClB,eAAe;IAoFlB,MAAM,CAAC,qBAAqB,CAC1B,YAAY,EAAE,kBAAkB,EAChC,QAAQ,EAAE,MAAM,GACf,MAAM,EAAE,GAAG,IAAI;CASnB;AAgJD,6DAA6D;AAC7D,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAKtD"}
@@ -5,13 +5,13 @@ exports.escapeForTemplate = escapeForTemplate;
5
5
  // ═══════════════════════════════════════════════════════════════════
6
6
  // TemplateDiffService
7
7
  //
8
- // T-8: String-based API diffAndPatch()
8
+ // T-8: String-based API - diffAndPatch()
9
9
  // Given a template source like `input[data-role="${role}_legacy"]`,
10
10
  // its resolved old string, and an AI-proposed new string, compute
11
11
  // the patched template that preserves ${...} spans while updating
12
12
  // only the changed static segments.
13
13
  //
14
- // T-8.1: Node-based API computeNodePatch()
14
+ // T-8.1: Node-based API - computeNodePatch()
15
15
  // Wraps diffAndPatch() using the TemplateExpression AST node as the
16
16
  // source of truth (avoids text-parsing ambiguity). Returns the full
17
17
  // patched template text for use with templateNode.replaceWithText().
@@ -34,7 +34,7 @@ class TemplateDiffService {
34
34
  const exprSegs = segments
35
35
  .filter((s) => s.type === "expr")
36
36
  .map((s) => s.text);
37
- // No spans the "template" is just a plain string.
37
+ // No spans - the "template" is just a plain string.
38
38
  if (exprSegs.length === 0) {
39
39
  if (resolvedOld !== resolvedNew) {
40
40
  return {
@@ -43,18 +43,21 @@ class TemplateDiffService {
43
43
  changedSegmentIndices: [0],
44
44
  };
45
45
  }
46
- return { ok: false, reason: "resolvedOld === resolvedNew — no change needed" };
46
+ return {
47
+ ok: false,
48
+ reason: "resolvedOld === resolvedNew - no change needed",
49
+ };
47
50
  }
48
51
  // Extract span values from resolvedOld using static segments as anchors.
49
52
  const spanValues = extractSpanValues(staticSegs, resolvedOld);
50
53
  if (!spanValues) {
51
54
  return {
52
55
  ok: false,
53
- reason: "template static segments don't align with resolvedOld possible desync. " +
56
+ reason: "template static segments don't align with resolvedOld - possible desync. " +
54
57
  `template="${templateText}", resolvedOld="${resolvedOld}"`,
55
58
  };
56
59
  }
57
- // Verify reconstruction extractSpanValues already guarantees this
60
+ // Verify reconstruction - extractSpanValues already guarantees this
58
61
  // implicitly, but an explicit check catches any edge-case bugs early.
59
62
  {
60
63
  let check = "";
@@ -76,13 +79,13 @@ class TemplateDiffService {
76
79
  return {
77
80
  ok: false,
78
81
  reason: `dynamic span value(s) [${spanValues.map((v) => `"${v}"`).join(", ")}] ` +
79
- `not found in resolvedNew="${resolvedNew}" structural change, manual review required`,
82
+ `not found in resolvedNew="${resolvedNew}" - structural change, manual review required`,
80
83
  };
81
84
  }
82
85
  if (newStaticSegs.length !== staticSegs.length) {
83
86
  return {
84
87
  ok: false,
85
- reason: "static segment count mismatch after alignment structural change",
88
+ reason: "static segment count mismatch after alignment - structural change",
86
89
  };
87
90
  }
88
91
  // Diff: find which static segments changed.
@@ -94,14 +97,14 @@ class TemplateDiffService {
94
97
  if (changedIndices.length === 0) {
95
98
  return {
96
99
  ok: false,
97
- reason: "no static segment changed the difference is in a dynamic span. " +
100
+ reason: "no static segment changed - the difference is in a dynamic span. " +
98
101
  "Update the argument passed to the function instead.",
99
102
  };
100
103
  }
101
104
  if (changedIndices.length > 1) {
102
105
  return {
103
106
  ok: false,
104
- reason: `${changedIndices.length} static segments changed simultaneously ` +
107
+ reason: `${changedIndices.length} static segments changed simultaneously - ` +
105
108
  "ambiguous, manual review required",
106
109
  };
107
110
  }
@@ -119,7 +122,7 @@ class TemplateDiffService {
119
122
  //
120
123
  // Uses the TemplateExpression AST node as the authoritative source
121
124
  // of static/expr segments (avoids text-parsing edge cases).
122
- // Returns `patchedText` pass directly to templateNode.replaceWithText().
125
+ // Returns `patchedText` - pass directly to templateNode.replaceWithText().
123
126
  // ─────────────────────────────────────────────────────────────────
124
127
  static computeNodePatch(templateNode, resolvedOld, resolvedNew) {
125
128
  // Extract static segments and expr texts directly from the AST.
@@ -172,13 +175,13 @@ class TemplateDiffService {
172
175
  if (changedIndices.length === 0) {
173
176
  return {
174
177
  ok: false,
175
- reason: "difference is in dynamic span update call-site argument",
178
+ reason: "difference is in dynamic span - update call-site argument",
176
179
  };
177
180
  }
178
181
  if (changedIndices.length > 1) {
179
182
  return {
180
183
  ok: false,
181
- reason: `${changedIndices.length} static segments changed ambiguous`,
184
+ reason: `${changedIndices.length} static segments changed - ambiguous`,
182
185
  };
183
186
  }
184
187
  const patchedStatics = [...staticSegs];
@@ -238,7 +241,7 @@ function parseTemplateSource(text) {
238
241
  *
239
242
  * Algorithm: iterate over all static segments in order. After consuming
240
243
  * each static segment, find the next static as the delimiter for the
241
- * span value then advance pos to the start of that next static so
244
+ * span value - then advance pos to the start of that next static so
242
245
  * the following iteration can consume it. This ensures pos is always
243
246
  * consistent at the start of each static segment.
244
247
  *
@@ -265,7 +268,7 @@ function extractSpanValues(staticSegments, resolved) {
265
268
  break;
266
269
  }
267
270
  if (nextStatic === "") {
268
- // Empty non-trailing static: adjacent spans boundary is ambiguous.
271
+ // Empty non-trailing static: adjacent spans - boundary is ambiguous.
269
272
  return null;
270
273
  }
271
274
  const delimIdx = resolved.indexOf(nextStatic, pos);
@@ -1,16 +1,16 @@
1
1
  export interface FileSnapshot {
2
2
  /** Absolute, normalised path of the tracked file. */
3
3
  absolutePath: string;
4
- /** Project-relative path (posix slashes) for diff headers + PR commits. */
4
+ /** Project-relative path (posix slashes) - for diff headers + PR commits. */
5
5
  relativePath: string;
6
6
  /**
7
7
  * Disk content captured BEFORE Sela's first write to this file.
8
- * May contain the developer's uncommitted edits that's the point.
8
+ * May contain the developer's uncommitted edits - that's the point.
9
9
  */
10
10
  contentBefore: string;
11
11
  /** Disk content captured AFTER Sela's latest write. `null` until first postWrite(). */
12
12
  contentAfter: string | null;
13
- /** Content of the file at `HEAD` (last committed) `null` when untracked / no git. */
13
+ /** Content of the file at `HEAD` (last committed) - `null` when untracked / no git. */
14
14
  headContent: string | null;
15
15
  /** True when `contentBefore !== headContent`, i.e. developer had dirty edits. */
16
16
  hadUncommittedChanges: boolean;
@@ -25,11 +25,11 @@ export declare class WorkspaceSnapshotService {
25
25
  setCwd(cwd: string): void;
26
26
  /**
27
27
  * Record the pre-mutation state of `filePath` if not already tracked.
28
- * Idempotent only the FIRST call per file matters.
28
+ * Idempotent - only the FIRST call per file matters.
29
29
  */
30
30
  preWrite(filePath: string): void;
31
31
  /**
32
- * Refresh the post-mutation state. Safe to call multiple times each
32
+ * Refresh the post-mutation state. Safe to call multiple times - each
33
33
  * call overwrites `contentAfter` with the latest disk state.
34
34
  */
35
35
  postWrite(filePath: string): void;
@@ -45,7 +45,7 @@ export declare class WorkspaceSnapshotService {
45
45
  /** All snapshots with a real mutation recorded. */
46
46
  getMutatedSnapshots(): FileSnapshot[];
47
47
  /**
48
- * Rewind every tracked file on disk to `contentBefore` restoring the
48
+ * Rewind every tracked file on disk to `contentBefore` - restoring the
49
49
  * developer's pre-Sela workspace state byte-for-byte.
50
50
  */
51
51
  restoreOriginal(): void;
@@ -1 +1 @@
1
- {"version":3,"file":"WorkspaceSnapshotService.d.ts","sourceRoot":"","sources":["../../src/services/WorkspaceSnapshotService.ts"],"names":[],"mappings":"AAyBA,MAAM,WAAW,YAAY;IAC3B,qDAAqD;IACrD,YAAY,EAAE,MAAM,CAAC;IACrB,6EAA6E;IAC7E,YAAY,EAAE,MAAM,CAAC;IACrB;;;OAGG;IACH,aAAa,EAAE,MAAM,CAAC;IACtB,uFAAuF;IACvF,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,uFAAuF;IACvF,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,iFAAiF;IACjF,qBAAqB,EAAE,OAAO,CAAC;IAC/B,uEAAuE;IACvE,aAAa,EAAE,OAAO,CAAC;CACxB;AAED,qBAAa,wBAAwB;IACnC,OAAO,CAAC,SAAS,CAAmC;IACpD,OAAO,CAAC,GAAG,CAAS;gBAER,GAAG,GAAE,MAAsB;IAIvC,sEAAsE;IACtE,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAIzB;;;OAGG;IACH,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAqBhC;;;OAGG;IACH,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IASjC,0EAA0E;IAC1E,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI;IAIlD,+CAA+C;IAC/C,eAAe,IAAI,YAAY,EAAE;IAIjC;;;OAGG;IACH,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO;IAMpC,mDAAmD;IACnD,mBAAmB,IAAI,YAAY,EAAE;IAMrC;;;OAGG;IACH,eAAe,IAAI,IAAI;IAMvB;;;;OAIG;IACH,qBAAqB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO;IAOhD,OAAO,CAAC,cAAc;IAUtB;;;;OAIG;IACH,cAAc,IAAI,IAAI;IAOtB,KAAK,IAAI,IAAI;IAQb,OAAO,CAAC,SAAS;IAMjB,OAAO,CAAC,UAAU;IAKlB,OAAO,CAAC,eAAe;CAcxB;AAED,eAAO,MAAM,uBAAuB,0BAAiC,CAAC"}
1
+ {"version":3,"file":"WorkspaceSnapshotService.d.ts","sourceRoot":"","sources":["../../src/services/WorkspaceSnapshotService.ts"],"names":[],"mappings":"AAyBA,MAAM,WAAW,YAAY;IAC3B,qDAAqD;IACrD,YAAY,EAAE,MAAM,CAAC;IACrB,6EAA6E;IAC7E,YAAY,EAAE,MAAM,CAAC;IACrB;;;OAGG;IACH,aAAa,EAAE,MAAM,CAAC;IACtB,uFAAuF;IACvF,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,uFAAuF;IACvF,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,iFAAiF;IACjF,qBAAqB,EAAE,OAAO,CAAC;IAC/B,uEAAuE;IACvE,aAAa,EAAE,OAAO,CAAC;CACxB;AAED,qBAAa,wBAAwB;IACnC,OAAO,CAAC,SAAS,CAAmC;IACpD,OAAO,CAAC,GAAG,CAAS;gBAER,GAAG,GAAE,MAAsB;IAIvC,sEAAsE;IACtE,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAIzB;;;OAGG;IACH,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAqBhC;;;OAGG;IACH,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAOjC,0EAA0E;IAC1E,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI;IAIlD,+CAA+C;IAC/C,eAAe,IAAI,YAAY,EAAE;IAIjC;;;OAGG;IACH,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO;IAMpC,mDAAmD;IACnD,mBAAmB,IAAI,YAAY,EAAE;IAMrC;;;OAGG;IACH,eAAe,IAAI,IAAI;IAMvB;;;;OAIG;IACH,qBAAqB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO;IAOhD,OAAO,CAAC,cAAc;IAUtB;;;;OAIG;IACH,cAAc,IAAI,IAAI;IAOtB,KAAK,IAAI,IAAI;IAQb,OAAO,CAAC,SAAS;IAMjB,OAAO,CAAC,UAAU;IAKlB,OAAO,CAAC,eAAe;CAcxB;AAED,eAAO,MAAM,uBAAuB,0BAAiC,CAAC"}
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  // src/services/WorkspaceSnapshotService.ts
3
3
  //
4
- // Clean-Room Architecture file 1 of 2.
4
+ // Clean-Room Architecture - file 1 of 2.
5
5
  //
6
6
  // Tracks the EXACT content of every file Sela mutates during a session, so:
7
7
  // • The HTML report diff can be generated from an isolated in-memory diff
@@ -10,12 +10,12 @@
10
10
  // byte-for-byte after a PR is opened on an isolated branch.
11
11
  //
12
12
  // Lifecycle:
13
- // preWrite(path) first call per file records `contentBefore` (disk
13
+ // preWrite(path) - first call per file records `contentBefore` (disk
14
14
  // snapshot right before Sela touches it) + HEAD blob.
15
- // postWrite(path) refreshes `contentAfter` (latest disk state).
16
- // restoreOriginal() writes contentBefore back to every tracked file.
17
- // restoreMutated() writes contentAfter back to every tracked file.
18
- // clear() empties the ledger.
15
+ // postWrite(path) - refreshes `contentAfter` (latest disk state).
16
+ // restoreOriginal()- writes contentBefore back to every tracked file.
17
+ // restoreMutated() - writes contentAfter back to every tracked file.
18
+ // clear() - empties the ledger.
19
19
  //
20
20
  // Singleton `sharedWorkspaceSnapshot` is the canonical instance the
21
21
  // SourceUpdater / ASTSourceUpdater write hooks talk to.
@@ -69,7 +69,7 @@ class WorkspaceSnapshotService {
69
69
  }
70
70
  /**
71
71
  * Record the pre-mutation state of `filePath` if not already tracked.
72
- * Idempotent only the FIRST call per file matters.
72
+ * Idempotent - only the FIRST call per file matters.
73
73
  */
74
74
  preWrite(filePath) {
75
75
  const abs = this.normalise(filePath);
@@ -90,7 +90,7 @@ class WorkspaceSnapshotService {
90
90
  });
91
91
  }
92
92
  /**
93
- * Refresh the post-mutation state. Safe to call multiple times each
93
+ * Refresh the post-mutation state. Safe to call multiple times - each
94
94
  * call overwrites `contentAfter` with the latest disk state.
95
95
  */
96
96
  postWrite(filePath) {
@@ -98,9 +98,7 @@ class WorkspaceSnapshotService {
98
98
  const snap = this.snapshots.get(abs);
99
99
  if (!snap)
100
100
  return;
101
- snap.contentAfter = fs.existsSync(abs)
102
- ? fs.readFileSync(abs, "utf8")
103
- : "";
101
+ snap.contentAfter = fs.existsSync(abs) ? fs.readFileSync(abs, "utf8") : "";
104
102
  }
105
103
  /** Lookup by absolute or relative path. Returns `null` when untracked. */
106
104
  getSnapshot(filePath) {
@@ -125,7 +123,7 @@ class WorkspaceSnapshotService {
125
123
  return this.getAllSnapshots().filter((s) => s.contentAfter !== null && s.contentAfter !== s.contentBefore);
126
124
  }
127
125
  /**
128
- * Rewind every tracked file on disk to `contentBefore` restoring the
126
+ * Rewind every tracked file on disk to `contentBefore` - restoring the
129
127
  * developer's pre-Sela workspace state byte-for-byte.
130
128
  */
131
129
  restoreOriginal() {
@@ -2,7 +2,7 @@ export interface AncestorNode {
2
2
  tag: string;
3
3
  id: string | null;
4
4
  classes: string[];
5
- /** "{tag}#{id}[{classes_sorted_asc}]" stable fingerprint for drift comparison */
5
+ /** "{tag}#{id}[{classes_sorted_asc}]" - stable fingerprint for drift comparison */
6
6
  fingerprint: string;
7
7
  }
8
8
  export type GhostCondition = "G1_DISPLAY_NONE" | "G2_VISIBILITY_HIDDEN" | "G3_OPACITY_ZERO" | "G4_POINTER_EVENTS_NONE" | "G5_ZERO_AREA" | "G6_CONTENT_VISIBILITY_HIDDEN";
@@ -32,13 +32,13 @@ export declare function extractChangeBlocks(before: string, after: string): Chan
32
32
  export interface ApplyBlocksResult {
33
33
  ok: boolean;
34
34
  result?: string;
35
- /** Human-readable failure reason surfaced in the PR-automation log. */
35
+ /** Human-readable failure reason - surfaced in the PR-automation log. */
36
36
  reason?: string;
37
37
  }
38
38
  /**
39
39
  * Replay a list of change blocks against a fresh base buffer (typically
40
40
  * the file's `HEAD` blob). Each block is applied via UNIQUE substring
41
- * replacement when the old block is missing or ambiguous in the base,
41
+ * replacement - when the old block is missing or ambiguous in the base,
42
42
  * we fail loudly rather than silently mutating the wrong spot.
43
43
  */
44
44
  export declare function applyChangeBlocks(base: string, blocks: ChangeBlock[]): ApplyBlocksResult;
@@ -1 +1 @@
1
- {"version":3,"file":"IsolatedDiff.d.ts","sourceRoot":"","sources":["../../src/utils/IsolatedDiff.ts"],"names":[],"mappings":"AAcA,MAAM,WAAW,mBAAmB;IAClC,4EAA4E;IAC5E,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,EACb,IAAI,GAAE,mBAAwB,GAC7B,MAAM,CAsBR;AA2PD,MAAM,WAAW,WAAW;IAC1B,sEAAsE;IACtE,QAAQ,EAAE,MAAM,CAAC;IACjB,sEAAsE;IACtE,QAAQ,EAAE,MAAM,CAAC;IACjB,uEAAuE;IACvE,YAAY,EAAE,MAAM,CAAC;IACrB,yEAAyE;IACzE,YAAY,EAAE,MAAM,CAAC;IACrB;;;;OAIG;IACH,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B;AAED,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,WAAW,EAAE,CAoDhF;AAED,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,OAAO,CAAC;IACZ,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,yEAAyE;IACzE,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,WAAW,EAAE,GACpB,iBAAiB,CAoDnB"}
1
+ {"version":3,"file":"IsolatedDiff.d.ts","sourceRoot":"","sources":["../../src/utils/IsolatedDiff.ts"],"names":[],"mappings":"AAcA,MAAM,WAAW,mBAAmB;IAClC,4EAA4E;IAC5E,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,EACb,IAAI,GAAE,mBAAwB,GAC7B,MAAM,CAsBR;AA6PD,MAAM,WAAW,WAAW;IAC1B,sEAAsE;IACtE,QAAQ,EAAE,MAAM,CAAC;IACjB,sEAAsE;IACtE,QAAQ,EAAE,MAAM,CAAC;IACjB,uEAAuE;IACvE,YAAY,EAAE,MAAM,CAAC;IACrB,yEAAyE;IACzE,YAAY,EAAE,MAAM,CAAC;IACrB;;;;OAIG;IACH,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B;AAED,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,GACZ,WAAW,EAAE,CAoDf;AAED,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,OAAO,CAAC;IACZ,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,yEAAyE;IACzE,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,WAAW,EAAE,GACpB,iBAAiB,CAuDnB"}
@@ -2,7 +2,7 @@
2
2
  // src/utils/IsolatedDiff.ts
3
3
  //
4
4
  // Pure-JS unified-diff generator. No external `diff` package, no shell-out to
5
- // `git diff` the result is guaranteed to be a function ONLY of the two
5
+ // `git diff` - the result is guaranteed to be a function ONLY of the two
6
6
  // in-memory buffers passed in, never of any global working-tree state.
7
7
  //
8
8
  // This is the foundation of the Clean-Room Architecture: the HTML report
@@ -47,7 +47,7 @@ function generateUnifiedDiff(before, after, opts = {}) {
47
47
  return out.join("\n") + "\n";
48
48
  }
49
49
  // ────────────────────────────────────────────────────────────────────
50
- // LINE SPLITTER preserves trailing newline / CRLF so we can emit the
50
+ // LINE SPLITTER - preserves trailing newline / CRLF so we can emit the
51
51
  // canonical `` marker when needed.
52
52
  // ────────────────────────────────────────────────────────────────────
53
53
  function splitKeepEol(text) {
@@ -200,7 +200,7 @@ function groupHunks(ops, ctx) {
200
200
  // Anchor on the corresponding `b` position. For pure-deletions at
201
201
  // the top of file `op.a === 0` ⇒ newStart should be 0 (special
202
202
  // header form `+0,0`). For mid-file deletions use the running b
203
- // cursor derive it from prior ops.
203
+ // cursor - derive it from prior ops.
204
204
  newStartIdx = computeBAnchor(ops, k);
205
205
  }
206
206
  const line = ctx.a[op.a];
@@ -296,7 +296,7 @@ function extractChangeBlocks(before, after) {
296
296
  }
297
297
  let anchorBefore = null;
298
298
  if (oldLines.length === 0) {
299
- // Pure addition find preceding unchanged anchor line.
299
+ // Pure addition - find preceding unchanged anchor line.
300
300
  for (let k = start - 1; k >= 0; k--) {
301
301
  const op = ops[k];
302
302
  if (op.kind === "eq") {
@@ -318,7 +318,7 @@ function extractChangeBlocks(before, after) {
318
318
  /**
319
319
  * Replay a list of change blocks against a fresh base buffer (typically
320
320
  * the file's `HEAD` blob). Each block is applied via UNIQUE substring
321
- * replacement when the old block is missing or ambiguous in the base,
321
+ * replacement - when the old block is missing or ambiguous in the base,
322
322
  * we fail loudly rather than silently mutating the wrong spot.
323
323
  */
324
324
  function applyChangeBlocks(base, blocks) {
@@ -328,7 +328,7 @@ function applyChangeBlocks(base, blocks) {
328
328
  // Pure addition.
329
329
  if (block.anchorBefore === null) {
330
330
  if (working.length === 0) {
331
- // Empty file prepend.
331
+ // Empty file - prepend.
332
332
  working = block.newBlock + working;
333
333
  continue;
334
334
  }
@@ -351,25 +351,28 @@ function applyChangeBlocks(base, blocks) {
351
351
  };
352
352
  }
353
353
  const insertAt = idx + block.anchorBefore.length;
354
- working = working.slice(0, insertAt) + block.newBlock + working.slice(insertAt);
354
+ working =
355
+ working.slice(0, insertAt) + block.newBlock + working.slice(insertAt);
355
356
  continue;
356
357
  }
357
358
  const idx = working.indexOf(block.oldBlock);
358
359
  if (idx === -1) {
359
360
  return {
360
361
  ok: false,
361
- reason: `block not found in clean base developer's dirty state likely overlaps Sela's mutation site: "${snippet(block.oldBlock)}"`,
362
+ reason: `block not found in clean base - developer's dirty state likely overlaps Sela's mutation site: "${snippet(block.oldBlock)}"`,
362
363
  };
363
364
  }
364
365
  const lastIdx = working.lastIndexOf(block.oldBlock);
365
366
  if (idx !== lastIdx) {
366
367
  return {
367
368
  ok: false,
368
- reason: `block matches multiple locations in clean base refusing to guess: "${snippet(block.oldBlock)}"`,
369
+ reason: `block matches multiple locations in clean base - refusing to guess: "${snippet(block.oldBlock)}"`,
369
370
  };
370
371
  }
371
372
  working =
372
- working.slice(0, idx) + block.newBlock + working.slice(idx + block.oldBlock.length);
373
+ working.slice(0, idx) +
374
+ block.newBlock +
375
+ working.slice(idx + block.oldBlock.length);
373
376
  }
374
377
  return { ok: true, result: working };
375
378
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "sela-core",
3
- "version": "1.0.7",
4
- "description": "AI self-healing Playwright wrapper drop-in replacement for @playwright/test",
3
+ "version": "1.0.8",
4
+ "description": "AI self-healing Playwright wrapper - drop-in replacement for @playwright/test",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
7
7
  "exports": {