@quantiya/codevibe-antigravity-plugin 1.0.1 → 1.0.2
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/dist/server.js +139 -4
- package/package.json +1 -1
package/dist/server.js
CHANGED
|
@@ -1457,6 +1457,7 @@ function parseApprovalUISnapshot(stripped, originalSnapshot) {
|
|
|
1457
1457
|
if (options.length < 2) return null;
|
|
1458
1458
|
const submitMap = buildApprovalSubmitMap(options);
|
|
1459
1459
|
const { command, filePath } = extractIdentity(headerText);
|
|
1460
|
+
const body = extractBodyBetweenHeaderAndFirstOption(belowHeader);
|
|
1460
1461
|
return {
|
|
1461
1462
|
kind: "approval",
|
|
1462
1463
|
headerText,
|
|
@@ -1465,6 +1466,7 @@ function parseApprovalUISnapshot(stripped, originalSnapshot) {
|
|
|
1465
1466
|
filePath,
|
|
1466
1467
|
options,
|
|
1467
1468
|
submitMap,
|
|
1469
|
+
body,
|
|
1468
1470
|
paneHash: hashPromptSnapshot(originalSnapshot)
|
|
1469
1471
|
};
|
|
1470
1472
|
}
|
|
@@ -1481,6 +1483,7 @@ function parseQuestionSnapshot(stripped, originalSnapshot, header) {
|
|
|
1481
1483
|
const options = parseOptions(belowHeader);
|
|
1482
1484
|
if (options.length < 2) return null;
|
|
1483
1485
|
const submitMap = buildQuestionSubmitMap(options);
|
|
1486
|
+
const body = extractBodyBetweenHeaderAndFirstOption(belowHeader);
|
|
1484
1487
|
return {
|
|
1485
1488
|
kind: "question",
|
|
1486
1489
|
headerText: header.body,
|
|
@@ -1489,9 +1492,30 @@ function parseQuestionSnapshot(stripped, originalSnapshot, header) {
|
|
|
1489
1492
|
filePath: void 0,
|
|
1490
1493
|
options,
|
|
1491
1494
|
submitMap,
|
|
1495
|
+
body,
|
|
1492
1496
|
paneHash: hashPromptSnapshot(originalSnapshot)
|
|
1493
1497
|
};
|
|
1494
1498
|
}
|
|
1499
|
+
function extractBodyBetweenHeaderAndFirstOption(belowHeader) {
|
|
1500
|
+
const lines = belowHeader.split("\n");
|
|
1501
|
+
const optionRegex = /^[>\s]*([1-9])\. (.+?)\s*$/;
|
|
1502
|
+
const fenceRegex = /^```/;
|
|
1503
|
+
let firstOptionIdx = -1;
|
|
1504
|
+
let inFence = false;
|
|
1505
|
+
for (let i = 0; i < lines.length; i++) {
|
|
1506
|
+
if (fenceRegex.test(lines[i])) {
|
|
1507
|
+
inFence = !inFence;
|
|
1508
|
+
continue;
|
|
1509
|
+
}
|
|
1510
|
+
if (inFence) continue;
|
|
1511
|
+
if (optionRegex.test(lines[i])) {
|
|
1512
|
+
firstOptionIdx = i;
|
|
1513
|
+
break;
|
|
1514
|
+
}
|
|
1515
|
+
}
|
|
1516
|
+
if (firstOptionIdx <= 0) return "";
|
|
1517
|
+
return lines.slice(0, firstOptionIdx).join("\n").trim();
|
|
1518
|
+
}
|
|
1495
1519
|
function parseOptions(snapshot) {
|
|
1496
1520
|
const recent = snapshot.split("\n").slice(-30);
|
|
1497
1521
|
const optionRegex = /^[>\s]*([1-9])\. (.+?)\s*$/;
|
|
@@ -1720,6 +1744,7 @@ var ApprovalDetector = class extends import_events3.EventEmitter {
|
|
|
1720
1744
|
submitMap: candidate.submitMap,
|
|
1721
1745
|
matchedPaneHeader: candidate.headerText,
|
|
1722
1746
|
paneDisplayHeader: candidate.fullHeaderLine,
|
|
1747
|
+
body: candidate.body,
|
|
1723
1748
|
emittedAt: Date.now(),
|
|
1724
1749
|
ttlMs: this.promptTtlMs,
|
|
1725
1750
|
paneOptions: candidate.options
|
|
@@ -1904,6 +1929,7 @@ var ApprovalDetector = class extends import_events3.EventEmitter {
|
|
|
1904
1929
|
submitMap: candidate.submitMap,
|
|
1905
1930
|
matchedPaneHeader: candidate.headerText,
|
|
1906
1931
|
paneDisplayHeader: candidate.fullHeaderLine,
|
|
1932
|
+
body: candidate.body,
|
|
1907
1933
|
emittedAt: Date.now(),
|
|
1908
1934
|
ttlMs: this.promptTtlMs
|
|
1909
1935
|
};
|
|
@@ -3270,12 +3296,36 @@ var McpServer = class {
|
|
|
3270
3296
|
return;
|
|
3271
3297
|
}
|
|
3272
3298
|
const optionsArr = state.paneOptions ? state.paneOptions.map((o) => ({ number: o.number, text: o.text })) : Object.keys(state.submitMap).map((n) => ({ number: n }));
|
|
3299
|
+
const diffParsed = parseFencedDiffFromBody(
|
|
3300
|
+
state.body,
|
|
3301
|
+
state.paneDisplayHeader
|
|
3302
|
+
);
|
|
3303
|
+
if (diffParsed) {
|
|
3304
|
+
logger.info("Parsed fenced diff for INTERACTIVE_PROMPT", {
|
|
3305
|
+
promptId: state.promptId,
|
|
3306
|
+
filePath: diffParsed.filePath,
|
|
3307
|
+
oldLines: diffParsed.oldString.split("\n").length,
|
|
3308
|
+
newLines: diffParsed.newString.split("\n").length,
|
|
3309
|
+
rawDiffLength: diffParsed.rawDiff.length
|
|
3310
|
+
});
|
|
3311
|
+
}
|
|
3312
|
+
const toolName = diffParsed ? "Edit" : state.pendingCall?.toolType;
|
|
3313
|
+
const filePath = diffParsed?.filePath ?? state.pendingCall?.filePath;
|
|
3314
|
+
const toolInput = diffParsed ? {
|
|
3315
|
+
file_path: diffParsed.filePath,
|
|
3316
|
+
old_string: diffParsed.oldString,
|
|
3317
|
+
new_string: diffParsed.newString,
|
|
3318
|
+
old_start_line: diffParsed.oldStartLine,
|
|
3319
|
+
new_start_line: diffParsed.newStartLine,
|
|
3320
|
+
diff: diffParsed.rawDiff
|
|
3321
|
+
} : void 0;
|
|
3273
3322
|
const optionsForMobile = state.pendingCall ? {
|
|
3274
3323
|
promptId: state.promptId,
|
|
3275
|
-
tool_name:
|
|
3324
|
+
tool_name: toolName,
|
|
3276
3325
|
command: state.pendingCall.command,
|
|
3277
|
-
file_path:
|
|
3278
|
-
options: optionsArr
|
|
3326
|
+
file_path: filePath,
|
|
3327
|
+
options: optionsArr,
|
|
3328
|
+
...toolInput ? { tool_input: toolInput } : {}
|
|
3279
3329
|
} : { promptId: state.promptId };
|
|
3280
3330
|
const content = state.paneDisplayHeader || state.matchedPaneHeader || state.pendingCall?.command || state.pendingCall?.filePath || "approval requested";
|
|
3281
3331
|
const input = {
|
|
@@ -3657,11 +3707,96 @@ function parseArgs(argv) {
|
|
|
3657
3707
|
if (require.main === module) {
|
|
3658
3708
|
void main();
|
|
3659
3709
|
}
|
|
3710
|
+
function parseFencedDiffFromBody(body, header) {
|
|
3711
|
+
if (!body) return null;
|
|
3712
|
+
const fenceMatch = body.match(/```[^\n]*\n([\s\S]*?)\n```/i);
|
|
3713
|
+
if (!fenceMatch) return null;
|
|
3714
|
+
const rawDiff = fenceMatch[1];
|
|
3715
|
+
const oldLines = [];
|
|
3716
|
+
const newLines = [];
|
|
3717
|
+
const hunkHeaderPattern = /^@@ -(\d+)(?:,\d+)? \+(\d+)(?:,\d+)? @@/;
|
|
3718
|
+
let currentOldLine = 0;
|
|
3719
|
+
let currentNewLine = 0;
|
|
3720
|
+
let oldStartLine;
|
|
3721
|
+
let newStartLine;
|
|
3722
|
+
let hunkCount = 0;
|
|
3723
|
+
let filePath;
|
|
3724
|
+
const stripPrefix = (raw) => {
|
|
3725
|
+
let p = raw.trim();
|
|
3726
|
+
if (p.startsWith("a/") || p.startsWith("b/")) p = p.slice(2);
|
|
3727
|
+
if (p === "/dev/null") return "";
|
|
3728
|
+
return p;
|
|
3729
|
+
};
|
|
3730
|
+
for (const line of rawDiff.split("\n")) {
|
|
3731
|
+
const hunkMatch = line.match(hunkHeaderPattern);
|
|
3732
|
+
if (hunkMatch) {
|
|
3733
|
+
hunkCount += 1;
|
|
3734
|
+
currentOldLine = Number.parseInt(hunkMatch[1], 10);
|
|
3735
|
+
currentNewLine = Number.parseInt(hunkMatch[2], 10);
|
|
3736
|
+
continue;
|
|
3737
|
+
}
|
|
3738
|
+
if (line.startsWith("+++ ")) {
|
|
3739
|
+
const pathVal = stripPrefix(line.slice(4));
|
|
3740
|
+
if (pathVal) filePath = pathVal;
|
|
3741
|
+
continue;
|
|
3742
|
+
}
|
|
3743
|
+
if (line.startsWith("--- ")) {
|
|
3744
|
+
if (!filePath) {
|
|
3745
|
+
const pathVal = stripPrefix(line.slice(4));
|
|
3746
|
+
if (pathVal) filePath = pathVal;
|
|
3747
|
+
}
|
|
3748
|
+
continue;
|
|
3749
|
+
}
|
|
3750
|
+
if (line.startsWith("+")) {
|
|
3751
|
+
if (newStartLine === void 0) newStartLine = currentNewLine;
|
|
3752
|
+
newLines.push(line.slice(1));
|
|
3753
|
+
currentNewLine += 1;
|
|
3754
|
+
} else if (line.startsWith("-")) {
|
|
3755
|
+
if (oldStartLine === void 0) oldStartLine = currentOldLine;
|
|
3756
|
+
oldLines.push(line.slice(1));
|
|
3757
|
+
currentOldLine += 1;
|
|
3758
|
+
} else if (line.startsWith(" ")) {
|
|
3759
|
+
const ctx = line.slice(1);
|
|
3760
|
+
oldLines.push(ctx);
|
|
3761
|
+
newLines.push(ctx);
|
|
3762
|
+
currentOldLine += 1;
|
|
3763
|
+
currentNewLine += 1;
|
|
3764
|
+
}
|
|
3765
|
+
}
|
|
3766
|
+
if (hunkCount > 1) {
|
|
3767
|
+
oldStartLine = void 0;
|
|
3768
|
+
newStartLine = void 0;
|
|
3769
|
+
}
|
|
3770
|
+
if (!filePath) {
|
|
3771
|
+
const searchTargets = [body, header ?? ""];
|
|
3772
|
+
for (const target of searchTargets) {
|
|
3773
|
+
if (!target) continue;
|
|
3774
|
+
const m = target.match(/\[.*?\]\(file:\/\/([^\s\)]+)\)/) || target.match(/file:\/\/([^\s\)]+)/);
|
|
3775
|
+
if (m) {
|
|
3776
|
+
try {
|
|
3777
|
+
filePath = decodeURIComponent(m[1]);
|
|
3778
|
+
} catch {
|
|
3779
|
+
filePath = m[1];
|
|
3780
|
+
}
|
|
3781
|
+
break;
|
|
3782
|
+
}
|
|
3783
|
+
}
|
|
3784
|
+
}
|
|
3785
|
+
return {
|
|
3786
|
+
filePath,
|
|
3787
|
+
oldString: oldLines.join("\n"),
|
|
3788
|
+
newString: newLines.join("\n"),
|
|
3789
|
+
oldStartLine,
|
|
3790
|
+
newStartLine,
|
|
3791
|
+
rawDiff
|
|
3792
|
+
};
|
|
3793
|
+
}
|
|
3660
3794
|
var __testing = {
|
|
3661
3795
|
generateLaunchSessionId,
|
|
3662
3796
|
parseArgs,
|
|
3663
3797
|
parseMaybeJson,
|
|
3664
|
-
getActiveConversationFromCliLog
|
|
3798
|
+
getActiveConversationFromCliLog,
|
|
3799
|
+
parseFencedDiffFromBody
|
|
3665
3800
|
};
|
|
3666
3801
|
// Annotate the CommonJS export names for ESM import in node:
|
|
3667
3802
|
0 && (module.exports = {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@quantiya/codevibe-antigravity-plugin",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.2",
|
|
4
4
|
"description": "Control Antigravity CLI from your iPhone and Android — real-time sync, approve file edits, send prompts by voice. Part of CodeVibe.",
|
|
5
5
|
"main": "dist/server.js",
|
|
6
6
|
"bin": {
|