@bivy/bivy 0.17.3-staging.12 → 0.17.3-staging.14

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.
@@ -1271,6 +1271,7 @@ button.sheet-action:last-child { border-bottom: 0; }
1271
1271
  .fork-select-field select { width: 100%; padding: 10px 12px; border: 1px solid var(--line-strong); border-radius: var(--radius-md); background: var(--surface); color: var(--ink); }
1272
1272
  .fork-toggle { display: flex; align-items: center; gap: 8px; padding: 10px 12px; font-size: 13px; color: var(--ink); }
1273
1273
  .fork-toggle input { width: 16px; height: 16px; }
1274
+ .fork-note { margin: 0; padding: var(--space-2) var(--space-3); color: var(--muted); font-size: var(--text-sm); line-height: var(--lh-sm); }
1274
1275
  .fork-error { margin: 4px 12px; padding: 8px 10px; border-radius: var(--radius-md); background: var(--surface-2); color: var(--danger); font-size: 12px; }
1275
1276
  .fork-warn { margin: 4px 12px; padding: 8px 10px; border-radius: var(--radius-md); background: var(--surface-2); color: var(--muted); font-size: 12px; }
1276
1277
  .fork-submit { width: calc(100% - 24px); margin: var(--space-2) var(--space-3); }
@@ -3202,7 +3203,7 @@ select.picker-search { appearance: auto; }
3202
3203
  .automation-history-view .autom-section-head > strong { min-width: 0; line-height: var(--lh-lg); }
3203
3204
  }
3204
3205
 
3205
- /* Device handoff (HandoffBanner): sits above the composer like the composer
3206
- itself, with one line of the other device's draft. */
3206
+ /* Handoff notes above the composer (HandoffBanner, StandbyNotice): shaped like
3207
+ the composer itself, with one line of another device's draft. */
3207
3208
  .handoff-banner { border-radius: var(--radius-md); }
3208
3209
  .handoff-preview { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
package/dist/server.js CHANGED
@@ -1834,6 +1834,20 @@ const replication = new ReplicationService({
1834
1834
  },
1835
1835
  log: (m) => console.error(`[replication] ${m}`),
1836
1836
  });
1837
+ /** Take over a replicated session on this node (manual promotion). Once it
1838
+ * wins the epoch it is this node's session, not a standby copy: retag it so
1839
+ * every client stops offering "Continue here", and push the new list. */
1840
+ async function promoteReplicaHere(sessionId) {
1841
+ const epoch = await replication.promote(sessionId, identity.nodeId);
1842
+ if (epoch === undefined)
1843
+ return undefined;
1844
+ const source = metadata.getSession(sessionId)?.source;
1845
+ if (source?.startsWith("replica"))
1846
+ metadata.upsertSession({ id: sessionId, source: source.replace(/^replica/, "promoted") });
1847
+ broadcastSessionsList();
1848
+ scheduleAdvertise();
1849
+ return epoch;
1850
+ }
1837
1851
  // Retire the legacy overlay sidecars. The append-only log is the sole overlay
1838
1852
  // store now and every session was migrated into it by the prior release's boot
1839
1853
  // migration (.migrated-overlays-v1), verified complete on-disk before this landed.
@@ -2779,10 +2793,9 @@ const RELAY_COMMANDS = {
2779
2793
  const sessionId = String(msg.sessionId ?? "").trim();
2780
2794
  if (!sessionId)
2781
2795
  return ctx.reply({ type: "session.promote.result", requestId, ok: false, error: "Missing sessionId" });
2782
- const epoch = await replication.promote(sessionId, identity.nodeId);
2796
+ const epoch = await promoteReplicaHere(sessionId);
2783
2797
  if (epoch === undefined)
2784
2798
  return ctx.reply({ type: "session.promote.result", requestId, ok: false, error: "Promotion lost the epoch race" });
2785
- scheduleAdvertise();
2786
2799
  ctx.reply({ type: "session.promote.result", requestId, ok: true, sessionId, epoch });
2787
2800
  },
2788
2801
  // Ephemeral provisioning transport (node-broker path). A remote device that
@@ -11265,10 +11278,9 @@ app.post("/api/session/promote", async (req, res, next) => {
11265
11278
  const sessionId = String(req.body?.sessionId ?? "").trim();
11266
11279
  if (!sessionId)
11267
11280
  return res.status(400).json({ error: "Missing sessionId" });
11268
- const epoch = await replication.promote(sessionId, identity.nodeId);
11281
+ const epoch = await promoteReplicaHere(sessionId);
11269
11282
  if (epoch === undefined)
11270
11283
  return res.status(409).json({ error: "Promotion lost the epoch race (another node owns it, or it isn't replicated)" });
11271
- scheduleAdvertise();
11272
11284
  res.json({ ok: true, epoch });
11273
11285
  }
11274
11286
  catch (error) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bivy/bivy",
3
- "version": "0.17.3-staging.12",
3
+ "version": "0.17.3-staging.14",
4
4
  "type": "module",
5
5
  "license": "AGPL-3.0-only",
6
6
  "description": "Run coding agents on machines you own. Open-source, self-hostable agent workspace.",