antigravity-autopilot 1.4.4 → 1.4.6
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.
- package/{AutoAccept.ps1 → AutoPilot.ps1} +1 -1
- package/README.md +1 -1
- package/cli.js +220 -52
- package/extension.js +25 -25
- package/package.json +15 -15
- package/patcher.js +21 -21
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Antigravity Auto-Accept - Floating Panel
|
|
2
2
|
# A small always-on-top window for toggling auto-accept
|
|
3
|
-
# Run with: powershell -WindowStyle Hidden -File
|
|
3
|
+
# Run with: powershell -WindowStyle Hidden -File AutoPilot.ps1
|
|
4
4
|
|
|
5
5
|
Add-Type -AssemblyName System.Windows.Forms
|
|
6
6
|
Add-Type -AssemblyName System.Drawing
|
package/README.md
CHANGED
|
@@ -95,7 +95,7 @@ Built-in protection against destructive commands. **54+ preset patterns** coveri
|
|
|
95
95
|
Add your own patterns via Settings:
|
|
96
96
|
|
|
97
97
|
```json
|
|
98
|
-
"
|
|
98
|
+
"antigravityAutoPilot.dangerousCommandBlocking.customPatterns": [
|
|
99
99
|
"^my-dangerous-script",
|
|
100
100
|
"DROP TABLE"
|
|
101
101
|
]
|
package/cli.js
CHANGED
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
* Antigravity AutoPilot — CLI v1.
|
|
4
|
+
* Antigravity AutoPilot — CLI v1.4.0
|
|
5
5
|
* ====================================
|
|
6
|
-
* npx antigravity-autopilot
|
|
7
|
-
* npx antigravity-autopilot --
|
|
8
|
-
* npx antigravity-autopilot --
|
|
9
|
-
* npx antigravity-autopilot --
|
|
6
|
+
* npx antigravity-autopilot Apply all patches
|
|
7
|
+
* npx antigravity-autopilot --only terminal Patch terminal only
|
|
8
|
+
* npx antigravity-autopilot --only browser Patch browser only
|
|
9
|
+
* npx antigravity-autopilot --only file Patch file only
|
|
10
|
+
* npx antigravity-autopilot --check Check status
|
|
11
|
+
* npx antigravity-autopilot --revert Restore originals
|
|
12
|
+
* npx antigravity-autopilot --help Show help
|
|
10
13
|
*/
|
|
11
14
|
|
|
12
15
|
'use strict';
|
|
@@ -71,7 +74,8 @@ function printBanner() {
|
|
|
71
74
|
|
|
72
75
|
function printHelp() {
|
|
73
76
|
const cmds = [
|
|
74
|
-
['(no args)', 'Apply
|
|
77
|
+
['(no args)', 'Apply all patches (terminal, browser, file)'],
|
|
78
|
+
['--only TYPE', 'Patch only: terminal | browser | file'],
|
|
75
79
|
['--check', 'Check current patch status'],
|
|
76
80
|
['--revert', 'Restore original files'],
|
|
77
81
|
['--help', 'Show this help screen'],
|
|
@@ -82,9 +86,15 @@ function printHelp() {
|
|
|
82
86
|
console.log(c.bold + c.white + ' OPTIONS' + c.reset);
|
|
83
87
|
console.log(c.gray + ' ─────────────────────────────────────────────' + c.reset);
|
|
84
88
|
for (const [flag, desc] of cmds) {
|
|
85
|
-
console.log(' ' + c.yellow + c.bold + flag.padEnd(
|
|
89
|
+
console.log(' ' + c.yellow + c.bold + flag.padEnd(14) + c.reset + ' ' + c.white + desc + c.reset);
|
|
86
90
|
}
|
|
87
91
|
console.log('');
|
|
92
|
+
console.log(c.bold + c.white + ' PATCH TYPES' + c.reset);
|
|
93
|
+
console.log(c.gray + ' ─────────────────────────────────────────────' + c.reset);
|
|
94
|
+
console.log(' ' + c.cyan + 'terminal' + c.reset + ' Auto-execute terminal commands');
|
|
95
|
+
console.log(' ' + c.cyan + 'browser' + c.reset + ' Auto-confirm browser actions');
|
|
96
|
+
console.log(' ' + c.cyan + 'file' + c.reset + ' Auto-allow file permissions');
|
|
97
|
+
console.log('');
|
|
88
98
|
console.log(c.bold + c.white + ' WORKFLOW' + c.reset);
|
|
89
99
|
console.log(c.gray + ' ─────────────────────────────────────────────' + c.reset);
|
|
90
100
|
console.log(' ' + c.green + '1.' + c.reset + ' Run ' + c.cyan + 'npx antigravity-autopilot' + c.reset + ' → patch applied');
|
|
@@ -185,12 +195,12 @@ function getVersion(basePath) {
|
|
|
185
195
|
} catch { return 'unknown'; }
|
|
186
196
|
}
|
|
187
197
|
|
|
188
|
-
// ───
|
|
198
|
+
// ─── Analyze: Terminal Auto-Execute ───────────────────────────────────────────
|
|
189
199
|
|
|
190
|
-
function
|
|
200
|
+
function analyzeTerminal(content) {
|
|
191
201
|
const onChangeRe = /(\w+)=(\w+)\((\w+)=>\{\w+\?\.setTerminalAutoExecutionPolicy\?\.\(\3\),\3===(\w+)\.EAGER\&\&(\w+)\(!0\)\},\[[\w,]*\]\)/;
|
|
192
202
|
const onChangeMatch = content.match(onChangeRe);
|
|
193
|
-
if (!onChangeMatch)
|
|
203
|
+
if (!onChangeMatch) return null;
|
|
194
204
|
|
|
195
205
|
const [fullMatch, , callbackAlias, , enumAlias, confirmFn] = onChangeMatch;
|
|
196
206
|
const matchIndex = content.indexOf(fullMatch);
|
|
@@ -235,50 +245,183 @@ function analyzeFile(content, label) {
|
|
|
235
245
|
};
|
|
236
246
|
}
|
|
237
247
|
|
|
238
|
-
// ───
|
|
248
|
+
// ─── Analyze: Browser Action Auto-Confirm ─────────────────────────────────────
|
|
249
|
+
|
|
250
|
+
function analyzeBrowser(content) {
|
|
251
|
+
// Find the browserAction confirm:!0 callback pattern
|
|
252
|
+
const confirmRe = /(\w+)=Mt\(\(\)=>\{(\w+)\(Ui\((\w+),\{trajectoryId:(\w+),stepIndex:(\w+),interaction:\{case:"browserAction",value:Ui\((\w+),\{confirm:!0\}\)\}\}\)\)\},\[([\w,]*)\]\)/;
|
|
253
|
+
const confirmMatch = content.match(confirmRe);
|
|
254
|
+
if (!confirmMatch) return null;
|
|
255
|
+
|
|
256
|
+
const [fullMatch, confirmVar] = confirmMatch;
|
|
257
|
+
const matchIndex = content.indexOf(fullMatch);
|
|
258
|
+
|
|
259
|
+
// Find useEffect alias
|
|
260
|
+
const nearbyCode = content.substring(Math.max(0, matchIndex - 5000), matchIndex + 5000);
|
|
261
|
+
const effectCandidates = {};
|
|
262
|
+
const effectRe = /\b(\w{2,3})\(\(\)=>\{[^}]{3,80}\},\[/g;
|
|
263
|
+
let m;
|
|
264
|
+
while ((m = effectRe.exec(nearbyCode)) !== null) {
|
|
265
|
+
const alias = m[1];
|
|
266
|
+
if (alias !== 'Mt' && alias !== 'Vi' && alias !== 'var' && alias !== 'new') {
|
|
267
|
+
effectCandidates[alias] = (effectCandidates[alias] || 0) + 1;
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
const cleanupRe = /\b(\w{2,3})\(\(\)=>\{[^}]*return\s*\(\)=>/g;
|
|
271
|
+
while ((m = cleanupRe.exec(content)) !== null) {
|
|
272
|
+
const alias = m[1];
|
|
273
|
+
if (alias !== 'Mt' && alias !== 'Vi') {
|
|
274
|
+
effectCandidates[alias] = (effectCandidates[alias] || 0) + 5;
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
let useEffectAlias = null, maxCount = 0;
|
|
278
|
+
for (const [alias, count] of Object.entries(effectCandidates)) {
|
|
279
|
+
if (count > maxCount) { maxCount = count; useEffectAlias = alias; }
|
|
280
|
+
}
|
|
281
|
+
if (!useEffectAlias) return null;
|
|
239
282
|
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
283
|
+
const patchCode = `_abp=${useEffectAlias}(()=>{${confirmVar}()},[${confirmVar}]),`;
|
|
284
|
+
return {
|
|
285
|
+
target: fullMatch,
|
|
286
|
+
replacement: patchCode + fullMatch,
|
|
287
|
+
patchMarker: `_abp=${useEffectAlias}(()=>{${confirmVar}()}`,
|
|
288
|
+
};
|
|
244
289
|
}
|
|
245
290
|
|
|
291
|
+
// ─── Analyze: File Permission Auto-Allow ──────────────────────────────────────
|
|
292
|
+
|
|
293
|
+
function analyzeFile_(content) {
|
|
294
|
+
// Find the filePermission sender pattern
|
|
295
|
+
const senderRe = /(\w+)=\((\w+),(\w+)\)=>\{(\w+)\(Ui\((\w+),\{trajectoryId:(\w+),stepIndex:(\w+),interaction:\{case:"filePermission",value:Ui\((\w+),\{allow:\2,scope:\3,absolutePathUri:(\w+)\.absolutePathUri\}\)\}\}\)\)\}/;
|
|
296
|
+
const senderMatch = content.match(senderRe);
|
|
297
|
+
if (!senderMatch) return null;
|
|
298
|
+
|
|
299
|
+
const [fullMatch, senderVar, , , , , , , , reqVar] = senderMatch;
|
|
300
|
+
const matchIndex = content.indexOf(fullMatch);
|
|
301
|
+
|
|
302
|
+
// Find scope enum — look for senderVar(!0, ENUM.CONVERSATION)
|
|
303
|
+
const scopeRe = new RegExp(`${senderVar.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}\\(!0,(\\w+)\\.CONVERSATION\\)`);
|
|
304
|
+
const scopeMatch = content.substring(matchIndex, matchIndex + 2000).match(scopeRe);
|
|
305
|
+
if (!scopeMatch) return null;
|
|
306
|
+
const scopeEnum = scopeMatch[1];
|
|
307
|
+
|
|
308
|
+
// Find useEffect alias
|
|
309
|
+
const nearbyCode = content.substring(Math.max(0, matchIndex - 5000), matchIndex + 5000);
|
|
310
|
+
const effectCandidates = {};
|
|
311
|
+
const effectRe = /\b(\w{2,3})\(\(\)=>\{[^}]{3,80}\},\[/g;
|
|
312
|
+
let m2;
|
|
313
|
+
while ((m2 = effectRe.exec(nearbyCode)) !== null) {
|
|
314
|
+
const alias = m2[1];
|
|
315
|
+
if (alias !== 'Mt' && alias !== 'Vi' && alias !== 'var' && alias !== 'new') {
|
|
316
|
+
effectCandidates[alias] = (effectCandidates[alias] || 0) + 1;
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
const cleanupRe = /\b(\w{2,3})\(\(\)=>\{[^}]*return\s*\(\)=>/g;
|
|
320
|
+
while ((m2 = cleanupRe.exec(content)) !== null) {
|
|
321
|
+
const alias = m2[1];
|
|
322
|
+
if (alias !== 'Mt' && alias !== 'Vi') {
|
|
323
|
+
effectCandidates[alias] = (effectCandidates[alias] || 0) + 5;
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
let useEffectAlias = null, maxCount = 0;
|
|
327
|
+
for (const [alias, count] of Object.entries(effectCandidates)) {
|
|
328
|
+
if (count > maxCount) { maxCount = count; useEffectAlias = alias; }
|
|
329
|
+
}
|
|
330
|
+
if (!useEffectAlias) return null;
|
|
331
|
+
|
|
332
|
+
const patchCode = `_afp=${useEffectAlias}(()=>{${senderVar}(!0,${scopeEnum}.CONVERSATION)},[${senderVar}]),`;
|
|
333
|
+
return {
|
|
334
|
+
target: fullMatch,
|
|
335
|
+
replacement: patchCode + fullMatch,
|
|
336
|
+
patchMarker: `_afp=${useEffectAlias}(()=>{${senderVar}(!0,${scopeEnum}.CONVERSATION)`,
|
|
337
|
+
};
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
// ─── Patch Status Detection ───────────────────────────────────────────────────
|
|
341
|
+
|
|
342
|
+
const PATCH_TYPES = ['terminal', 'browser', 'file'];
|
|
343
|
+
const PATCH_LABELS = { terminal: 'Terminal auto-execute', browser: 'Browser auto-confirm', file: 'File auto-allow' };
|
|
344
|
+
const PATCH_MARKERS = {
|
|
345
|
+
terminal: { includes: '_aep=', re: /_aep=\w+\(\(\)=>\{[^}]+EAGER/ },
|
|
346
|
+
browser: { includes: '_abp=', re: /_abp=\w+\(\(\)=>\{\w+\(\)\}/ },
|
|
347
|
+
file: { includes: '_afp=', re: /_afp=\w+\(\(\)=>\{\w+\(!0,/ },
|
|
348
|
+
};
|
|
349
|
+
const ANALYZERS = {
|
|
350
|
+
terminal: analyzeTerminal,
|
|
351
|
+
browser: analyzeBrowser,
|
|
352
|
+
file: analyzeFile_,
|
|
353
|
+
};
|
|
354
|
+
|
|
355
|
+
function getPatchStatus(content) {
|
|
356
|
+
const status = {};
|
|
357
|
+
for (const type of PATCH_TYPES) {
|
|
358
|
+
const m = PATCH_MARKERS[type];
|
|
359
|
+
status[type] = content.includes(m.includes) && m.re.test(content);
|
|
360
|
+
}
|
|
361
|
+
return status;
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
// ─── Display Helpers ──────────────────────────────────────────────────────────
|
|
365
|
+
|
|
246
366
|
function row(icon, color, label, msg) {
|
|
247
367
|
console.log(' ' + color + icon + c.reset + ' ' + c.bold + label.padEnd(14) + c.reset + c.gray + msg + c.reset);
|
|
248
368
|
}
|
|
249
369
|
|
|
250
|
-
function
|
|
370
|
+
function patchRow(icon, color, fileLabel, patchType, msg) {
|
|
371
|
+
const combined = `[${fileLabel}]`;
|
|
372
|
+
console.log(' ' + color + icon + c.reset + ' ' + c.bold + combined.padEnd(16) + c.reset + c.cyan + patchType.padEnd(10) + c.reset + c.gray + msg + c.reset);
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
// ─── File Operations ──────────────────────────────────────────────────────────
|
|
376
|
+
|
|
377
|
+
function patchFile(filePath, label, onlyTypes) {
|
|
251
378
|
if (!fs.existsSync(filePath)) {
|
|
252
379
|
row('⊘', c.gray, `[${label}]`, 'File not found — skipping');
|
|
253
380
|
return true;
|
|
254
381
|
}
|
|
382
|
+
|
|
255
383
|
const content = fs.readFileSync(filePath, 'utf8');
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
return true;
|
|
259
|
-
}
|
|
260
|
-
const analysis = analyzeFile(content, label);
|
|
261
|
-
if (!analysis) {
|
|
262
|
-
row('✖', c.red, `[${label}]`, 'Pattern not found — may be incompatible version');
|
|
263
|
-
return false;
|
|
264
|
-
}
|
|
384
|
+
const status = getPatchStatus(content);
|
|
385
|
+
const typesToPatch = onlyTypes || PATCH_TYPES;
|
|
265
386
|
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
387
|
+
let patched = content;
|
|
388
|
+
let anyNewPatch = false;
|
|
389
|
+
let anyFailure = false;
|
|
390
|
+
|
|
391
|
+
for (const type of typesToPatch) {
|
|
392
|
+
if (status[type]) {
|
|
393
|
+
patchRow('✔', c.green, label, type, 'Already patched — skipped');
|
|
394
|
+
continue;
|
|
395
|
+
}
|
|
396
|
+
const analysis = ANALYZERS[type](patched);
|
|
397
|
+
if (!analysis) {
|
|
398
|
+
patchRow('⊘', c.yellow, label, type, 'Pattern not found — may be incompatible');
|
|
399
|
+
// Not a hard failure — the pattern might not exist in this file
|
|
400
|
+
continue;
|
|
401
|
+
}
|
|
402
|
+
const count = patched.split(analysis.target).length - 1;
|
|
403
|
+
if (count !== 1) {
|
|
404
|
+
patchRow('✖', c.red, label, type, `Target found ${count}× (expected 1)`);
|
|
405
|
+
anyFailure = true;
|
|
406
|
+
continue;
|
|
407
|
+
}
|
|
408
|
+
patched = patched.replace(analysis.target, analysis.replacement);
|
|
409
|
+
anyNewPatch = true;
|
|
410
|
+
patchRow('✔', c.green, label, type, 'Patched successfully');
|
|
270
411
|
}
|
|
271
412
|
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
413
|
+
if (anyNewPatch) {
|
|
414
|
+
// Backup original (before any patching)
|
|
415
|
+
const bak = filePath + '.bak';
|
|
416
|
+
if (!fs.existsSync(bak)) {
|
|
417
|
+
fs.copyFileSync(filePath, filePath + '.bak');
|
|
418
|
+
}
|
|
419
|
+
fs.writeFileSync(filePath, patched, 'utf8');
|
|
420
|
+
const diff = fs.statSync(filePath).size - fs.statSync(filePath + '.bak').size;
|
|
421
|
+
row('◈', c.blue, `[${label}]`, `Written (+${diff} bytes)`);
|
|
276
422
|
}
|
|
277
423
|
|
|
278
|
-
|
|
279
|
-
const diff = fs.statSync(filePath).size - fs.statSync(bak).size;
|
|
280
|
-
row('✔', c.green, `[${label}]`, `Patched successfully (+${diff} bytes)`);
|
|
281
|
-
return true;
|
|
424
|
+
return !anyFailure;
|
|
282
425
|
}
|
|
283
426
|
|
|
284
427
|
function revertFile(filePath, label) {
|
|
@@ -293,22 +436,28 @@ function revertFile(filePath, label) {
|
|
|
293
436
|
|
|
294
437
|
function checkFile(filePath, label) {
|
|
295
438
|
if (!fs.existsSync(filePath)) {
|
|
296
|
-
row('
|
|
439
|
+
row('⊘', c.gray, `[${label}]`, 'File not found');
|
|
297
440
|
return false;
|
|
298
441
|
}
|
|
299
442
|
const content = fs.readFileSync(filePath, 'utf8');
|
|
300
|
-
const
|
|
443
|
+
const status = getPatchStatus(content);
|
|
301
444
|
const hasBak = fs.existsSync(filePath + '.bak');
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
445
|
+
let allPatched = true;
|
|
446
|
+
|
|
447
|
+
for (const type of PATCH_TYPES) {
|
|
448
|
+
if (status[type]) {
|
|
449
|
+
patchRow('✔', c.green, label, type, 'PATCHED' + (hasBak ? ' · backup exists' : ''));
|
|
450
|
+
} else {
|
|
451
|
+
const analysis = ANALYZERS[type](content);
|
|
452
|
+
if (analysis) {
|
|
453
|
+
patchRow('○', c.yellow, label, type, 'NOT PATCHED · patchable');
|
|
454
|
+
} else {
|
|
455
|
+
patchRow('⊘', c.gray, label, type, 'NOT PATCHED · pattern not found');
|
|
456
|
+
}
|
|
457
|
+
allPatched = false;
|
|
458
|
+
}
|
|
310
459
|
}
|
|
311
|
-
return
|
|
460
|
+
return allPatched;
|
|
312
461
|
}
|
|
313
462
|
|
|
314
463
|
// ─── Main ─────────────────────────────────────────────────────────────────────
|
|
@@ -320,6 +469,18 @@ function main() {
|
|
|
320
469
|
: args.includes('--help') ? 'help'
|
|
321
470
|
: 'apply';
|
|
322
471
|
|
|
472
|
+
// Parse --only flag
|
|
473
|
+
let onlyTypes = null;
|
|
474
|
+
const onlyIdx = args.indexOf('--only');
|
|
475
|
+
if (onlyIdx !== -1 && args[onlyIdx + 1]) {
|
|
476
|
+
const requested = args[onlyIdx + 1].toLowerCase();
|
|
477
|
+
if (!PATCH_TYPES.includes(requested)) {
|
|
478
|
+
console.error(`Unknown patch type: ${requested}. Valid types: ${PATCH_TYPES.join(', ')}`);
|
|
479
|
+
process.exit(1);
|
|
480
|
+
}
|
|
481
|
+
onlyTypes = [requested];
|
|
482
|
+
}
|
|
483
|
+
|
|
323
484
|
printBanner();
|
|
324
485
|
|
|
325
486
|
if (action === 'help') { printHelp(); return; }
|
|
@@ -346,7 +507,12 @@ function main() {
|
|
|
346
507
|
console.log('');
|
|
347
508
|
files.forEach(f => checkFile(f.filePath, f.label));
|
|
348
509
|
console.log('');
|
|
349
|
-
const allPatched = files.every(f =>
|
|
510
|
+
const allPatched = files.every(f => {
|
|
511
|
+
if (!fs.existsSync(f.filePath)) return true;
|
|
512
|
+
const content = fs.readFileSync(f.filePath, 'utf8');
|
|
513
|
+
const s = getPatchStatus(content);
|
|
514
|
+
return s.terminal && s.browser && s.file;
|
|
515
|
+
});
|
|
350
516
|
if (allPatched) {
|
|
351
517
|
console.log(' ' + c.green + c.bold + '✔ AutoPilot is ACTIVE on this machine.' + c.reset);
|
|
352
518
|
console.log(' ' + c.gray + 'Restart Antigravity for changes to take effect.' + c.reset);
|
|
@@ -369,9 +535,10 @@ function main() {
|
|
|
369
535
|
|
|
370
536
|
case 'apply':
|
|
371
537
|
default: {
|
|
372
|
-
|
|
538
|
+
const typeLabel = onlyTypes ? onlyTypes.join(', ') : 'all';
|
|
539
|
+
section(`Applying AutoPilot Patch (${typeLabel})`, '⚡');
|
|
373
540
|
console.log('');
|
|
374
|
-
const ok = files.every(f => patchFile(f.filePath, f.label));
|
|
541
|
+
const ok = files.every(f => patchFile(f.filePath, f.label, onlyTypes));
|
|
375
542
|
console.log('');
|
|
376
543
|
if (ok) {
|
|
377
544
|
console.log(' +' + repeat('-', W - 2) + '+');
|
|
@@ -379,10 +546,11 @@ function main() {
|
|
|
379
546
|
console.log(' |' + pad(c.white + ' Restart Antigravity to activate AutoPilot.' + c.reset, W - 2) + '|');
|
|
380
547
|
console.log(' |' + repeat(' ', W - 2) + '|');
|
|
381
548
|
console.log(' |' + pad(c.gray + ' TIP Run with --revert to undo at any time.' + c.reset, W - 2) + '|');
|
|
549
|
+
console.log(' |' + pad(c.gray + ' TIP Run with --check to see patch status.' + c.reset, W - 2) + '|');
|
|
382
550
|
console.log(' |' + pad(c.gray + ' NOTE Re-run this command after Antigravity updates.' + c.reset, W - 2) + '|');
|
|
383
551
|
console.log(' +' + repeat('-', W - 2) + '+');
|
|
384
552
|
} else {
|
|
385
|
-
console.log(' ' + c.red + c.bold + '✖ Some
|
|
553
|
+
console.log(' ' + c.red + c.bold + '✖ Some patches could not be applied.' + c.reset);
|
|
386
554
|
console.log(' ' + c.gray + 'Check output above for details.' + c.reset);
|
|
387
555
|
process.exit(1);
|
|
388
556
|
}
|
package/extension.js
CHANGED
|
@@ -112,7 +112,7 @@ function getActiveBuiltinPatterns() {
|
|
|
112
112
|
* @returns {{ matched: boolean, label: string, pattern: string }}
|
|
113
113
|
*/
|
|
114
114
|
function checkDangerousCommand(cmd) {
|
|
115
|
-
const cfg = vscode.workspace.getConfiguration('
|
|
115
|
+
const cfg = vscode.workspace.getConfiguration('antigravityAutoPilot');
|
|
116
116
|
const enabled = cfg.get('dangerousCommandBlocking.enabled', true);
|
|
117
117
|
if (!enabled) return { matched: false, label: '', pattern: '' };
|
|
118
118
|
|
|
@@ -149,7 +149,7 @@ function checkDangerousCommand(cmd) {
|
|
|
149
149
|
* @param {string} label - Human-readable reason
|
|
150
150
|
*/
|
|
151
151
|
function handleDangerousCommand(cmd, label) {
|
|
152
|
-
const cfg = vscode.workspace.getConfiguration('
|
|
152
|
+
const cfg = vscode.workspace.getConfiguration('antigravityAutoPilot');
|
|
153
153
|
const action = cfg.get('dangerousCommandBlocking.action', 'block');
|
|
154
154
|
const msg = `🛡️ Dangerous command detected: "${label}" — \`${cmd.trim().substring(0, 80)}\``;
|
|
155
155
|
|
|
@@ -326,16 +326,16 @@ class AntigravityPanelProvider {
|
|
|
326
326
|
} else if (msg.command === 'toggleEnabled') {
|
|
327
327
|
autoPilotEnabled = !autoPilotEnabled;
|
|
328
328
|
updateStatusBarFromCache();
|
|
329
|
-
const cfg = vscode.workspace.getConfiguration('
|
|
329
|
+
const cfg = vscode.workspace.getConfiguration('antigravityAutoPilot');
|
|
330
330
|
await cfg.update('enabledOnStartup', autoPilotEnabled, vscode.ConfigurationTarget.Global);
|
|
331
331
|
if (panelProvider) panelProvider.sendEnabled(autoPilotEnabled);
|
|
332
332
|
vscode.window.showInformationMessage(
|
|
333
333
|
autoPilotEnabled ? '⚡ AutoPilot resumed' : '⏸ AutoPilot suspended',
|
|
334
334
|
);
|
|
335
335
|
} else if (msg.command === 'openSettings') {
|
|
336
|
-
vscode.commands.executeCommand('workbench.action.openSettings', '
|
|
336
|
+
vscode.commands.executeCommand('workbench.action.openSettings', 'antigravityAutoPilot');
|
|
337
337
|
} else if (msg.command === 'toggleCommandBlocking') {
|
|
338
|
-
const cfg = vscode.workspace.getConfiguration('
|
|
338
|
+
const cfg = vscode.workspace.getConfiguration('antigravityAutoPilot');
|
|
339
339
|
const current = cfg.get('dangerousCommandBlocking.enabled', true);
|
|
340
340
|
const next = !current;
|
|
341
341
|
await cfg.update('dangerousCommandBlocking.enabled', next, vscode.ConfigurationTarget.Global);
|
|
@@ -344,19 +344,19 @@ class AntigravityPanelProvider {
|
|
|
344
344
|
next ? '🛡️ Command Blocking enabled' : '⚠️ Command Blocking disabled',
|
|
345
345
|
);
|
|
346
346
|
} else if (msg.command === 'toggleBrowserPermission') {
|
|
347
|
-
const cfg = vscode.workspace.getConfiguration('
|
|
348
|
-
const current = cfg.get('
|
|
347
|
+
const cfg = vscode.workspace.getConfiguration('antigravityAutoPilot');
|
|
348
|
+
const current = cfg.get('browserPermission', true);
|
|
349
349
|
const next = !current;
|
|
350
|
-
await cfg.update('
|
|
350
|
+
await cfg.update('browserPermission', next, vscode.ConfigurationTarget.Global);
|
|
351
351
|
this.sendBrowserPermissionEnabled(next);
|
|
352
352
|
vscode.window.showInformationMessage(
|
|
353
353
|
next ? '🌐 Auto-accept browser permission enabled' : '🌐 Auto-accept browser permission disabled',
|
|
354
354
|
);
|
|
355
355
|
} else if (msg.command === 'toggleFilePermission') {
|
|
356
|
-
const cfg = vscode.workspace.getConfiguration('
|
|
357
|
-
const current = cfg.get('
|
|
356
|
+
const cfg = vscode.workspace.getConfiguration('antigravityAutoPilot');
|
|
357
|
+
const current = cfg.get('filePermission', true);
|
|
358
358
|
const next = !current;
|
|
359
|
-
await cfg.update('
|
|
359
|
+
await cfg.update('filePermission', next, vscode.ConfigurationTarget.Global);
|
|
360
360
|
this.sendFilePermissionEnabled(next);
|
|
361
361
|
vscode.window.showInformationMessage(
|
|
362
362
|
next ? '📁 Auto-accept file permission enabled' : '📁 Auto-accept file permission disabled',
|
|
@@ -380,13 +380,13 @@ class AntigravityPanelProvider {
|
|
|
380
380
|
refreshStatus();
|
|
381
381
|
this.sendEnabled(autoPilotEnabled);
|
|
382
382
|
this.sendBlockingEnabled(
|
|
383
|
-
vscode.workspace.getConfiguration('
|
|
383
|
+
vscode.workspace.getConfiguration('antigravityAutoPilot').get('dangerousCommandBlocking.enabled', true),
|
|
384
384
|
);
|
|
385
385
|
this.sendBrowserPermissionEnabled(
|
|
386
|
-
vscode.workspace.getConfiguration('
|
|
386
|
+
vscode.workspace.getConfiguration('antigravityAutoPilot').get('browserPermission', true),
|
|
387
387
|
);
|
|
388
388
|
this.sendFilePermissionEnabled(
|
|
389
|
-
vscode.workspace.getConfiguration('
|
|
389
|
+
vscode.workspace.getConfiguration('antigravityAutoPilot').get('filePermission', true),
|
|
390
390
|
);
|
|
391
391
|
this.sendPatterns();
|
|
392
392
|
}
|
|
@@ -894,12 +894,12 @@ function activate(context) {
|
|
|
894
894
|
context.subscriptions.push(outputChannel);
|
|
895
895
|
|
|
896
896
|
// Read enabledOnStartup setting
|
|
897
|
-
const cfg = vscode.workspace.getConfiguration('
|
|
897
|
+
const cfg = vscode.workspace.getConfiguration('antigravityAutoPilot');
|
|
898
898
|
autoPilotEnabled = cfg.get('enabledOnStartup', true);
|
|
899
899
|
|
|
900
900
|
// Status bar
|
|
901
901
|
statusBarItem = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Right, 100);
|
|
902
|
-
statusBarItem.command = '
|
|
902
|
+
statusBarItem.command = 'antigravityAutoPilot.openPanel';
|
|
903
903
|
statusBarItem.text = `$(sync~spin) AG Patch`;
|
|
904
904
|
statusBarItem.tooltip = 'Checking patch status...';
|
|
905
905
|
statusBarItem.show();
|
|
@@ -909,7 +909,7 @@ function activate(context) {
|
|
|
909
909
|
panelProvider = new AntigravityPanelProvider(context);
|
|
910
910
|
context.subscriptions.push(
|
|
911
911
|
vscode.window.registerWebviewViewProvider(
|
|
912
|
-
'
|
|
912
|
+
'antigravityAutoPilot.panel',
|
|
913
913
|
panelProvider,
|
|
914
914
|
{ webviewOptions: { retainContextWhenHidden: true } },
|
|
915
915
|
),
|
|
@@ -932,8 +932,8 @@ function activate(context) {
|
|
|
932
932
|
// Config change listener
|
|
933
933
|
context.subscriptions.push(
|
|
934
934
|
vscode.workspace.onDidChangeConfiguration((e) => {
|
|
935
|
-
if (e.affectsConfiguration('
|
|
936
|
-
autoPilotEnabled = vscode.workspace.getConfiguration('
|
|
935
|
+
if (e.affectsConfiguration('antigravityAutoPilot.enabledOnStartup')) {
|
|
936
|
+
autoPilotEnabled = vscode.workspace.getConfiguration('antigravityAutoPilot').get('enabledOnStartup', true);
|
|
937
937
|
updateStatusBarFromCache();
|
|
938
938
|
if (panelProvider) panelProvider.sendEnabled(autoPilotEnabled);
|
|
939
939
|
}
|
|
@@ -942,18 +942,18 @@ function activate(context) {
|
|
|
942
942
|
|
|
943
943
|
// Commands
|
|
944
944
|
context.subscriptions.push(
|
|
945
|
-
vscode.commands.registerCommand('
|
|
945
|
+
vscode.commands.registerCommand('antigravityAutoPilot.applyPatch', async () => {
|
|
946
946
|
const result = await applyPatch();
|
|
947
947
|
vscode.window.showInformationMessage(result.message);
|
|
948
948
|
}),
|
|
949
|
-
vscode.commands.registerCommand('
|
|
949
|
+
vscode.commands.registerCommand('antigravityAutoPilot.revertPatch', async () => {
|
|
950
950
|
const result = await revertPatch();
|
|
951
951
|
vscode.window.showInformationMessage(result.message);
|
|
952
952
|
}),
|
|
953
|
-
vscode.commands.registerCommand('
|
|
954
|
-
vscode.commands.executeCommand('
|
|
953
|
+
vscode.commands.registerCommand('antigravityAutoPilot.openPanel', () => {
|
|
954
|
+
vscode.commands.executeCommand('antigravityAutoPilot.panel.focus');
|
|
955
955
|
}),
|
|
956
|
-
vscode.commands.registerCommand('
|
|
956
|
+
vscode.commands.registerCommand('antigravityAutoPilot.checkStatus', async () => {
|
|
957
957
|
const status = await getPatchStatus();
|
|
958
958
|
if (!status.basePath) {
|
|
959
959
|
vscode.window.showWarningMessage('Antigravity not found!');
|
|
@@ -975,7 +975,7 @@ function activate(context) {
|
|
|
975
975
|
panelProvider.sendEnabled(autoPilotEnabled);
|
|
976
976
|
}
|
|
977
977
|
|
|
978
|
-
const startCfg = vscode.workspace.getConfiguration('
|
|
978
|
+
const startCfg = vscode.workspace.getConfiguration('antigravityAutoPilot');
|
|
979
979
|
if (startCfg.get('applyOnStartup') && !status.patched && status.basePath) {
|
|
980
980
|
const result = await applyPatch();
|
|
981
981
|
if (result.success) {
|
package/package.json
CHANGED
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
"name": "antigravity-autopilot",
|
|
3
3
|
"displayName": "Antigravity AutoPilot",
|
|
4
4
|
"description": "Enables autopilot mode for Antigravity: automatically executes all tool calls and terminal commands without manual confirmation. Patches the runtime JS bundle to inject auto-accept logic whenever the 'Always Proceed' policy is active — regex-based and version-agnostic.",
|
|
5
|
-
"version": "1.4.
|
|
5
|
+
"version": "1.4.6",
|
|
6
6
|
"license": "MIT",
|
|
7
|
-
"publisher": "
|
|
7
|
+
"publisher": "nguyenhx2",
|
|
8
8
|
"bin": {
|
|
9
9
|
"antigravity-autopilot": "./cli.js"
|
|
10
10
|
},
|
|
@@ -37,57 +37,57 @@
|
|
|
37
37
|
"antigravity-autopilot": [
|
|
38
38
|
{
|
|
39
39
|
"type": "webview",
|
|
40
|
-
"id": "
|
|
40
|
+
"id": "antigravityAutoPilot.panel",
|
|
41
41
|
"name": "AutoPilot"
|
|
42
42
|
}
|
|
43
43
|
]
|
|
44
44
|
},
|
|
45
45
|
"commands": [
|
|
46
46
|
{
|
|
47
|
-
"command": "
|
|
47
|
+
"command": "antigravityAutoPilot.applyPatch",
|
|
48
48
|
"title": "Antigravity: Apply AutoPilot Patch",
|
|
49
49
|
"icon": "$(zap)"
|
|
50
50
|
},
|
|
51
51
|
{
|
|
52
|
-
"command": "
|
|
52
|
+
"command": "antigravityAutoPilot.revertPatch",
|
|
53
53
|
"title": "Antigravity: Revert AutoPilot Patch",
|
|
54
54
|
"icon": "$(discard)"
|
|
55
55
|
},
|
|
56
56
|
{
|
|
57
|
-
"command": "
|
|
57
|
+
"command": "antigravityAutoPilot.checkStatus",
|
|
58
58
|
"title": "Antigravity: Check Patch Status",
|
|
59
59
|
"icon": "$(info)"
|
|
60
60
|
},
|
|
61
61
|
{
|
|
62
|
-
"command": "
|
|
62
|
+
"command": "antigravityAutoPilot.openPanel",
|
|
63
63
|
"title": "Antigravity: Open AutoPilot Panel"
|
|
64
64
|
}
|
|
65
65
|
],
|
|
66
66
|
"keybindings": [
|
|
67
67
|
{
|
|
68
|
-
"command": "
|
|
68
|
+
"command": "antigravityAutoPilot.applyPatch",
|
|
69
69
|
"key": "ctrl+shift+f12"
|
|
70
70
|
}
|
|
71
71
|
],
|
|
72
72
|
"configuration": {
|
|
73
73
|
"title": "Antigravity AutoPilot",
|
|
74
74
|
"properties": {
|
|
75
|
-
"
|
|
75
|
+
"antigravityAutoPilot.applyOnStartup": {
|
|
76
76
|
"type": "boolean",
|
|
77
77
|
"default": false,
|
|
78
78
|
"description": "Automatically apply the AutoPilot patch when VS Code starts. Safe to enable — patch is idempotent."
|
|
79
79
|
},
|
|
80
|
-
"
|
|
80
|
+
"antigravityAutoPilot.enabledOnStartup": {
|
|
81
81
|
"type": "boolean",
|
|
82
82
|
"default": true,
|
|
83
83
|
"description": "Keep AutoPilot enabled (active) when VS Code starts. When disabled, AutoPilot will be suspended until manually turned on from the sidebar."
|
|
84
84
|
},
|
|
85
|
-
"
|
|
85
|
+
"antigravityAutoPilot.dangerousCommandBlocking.enabled": {
|
|
86
86
|
"type": "boolean",
|
|
87
87
|
"default": true,
|
|
88
88
|
"description": "Block dangerous terminal commands (e.g. rm -rf /, format C:) before they execute. Fully customizable via the blocklist setting."
|
|
89
89
|
},
|
|
90
|
-
"
|
|
90
|
+
"antigravityAutoPilot.dangerousCommandBlocking.action": {
|
|
91
91
|
"type": "string",
|
|
92
92
|
"enum": [
|
|
93
93
|
"block",
|
|
@@ -102,7 +102,7 @@
|
|
|
102
102
|
"default": "block",
|
|
103
103
|
"description": "Action to take when a dangerous command is detected."
|
|
104
104
|
},
|
|
105
|
-
"
|
|
105
|
+
"antigravityAutoPilot.dangerousCommandBlocking.customPatterns": {
|
|
106
106
|
"type": "array",
|
|
107
107
|
"items": {
|
|
108
108
|
"type": "string"
|
|
@@ -110,12 +110,12 @@
|
|
|
110
110
|
"default": [],
|
|
111
111
|
"description": "Additional regex patterns (JavaScript syntax) to treat as dangerous commands. Example: [\"^dd if=.*of=/dev/sd\", \"^shred\"]"
|
|
112
112
|
},
|
|
113
|
-
"
|
|
113
|
+
"antigravityAutoPilot.browserPermission": {
|
|
114
114
|
"type": "boolean",
|
|
115
115
|
"default": true,
|
|
116
116
|
"description": "Automatically accept browser action permissions (e.g. 'Agent needs permission to act on chromewebdata'). Requires patch to be applied."
|
|
117
117
|
},
|
|
118
|
-
"
|
|
118
|
+
"antigravityAutoPilot.filePermission": {
|
|
119
119
|
"type": "boolean",
|
|
120
120
|
"default": true,
|
|
121
121
|
"description": "Automatically allow file access permissions with conversation scope. Requires patch to be applied."
|
package/patcher.js
CHANGED
|
@@ -95,7 +95,7 @@ function getTargetFiles(basePath) {
|
|
|
95
95
|
* Port of: https://github.com/Kanezal/better-antigravity/blob/main/fixes/auto-run-fix/patch.js
|
|
96
96
|
*/
|
|
97
97
|
function analyzeFile(content, label) {
|
|
98
|
-
const log = (msg) => process.send({ type: 'log', msg: `[
|
|
98
|
+
const log = (msg) => process.send({ type: 'log', msg: `[AutoPilot] [${label}] ${msg}` });
|
|
99
99
|
|
|
100
100
|
// 1. Find the onChange handler: contains setTerminalAutoExecutionPolicy AND .EAGER
|
|
101
101
|
// Pattern: VARNAME=CALLBACK(ARG=>{...setTerminalAutoExecutionPolicy...,ARG===ENUM.EAGER&&CONFIRM(!0)},[...])
|
|
@@ -196,7 +196,7 @@ function analyzeFile(content, label) {
|
|
|
196
196
|
* Pattern: COMP=({sourceTrajectoryStepInfo:VAR,...,url:VAR})=>{...CONFIRM_FN=Mt(()=>{SEND(Ui(MSG,{...,interaction:{case:"browserAction",value:Ui(TYPE,{confirm:!0})}}))},...)...}
|
|
197
197
|
*/
|
|
198
198
|
function analyzeBrowserAction(content, label) {
|
|
199
|
-
const log = (msg) => process.send({ type: 'log', msg: `[
|
|
199
|
+
const log = (msg) => process.send({ type: 'log', msg: `[AutoPilot] [${label}] [browser] ${msg}` });
|
|
200
200
|
|
|
201
201
|
// 1. Find the browserAction confirm:!0 callback pattern
|
|
202
202
|
// VAR=Mt(()=>{SEND(Ui(MSG,{trajectoryId:VAR,stepIndex:VAR,interaction:{case:"browserAction",value:Ui(TYPE,{confirm:!0})}}))},DEPS)
|
|
@@ -267,7 +267,7 @@ function analyzeBrowserAction(content, label) {
|
|
|
267
267
|
* Pattern: COMP=({sourceTrajectoryStepInfo:VAR,req:VAR,status:VAR})=>{...SEND_FN...filePermission...scope...}
|
|
268
268
|
*/
|
|
269
269
|
function analyzeFilePermission(content, label) {
|
|
270
|
-
const log = (msg) => process.send({ type: 'log', msg: `[
|
|
270
|
+
const log = (msg) => process.send({ type: 'log', msg: `[AutoPilot] [${label}] [file] ${msg}` });
|
|
271
271
|
|
|
272
272
|
// 1. Find the filePermission sender pattern
|
|
273
273
|
// VAR=(ALLOW_VAR,SCOPE_VAR)=>{SEND(Ui(MSG,{trajectoryId:VAR,stepIndex:VAR,interaction:{case:"filePermission",value:Ui(TYPE,{allow:ALLOW_VAR,scope:SCOPE_VAR,absolutePathUri:REQ.absolutePathUri})}}))};
|
|
@@ -360,7 +360,7 @@ function isFilePatched(filePath) {
|
|
|
360
360
|
|
|
361
361
|
function patchFile(filePath, label) {
|
|
362
362
|
if (!fs.existsSync(filePath)) {
|
|
363
|
-
process.send({ type: 'log', msg: `[
|
|
363
|
+
process.send({ type: 'log', msg: `[AutoPilot] ⏭️ [${label}] File not found, skipping` });
|
|
364
364
|
return true; // optional file missing is not a failure
|
|
365
365
|
}
|
|
366
366
|
|
|
@@ -368,7 +368,7 @@ function patchFile(filePath, label) {
|
|
|
368
368
|
try {
|
|
369
369
|
content = fs.readFileSync(filePath, 'utf8');
|
|
370
370
|
} catch (e) {
|
|
371
|
-
process.send({ type: 'log', msg: `[
|
|
371
|
+
process.send({ type: 'log', msg: `[AutoPilot] ❌ [${label}] Read error: ${e.message}` });
|
|
372
372
|
return false;
|
|
373
373
|
}
|
|
374
374
|
|
|
@@ -376,7 +376,7 @@ function patchFile(filePath, label) {
|
|
|
376
376
|
const bakPath = filePath + '.bak';
|
|
377
377
|
if (!fs.existsSync(bakPath)) {
|
|
378
378
|
fs.copyFileSync(filePath, bakPath);
|
|
379
|
-
process.send({ type: 'log', msg: `[
|
|
379
|
+
process.send({ type: 'log', msg: `[AutoPilot] 📦 [${label}] Backup created` });
|
|
380
380
|
}
|
|
381
381
|
|
|
382
382
|
let patched = content;
|
|
@@ -390,13 +390,13 @@ function patchFile(filePath, label) {
|
|
|
390
390
|
if (count === 1) {
|
|
391
391
|
patched = patched.replace(analysis.target, analysis.replacement);
|
|
392
392
|
anyPatched = true;
|
|
393
|
-
process.send({ type: 'log', msg: `[
|
|
393
|
+
process.send({ type: 'log', msg: `[AutoPilot] ✅ [${label}] Terminal auto-execute patched` });
|
|
394
394
|
} else {
|
|
395
|
-
process.send({ type: 'log', msg: `[
|
|
395
|
+
process.send({ type: 'log', msg: `[AutoPilot] ⚠️ [${label}] Terminal target found ${count}x (expected 1)` });
|
|
396
396
|
}
|
|
397
397
|
}
|
|
398
398
|
} else {
|
|
399
|
-
process.send({ type: 'log', msg: `[
|
|
399
|
+
process.send({ type: 'log', msg: `[AutoPilot] ⏭️ [${label}] Terminal already patched` });
|
|
400
400
|
}
|
|
401
401
|
|
|
402
402
|
// ── Browser action auto-confirm patch ──
|
|
@@ -407,13 +407,13 @@ function patchFile(filePath, label) {
|
|
|
407
407
|
if (count === 1) {
|
|
408
408
|
patched = patched.replace(browserAnalysis.target, browserAnalysis.replacement);
|
|
409
409
|
anyPatched = true;
|
|
410
|
-
process.send({ type: 'log', msg: `[
|
|
410
|
+
process.send({ type: 'log', msg: `[AutoPilot] ✅ [${label}] Browser action auto-confirm patched` });
|
|
411
411
|
} else {
|
|
412
|
-
process.send({ type: 'log', msg: `[
|
|
412
|
+
process.send({ type: 'log', msg: `[AutoPilot] ⚠️ [${label}] Browser target found ${count}x (expected 1)` });
|
|
413
413
|
}
|
|
414
414
|
}
|
|
415
415
|
} else {
|
|
416
|
-
process.send({ type: 'log', msg: `[
|
|
416
|
+
process.send({ type: 'log', msg: `[AutoPilot] ⏭️ [${label}] Browser action already patched` });
|
|
417
417
|
}
|
|
418
418
|
|
|
419
419
|
// ── File permission auto-allow patch ──
|
|
@@ -424,24 +424,24 @@ function patchFile(filePath, label) {
|
|
|
424
424
|
if (count === 1) {
|
|
425
425
|
patched = patched.replace(fileAnalysis.target, fileAnalysis.replacement);
|
|
426
426
|
anyPatched = true;
|
|
427
|
-
process.send({ type: 'log', msg: `[
|
|
427
|
+
process.send({ type: 'log', msg: `[AutoPilot] ✅ [${label}] File permission auto-allow patched` });
|
|
428
428
|
} else {
|
|
429
|
-
process.send({ type: 'log', msg: `[
|
|
429
|
+
process.send({ type: 'log', msg: `[AutoPilot] ⚠️ [${label}] File target found ${count}x (expected 1)` });
|
|
430
430
|
}
|
|
431
431
|
}
|
|
432
432
|
} else {
|
|
433
|
-
process.send({ type: 'log', msg: `[
|
|
433
|
+
process.send({ type: 'log', msg: `[AutoPilot] ⏭️ [${label}] File permission already patched` });
|
|
434
434
|
}
|
|
435
435
|
|
|
436
436
|
if (anyPatched) {
|
|
437
437
|
fs.writeFileSync(filePath, patched, 'utf8');
|
|
438
438
|
const sizeDiff = fs.statSync(filePath).size - fs.statSync(bakPath).size;
|
|
439
|
-
process.send({ type: 'log', msg: `[
|
|
439
|
+
process.send({ type: 'log', msg: `[AutoPilot] ✅ [${label}] All patches applied (+${sizeDiff} bytes)` });
|
|
440
440
|
} else if (!content.includes('_aep=') && !content.includes('_abp=') && !content.includes('_afp=')) {
|
|
441
|
-
process.send({ type: 'log', msg: `[
|
|
441
|
+
process.send({ type: 'log', msg: `[AutoPilot] ❌ [${label}] No patches could be applied` });
|
|
442
442
|
return false;
|
|
443
443
|
} else {
|
|
444
|
-
process.send({ type: 'log', msg: `[
|
|
444
|
+
process.send({ type: 'log', msg: `[AutoPilot] ⏭️ [${label}] All patches already applied` });
|
|
445
445
|
}
|
|
446
446
|
return true;
|
|
447
447
|
}
|
|
@@ -449,11 +449,11 @@ function patchFile(filePath, label) {
|
|
|
449
449
|
function revertFile(filePath, label) {
|
|
450
450
|
const bak = filePath + '.bak';
|
|
451
451
|
if (!fs.existsSync(bak)) {
|
|
452
|
-
process.send({ type: 'log', msg: `[
|
|
452
|
+
process.send({ type: 'log', msg: `[AutoPilot] ⏭️ [${label}] No backup, skipping` });
|
|
453
453
|
return;
|
|
454
454
|
}
|
|
455
455
|
fs.copyFileSync(bak, filePath);
|
|
456
|
-
process.send({ type: 'log', msg: `[
|
|
456
|
+
process.send({ type: 'log', msg: `[AutoPilot] ✅ [${label}] Reverted` });
|
|
457
457
|
}
|
|
458
458
|
|
|
459
459
|
// ─── Message Handler ──────────────────────────────────────────────────────────
|
|
@@ -501,7 +501,7 @@ process.on('message', (msg) => {
|
|
|
501
501
|
success,
|
|
502
502
|
message: success
|
|
503
503
|
? '✅ Patch thành công! Restart Antigravity để áp dụng.'
|
|
504
|
-
: '⚠️ Một số file không patch được. Xem Output >
|
|
504
|
+
: '⚠️ Một số file không patch được. Xem Output > AutoPilot để biết chi tiết.',
|
|
505
505
|
});
|
|
506
506
|
process.exit(success ? 0 : 1);
|
|
507
507
|
|