@quantiya/codevibe-antigravity-plugin 2.0.82 → 2.0.84

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.
Files changed (2) hide show
  1. package/dist/server.js +71 -10
  2. package/package.json +2 -2
package/dist/server.js CHANGED
@@ -2985,7 +2985,7 @@ function isPaneInputSafetyBlocked(input) {
2985
2985
  if (inInnerFence) {
2986
2986
  continue;
2987
2987
  }
2988
- if (isAgyStatusFooterLine(trimmed) || /^\s*(?:[❯>]\s*)?\?\s+for\s+(?:shortcuts|help)\b/i.test(trimmed) || isComposerBoxAt(lines, j)) {
2988
+ if (isAgyStatusFooterLine(trimmed) || /^\s*(?:[❯>]\s*)?\?\s+for\s+(?:shortcuts|help)\b/i.test(trimmed) || isComposerBoxAt(lines, j) || optCount > 0 && isResumedTurnSignal(trimmed)) {
2989
2989
  composerEncountered = true;
2990
2990
  break;
2991
2991
  }
@@ -3058,7 +3058,7 @@ function isPaneInputSafetyBlocked(input) {
3058
3058
  if (inInnerFence) {
3059
3059
  continue;
3060
3060
  }
3061
- if (isAgyStatusFooterLine(trimmed) || /^\s*(?:[❯>]\s*)?\?\s+for\s+(?:shortcuts|help)\b/i.test(trimmed) || isComposerBoxAt(lines, j)) {
3061
+ if (isAgyStatusFooterLine(trimmed) || /^\s*(?:[❯>]\s*)?\?\s+for\s+(?:shortcuts|help)\b/i.test(trimmed) || isComposerBoxAt(lines, j) || optCount > 0 && isResumedTurnSignal(trimmed)) {
3062
3062
  composerEncountered = true;
3063
3063
  break;
3064
3064
  }
@@ -3203,6 +3203,11 @@ function computeFenceMask(lines) {
3203
3203
  }
3204
3204
  return inFence;
3205
3205
  }
3206
+ function isResumedTurnSignal(line) {
3207
+ if (!line) return false;
3208
+ const trimmed = line.trim();
3209
+ return /^[❯>]\s+(?![1-9][.)\]])\S/.test(trimmed) || /^[▶▸○]\s*Thought\b/i.test(trimmed) || /^(?:[\u2800-\u28FF]\s*)?Working(?:\.\.\.)?\s*$/i.test(trimmed) || /^●\s+(?:Ran|Run|Running|Execute|Executing|Completed|Explored|Exploring|Read|Reading|Wrote|Writing|Edited|Editing|Created|Creating|Updated|Updating|Deleted|Deleting|Fetched|Fetching|Searched|Searching)\b/i.test(trimmed) || /^●.*\(ctrl\+[a-z0-9]+\s+to\s+(?:expand|view)\)/i.test(trimmed);
3210
+ }
3206
3211
  function hasTrailingAgyComposer(lines, afterLineIdx, fenceMask) {
3207
3212
  if (afterLineIdx < -1 || afterLineIdx >= lines.length - 1) return false;
3208
3213
  const trailingLines = [];
@@ -3227,9 +3232,21 @@ function hasTrailingAgyComposer(lines, afterLineIdx, fenceMask) {
3227
3232
  }
3228
3233
  }
3229
3234
  }
3230
- if (trailingLines.some((l) => isAgyStatusFooterLine(l) && /(?:Gemini|Flash|Pro|Claude|Sonnet|Opus|GPT|auto|high|low|medium)/i.test(l))) {
3235
+ if (trailingLines.some((l) => isResumedTurnSignal(l))) {
3231
3236
  return true;
3232
3237
  }
3238
+ const hasStatusLine = trailingLines.some(
3239
+ (l) => isAgyStatusFooterLine(l) && /(?:Gemini|Flash|Pro|Claude|Sonnet|Opus|GPT|auto|high|low|medium)/i.test(l)
3240
+ );
3241
+ if (hasStatusLine) {
3242
+ const nonDecorativeNonStatus = trailingLines.filter(
3243
+ (l) => !isAgyStatusFooterLine(l) && !isQuestionFooterLine(l) && !/^[─━│╭╰╮╯\s_-]{3,}$/.test(l)
3244
+ );
3245
+ if (nonDecorativeNonStatus.length > 0) {
3246
+ return true;
3247
+ }
3248
+ return false;
3249
+ }
3233
3250
  return false;
3234
3251
  }
3235
3252
  function reconstructFooter(rawLines) {
@@ -3408,7 +3425,13 @@ function looksLikePromptSnapshot(snapshot) {
3408
3425
  let footerIdx = lastOptionIdx;
3409
3426
  if (!hasQuestionFooter) {
3410
3427
  for (let i = lastOptionIdx + 1; i < allLines.length; i++) {
3411
- if (!fenceMask[i] && isQuestionFooterLine(allLines[i].trim())) {
3428
+ if (fenceMask[i]) continue;
3429
+ const trimmed = allLines[i].trim();
3430
+ if (!trimmed) continue;
3431
+ if (isResumedTurnSignal(trimmed)) {
3432
+ break;
3433
+ }
3434
+ if (isQuestionFooterLine(trimmed)) {
3412
3435
  hasQuestionFooter = true;
3413
3436
  footerIdx = i;
3414
3437
  break;
@@ -3745,6 +3768,9 @@ function detectActivePromptKind(snapshot) {
3745
3768
  for (let j = lastSystemErrorLineIdx + 1; j < lines.length; j++) {
3746
3769
  if (!lineInFence[j]) {
3747
3770
  const trimmed = lines[j].trim();
3771
+ if (hasQuestionOptions && isResumedTurnSignal(trimmed)) {
3772
+ break;
3773
+ }
3748
3774
  if (/^[>\s❯]*[1-9][.)]\s+\S/.test(trimmed)) {
3749
3775
  hasQuestionOptions = true;
3750
3776
  promptEndIdx = j;
@@ -3787,12 +3813,20 @@ function detectActivePromptKind(snapshot) {
3787
3813
  }
3788
3814
  if (latestChooserIdx === lastQuestionLineIdx) {
3789
3815
  let promptEndIdx = lastQuestionLineIdx;
3816
+ let hasFoundOptions = false;
3790
3817
  for (let j = lastQuestionLineIdx + 1; j < lines.length; j++) {
3791
3818
  if (!lineInFence[j]) {
3792
- if (isAgyStatusFooterLine(lines[j].trim()) || /^\s*(?:[❯>]\s*)?\?\s+for\s+(?:shortcuts|help)\b/i.test(lines[j].trim()) || isComposerBoxAt(lines, j)) {
3819
+ const trimmed = lines[j].trim();
3820
+ if (isAgyStatusFooterLine(trimmed) || /^\s*(?:[❯>]\s*)?\?\s+for\s+(?:shortcuts|help)\b/i.test(trimmed) || isComposerBoxAt(lines, j)) {
3793
3821
  break;
3794
3822
  }
3795
- if (/^[>\s❯]*[1-9][.)]\s+\S/.test(lines[j].trim()) || isQuestionFooterLine(lines[j])) {
3823
+ if (hasFoundOptions && isResumedTurnSignal(trimmed)) {
3824
+ break;
3825
+ }
3826
+ if (/^[>\s❯]*[1-9][.)]\s+\S/.test(trimmed)) {
3827
+ hasFoundOptions = true;
3828
+ promptEndIdx = j;
3829
+ } else if (isQuestionFooterLine(lines[j])) {
3796
3830
  promptEndIdx = j;
3797
3831
  }
3798
3832
  }
@@ -4171,7 +4205,7 @@ function isQuestionFooterLine(line) {
4171
4205
  }
4172
4206
  if (/^[>\s❯]*[1-9][.)]\s+\S/.test(trimmed)) return false;
4173
4207
  if (isQuestionHeaderLine(trimmed)) return false;
4174
- return /^(?:esc|<esc>)\s+(?:to\s+)?(?:cancel|skip)(?:\s*[·│,]\s*(?:enter|<enter>)\s+(?:to\s+)?select)?$/i.test(trimmed) || /^(?:enter|<enter>)\s+(?:to\s+)?select(?:\s*[·│,]\s*(?:esc|<esc>)\s+(?:to\s+)?(?:cancel|skip))?$/i.test(trimmed) || /^(?:↑\/↓|↑|↓|\^|v)\s*(?:\/|\s+)?Navigate(?:\s*[·│,]\s*(?:enter|<enter>)?\s*(?:Select|to select))?(?:\s*[·│,]\s*(?:esc|<esc>)?\s*(?:Skip|Cancel))?$/i.test(trimmed) || /^press\s+<?(?:enter|return|space)>?\s+to\s+select$/i.test(trimmed) || /^space\s+to\s+select$/i.test(trimmed) || /^(?:\(?use\s+arrow\s+keys(?:\s+to\s+navigate)?\)?)$/i.test(trimmed) || /^waiting(?:\.\.\.)?$/i.test(trimmed);
4208
+ return /^(?:esc|<esc>)\s+(?:to\s+)?(?:cancel|skip)(?:\s*[·│,]\s*(?:enter|<enter>)\s+(?:to\s+)?select)?(?:\s*[·│,]\s*ctrl\+[a-z0-9]+\s+[a-zA-Z]+)*$/i.test(trimmed) || /^(?:enter|<enter>)\s+(?:to\s+)?select(?:\s*[·│,]\s*(?:esc|<esc>)\s+(?:to\s+)?(?:cancel|skip))?(?:\s*[·│,]\s*ctrl\+[a-z0-9]+\s+[a-zA-Z]+)*$/i.test(trimmed) || /^(?:↑\/↓|↑|↓|\^|v)\s*(?:\/|\s+)?Navigate(?:\s*[·│,]\s*(?:enter|<enter>)?\s*(?:Select|to select))(?:\s*[·│,]\s*(?:esc|<esc>)?\s*(?:Skip|Cancel))?(?:\s*[·│,]\s*ctrl\+[a-z0-9]+\s+[a-zA-Z]+)*$/i.test(trimmed) || /^(?:↑\/↓|↑|↓|\^|v)\s*(?:\/|\s+)?Navigate(?:\s*[·│,]\s*(?:esc|<esc>)?\s*(?:Skip|Cancel))?$/i.test(trimmed) || /^press\s+<?(?:enter|return|space)>?\s+to\s+select$/i.test(trimmed) || /^space\s+to\s+select$/i.test(trimmed) || /^(?:\(?use\s+arrow\s+keys(?:\s+to\s+navigate)?\)?)$/i.test(trimmed) || /^(?:[\u2800-\u28FF]+(?:\s*waiting(?:\.\.\.)?)?|waiting(?:\.\.\.)?)$/i.test(trimmed);
4175
4209
  }
4176
4210
  function extractQuestionHeader(snapshot) {
4177
4211
  const stripped = snapshot.replace(ANSI_ESCAPE_REGEX, "");
@@ -4342,8 +4376,33 @@ function parseQuestionSnapshot(stripped, originalSnapshot, header) {
4342
4376
  const options = parseOptions(belowHeader);
4343
4377
  if (options.length < 2) return null;
4344
4378
  const normalizedHeader = header.fullLine.replace(/^[❯>\s*•-]+\s*/, "").trim();
4345
- const hasArrowKeyHint = /\((?:Use\s+arrow\s+keys|Use\s+\S+\s+keys)[^)]*\)/i.test(normalizedHeader);
4346
- const isBaseNumberedWizard = /^Question\s+\d+\/\d+:/i.test(normalizedHeader) && !hasArrowKeyHint;
4379
+ const headerHasArrowHint = /\((?:Use\s+arrow\s+keys|Use\s+\S+\s+keys)[^)]*\)/i.test(normalizedHeader);
4380
+ let footerHasArrowHint = false;
4381
+ let footerHasCtrlRReview = false;
4382
+ const startLine = headerIdx >= 0 ? headerIdx + 1 : 0;
4383
+ let hasSeenOptions = false;
4384
+ for (let i = startLine; i < lines.length; i++) {
4385
+ if (lineInFence[i]) continue;
4386
+ const trimmed = lines[i].trim();
4387
+ if (!trimmed) continue;
4388
+ if (hasSeenOptions && isResumedTurnSignal(trimmed)) break;
4389
+ if (/^[>\s❯]*[1-9][.)]\s+\S/.test(trimmed)) {
4390
+ hasSeenOptions = true;
4391
+ }
4392
+ const isFooter = isQuestionFooterLine(trimmed) || /^(?:ctrl\+[a-z0-9]+\s+[a-zA-Z]+|\(?use\s+arrow\s+keys(?:\s+to\s+navigate)?\)?)$/i.test(trimmed);
4393
+ if (isFooter) {
4394
+ if (/(?:↑\/↓|↑|↓|\^|v)\s*(?:\/|\s+)?Navigate\b/i.test(trimmed) || /\(?use\s+arrow\s+keys(?:\s+to\s+navigate)?\)?/i.test(trimmed)) {
4395
+ footerHasArrowHint = true;
4396
+ }
4397
+ if (/ctrl\+r\s+Review\b/i.test(trimmed)) {
4398
+ footerHasCtrlRReview = true;
4399
+ }
4400
+ }
4401
+ }
4402
+ const hasArrowKeyHint = headerHasArrowHint || footerHasArrowHint;
4403
+ const hasWriteInOption = options.some((opt) => /^\s*write-?in\b/i.test(opt.text));
4404
+ const hasCtrlRReviewFooter = footerHasCtrlRReview;
4405
+ const isBaseNumberedWizard = /^Question\s+\d+\/\d+:/i.test(normalizedHeader) && !hasArrowKeyHint && !hasWriteInOption && !hasCtrlRReviewFooter;
4347
4406
  const submitMap = isBaseNumberedWizard ? buildQuestionSubmitMap(options) : {};
4348
4407
  const body = extractBodyBetweenHeaderAndFirstOption(belowHeader);
4349
4408
  return {
@@ -4406,7 +4465,9 @@ function buildApprovalSubmitMap(options) {
4406
4465
  function buildQuestionSubmitMap(options) {
4407
4466
  const map = {};
4408
4467
  for (const opt of options) {
4409
- map[opt.number] = [opt.number, "Enter"];
4468
+ if (!/^\s*write-?in\b/i.test(opt.text)) {
4469
+ map[opt.number] = [opt.number, "Enter"];
4470
+ }
4410
4471
  }
4411
4472
  return map;
4412
4473
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@quantiya/codevibe-antigravity-plugin",
3
- "version": "2.0.82",
3
+ "version": "2.0.84",
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
  "codevibe": {
@@ -46,7 +46,7 @@
46
46
  "node": ">=22.0.0"
47
47
  },
48
48
  "dependencies": {
49
- "@quantiya/codevibe-core": "^2.0.74",
49
+ "@quantiya/codevibe-core": "^2.0.75",
50
50
  "chokidar": "^5.0.0",
51
51
  "dotenv": "^16.6.1",
52
52
  "express": "^5.1.0",