@quantiya/codevibe-codex-plugin 2.0.53 → 2.0.54

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.
@@ -8786,7 +8786,7 @@ function reduceAction(state, action) {
8786
8786
  case "TEAM_TRACK_TERMINAL":
8787
8787
  return reduceTeamTrackTerminal(state, action.trackIndex, action.state);
8788
8788
  case "TEAM_TRACK_REVISING":
8789
- return reduceTeamTrackTerminal(state, action.trackIndex, "Revising");
8789
+ return reduceTeamTrackTerminal(state, action.trackIndex, "Revising", action.round);
8790
8790
  case "TEAM_TRACK_AWAITING_DECISION":
8791
8791
  return reduceTeamTrackTerminal(state, action.trackIndex, "AwaitingDecision");
8792
8792
  case "TEAM_GROUP_RESOLVED":
@@ -8795,7 +8795,10 @@ function reduceAction(state, action) {
8795
8795
  return reduceTaskProgressByTask(
8796
8796
  reduceTaskProgress(
8797
8797
  reduceReviewerStatusLine(
8798
- reduceSessionTaskTerminal(state, action.event),
8798
+ reduceSessionTaskTerminal(
8799
+ reduceTaskProgressForTeamTrack(state, action.event),
8800
+ action.event
8801
+ ),
8799
8802
  action.event
8800
8803
  ),
8801
8804
  action.event
@@ -8929,6 +8932,30 @@ function reduceSessionTaskTerminal(state, event) {
8929
8932
  });
8930
8933
  return { ...state, runningTasks, sessionTasks, terminalSequence: nextSeq };
8931
8934
  }
8935
+ function reduceTaskProgressForTeamTrack(state, event) {
8936
+ if (!state.team) return state;
8937
+ let taskId = event.progressTaskId ?? ("taskId" in event && typeof event.taskId == "string" ? event.taskId : void 0);
8938
+ if (!taskId) return state;
8939
+ for (let [trackIndex, track] of state.team.tracks.entries())
8940
+ if (track.taskId === taskId) {
8941
+ let eventRound = "round" in event && typeof event.round == "number" && event.round > 0 ? event.round : void 0, nextRound = eventRound !== void 0 ? Math.max(track.round ?? 0, eventRound) : track.round, nextState = event.phase === "revise_round" ? "Revising" : track.state;
8942
+ if (track.round === nextRound && track.state === nextState)
8943
+ return state;
8944
+ let tracks = new Map(state.team.tracks);
8945
+ return tracks.set(trackIndex, {
8946
+ ...track,
8947
+ state: nextState,
8948
+ ...nextRound !== void 0 ? { round: nextRound } : {}
8949
+ }), {
8950
+ ...state,
8951
+ team: {
8952
+ ...state.team,
8953
+ tracks
8954
+ }
8955
+ };
8956
+ }
8957
+ return state;
8958
+ }
8932
8959
  var REVIEWER_STATUS_PHASES = /* @__PURE__ */ new Set([
8933
8960
  "reviewers_dispatched",
8934
8961
  "seat_update",
@@ -9785,12 +9812,18 @@ function reduceTeamHalted(state, haltReason, completedAt) {
9785
9812
  lastReviewerProgress: null
9786
9813
  };
9787
9814
  }
9788
- function reduceTeamTrackTerminal(state, trackIndex, trackState) {
9815
+ function reduceTeamTrackTerminal(state, trackIndex, trackState, round) {
9789
9816
  if (!state.team) return state;
9790
9817
  let prior = state.team.tracks.get(trackIndex);
9791
- if (!prior || prior.state === trackState) return state;
9818
+ if (!prior) return state;
9819
+ let targetRound = round !== void 0 ? round : trackState === "Revising" ? typeof prior.round == "number" && prior.round > 0 ? prior.round : 1 : prior.round;
9820
+ if (prior.state === trackState && prior.round === targetRound) return state;
9792
9821
  let tracks = new Map(state.team.tracks);
9793
- tracks.set(trackIndex, { ...prior, state: trackState });
9822
+ tracks.set(trackIndex, {
9823
+ ...prior,
9824
+ state: trackState,
9825
+ ...targetRound !== void 0 ? { round: targetRound } : {}
9826
+ });
9794
9827
  let sessionTasks = state.sessionTasks, record = prior.taskId ? state.sessionTasks.get(prior.taskId) : void 0, terminalSequence = state.terminalSequence;
9795
9828
  if (prior.taskId && record) {
9796
9829
  let isTerminal = trackState === "Passed" || trackState === "Failed", nextSeq = isTerminal ? record.terminalSeq ?? (state.terminalSequence ?? 0) + 1 : void 0;
@@ -11797,7 +11830,7 @@ function MultiTrackStatusNode(props) {
11797
11830
  let entry = team.tracks.get(idx), details = [
11798
11831
  entry.agent,
11799
11832
  entry.taskId ? truncate(entry.taskId, 12) : null
11800
- ].filter((value) => value != null), detailsSuffix = details.length > 0 ? ` (${details.join(", ")})` : "";
11833
+ ].filter((value) => value != null), detailsSuffix = details.length > 0 ? ` (${details.join(", ")})` : "", stateLabel = entry.state === "Revising" && typeof entry.round == "number" && entry.round > 0 ? `Revising (Round ${entry.round})` : entry.state;
11801
11834
  return React14.createElement(
11802
11835
  Box,
11803
11836
  { key: `track-${idx}`, flexDirection: "row" },
@@ -11805,7 +11838,7 @@ function MultiTrackStatusNode(props) {
11805
11838
  React14.createElement(
11806
11839
  Text,
11807
11840
  { color: TRACK_STATE_COLOR[entry.state] },
11808
- entry.state
11841
+ stateLabel
11809
11842
  ),
11810
11843
  React14.createElement(Text, { dimColor: !0 }, detailsSuffix)
11811
11844
  );
@@ -54761,6 +54794,19 @@ var QuorumLoop = class _QuorumLoop {
54761
54794
  static resetGlobalAnnouncedOutages() {
54762
54795
  _QuorumLoop.globalAnnouncedOutages.clear(), _QuorumLoop.inFlightOutageEmissions.clear();
54763
54796
  }
54797
+ /**
54798
+ * Clears seen/recovered GateDispatch identifiers for a given task.
54799
+ * Invoked when a task transitions to auto-revise, handles revise feedback,
54800
+ * or restarts / replaces round-0 shadow so subsequent dispatches or recovery
54801
+ * for this task are not dropped as duplicate no-ops.
54802
+ */
54803
+ clearSeenGateDispatchRunIdsForTask(taskId, extraGateId) {
54804
+ extraGateId && (this.seenGateDispatchRunIds.delete(extraGateId), this.recoveredGateRunIds.delete(extraGateId));
54805
+ let activeGate = this.activeGateByTaskId.get(taskId);
54806
+ activeGate && (this.seenGateDispatchRunIds.delete(activeGate), this.recoveredGateRunIds.delete(activeGate));
54807
+ for (let [gateId, mappedTaskId] of this.taskByGateId.entries())
54808
+ mappedTaskId === taskId && (this.seenGateDispatchRunIds.delete(gateId), this.recoveredGateRunIds.delete(gateId));
54809
+ }
54764
54810
  /**
54765
54811
  * Slot key for parse-time briefs and the selected recovery projection.
54766
54812
  * Deletion/launch authority never uses this key alone.
@@ -55716,15 +55762,15 @@ var QuorumLoop = class _QuorumLoop {
55716
55762
  });
55717
55763
  return;
55718
55764
  }
55719
- if (this.seenGateDispatchRunIds.has(payload.gateRunId)) {
55720
- logger.info("[QuorumLoop] GateDispatch dedup no-op", { gateRunId: payload.gateRunId });
55721
- return;
55722
- }
55723
55765
  if (typeof envelopeTaskId == "string" && envelopeTaskId.length > 0 && // P45 D1 / P46a B1 — a dispatch for ANY single task this loop started (in
55724
55766
  // flight or confirmed, earlier or later) is a single-implementor dispatch;
55725
55767
  // only an unknown task id routes to the team handler.
55726
55768
  !this.singleTaskContextByTask.has(envelopeTaskId))
55727
55769
  return this.bufferTeamPacketDuringSeeding("gateDispatch", payload, envelopeTaskId) ? void 0 : this.handleTeamGateDispatch(payload, envelopeTaskId);
55770
+ if (this.seenGateDispatchRunIds.has(payload.gateRunId)) {
55771
+ logger.info("[QuorumLoop] GateDispatch dedup no-op", { gateRunId: payload.gateRunId });
55772
+ return;
55773
+ }
55728
55774
  let inFlightFor = typeof envelopeTaskId == "string" && envelopeTaskId.length > 0 ? envelopeTaskId : this.latestInFlightStart;
55729
55775
  if (inFlightFor !== null && this.startTasksInFlight.has(inFlightFor)) {
55730
55776
  logger.info("[QuorumLoop] GateDispatch buffered \u2014 startTask in flight (early-packet race)", {
@@ -56144,7 +56190,7 @@ var QuorumLoop = class _QuorumLoop {
56144
56190
  if (!stale) return;
56145
56191
  await stale.assertCanDiscard(), logger.info("[QuorumLoop] replacing a stale shadow for a fresh round-0 dispatch (restart)", {
56146
56192
  taskId
56147
- }), await stale.discard(), this.shadowsByTask.get(taskId) === stale && this.shadowsByTask.delete(taskId), this.userNotesByTask.delete(taskId), this.reviewScopeResetTasks.delete(taskId), this.roundHistoryByTask.delete(taskId), this.rationaleByTask.delete(taskId), this.taskDegradedMetadataByTask.delete(taskId), this.expectedRosterByTask.delete(taskId), this.activeGateByTaskId.delete(taskId), this.conflictedSeatsByTask.delete(taskId), this.nonApprovedSeatsByTask.delete(taskId);
56193
+ }), await stale.discard(), this.shadowsByTask.get(taskId) === stale && this.shadowsByTask.delete(taskId), this.userNotesByTask.delete(taskId), this.reviewScopeResetTasks.delete(taskId), this.roundHistoryByTask.delete(taskId), this.rationaleByTask.delete(taskId), this.taskDegradedMetadataByTask.delete(taskId), this.expectedRosterByTask.delete(taskId), this.clearSeenGateDispatchRunIdsForTask(taskId), this.activeGateByTaskId.delete(taskId), this.conflictedSeatsByTask.delete(taskId), this.nonApprovedSeatsByTask.delete(taskId);
56148
56194
  let nextFence = (this.restartFenceByTaskId.get(taskId) ?? 0) + 1;
56149
56195
  this.restartFenceByTaskId.set(taskId, nextFence), this.reviewedSnapshotByTask.delete(taskId);
56150
56196
  }
@@ -56920,7 +56966,7 @@ ${section}`);
56920
56966
  }
56921
56967
  let autoRevised = returnedState !== void 0 && returnedState !== "Failed";
56922
56968
  try {
56923
- autoRevised ? this.deps.onTeamTrackRevising?.({ taskGroupId, trackIndex }) : this.deps.onTeamTrackFailed?.({ taskGroupId, trackIndex, reason });
56969
+ autoRevised ? (this.clearSeenGateDispatchRunIdsForTask(taskId, gateId), this.deps.onTeamTrackRevising?.({ taskGroupId, trackIndex })) : this.deps.onTeamTrackFailed?.({ taskGroupId, trackIndex, reason });
56924
56970
  } catch (err) {
56925
56971
  logger.warn("[QuorumLoop] team-track render callback threw (non-fatal)", {
56926
56972
  taskGroupId,
@@ -60412,7 +60458,7 @@ ${section}`);
60412
60458
  });
60413
60459
  return;
60414
60460
  }
60415
- this.seenReviseFeedbackIds.add(payload.reviseFeedbackId);
60461
+ this.clearSeenGateDispatchRunIdsForTask(taskId, payload.gateId), this.seenReviseFeedbackIds.add(payload.reviseFeedbackId);
60416
60462
  let sessionKey = await this.deps.getSessionKey(this.deps.session.sessionId);
60417
60463
  if (trackEntry && teamAuthority && !this.teamEntryMayContinue(taskId, trackEntry, teamAuthority)) return;
60418
60464
  if (!sessionKey) {
@@ -81258,7 +81304,7 @@ function resolvePlannerAdapter(args) {
81258
81304
  adapter: hostedStack.adapter,
81259
81305
  runtimeKind: "hosted",
81260
81306
  runtimeLabel: "Hosted Gemma (AWS Bedrock)",
81261
- advisoryRunner: null,
81307
+ advisoryRunner: args.localPlanner.advisoryRunner,
81262
81308
  classifyRunner: args.localPlanner.classifyRunner,
81263
81309
  cache: hostedStack.cache,
81264
81310
  health: hostedStack.health,
@@ -1162,6 +1162,13 @@ export declare class QuorumLoop {
1162
1162
  * (stamping that set here would suppress the implementor entirely).
1163
1163
  */
1164
1164
  private readonly recoveredGateRunIds;
1165
+ /**
1166
+ * Clears seen/recovered GateDispatch identifiers for a given task.
1167
+ * Invoked when a task transitions to auto-revise, handles revise feedback,
1168
+ * or restarts / replaces round-0 shadow so subsequent dispatches or recovery
1169
+ * for this task are not dropped as duplicate no-ops.
1170
+ */
1171
+ private clearSeenGateDispatchRunIdsForTask;
1165
1172
  /**
1166
1173
  * §4.1 — in-session per-authority tombstone for a present-but-CORRUPT brief
1167
1174
  * ciphertext (decrypt threw during recovery PASS 1). Blocks BOTH recovery
@@ -649,6 +649,7 @@ export interface TeamTrackEntry {
649
649
  state: TeamTrackState;
650
650
  taskId?: string;
651
651
  agent?: string;
652
+ round?: number;
652
653
  }
653
654
  /**
654
655
  * [ADDITIVE WIDENING — CP-12 W3] Minimal team state. `null` for
@@ -1146,6 +1147,7 @@ export type OrchestrationAction = {
1146
1147
  } | {
1147
1148
  type: 'TEAM_TRACK_REVISING';
1148
1149
  trackIndex: number;
1150
+ round?: number;
1149
1151
  } | {
1150
1152
  type: 'TEAM_TRACK_AWAITING_DECISION';
1151
1153
  trackIndex: number;
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@quantiya/codevibe-core",
3
- "version": "2.0.46",
3
+ "version": "2.0.48",
4
4
  "description": "Core library for CodeVibe plugins - shared keychain, crypto, AppSync, and auth functionality",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@quantiya/codevibe-codex-plugin",
3
- "version": "2.0.53",
3
+ "version": "2.0.54",
4
4
  "description": "Control OpenAI Codex 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": {
@@ -47,7 +47,7 @@
47
47
  "node": ">=22.0.0"
48
48
  },
49
49
  "dependencies": {
50
- "@quantiya/codevibe-core": "^2.0.46",
50
+ "@quantiya/codevibe-core": "^2.0.48",
51
51
  "@quantiya/quorum-core": "^1.0.1",
52
52
  "chokidar": "^4.0.0",
53
53
  "dotenv": "^16.6.1",