fix(bridge): disable pending generation for SafeToAutoRun

This commit is contained in:
Variet Worker
2026-04-08 05:52:20 +09:00
parent ab8df32742
commit e5d45b589c
5 changed files with 34 additions and 24 deletions

View File

@@ -3,3 +3,4 @@
| NNN | HH:MM | 작업 설명 | 커밋해시 | 상태 | | NNN | HH:MM | 작업 설명 | 커밋해시 | 상태 |
|---|---|---|---|---| |---|---|---|---|---|
| 001 | 05:18 | Gravity Bridge 무결성 롤백, SafeToAutoRun 메모리 누수 방지(LRU), UI 프리징(execSync) 제거 및 v0.5.15 배포 | `bf7db72` | ✅ | | 001 | 05:18 | Gravity Bridge 무결성 롤백, SafeToAutoRun 메모리 누수 방지(LRU), UI 프리징(execSync) 제거 및 v0.5.15 배포 | `bf7db72` | ✅ |
| 002 | 05:45 | SafeToAutoRun 명령어의 불필요한 Pending 파일 생성 방지 (Discord 중복 알림 차단) 및 v0.5.16 배포 | ⏳ | ⏳ |

View File

@@ -0,0 +1,17 @@
# Gravity Bridge 중복 메시지 알림(SafeToAutoRun) 이슈 해결
- **시간**: 2026-04-08 05:40~05:45
- **버전**: `v0.5.16`
## 작업 사항
1. **단백한 백그라운드 메시지 지원 (중복 알림 제거)**
- 문제: 배경 실행 명령어(`SafeToAutoRun: true`)가 찰나의 순간 동안 `WAITING`에 진입하면서 익스텐션이 Pending 파일을 생성하고, 이를 봇이 즉시 처리하며 `🤖 자동 승인됨`이라는 불필요한 메시지가 중복으로 발송되고 있었음. (프록시 단에서 `💬 AI 대화 내용: ⚡ 자동 실행됨` 기록을 자체 발송하고 있어 중복 됨)
- 스텝 프로브(`step-probe.ts`)가 WAITING 상태를 감지하더라도, 해당 명령어의 플래그에 `SafeToAutoRun`이 true로 존재하면 Pending 파일을 일체 생성하지 않도록 스킵 처리를 추가 (`if (!safeToAutoRun)`)
- 이를 통해 봇(`bot.py`)으로 불필요한 Pending 요청이 가지 않게 차단되었으며, `🤖 자동 승인됨` 텍스트 스팸이 완전히 해결됨.
2. **v0.5.15 잔재 코드 삭제**
- 어설프게 추가되었던 `🤖 [Background Execution]` 직접 Snapshot 생성 로직 삭제.
## 미완료
- 없음 (VSIX 배포/로컬 설치 완료)

View File

@@ -2,7 +2,7 @@
"name": "gravity-bridge", "name": "gravity-bridge",
"displayName": "Gravity Bridge", "displayName": "Gravity Bridge",
"description": "Antigravity ↔ Discord 브리지 연동 확장", "description": "Antigravity ↔ Discord 브리지 연동 확장",
"version": "0.5.15", "version": "0.5.16",
"publisher": "variet", "publisher": "variet",
"engines": { "engines": {
"vscode": "^1.100.0" "vscode": "^1.100.0"

View File

@@ -343,9 +343,7 @@ function setupMonitor() {
} }
autoRunSteps.add(actualIdx); autoRunSteps.add(actualIdx);
const cmdText = tcArgs.CommandLine || tcArgs.command || tcArgs.Command || JSON.stringify(tcArgs); const cmdText = tcArgs.CommandLine || tcArgs.command || tcArgs.Command || JSON.stringify(tcArgs);
const truncatedCmd = cmdText.length > 500 ? cmdText.substring(0, 500) + '...' : cmdText;
ctx.logToFile(`[AUTO-RUN] step=${actualIdx} captured`); ctx.logToFile(`[AUTO-RUN] step=${actualIdx} captured`);
ctx.writeChatSnapshot(`🤖 **[Background Execution]**\n\n\`\`\`bash\n${truncatedCmd}\n\`\`\``);
} }
} catch { } } catch { }
} }
@@ -496,9 +494,11 @@ function setupMonitor() {
const toolCall = oStep?.metadata?.toolCall; const toolCall = oStep?.metadata?.toolCall;
const toolName = toolCall?.name || (oStep.type || '').replace('CORTEX_STEP_TYPE_', '').toLowerCase(); const toolName = toolCall?.name || (oStep.type || '').replace('CORTEX_STEP_TYPE_', '').toLowerCase();
let command = toolName; let command = toolName;
let safeToAutoRun = false;
if (toolCall?.argumentsJson) { if (toolCall?.argumentsJson) {
try { try {
const args = JSON.parse(toolCall.argumentsJson); const args = JSON.parse(toolCall.argumentsJson);
safeToAutoRun = args.SafeToAutoRun === true || args.safeToAutoRun === true;
if (args.CommandLine) command = `${toolName}: ${args.CommandLine.substring(0, 1500)}`; if (args.CommandLine) command = `${toolName}: ${args.CommandLine.substring(0, 1500)}`;
else if (args.TargetFile) command = `${toolName}: ${args.TargetFile}`; else if (args.TargetFile) command = `${toolName}: ${args.TargetFile}`;
else { else {
@@ -521,6 +521,8 @@ function setupMonitor() {
// Skip pending for workspace-less AG windows (project=default) // Skip pending for workspace-less AG windows (project=default)
if (ctx.projectName === 'default') { if (ctx.projectName === 'default') {
ctx.logToFile(`[STEP-PROBE] skip pending: ctx.projectName=default (no workspace)`); ctx.logToFile(`[STEP-PROBE] skip pending: ctx.projectName=default (no workspace)`);
} else if (safeToAutoRun) {
ctx.logToFile(`[STEP-PROBE] skip pending: SafeToAutoRun is true (step=${actualIndex})`);
} else { } else {
// Always write pending — Bot decides auto-approve (prevents double-fire) // Always write pending — Bot decides auto-approve (prevents double-fire)
writePendingApproval({ writePendingApproval({
@@ -558,11 +560,13 @@ function setupMonitor() {
const toolCall = step?.metadata?.toolCall; const toolCall = step?.metadata?.toolCall;
const toolName = toolCall?.name || stepType.replace('CORTEX_STEP_TYPE_', '').toLowerCase(); const toolName = toolCall?.name || stepType.replace('CORTEX_STEP_TYPE_', '').toLowerCase();
let command = toolName; let command = toolName;
let safeToAutoRun = false;
// Parse argumentsJson for command details // Parse argumentsJson for command details
if (toolCall?.argumentsJson) { if (toolCall?.argumentsJson) {
try { try {
const args = JSON.parse(toolCall.argumentsJson); const args = JSON.parse(toolCall.argumentsJson);
safeToAutoRun = args.SafeToAutoRun === true || args.safeToAutoRun === true;
if (args.CommandLine) { if (args.CommandLine) {
command = `${toolName}: ${args.CommandLine.substring(0, 1500)}`; command = `${toolName}: ${args.CommandLine.substring(0, 1500)}`;
} else if (args.TargetFile) { } else if (args.TargetFile) {
@@ -588,6 +592,8 @@ function setupMonitor() {
// Skip pending for workspace-less AG windows (project=default) // Skip pending for workspace-less AG windows (project=default)
if (ctx.projectName === 'default') { if (ctx.projectName === 'default') {
ctx.logToFile(`[STEP-PROBE] skip pending: ctx.projectName=default (no workspace)`); ctx.logToFile(`[STEP-PROBE] skip pending: ctx.projectName=default (no workspace)`);
} else if (safeToAutoRun) {
ctx.logToFile(`[STEP-PROBE] skip pending: SafeToAutoRun is true (step=${si})`);
} else { } else {
// Always write pending — Bot decides auto-approve (prevents double-fire) // Always write pending — Bot decides auto-approve (prevents double-fire)
writePendingApproval({ writePendingApproval({
@@ -640,9 +646,11 @@ function setupMonitor() {
const toolCall = oStep?.metadata?.toolCall; const toolCall = oStep?.metadata?.toolCall;
const toolName = toolCall?.name || (oStep.type || '').replace('CORTEX_STEP_TYPE_', '').toLowerCase(); const toolName = toolCall?.name || (oStep.type || '').replace('CORTEX_STEP_TYPE_', '').toLowerCase();
let command = toolName; let command = toolName;
let safeToAutoRun = false;
if (toolCall?.argumentsJson) { if (toolCall?.argumentsJson) {
try { try {
const args = JSON.parse(toolCall.argumentsJson); const args = JSON.parse(toolCall.argumentsJson);
safeToAutoRun = args.SafeToAutoRun === true || args.safeToAutoRun === true;
if (args.CommandLine) command = `${toolName}: ${args.CommandLine.substring(0, 1500)}`; if (args.CommandLine) command = `${toolName}: ${args.CommandLine.substring(0, 1500)}`;
else if (args.TargetFile) command = `${toolName}: ${args.TargetFile}`; else if (args.TargetFile) command = `${toolName}: ${args.TargetFile}`;
else { else {
@@ -658,7 +666,11 @@ function setupMonitor() {
if (actualIndex > ctx.lastPendingStepIndex) ctx.lastPendingStepIndex = actualIndex; if (actualIndex > ctx.lastPendingStepIndex) ctx.lastPendingStepIndex = actualIndex;
lastPendingTime = Date.now(); lastPendingTime = Date.now();
ctx.sawRunningAfterPending = false; ctx.sawRunningAfterPending = false;
if (ctx.projectName !== 'default') { if (ctx.projectName === 'default') {
ctx.logToFile(`[STEP-PROBE] skip pending: ctx.projectName=default`);
} else if (safeToAutoRun) {
ctx.logToFile(`[STEP-PROBE] skip pending: SafeToAutoRun is true (step=${actualIndex})`);
} else {
writePendingApproval({ writePendingApproval({
conversation_id: ctx.activeSessionId, conversation_id: ctx.activeSessionId,
command, command,

View File

@@ -1,20 +0,0 @@
import zipfile, shutil, os
vsix = r"c:\Users\Variet-Worker\Desktop\gravity_control\extension\gravity-bridge-0.5.14.vsix"
dest = os.path.expanduser(r"~\.antigravity\extensions\variet.gravity-bridge-0.5.14")
tmp = r"C:\tmp\vsix_extract"
if os.path.exists(tmp):
shutil.rmtree(tmp)
os.makedirs(tmp, exist_ok=True)
with zipfile.ZipFile(vsix, 'r') as z:
z.extractall(tmp)
src = os.path.join(tmp, "extension")
if os.path.exists(dest):
shutil.rmtree(dest)
shutil.copytree(src, dest)
print(f"Installed to {dest}")
print("Files:", os.listdir(dest))