diff --git a/extension/package-lock.json b/extension/package-lock.json index 2af6c18..1b36257 100644 --- a/extension/package-lock.json +++ b/extension/package-lock.json @@ -1,12 +1,12 @@ { "name": "gravity-bridge", - "version": "0.5.58", + "version": "0.5.59", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "gravity-bridge", - "version": "0.5.58", + "version": "0.5.59", "dependencies": { "cheerio": "^1.2.0", "ws": "^8.19.0" diff --git a/extension/package.json b/extension/package.json index 42fbd55..fa3759b 100644 --- a/extension/package.json +++ b/extension/package.json @@ -2,7 +2,7 @@ "name": "gravity-bridge", "displayName": "Gravity Bridge", "description": "Discord-based unified approval system for Antigravity AI interactions.", - "version": "0.5.58", + "version": "0.5.59", "publisher": "variet", "engines": { "vscode": "^1.100.0" diff --git a/extension/src/observer-script.ts b/extension/src/observer-script.ts index deeab86..425623e 100644 --- a/extension/src/observer-script.ts +++ b/extension/src/observer-script.ts @@ -648,7 +648,63 @@ export function generateApprovalObserverScript(_port: number): string { } } - return finalLines.join('\\n').substring(0, 3500); + // v19: Post-process — wrap markdown table patterns in code blocks for Discord + // AG Native renders tables as divs, not HTML, so DOM-level handler can't catch them. + // Detect consecutive lines with pipe separators (| col1 | col2 |) and wrap in code block fences + var bt = String.fromCharCode(96, 96, 96); + var result = []; + var tableBlock = []; + var inCodeBlock = false; + for (var fi = 0; fi < finalLines.length; fi++) { + var fl = finalLines[fi]; + // Track existing code blocks to avoid double-wrapping + if (fl.trim().indexOf(bt) === 0) { + inCodeBlock = !inCodeBlock; + // Flush any pending table block before code block marker + if (tableBlock.length > 0) { + result.push(bt); + for (var ti = 0; ti < tableBlock.length; ti++) result.push(tableBlock[ti]); + result.push(bt); + tableBlock = []; + } + result.push(fl); + continue; + } + if (inCodeBlock) { + result.push(fl); + continue; + } + // Detect table row: has at least 2 pipe characters and content between them + var pipeCount = 0; + for (var pc = 0; pc < fl.length; pc++) { if (fl.charAt(pc) === '|') pipeCount++; } + var isTableRow = pipeCount >= 2 && fl.trim().charAt(0) === '|'; + var isSeparator = isTableRow && /^[\\s|:-]+$/.test(fl.trim()); + if (isTableRow) { + tableBlock.push(fl); + } else { + // Flush table block if it had enough rows (header + separator + data) + if (tableBlock.length >= 2) { + result.push(bt); + for (var ti2 = 0; ti2 < tableBlock.length; ti2++) result.push(tableBlock[ti2]); + result.push(bt); + } else { + // Not a real table, push lines back normally + for (var ti3 = 0; ti3 < tableBlock.length; ti3++) result.push(tableBlock[ti3]); + } + tableBlock = []; + result.push(fl); + } + } + // Flush trailing table block + if (tableBlock.length >= 2) { + result.push(bt); + for (var ti4 = 0; ti4 < tableBlock.length; ti4++) result.push(tableBlock[ti4]); + result.push(bt); + } else { + for (var ti5 = 0; ti5 < tableBlock.length; ti5++) result.push(tableBlock[ti5]); + } + + return result.join('\\n').substring(0, 3500); } function scanChatBodies() {