deflake 1.2.36 → 1.2.37

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 (2) hide show
  1. package/cli.js +27 -0
  2. package/package.json +1 -1
package/cli.js CHANGED
@@ -216,7 +216,27 @@ async function analyzeAndFix(artifacts, client, argv, capturedOutput = '') {
216
216
  }
217
217
  console.log(`${C.BRIGHT}━━━ DeFlake Summary: ${count}/${artifacts.length} fix(es) applied ━━━${C.RESET}\n`);
218
218
  return count;
219
+ }
219
220
 
221
+ function checkBalance(code) {
222
+ const pairs = { '(': ')', '{': '}', '[': ']' };
223
+ const stack = [];
224
+ // Skip strings and comments for accuracy
225
+ let inString = false, stringChar = '', escaped = false;
226
+ for (const ch of code) {
227
+ if (escaped) { escaped = false; continue; }
228
+ if (ch === '\\') { escaped = true; continue; }
229
+ if (inString) { if (ch === stringChar) inString = false; continue; }
230
+ if (ch === '"' || ch === "'" || ch === '`') { inString = true; stringChar = ch; continue; }
231
+ if (pairs[ch]) stack.push(pairs[ch]);
232
+ else if (ch === ')' || ch === '}' || ch === ']') {
233
+ if (stack.length === 0 || stack.pop() !== ch) {
234
+ return { balanced: false, detail: `unexpected '${ch}'` };
235
+ }
236
+ }
237
+ }
238
+ if (stack.length > 0) return { balanced: false, detail: `unclosed '${stack[stack.length - 1] === ')' ? '(' : stack[stack.length - 1] === '}' ? '{' : '['}'` };
239
+ return { balanced: true, detail: 'ok' };
220
240
  }
221
241
 
222
242
  async function applyFix(res, loc) {
@@ -270,6 +290,13 @@ async function applyFix(res, loc) {
270
290
  }
271
291
  }
272
292
  if (appliedCount > 0) {
293
+ // SAFETY: Bracket balance check — rollback if patches broke syntax
294
+ const originalBalance = checkBalance(original);
295
+ const patchedBalance = checkBalance(content);
296
+ if (originalBalance.balanced && !patchedBalance.balanced) {
297
+ console.log(` ${C.YELLOW}⏭️ Rollback: patches broke bracket balance (${patchedBalance.detail}). Reverting file.${C.RESET}`);
298
+ return false;
299
+ }
273
300
  fs.writeFileSync(loc.path, content);
274
301
  return true;
275
302
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "deflake",
3
- "version": "1.2.36",
3
+ "version": "1.2.37",
4
4
  "description": "AI-powered self-healing tool for Playwright, Cypress, and WebdriverIO tests.",
5
5
  "main": "client.js",
6
6
  "bin": {