antigravity-autopilot 1.4.3 → 1.4.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.
- package/extension.js +77 -0
- package/package.json +11 -1
- package/patcher.js +239 -26
package/extension.js
CHANGED
|
@@ -343,6 +343,24 @@ class AntigravityPanelProvider {
|
|
|
343
343
|
vscode.window.showInformationMessage(
|
|
344
344
|
next ? '🛡️ Command Blocking enabled' : '⚠️ Command Blocking disabled',
|
|
345
345
|
);
|
|
346
|
+
} else if (msg.command === 'toggleBrowserPermission') {
|
|
347
|
+
const cfg = vscode.workspace.getConfiguration('antigravityAutoAccept');
|
|
348
|
+
const current = cfg.get('autoAcceptBrowserPermission', true);
|
|
349
|
+
const next = !current;
|
|
350
|
+
await cfg.update('autoAcceptBrowserPermission', next, vscode.ConfigurationTarget.Global);
|
|
351
|
+
this.sendBrowserPermissionEnabled(next);
|
|
352
|
+
vscode.window.showInformationMessage(
|
|
353
|
+
next ? '🌐 Auto-accept browser permission enabled' : '🌐 Auto-accept browser permission disabled',
|
|
354
|
+
);
|
|
355
|
+
} else if (msg.command === 'toggleFilePermission') {
|
|
356
|
+
const cfg = vscode.workspace.getConfiguration('antigravityAutoAccept');
|
|
357
|
+
const current = cfg.get('autoAcceptFilePermission', true);
|
|
358
|
+
const next = !current;
|
|
359
|
+
await cfg.update('autoAcceptFilePermission', next, vscode.ConfigurationTarget.Global);
|
|
360
|
+
this.sendFilePermissionEnabled(next);
|
|
361
|
+
vscode.window.showInformationMessage(
|
|
362
|
+
next ? '📁 Auto-accept file permission enabled' : '📁 Auto-accept file permission disabled',
|
|
363
|
+
);
|
|
346
364
|
} else if (msg.command === 'removePattern') {
|
|
347
365
|
// Remove a built-in pattern by ID
|
|
348
366
|
const removed = getRemovedPatternIds();
|
|
@@ -364,6 +382,12 @@ class AntigravityPanelProvider {
|
|
|
364
382
|
this.sendBlockingEnabled(
|
|
365
383
|
vscode.workspace.getConfiguration('antigravityAutoAccept').get('dangerousCommandBlocking.enabled', true),
|
|
366
384
|
);
|
|
385
|
+
this.sendBrowserPermissionEnabled(
|
|
386
|
+
vscode.workspace.getConfiguration('antigravityAutoAccept').get('autoAcceptBrowserPermission', true),
|
|
387
|
+
);
|
|
388
|
+
this.sendFilePermissionEnabled(
|
|
389
|
+
vscode.workspace.getConfiguration('antigravityAutoAccept').get('autoAcceptFilePermission', true),
|
|
390
|
+
);
|
|
367
391
|
this.sendPatterns();
|
|
368
392
|
}
|
|
369
393
|
|
|
@@ -395,6 +419,18 @@ class AntigravityPanelProvider {
|
|
|
395
419
|
this._view.webview.postMessage({ command: 'setBlockingEnabled', enabled });
|
|
396
420
|
}
|
|
397
421
|
|
|
422
|
+
/** @param {boolean} enabled */
|
|
423
|
+
sendBrowserPermissionEnabled(enabled) {
|
|
424
|
+
if (!this._view) return;
|
|
425
|
+
this._view.webview.postMessage({ command: 'setBrowserPermissionEnabled', enabled });
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
/** @param {boolean} enabled */
|
|
429
|
+
sendFilePermissionEnabled(enabled) {
|
|
430
|
+
if (!this._view) return;
|
|
431
|
+
this._view.webview.postMessage({ command: 'setFilePermissionEnabled', enabled });
|
|
432
|
+
}
|
|
433
|
+
|
|
398
434
|
/** Send current pattern list to the webview */
|
|
399
435
|
sendPatterns() {
|
|
400
436
|
if (!this._view) return;
|
|
@@ -633,6 +669,30 @@ class AntigravityPanelProvider {
|
|
|
633
669
|
</label>
|
|
634
670
|
</div>
|
|
635
671
|
|
|
672
|
+
<!-- Browser Permission toggle -->
|
|
673
|
+
<div class="toggle-row" id="browserPermToggleRow">
|
|
674
|
+
<div>
|
|
675
|
+
<div class="toggle-label">🌐 Browser Permission</div>
|
|
676
|
+
<div class="toggle-sub" id="browserPermToggleSub">Active — auto-accepting browser actions</div>
|
|
677
|
+
</div>
|
|
678
|
+
<label class="switch" title="Toggle auto-accept browser permission">
|
|
679
|
+
<input type="checkbox" id="browserPermToggleCheck" checked onchange="send('toggleBrowserPermission')">
|
|
680
|
+
<span class="slider"></span>
|
|
681
|
+
</label>
|
|
682
|
+
</div>
|
|
683
|
+
|
|
684
|
+
<!-- File Permission toggle -->
|
|
685
|
+
<div class="toggle-row" id="filePermToggleRow">
|
|
686
|
+
<div>
|
|
687
|
+
<div class="toggle-label">📁 File Permission</div>
|
|
688
|
+
<div class="toggle-sub" id="filePermToggleSub">Active — auto-allowing file access</div>
|
|
689
|
+
</div>
|
|
690
|
+
<label class="switch" title="Toggle auto-accept file permission">
|
|
691
|
+
<input type="checkbox" id="filePermToggleCheck" checked onchange="send('toggleFilePermission')">
|
|
692
|
+
<span class="slider"></span>
|
|
693
|
+
</label>
|
|
694
|
+
</div>
|
|
695
|
+
|
|
636
696
|
<!-- Dangerous Command Blocking section -->
|
|
637
697
|
<div class="section" id="blockSection">
|
|
638
698
|
<div class="section-header" id="blockHeader">
|
|
@@ -660,6 +720,7 @@ class AntigravityPanelProvider {
|
|
|
660
720
|
|
|
661
721
|
function send(cmd, extra) {
|
|
662
722
|
if (cmd !== 'openSettings' && cmd !== 'toggleEnabled' && cmd !== 'toggleCommandBlocking'
|
|
723
|
+
&& cmd !== 'toggleBrowserPermission' && cmd !== 'toggleFilePermission'
|
|
663
724
|
&& cmd !== 'refresh' && cmd !== 'removePattern' && cmd !== 'resetPatterns') {
|
|
664
725
|
document.getElementById('btnApply').disabled = true;
|
|
665
726
|
document.getElementById('btnRevert').disabled = true;
|
|
@@ -751,6 +812,22 @@ class AntigravityPanelProvider {
|
|
|
751
812
|
if (section) section.style.opacity = data.enabled ? '1' : '0.4';
|
|
752
813
|
}
|
|
753
814
|
|
|
815
|
+
if (data.command === 'setBrowserPermissionEnabled') {
|
|
816
|
+
const chk = document.getElementById('browserPermToggleCheck');
|
|
817
|
+
chk.checked = data.enabled;
|
|
818
|
+
document.getElementById('browserPermToggleSub').textContent = data.enabled
|
|
819
|
+
? 'Active — auto-accepting browser actions'
|
|
820
|
+
: 'Disabled — browser actions require confirmation';
|
|
821
|
+
}
|
|
822
|
+
|
|
823
|
+
if (data.command === 'setFilePermissionEnabled') {
|
|
824
|
+
const chk = document.getElementById('filePermToggleCheck');
|
|
825
|
+
chk.checked = data.enabled;
|
|
826
|
+
document.getElementById('filePermToggleSub').textContent = data.enabled
|
|
827
|
+
? 'Active — auto-allowing file access'
|
|
828
|
+
: 'Disabled — file access requires confirmation';
|
|
829
|
+
}
|
|
830
|
+
|
|
754
831
|
if (data.command === 'patterns') {
|
|
755
832
|
renderPatterns(data.patterns, data.totalBuiltin);
|
|
756
833
|
}
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
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.4",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"publisher": "nguyen-hoang",
|
|
8
8
|
"bin": {
|
|
@@ -109,6 +109,16 @@
|
|
|
109
109
|
},
|
|
110
110
|
"default": [],
|
|
111
111
|
"description": "Additional regex patterns (JavaScript syntax) to treat as dangerous commands. Example: [\"^dd if=.*of=/dev/sd\", \"^shred\"]"
|
|
112
|
+
},
|
|
113
|
+
"antigravityAutoAccept.autoAcceptBrowserPermission": {
|
|
114
|
+
"type": "boolean",
|
|
115
|
+
"default": true,
|
|
116
|
+
"description": "Automatically accept browser action permissions (e.g. 'Agent needs permission to act on chromewebdata'). Requires patch to be applied."
|
|
117
|
+
},
|
|
118
|
+
"antigravityAutoAccept.autoAcceptFilePermission": {
|
|
119
|
+
"type": "boolean",
|
|
120
|
+
"default": true,
|
|
121
|
+
"description": "Automatically allow file access permissions with conversation scope. Requires patch to be applied."
|
|
112
122
|
}
|
|
113
123
|
}
|
|
114
124
|
}
|
package/patcher.js
CHANGED
|
@@ -189,13 +189,170 @@ function analyzeFile(content, label) {
|
|
|
189
189
|
};
|
|
190
190
|
}
|
|
191
191
|
|
|
192
|
+
// ─── Browser Action Permission (auto-confirm) ───────────────────────────────
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
* Finds the JPc browser-action confirmation component and builds auto-confirm patch.
|
|
196
|
+
* Pattern: COMP=({sourceTrajectoryStepInfo:VAR,...,url:VAR})=>{...CONFIRM_FN=Mt(()=>{SEND(Ui(MSG,{...,interaction:{case:"browserAction",value:Ui(TYPE,{confirm:!0})}}))},...)...}
|
|
197
|
+
*/
|
|
198
|
+
function analyzeBrowserAction(content, label) {
|
|
199
|
+
const log = (msg) => process.send({ type: 'log', msg: `[AutoAccept] [${label}] [browser] ${msg}` });
|
|
200
|
+
|
|
201
|
+
// 1. Find the browserAction confirm:!0 callback pattern
|
|
202
|
+
// VAR=Mt(()=>{SEND(Ui(MSG,{trajectoryId:VAR,stepIndex:VAR,interaction:{case:"browserAction",value:Ui(TYPE,{confirm:!0})}}))},DEPS)
|
|
203
|
+
const confirmRe = /(\w+)=Mt\(\(\)=>\{(\w+)\(Ui\((\w+),\{trajectoryId:(\w+),stepIndex:(\w+),interaction:\{case:"browserAction",value:Ui\((\w+),\{confirm:!0\}\)\}\}\)\)\},\[([\w,]*)\]\)/;
|
|
204
|
+
const confirmMatch = content.match(confirmRe);
|
|
205
|
+
|
|
206
|
+
if (!confirmMatch) {
|
|
207
|
+
log('❌ Could not find browserAction confirm pattern');
|
|
208
|
+
const idx = content.indexOf('browserAction');
|
|
209
|
+
if (idx >= 0) {
|
|
210
|
+
log(` Context: ...${content.slice(Math.max(0, idx - 80), idx + 120)}...`);
|
|
211
|
+
}
|
|
212
|
+
return null;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
const [fullMatch, confirmVar] = confirmMatch;
|
|
216
|
+
const matchIndex = content.indexOf(fullMatch);
|
|
217
|
+
log(`✓ Found browserAction confirm at offset ${matchIndex}`);
|
|
218
|
+
log(` confirmVar=${confirmVar}`);
|
|
219
|
+
|
|
220
|
+
// 2. Find useEffect alias (reuse from nearby code)
|
|
221
|
+
const nearbyCode = content.substring(Math.max(0, matchIndex - 5000), matchIndex + 5000);
|
|
222
|
+
const effectCandidates = {};
|
|
223
|
+
const effectRe = /\b(\w{2,3})\(\(\)=>\{[^}]{3,80}\},\[/g;
|
|
224
|
+
let m;
|
|
225
|
+
while ((m = effectRe.exec(nearbyCode)) !== null) {
|
|
226
|
+
const alias = m[1];
|
|
227
|
+
if (alias !== 'Mt' && alias !== 'Vi' && alias !== 'var' && alias !== 'new') {
|
|
228
|
+
effectCandidates[alias] = (effectCandidates[alias] || 0) + 1;
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
const cleanupRe = /\b(\w{2,3})\(\(\)=>\{[^}]*return\s*\(\)=>/g;
|
|
232
|
+
while ((m = cleanupRe.exec(content)) !== null) {
|
|
233
|
+
const alias = m[1];
|
|
234
|
+
if (alias !== 'Mt' && alias !== 'Vi') {
|
|
235
|
+
effectCandidates[alias] = (effectCandidates[alias] || 0) + 5;
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
let useEffectAlias = null;
|
|
239
|
+
let maxCount = 0;
|
|
240
|
+
for (const [alias, count] of Object.entries(effectCandidates)) {
|
|
241
|
+
if (count > maxCount) {
|
|
242
|
+
maxCount = count;
|
|
243
|
+
useEffectAlias = alias;
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
if (!useEffectAlias) {
|
|
247
|
+
log('❌ Could not determine useEffect alias');
|
|
248
|
+
return null;
|
|
249
|
+
}
|
|
250
|
+
log(` useEffect=${useEffectAlias} (confidence: ${maxCount} hits)`);
|
|
251
|
+
|
|
252
|
+
// 3. Build patch — auto-call confirmVar() on mount
|
|
253
|
+
const patchCode = `_abp=${useEffectAlias}(()=>{${confirmVar}()},[${confirmVar}]),`;
|
|
254
|
+
|
|
255
|
+
return {
|
|
256
|
+
target: fullMatch,
|
|
257
|
+
replacement: patchCode + fullMatch,
|
|
258
|
+
patchMarker: `_abp=${useEffectAlias}(()=>{${confirmVar}()}`,
|
|
259
|
+
label
|
|
260
|
+
};
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
// ─── File Access Permission (auto-allow with conversation scope) ─────────────
|
|
264
|
+
|
|
265
|
+
/**
|
|
266
|
+
* Finds the rBe file-permission component and builds auto-allow patch.
|
|
267
|
+
* Pattern: COMP=({sourceTrajectoryStepInfo:VAR,req:VAR,status:VAR})=>{...SEND_FN...filePermission...scope...}
|
|
268
|
+
*/
|
|
269
|
+
function analyzeFilePermission(content, label) {
|
|
270
|
+
const log = (msg) => process.send({ type: 'log', msg: `[AutoAccept] [${label}] [file] ${msg}` });
|
|
271
|
+
|
|
272
|
+
// 1. Find the filePermission sender pattern
|
|
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})}}))};
|
|
274
|
+
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\}\)\}\}\)\)\}/;
|
|
275
|
+
const senderMatch = content.match(senderRe);
|
|
276
|
+
|
|
277
|
+
if (!senderMatch) {
|
|
278
|
+
log('❌ Could not find filePermission sender pattern');
|
|
279
|
+
const idx = content.indexOf('filePermission');
|
|
280
|
+
if (idx >= 0) {
|
|
281
|
+
log(` Context: ...${content.slice(Math.max(0, idx - 80), idx + 120)}...`);
|
|
282
|
+
}
|
|
283
|
+
return null;
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
const [fullMatch, senderVar, , , , , , , , reqVar] = senderMatch;
|
|
287
|
+
const matchIndex = content.indexOf(fullMatch);
|
|
288
|
+
log(`✓ Found filePermission sender at offset ${matchIndex}`);
|
|
289
|
+
log(` senderVar=${senderVar}, reqVar=${reqVar}`);
|
|
290
|
+
|
|
291
|
+
// 2. Find the scope enum (kot) — look for kot.CONVERSATION or similar near filePermission
|
|
292
|
+
// Pattern: o(!0,ENUM.CONVERSATION) in the Allow This Conversation button
|
|
293
|
+
const scopeRe = new RegExp(`${senderVar.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}\(!0,(\w+)\.CONVERSATION\)`);
|
|
294
|
+
const scopeMatch = content.substring(matchIndex, matchIndex + 2000).match(scopeRe);
|
|
295
|
+
|
|
296
|
+
if (!scopeMatch) {
|
|
297
|
+
log('❌ Could not find scope enum (CONVERSATION)');
|
|
298
|
+
return null;
|
|
299
|
+
}
|
|
300
|
+
const scopeEnum = scopeMatch[1];
|
|
301
|
+
log(` scopeEnum=${scopeEnum}`);
|
|
302
|
+
|
|
303
|
+
// 3. Find useEffect alias
|
|
304
|
+
const nearbyCode = content.substring(Math.max(0, matchIndex - 5000), matchIndex + 5000);
|
|
305
|
+
const effectCandidates = {};
|
|
306
|
+
const effectRe = /\b(\w{2,3})\(\(\)=>\{[^}]{3,80}\},\[/g;
|
|
307
|
+
let m2;
|
|
308
|
+
while ((m2 = effectRe.exec(nearbyCode)) !== null) {
|
|
309
|
+
const alias = m2[1];
|
|
310
|
+
if (alias !== 'Mt' && alias !== 'Vi' && alias !== 'var' && alias !== 'new') {
|
|
311
|
+
effectCandidates[alias] = (effectCandidates[alias] || 0) + 1;
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
const cleanupRe = /\b(\w{2,3})\(\(\)=>\{[^}]*return\s*\(\)=>/g;
|
|
315
|
+
while ((m2 = cleanupRe.exec(content)) !== null) {
|
|
316
|
+
const alias = m2[1];
|
|
317
|
+
if (alias !== 'Mt' && alias !== 'Vi') {
|
|
318
|
+
effectCandidates[alias] = (effectCandidates[alias] || 0) + 5;
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
let useEffectAlias = null;
|
|
322
|
+
let maxCount = 0;
|
|
323
|
+
for (const [alias, count] of Object.entries(effectCandidates)) {
|
|
324
|
+
if (count > maxCount) {
|
|
325
|
+
maxCount = count;
|
|
326
|
+
useEffectAlias = alias;
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
if (!useEffectAlias) {
|
|
330
|
+
log('❌ Could not determine useEffect alias');
|
|
331
|
+
return null;
|
|
332
|
+
}
|
|
333
|
+
log(` useEffect=${useEffectAlias} (confidence: ${maxCount} hits)`);
|
|
334
|
+
|
|
335
|
+
// 4. Build patch — auto-call senderVar(!0, scopeEnum.CONVERSATION) on mount
|
|
336
|
+
const patchCode = `_afp=${useEffectAlias}(()=>{${senderVar}(!0,${scopeEnum}.CONVERSATION)},[${senderVar}]),`;
|
|
337
|
+
|
|
338
|
+
return {
|
|
339
|
+
target: fullMatch,
|
|
340
|
+
replacement: patchCode + fullMatch,
|
|
341
|
+
patchMarker: `_afp=${useEffectAlias}(()=>{${senderVar}(!0,${scopeEnum}.CONVERSATION)`,
|
|
342
|
+
label
|
|
343
|
+
};
|
|
344
|
+
}
|
|
345
|
+
|
|
192
346
|
// ─── File Operations ─────────────────────────────────────────────────────────
|
|
193
347
|
|
|
194
348
|
function isFilePatched(filePath) {
|
|
195
349
|
if (!fs.existsSync(filePath)) return false;
|
|
196
350
|
try {
|
|
197
351
|
const content = fs.readFileSync(filePath, 'utf8');
|
|
198
|
-
|
|
352
|
+
const hasTerminal = content.includes('_aep=') && /_aep=\w+\(\(\)=>\{[^}]+EAGER/.test(content);
|
|
353
|
+
const hasBrowser = content.includes('_abp=') && /_abp=\w+\(\(\)=>\{\w+\(\)\}/.test(content);
|
|
354
|
+
const hasFile = content.includes('_afp=') && /_afp=\w+\(\(\)=>\{\w+\(!0,/.test(content);
|
|
355
|
+
return hasTerminal || hasBrowser || hasFile;
|
|
199
356
|
} catch {
|
|
200
357
|
return false;
|
|
201
358
|
}
|
|
@@ -215,33 +372,77 @@ function patchFile(filePath, label) {
|
|
|
215
372
|
return false;
|
|
216
373
|
}
|
|
217
374
|
|
|
218
|
-
|
|
219
|
-
process.send({ type: 'log', msg: `[AutoAccept] ⏭️ [${label}] Already patched` });
|
|
220
|
-
return true;
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
const analysis = analyzeFile(content, label);
|
|
224
|
-
if (!analysis) return false;
|
|
225
|
-
|
|
226
|
-
// Verify target uniqueness
|
|
227
|
-
const count = content.split(analysis.target).length - 1;
|
|
228
|
-
if (count !== 1) {
|
|
229
|
-
process.send({ type: 'log', msg: `[AutoAccept] ❌ [${label}] Target found ${count}x (expected 1)` });
|
|
230
|
-
return false;
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
// Backup original
|
|
375
|
+
// Backup original (before any patching)
|
|
234
376
|
const bakPath = filePath + '.bak';
|
|
235
377
|
if (!fs.existsSync(bakPath)) {
|
|
236
378
|
fs.copyFileSync(filePath, bakPath);
|
|
237
379
|
process.send({ type: 'log', msg: `[AutoAccept] 📦 [${label}] Backup created` });
|
|
238
380
|
}
|
|
239
381
|
|
|
240
|
-
|
|
241
|
-
|
|
382
|
+
let patched = content;
|
|
383
|
+
let anyPatched = false;
|
|
384
|
+
|
|
385
|
+
// ── Terminal auto-execute patch ──
|
|
386
|
+
if (!content.includes('_aep=')) {
|
|
387
|
+
const analysis = analyzeFile(content, label);
|
|
388
|
+
if (analysis) {
|
|
389
|
+
const count = patched.split(analysis.target).length - 1;
|
|
390
|
+
if (count === 1) {
|
|
391
|
+
patched = patched.replace(analysis.target, analysis.replacement);
|
|
392
|
+
anyPatched = true;
|
|
393
|
+
process.send({ type: 'log', msg: `[AutoAccept] ✅ [${label}] Terminal auto-execute patched` });
|
|
394
|
+
} else {
|
|
395
|
+
process.send({ type: 'log', msg: `[AutoAccept] ⚠️ [${label}] Terminal target found ${count}x (expected 1)` });
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
} else {
|
|
399
|
+
process.send({ type: 'log', msg: `[AutoAccept] ⏭️ [${label}] Terminal already patched` });
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
// ── Browser action auto-confirm patch ──
|
|
403
|
+
if (!patched.includes('_abp=')) {
|
|
404
|
+
const browserAnalysis = analyzeBrowserAction(patched, label);
|
|
405
|
+
if (browserAnalysis) {
|
|
406
|
+
const count = patched.split(browserAnalysis.target).length - 1;
|
|
407
|
+
if (count === 1) {
|
|
408
|
+
patched = patched.replace(browserAnalysis.target, browserAnalysis.replacement);
|
|
409
|
+
anyPatched = true;
|
|
410
|
+
process.send({ type: 'log', msg: `[AutoAccept] ✅ [${label}] Browser action auto-confirm patched` });
|
|
411
|
+
} else {
|
|
412
|
+
process.send({ type: 'log', msg: `[AutoAccept] ⚠️ [${label}] Browser target found ${count}x (expected 1)` });
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
} else {
|
|
416
|
+
process.send({ type: 'log', msg: `[AutoAccept] ⏭️ [${label}] Browser action already patched` });
|
|
417
|
+
}
|
|
242
418
|
|
|
243
|
-
|
|
244
|
-
|
|
419
|
+
// ── File permission auto-allow patch ──
|
|
420
|
+
if (!patched.includes('_afp=')) {
|
|
421
|
+
const fileAnalysis = analyzeFilePermission(patched, label);
|
|
422
|
+
if (fileAnalysis) {
|
|
423
|
+
const count = patched.split(fileAnalysis.target).length - 1;
|
|
424
|
+
if (count === 1) {
|
|
425
|
+
patched = patched.replace(fileAnalysis.target, fileAnalysis.replacement);
|
|
426
|
+
anyPatched = true;
|
|
427
|
+
process.send({ type: 'log', msg: `[AutoAccept] ✅ [${label}] File permission auto-allow patched` });
|
|
428
|
+
} else {
|
|
429
|
+
process.send({ type: 'log', msg: `[AutoAccept] ⚠️ [${label}] File target found ${count}x (expected 1)` });
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
} else {
|
|
433
|
+
process.send({ type: 'log', msg: `[AutoAccept] ⏭️ [${label}] File permission already patched` });
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
if (anyPatched) {
|
|
437
|
+
fs.writeFileSync(filePath, patched, 'utf8');
|
|
438
|
+
const sizeDiff = fs.statSync(filePath).size - fs.statSync(bakPath).size;
|
|
439
|
+
process.send({ type: 'log', msg: `[AutoAccept] ✅ [${label}] All patches applied (+${sizeDiff} bytes)` });
|
|
440
|
+
} else if (!content.includes('_aep=') && !content.includes('_abp=') && !content.includes('_afp=')) {
|
|
441
|
+
process.send({ type: 'log', msg: `[AutoAccept] ❌ [${label}] No patches could be applied` });
|
|
442
|
+
return false;
|
|
443
|
+
} else {
|
|
444
|
+
process.send({ type: 'log', msg: `[AutoAccept] ⏭️ [${label}] All patches already applied` });
|
|
445
|
+
}
|
|
245
446
|
return true;
|
|
246
447
|
}
|
|
247
448
|
|
|
@@ -266,11 +467,23 @@ process.on('message', (msg) => {
|
|
|
266
467
|
process.exit(0);
|
|
267
468
|
return;
|
|
268
469
|
}
|
|
269
|
-
const files = getTargetFiles(basePath).map(f =>
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
470
|
+
const files = getTargetFiles(basePath).map(f => {
|
|
471
|
+
let patchDetails = { terminal: false, browser: false, file: false };
|
|
472
|
+
if (fs.existsSync(f.filePath)) {
|
|
473
|
+
try {
|
|
474
|
+
const fc = fs.readFileSync(f.filePath, 'utf8');
|
|
475
|
+
patchDetails.terminal = fc.includes('_aep=') && /_aep=\w+\(\(\)=>\{[^}]+EAGER/.test(fc);
|
|
476
|
+
patchDetails.browser = fc.includes('_abp=') && /_abp=\w+\(\(\)=>\{\w+\(\)\}/.test(fc);
|
|
477
|
+
patchDetails.file = fc.includes('_afp=') && /_afp=\w+\(\(\)=>\{\w+\(!0,/.test(fc);
|
|
478
|
+
} catch { }
|
|
479
|
+
}
|
|
480
|
+
return {
|
|
481
|
+
label: f.label,
|
|
482
|
+
patched: patchDetails.terminal || patchDetails.browser || patchDetails.file,
|
|
483
|
+
patchDetails,
|
|
484
|
+
exists: fs.existsSync(f.filePath),
|
|
485
|
+
};
|
|
486
|
+
});
|
|
274
487
|
process.send({ type: 'status', basePath, files });
|
|
275
488
|
process.exit(0);
|
|
276
489
|
|