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() {