@quantiya/codevibe-antigravity-plugin 1.0.7 → 1.0.9

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 +51 -19
  2. package/package.json +2 -2
package/dist/server.js CHANGED
@@ -2502,14 +2502,14 @@ var import_codevibe_core3 = require("@quantiya/codevibe-core");
2502
2502
  var CONTENT_MAX = 150 * 1024;
2503
2503
  var TOOL_OUTPUT_MAX = 50 * 1024;
2504
2504
  var TOOL_DIFF_MAX = 100 * 1024;
2505
- function mapTranscriptEvent(emit, sessionId) {
2505
+ function mapTranscriptEvent(emit, sessionId, notBeforeMs) {
2506
2506
  const { event } = emit;
2507
2507
  const base = {
2508
2508
  sessionId,
2509
2509
  source: import_codevibe_core3.EventSource.DESKTOP
2510
2510
  };
2511
2511
  const orderingKey = `${sessionId}:${emit.conversationId}`;
2512
- const nextTimestamp = () => (0, import_codevibe_core3.prepareEventTimestamp)({ orderingKey, agentClock: event.created_at });
2512
+ const nextTimestamp = () => (0, import_codevibe_core3.prepareEventTimestamp)({ orderingKey, agentClock: event.created_at, notBeforeMs });
2513
2513
  const baseMetadata = {
2514
2514
  step_index: event.step_index,
2515
2515
  agy_source: event.source,
@@ -2788,8 +2788,18 @@ function truncate(s, maxBytes) {
2788
2788
  }
2789
2789
 
2790
2790
  // src/server.ts
2791
+ var MOBILE_PROMPT_FLOOR_RECENCY_MS = 12e4;
2791
2792
  var McpServer = class {
2792
2793
  constructor(options) {
2794
+ /** Per-session causal floor for transcript-event timestamps emitted right
2795
+ * after a MOBILE prompt. The mobile USER_PROMPT is created by the iOS app
2796
+ * (real ms clock) and never flows through prepareEventTimestamp, while the
2797
+ * agy ASSISTANT_RESPONSE is reconstructed from agy's SECOND-precision
2798
+ * transcript created_at — so within a shared wall-clock second the response
2799
+ * can sort BEFORE the prompt. We capture the prompt ms here and pass it as
2800
+ * `notBeforeMs`. Per-session + recency-bounded (MOBILE_PROMPT_FLOOR_RECENCY_MS).
2801
+ * (agy event-ordering fix 2026-05-30.) */
2802
+ this.mobilePromptFloorBySession = /* @__PURE__ */ new Map();
2793
2803
  /** v9 launch-session: ONE backend session per wrapper lifetime.
2794
2804
  * Created at start() before any tailer event can fire. All agy
2795
2805
  * conv UUIDs observed during this wrapper's lifetime emit events
@@ -2891,7 +2901,13 @@ var McpServer = class {
2891
2901
  (0, import_codevibe_core4.startDeviceKeyWatcher)(this.appSyncClient, logger);
2892
2902
  try {
2893
2903
  const swept = await this.appSyncClient.sweepOrphanSessions({
2894
- agentType: "ANTIGRAVITY"
2904
+ agentType: "ANTIGRAVITY",
2905
+ // 6 min (core default is 15 min). A live daemon heartbeats every
2906
+ // 2 min, so a session stale >6 min has missed 3 beats and is
2907
+ // provably dead — safe to reap without false-positiving a
2908
+ // concurrently-running agy wrapper, while catching orphans on the
2909
+ // next start sooner. (agy orphaned-session fix 2026-05-31.)
2910
+ staleThresholdMs: 6 * 60 * 1e3
2895
2911
  });
2896
2912
  if (swept > 0) {
2897
2913
  logger.info("Orphan sweep: marked stale Antigravity sessions INACTIVE", { swept });
@@ -2956,16 +2972,6 @@ var McpServer = class {
2956
2972
  }
2957
2973
  async doStop() {
2958
2974
  this.started = false;
2959
- try {
2960
- await this.transcriptTailer.stop();
2961
- } catch (err) {
2962
- logger.warn("transcriptTailer.stop failed", { error: String(err) });
2963
- }
2964
- try {
2965
- await this.paneObserver.stop();
2966
- } catch (err) {
2967
- logger.warn("paneObserver.stop failed", { error: String(err) });
2968
- }
2969
2975
  if (this.subscription) {
2970
2976
  try {
2971
2977
  this.subscription();
@@ -2980,8 +2986,11 @@ var McpServer = class {
2980
2986
  }
2981
2987
  }
2982
2988
  this.listenerHandles = [];
2983
- this.unregisterSignalHandlers();
2984
2989
  if (this.session) {
2990
+ try {
2991
+ this.appSyncClient.stopHeartbeat(this.session.sessionId);
2992
+ } catch {
2993
+ }
2985
2994
  try {
2986
2995
  await this.appSyncClient.updateSession({
2987
2996
  sessionId: this.session.sessionId,
@@ -2993,10 +3002,17 @@ var McpServer = class {
2993
3002
  error: String(err)
2994
3003
  });
2995
3004
  }
2996
- try {
2997
- this.appSyncClient.stopHeartbeat(this.session.sessionId);
2998
- } catch {
2999
- }
3005
+ }
3006
+ this.unregisterSignalHandlers();
3007
+ try {
3008
+ await this.transcriptTailer.stop();
3009
+ } catch (err) {
3010
+ logger.warn("transcriptTailer.stop failed", { error: String(err) });
3011
+ }
3012
+ try {
3013
+ await this.paneObserver.stop();
3014
+ } catch (err) {
3015
+ logger.warn("paneObserver.stop failed", { error: String(err) });
3000
3016
  }
3001
3017
  try {
3002
3018
  await this.approvalDetector.stop();
@@ -3146,7 +3162,16 @@ var McpServer = class {
3146
3162
  }
3147
3163
  this.observedMainConversationIds.add(conversationId);
3148
3164
  const session = this.session;
3149
- const mapped = mapTranscriptEvent(emit, session.sessionId);
3165
+ let notBeforeMs;
3166
+ const promptFloor = this.mobilePromptFloorBySession.get(session.sessionId);
3167
+ if (promptFloor) {
3168
+ if (Date.now() - promptFloor.setAtWallMs <= MOBILE_PROMPT_FLOOR_RECENCY_MS) {
3169
+ notBeforeMs = promptFloor.floorMs;
3170
+ } else {
3171
+ this.mobilePromptFloorBySession.delete(session.sessionId);
3172
+ }
3173
+ }
3174
+ const mapped = mapTranscriptEvent(emit, session.sessionId, notBeforeMs);
3150
3175
  for (const reg of mapped.pendingCallRegistrations) {
3151
3176
  this.approvalDetector.registerPendingCall(reg);
3152
3177
  }
@@ -3464,6 +3489,13 @@ var McpServer = class {
3464
3489
  }
3465
3490
  evt = decrypted;
3466
3491
  await this.markDelivered(evt);
3492
+ if (evt.type === import_codevibe_core4.EventType.USER_PROMPT || evt.type === import_codevibe_core4.EventType.PROMPT_RESPONSE) {
3493
+ const mobileFloorMs = Date.parse(evt.timestamp);
3494
+ this.mobilePromptFloorBySession.set(session.sessionId, {
3495
+ floorMs: Number.isNaN(mobileFloorMs) ? Date.now() : mobileFloorMs,
3496
+ setAtWallMs: Date.now()
3497
+ });
3498
+ }
3467
3499
  if (evt.type === import_codevibe_core4.EventType.USER_PROMPT) {
3468
3500
  let promptContent = evt.content;
3469
3501
  const attachments = evt.attachments ?? [];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@quantiya/codevibe-antigravity-plugin",
3
- "version": "1.0.7",
3
+ "version": "1.0.9",
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": {
@@ -48,7 +48,7 @@
48
48
  "node": ">=18.0.0"
49
49
  },
50
50
  "dependencies": {
51
- "@quantiya/codevibe-core": "^1.0.27",
51
+ "@quantiya/codevibe-core": "^1.0.28",
52
52
  "chokidar": "^5.0.0",
53
53
  "dotenv": "^16.6.1",
54
54
  "express": "^5.1.0",