instar 1.3.627 → 1.3.629

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 (48) hide show
  1. package/dashboard/subscriptions.js +50 -0
  2. package/dist/commands/server.d.ts.map +1 -1
  3. package/dist/commands/server.js +9 -0
  4. package/dist/commands/server.js.map +1 -1
  5. package/dist/config/ConfigDefaults.d.ts.map +1 -1
  6. package/dist/config/ConfigDefaults.js +28 -0
  7. package/dist/config/ConfigDefaults.js.map +1 -1
  8. package/dist/core/EnrollmentWizard.d.ts +8 -0
  9. package/dist/core/EnrollmentWizard.d.ts.map +1 -1
  10. package/dist/core/EnrollmentWizard.js +12 -0
  11. package/dist/core/EnrollmentWizard.js.map +1 -1
  12. package/dist/core/FencedLease.d.ts +23 -4
  13. package/dist/core/FencedLease.d.ts.map +1 -1
  14. package/dist/core/FencedLease.js +44 -4
  15. package/dist/core/FencedLease.js.map +1 -1
  16. package/dist/core/LeaseCoordinator.d.ts +47 -0
  17. package/dist/core/LeaseCoordinator.d.ts.map +1 -1
  18. package/dist/core/LeaseCoordinator.js +89 -7
  19. package/dist/core/LeaseCoordinator.js.map +1 -1
  20. package/dist/core/MultiMachineCoordinator.d.ts +73 -0
  21. package/dist/core/MultiMachineCoordinator.d.ts.map +1 -1
  22. package/dist/core/MultiMachineCoordinator.js +221 -6
  23. package/dist/core/MultiMachineCoordinator.js.map +1 -1
  24. package/dist/core/PendingLoginStore.d.ts.map +1 -1
  25. package/dist/core/PendingLoginStore.js +21 -2
  26. package/dist/core/PendingLoginStore.js.map +1 -1
  27. package/dist/core/PostUpdateMigrator.d.ts.map +1 -1
  28. package/dist/core/PostUpdateMigrator.js +18 -1
  29. package/dist/core/PostUpdateMigrator.js.map +1 -1
  30. package/dist/core/devGatedFeatures.d.ts.map +1 -1
  31. package/dist/core/devGatedFeatures.js +10 -0
  32. package/dist/core/devGatedFeatures.js.map +1 -1
  33. package/dist/core/types.d.ts +66 -0
  34. package/dist/core/types.d.ts.map +1 -1
  35. package/dist/core/types.js.map +1 -1
  36. package/dist/scaffold/templates.d.ts.map +1 -1
  37. package/dist/scaffold/templates.js +2 -0
  38. package/dist/scaffold/templates.js.map +1 -1
  39. package/dist/server/routes.d.ts.map +1 -1
  40. package/dist/server/routes.js +112 -0
  41. package/dist/server/routes.js.map +1 -1
  42. package/package.json +1 -1
  43. package/src/data/builtin-manifest.json +64 -64
  44. package/src/scaffold/templates.ts +2 -0
  45. package/upgrades/1.3.628.md +23 -0
  46. package/upgrades/1.3.629.md +31 -0
  47. package/upgrades/side-effects/matrix-cell-operator-cancel.md +151 -0
  48. package/upgrades/side-effects/multi-machine-lease-self-heal.md +45 -0
@@ -471,6 +471,17 @@ export function renderAccountMatrix(doc, target, poolScope, pendingScope, transi
471
471
  const word = c.state === 'offline' ? 'unknown' : MATRIX_CELL_WORD[c.state];
472
472
  const glyph = MATRIX_CELL_GLYPH[c.state] || '';
473
473
  td.appendChild(el(doc, 'span', 'sub-matrix-glyph', `${glyph} ${word}`.trim()));
474
+ // An in-progress (◷) cell gets a tappable Cancel so a mis-tapped setup can be
475
+ // reversed (abandon the login + tear down its pane). Emitted on the DURABLE
476
+ // re-rendered cell (not just the live sign-in DOM) so it survives the poll loop.
477
+ // The login id === accountId for a matrix login; the relay routes to self/peer.
478
+ if (c.state === 'in-progress') {
479
+ const cancelBtn = el(doc, 'button', 'sub-matrix-cancel', 'Cancel');
480
+ cancelBtn.setAttribute('data-matrix-cancel', '1');
481
+ cancelBtn.setAttribute('data-account-id', sanitizeForDisplay(c.accountId, 'label'));
482
+ cancelBtn.setAttribute('data-machine-id', sanitizeForDisplay(c.machineId, 'label'));
483
+ td.appendChild(cancelBtn);
484
+ }
474
485
  }
475
486
  tr.appendChild(td);
476
487
  }
@@ -503,6 +514,7 @@ const URLS = {
503
514
  // uses, with peers merged); start-cell is the PIN-gated "Set up" orchestrator over the chain.
504
515
  accountsPool: '/subscription-pool?scope=pool',
505
516
  startCell: '/subscription-pool/matrix/start-cell', // POST (PIN-gated) — start a cell's sign-in
517
+ cancel: '/subscription-pool/follow-me/cancel', // POST (Bearer, no PIN) — cancel an in-flight cell (relay → self/peer)
506
518
  };
507
519
 
508
520
  export function createController(opts) {
@@ -711,6 +723,8 @@ export function createController(opts) {
711
723
  if (confirmBtn && els.matrix.contains(confirmBtn)) { onConfirmTap(confirmBtn); return; }
712
724
  const codeBtn = t.closest('[data-matrix-code-submit]');
713
725
  if (codeBtn && els.matrix.contains(codeBtn)) { onCodeTap(codeBtn); return; }
726
+ const cancelBtn = t.closest('[data-matrix-cancel]');
727
+ if (cancelBtn && els.matrix.contains(cancelBtn)) { onCancelTap(cancelBtn); return; }
714
728
  });
715
729
  }
716
730
 
@@ -848,6 +862,42 @@ export function createController(opts) {
848
862
  })();
849
863
  }
850
864
 
865
+ // Cancel an in-flight cell: POST the Bearer-only cancel relay (self/peer), abandoning
866
+ // the login + tearing down its pane. No PIN (mirrors the code-submit step — a PIN can't
867
+ // cross the mesh). Reversible: the cell frees up to re-tap "Set up". Guarded by a native
868
+ // confirm where available (degrades to proceed under jsdom/headless).
869
+ function onCancelTap(btn) {
870
+ const cell = matrixCellOf(btn);
871
+ if (!cell) return;
872
+ const accountId = btn.getAttribute('data-account-id');
873
+ const machineId = btn.getAttribute('data-machine-id');
874
+ if (!accountId || !machineId) { setCellStatus(cell, 'Couldn’t prepare this — please refresh.'); return; }
875
+ const view = doc.defaultView;
876
+ if (view && typeof view.confirm === 'function') {
877
+ let ok = true;
878
+ try { ok = view.confirm('Cancel this in-progress setup?'); } catch (e) { ok = true; }
879
+ if (!ok) return;
880
+ }
881
+ setCellStatus(cell, 'Cancelling…');
882
+ btn.setAttribute('disabled', '1');
883
+ void (async () => {
884
+ try {
885
+ const r = await postJson(URLS.cancel, { machineId, id: accountId });
886
+ if (r.ok && r.json && (r.json.cancelled || r.json.alreadyTerminal)) {
887
+ delete state.matrixTransient[`${accountId}::${machineId}`];
888
+ setCellStatus(cell, 'Cancelled — you can set this up again.');
889
+ } else {
890
+ const msg = (r.json && (r.json.error || r.json.reason)) ? (r.json.error || r.json.reason) : `failed (${r.status})`;
891
+ setCellStatus(cell, `Couldn’t cancel: ${msg}`);
892
+ btn.removeAttribute('disabled');
893
+ }
894
+ } catch (e) {
895
+ setCellStatus(cell, 'Couldn’t reach the server — try again.');
896
+ btn.removeAttribute('disabled');
897
+ }
898
+ })();
899
+ }
900
+
851
901
  function reschedule() {
852
902
  if (!state.active) return;
853
903
  if (state.timerId != null) cancel(state.timerId);
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/commands/server.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAoCH,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAS3D,OAAO,EAAE,eAAe,EAAiC,MAAM,iCAAiC,CAAC;AAwBjG,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAGvD,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAkH7D,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAsBtD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,yBAAyB,CACvC,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,gBAAgB,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAC1C,OAAO,CAUT;AAyID,UAAU,YAAY;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;2DACuD;IACvD,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAy4CD,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,eAAe,EACzB,cAAc,EAAE,cAAc,EAC9B,YAAY,CAAC,EAAE,YAAY,EAC3B,WAAW,CAAC,EAAE,WAAW,EACzB,WAAW,CAAC,EAAE,WAAW,EACzB,iBAAiB,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,EAGvE,UAAU,CAAC,EAAE,MAAM,OAAO,8BAA8B,EAAE,WAAW,GAAG,IAAI,EAK5E,qBAAqB,CAAC,EAAE,MAAM,OAAO,gCAAgC,EAAE,kBAAkB,GAAG,IAAI,EAKhG,mBAAmB,CAAC,EAAE,MAAM,MAAM,GAAG,IAAI,GAAG,SAAS,GACpD,IAAI,CA8eN;AA2lBD,wBAAsB,WAAW,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAi8etE;AAED,wBAAsB,UAAU,CAAC,OAAO,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAsDzE;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,aAAa,CAAC,OAAO,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAuD5E"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/commands/server.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAoCH,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAS3D,OAAO,EAAE,eAAe,EAAiC,MAAM,iCAAiC,CAAC;AAwBjG,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAGvD,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAkH7D,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAsBtD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,yBAAyB,CACvC,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,gBAAgB,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAC1C,OAAO,CAUT;AAyID,UAAU,YAAY;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;2DACuD;IACvD,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAy4CD,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,eAAe,EACzB,cAAc,EAAE,cAAc,EAC9B,YAAY,CAAC,EAAE,YAAY,EAC3B,WAAW,CAAC,EAAE,WAAW,EACzB,WAAW,CAAC,EAAE,WAAW,EACzB,iBAAiB,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,EAGvE,UAAU,CAAC,EAAE,MAAM,OAAO,8BAA8B,EAAE,WAAW,GAAG,IAAI,EAK5E,qBAAqB,CAAC,EAAE,MAAM,OAAO,gCAAgC,EAAE,kBAAkB,GAAG,IAAI,EAKhG,mBAAmB,CAAC,EAAE,MAAM,MAAM,GAAG,IAAI,GAAG,SAAS,GACpD,IAAI,CA8eN;AA2lBD,wBAAsB,WAAW,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAy8etE;AAED,wBAAsB,UAAU,CAAC,OAAO,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAsDzE;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,aAAa,CAAC,OAAO,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAuD5E"}
@@ -3931,6 +3931,15 @@ export async function startServer(options) {
3931
3931
  return dead;
3932
3932
  },
3933
3933
  onEpochAdvance: (epoch) => coordinator.emit('leaseEpochChange', epoch),
3934
+ // F2 (multi-machine-lease-self-heal staleHolderTakeover) — DARK by default.
3935
+ // Resolved LIVE each call so a config flip needs no restart; off ⇒ canAcquire
3936
+ // is byte-for-byte the legacy behavior.
3937
+ staleHolderTakeover: () => {
3938
+ const sht = config.multiMachine?.leaseSelfHeal?.staleHolderTakeover;
3939
+ if (!sht?.enabled)
3940
+ return null;
3941
+ return { enabled: true, nonRenewalMissedObservations: sht.nonRenewalMissedObservations ?? 6 };
3942
+ },
3934
3943
  onSelfSuspend: (reason) => console.log(pc.yellow(` [lease] self-suspend: ${reason}`)),
3935
3944
  onEscalate: (info) => console.log(pc.yellow(` [lease] split-brain escalation: ${info.reason} (holder ${info.holder})`)),
3936
3945
  logger: (m) => console.log(pc.dim(m)),