ccdeck 3.37.0 → 3.37.1

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.
@@ -64,7 +64,7 @@
64
64
  stored === "light" || (stored !== "dark" && light) ? "light" : "dark");
65
65
  })();
66
66
  </script>
67
- <script type="module" crossorigin src="/assets/index-wCbqcRJd.js"></script>
67
+ <script type="module" crossorigin src="/assets/index-DDxnWaTa.js"></script>
68
68
  <link rel="stylesheet" crossorigin href="/assets/index-B0SOa-XB.css">
69
69
  </head>
70
70
  <body>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ccdeck",
3
- "version": "3.37.0",
3
+ "version": "3.37.1",
4
4
  "description": "Local dashboard for Claude Code and Codex CLI sessions: which Claude Code session needs input, every tool call and Claude Code subagent live, token cost and quota, several Claude accounts. Run npx ccdeck.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -71,6 +71,12 @@
71
71
  "3.36.9",
72
72
  "3.37.0"
73
73
  ],
74
+ "3.37.1": [
75
+ {
76
+ "title": "🔁 Expired logins repair from your other machines",
77
+ "body": "When a login stops working on this machine and a machine you paired with still has it working and ticked, Local network now copies it back on the next round, whether or not the account is ticked here. Before, it stayed marked expired until the account was ticked here as well, or deleted so that it arrived again. A machine that paired on its own, through Say yes to every deck that asks, still repairs only the accounts ticked here."
78
+ }
79
+ ],
74
80
  "3.36.3": [
75
81
  {
76
82
  "title": "🔑 An expired login asks to be signed in again",
@@ -139,10 +139,10 @@ export { anotherMachine };
139
139
  /**
140
140
  * Whether an account this round just placed is ticked for sharing here (#1188).
141
141
  *
142
- * ONLY AN ADD: a heal needed the tick to happen at all — roundWith asks for a
143
- * heal only for an account this deck already shares — so there is nothing to
144
- * add for one, and an account healed after somebody unticked it must not be
145
- * ticked again behind them.
142
+ * ONLY AN ADD: a healed slot was already here, so whether it is ticked is
143
+ * already somebody's decision — ticked, there is nothing to add; unticked,
144
+ * possibly on purpose, and an account healed after somebody unticked it must
145
+ * not be ticked again behind them.
146
146
  *
147
147
  * ONLY FROM THE LOCAL NETWORK: the reasoning for the default is that the login
148
148
  * came from the group and the group therefore has it, and a tailnet can reach
@@ -727,23 +727,32 @@ export function createEngine({
727
727
  if (!stillPaired()) throw new Error("peer no longer paired");
728
728
  if (theirs?.t !== "manifest" || !Array.isArray(theirs.accounts)) throw new Error("no manifest");
729
729
  const list = keepManifest(conn.key, theirs, conn.peerFp);
730
- // Only accounts I have also ticked. Sharing is mutual by construction:
731
- // a peer cannot push an account at me that I never agreed to hold.
732
- // A HEAL NEEDS MY TICK; AN ADD DOES NOT, and the asymmetry is deliberate.
733
- // Healing replaces a slot I already have, so it is only reasonable for an
734
- // account I said I share. Adding is the case the owner asked for by name:
735
- // an account that appears among the decks I paired with appears on all of
736
- // them, which is the whole of "I do not want to paste blobs any more".
737
- // What can reach this is what a deck somebody here pressed accept on
738
- // chose to offer.
730
+ // FROM A DECK SOMEBODY HERE CHOSE, NEITHER AN ADD NOR A HEAL NEEDS MY
731
+ // TICK. Adding is the case the owner asked for by name: an account that
732
+ // appears among the decks I paired with appears on all of them, which is
733
+ // the whole of "I do not want to paste blobs any more". What can reach
734
+ // this is what a deck somebody here pressed accept on chose to offer.
735
+ //
736
+ // A heal used to need the tick, on the reasoning that it replaces a slot
737
+ // I already have. It replaces only one claude-swap has quarantined, with
738
+ // the same account's working copy, through the same plain import an add
739
+ // uses — strictly less than an add does. And the tick is the owner's
740
+ // answer to "offer this account" (LanSetupModal), not to "repair it":
741
+ // gating the repair on it left a login dead here for as long as nobody
742
+ // ticked it, while deleting the dead slot turned the same transfer into
743
+ // an add that went straight through. So people deleted accounts to fix
744
+ // them. A copy dies on its own, too — claude-swap's refresh rotates the
745
+ // token, and every other deck holding the old one gets invalid_grant —
746
+ // so this is the ordinary case between one person's machines, not an
747
+ // edge.
739
748
  //
740
749
  // WHICH IS ONLY TRUE OF A DECK SOMEBODY CHOSE. The accept switch presses
741
750
  // accept for the owner, so "somebody here pressed accept" is not a
742
751
  // premise about a deck it paired: nobody here chose that deck, and the
743
- // logins this store holds would be whatever it decided to offer. A deck
744
- // the switch paired is treated as a heal is — what it offers comes in
745
- // only for an account ticked here — and a person's own press or invite
746
- // takes the mark off its pin (see addTrusted).
752
+ // logins this store holds would be whatever it decided to offer. What a
753
+ // deck the switch paired offers comes in — added or healed — only for an
754
+ // account ticked here, and a person's own press or invite takes the mark
755
+ // off its pin (see addTrusted).
747
756
  // OVER `list`, NOT THE RAW ARRAY. `offered`, which keepManifest runs the
748
757
  // list through above (see lan-manifest.mjs), slices to 50 and type-
749
758
  // filters `key` and `email`; this line read `theirs.accounts` and got
@@ -755,12 +764,13 @@ export function createEngine({
755
764
  // waited behind it. `step.key` also reached transferChallenge and
756
765
  // importAccount untyped, which `offered`'s filter would have caught.
757
766
  const chosen = () => trustedPeer(cfg.trusted, conn.peerFp)?.auto !== true;
758
- const takes = step => cfg.shared.includes(step.key) || (step.action === "add" && chosen());
767
+ const takes = step => chosen() || cfg.shared.includes(step.key);
759
768
  const wanted = plan(mine, list).filter(takes);
760
769
  // TWO CHECKS, BECAUSE THEY END DIFFERENT THINGS. Losing the session —
761
770
  // LAN switched off, the peer unpaired (`stillPaired`, above) — ends the
762
- // round. A heal unticked mid-round ends only that heal: the adds behind
763
- // it need no tick, and the skipped row says why rather than vanishing.
771
+ // round. From a deck the switch paired, an account unticked mid-round
772
+ // ends only that step: the next one may still be ticked, and the skipped
773
+ // row says why rather than vanishing.
764
774
  const stillWanted = takes;
765
775
  /** One login, asked for and opened: a `want` carrying its own proof that
766
776
  * names the account (see transferChallenge), and the `have` opened under