ccdeck 3.43.0 → 3.43.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.
- package/dist/web/assets/{BrowserWatchModal-BPws0psH.js → BrowserWatchModal-1On-pA6T.js} +1 -1
- package/dist/web/assets/{RadioPanel-CDl7ZImm.js → RadioPanel-DkXAgxKR.js} +1 -1
- package/dist/web/assets/{TrafficRadar-D1hp6BgZ.js → TrafficRadar-DWilzdA3.js} +1 -1
- package/dist/web/assets/{UsageHistoryModal-DPcdpBpI.js → UsageHistoryModal-BW9jTi6E.js} +1 -1
- package/dist/web/assets/{app-9p127oSR.js → app-ByCusSHX.js} +5 -5
- package/dist/web/assets/{index-Bkx27-wy.js → index-CzIBjYsB.js} +1 -1
- package/dist/web/index.html +2 -2
- package/package.json +1 -1
- package/release-notes.json +2 -1
- package/src/server/cswap-auto-choice.mjs +13 -6
- package/src/server/cswap-auto-loop.mjs +16 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
import"./app-
|
|
1
|
+
import"./app-ByCusSHX.js";(function(){const t=document.createElement("link").relList;if(t&&t.supports&&t.supports("modulepreload"))return;for(const e of document.querySelectorAll('link[rel="modulepreload"]'))i(e);new MutationObserver(e=>{for(const r of e)if(r.type==="childList")for(const o of r.addedNodes)o.tagName==="LINK"&&o.rel==="modulepreload"&&i(o)}).observe(document,{childList:!0,subtree:!0});function s(e){const r={};return e.integrity&&(r.integrity=e.integrity),e.referrerPolicy&&(r.referrerPolicy=e.referrerPolicy),e.crossOrigin==="use-credentials"?r.credentials="include":e.crossOrigin==="anonymous"?r.credentials="omit":r.credentials="same-origin",r}function i(e){if(e.ep)return;e.ep=!0;const r=s(e);fetch(e.href,r)}})();
|
package/dist/web/index.html
CHANGED
|
@@ -77,8 +77,8 @@
|
|
|
77
77
|
document.documentElement.setAttribute("data-density", density === "tightest" || density === "tighter" || density === "compact" || density === "comfortable" ? density : "default");
|
|
78
78
|
})();
|
|
79
79
|
</script>
|
|
80
|
-
<script type="module" crossorigin src="/assets/index-
|
|
81
|
-
<link rel="modulepreload" crossorigin href="/assets/app-
|
|
80
|
+
<script type="module" crossorigin src="/assets/index-CzIBjYsB.js"></script>
|
|
81
|
+
<link rel="modulepreload" crossorigin href="/assets/app-ByCusSHX.js">
|
|
82
82
|
<link rel="stylesheet" crossorigin href="/assets/app-DsHSufBt.css">
|
|
83
83
|
</head>
|
|
84
84
|
<body>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ccdeck",
|
|
3
|
-
"version": "3.43.
|
|
3
|
+
"version": "3.43.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": {
|
package/release-notes.json
CHANGED
|
@@ -146,14 +146,21 @@ async function engineState(accounts) {
|
|
|
146
146
|
};
|
|
147
147
|
}
|
|
148
148
|
|
|
149
|
-
/** The accounts
|
|
149
|
+
/** The accounts paired decks have recently said they are working on.
|
|
150
150
|
* One login live on two machines races for every renewal (README, "One login
|
|
151
|
-
* live in one place"), so a tick never moves onto one of them.
|
|
152
|
-
|
|
151
|
+
* live in one place"), so a tick never moves onto one of them. The LAN table
|
|
152
|
+
* retains old manifests for display after a peer goes quiet; those are not
|
|
153
|
+
* current reservations. Use the authenticated manifest's receipt time, not a
|
|
154
|
+
* beacon or a failed round, which cannot confirm the account still in use. */
|
|
155
|
+
async function accountsOnOtherDecks(now) {
|
|
153
156
|
try {
|
|
154
|
-
const { lanEngine } = await
|
|
157
|
+
const [{ lanEngine }, { PRESENT_MS }] = await Promise.all([
|
|
158
|
+
import("./lan-deck.mjs"), import("./lan-sync.mjs"),
|
|
159
|
+
]);
|
|
155
160
|
const peers = lanEngine.status()?.peers ?? [];
|
|
156
|
-
return new Set(peers
|
|
161
|
+
return new Set(peers
|
|
162
|
+
.filter(p => p?.paired === true && Number.isFinite(p.offers?.at) && p.offers.at > 0 && now - p.offers.at < PRESENT_MS)
|
|
163
|
+
.map(p => p.offers.current?.key).filter(k => typeof k === "string"));
|
|
157
164
|
} catch {
|
|
158
165
|
return new Set();
|
|
159
166
|
}
|
|
@@ -242,7 +249,7 @@ export async function chooseBeforeEngine({ now = Date.now() } = {}) {
|
|
|
242
249
|
choice: { next: choice.next, home: choice.home?.key ?? null, manual, goHome },
|
|
243
250
|
threshold,
|
|
244
251
|
models,
|
|
245
|
-
busy: new Set([...await accountsOnOtherDecks(), ...await accountsInCswapRun(accounts)]),
|
|
252
|
+
busy: new Set([...await accountsOnOtherDecks(now), ...await accountsInCswapRun(accounts)]),
|
|
246
253
|
quarantined: engine.quarantined,
|
|
247
254
|
sinceMove: now - Math.max(choice.lastMoveAt, engine.lastSwitchAt),
|
|
248
255
|
cooldownMs: numberOr(cfg["autoswitch.cooldownSeconds"]?.value, 300) * 1000,
|
|
@@ -102,8 +102,23 @@ async function runAutoTick() {
|
|
|
102
102
|
if (await externalAutoRunning()) return { skipped: "external-engine" };
|
|
103
103
|
// The deck's own rules first. A move they make is the tick; when they have
|
|
104
104
|
// nothing to say — or cannot say it — the engine decides, as it always did.
|
|
105
|
-
|
|
105
|
+
let chose = await chooseBeforeEngine().catch(() => ({ result: null, accounts: null }));
|
|
106
106
|
if (chose.result) return { chose: chose.result };
|
|
107
|
+
// The store may still have a reading from before the active account
|
|
108
|
+
// reached its limit. The engine polls before deciding; letting
|
|
109
|
+
// its real tick run now would switch by `best` before our weekly/home
|
|
110
|
+
// rules ever saw that reading. Poll without moving first, then give the
|
|
111
|
+
// configured rules the refreshed roster under this same store lock.
|
|
112
|
+
// No rule configured (accounts === null) keeps the original single run.
|
|
113
|
+
if (chose.accounts) {
|
|
114
|
+
const preview = await run(await cswapBin(), ["auto", "--once", "--json", "--dry-run"], { timeout: TICK_TIMEOUT_MS });
|
|
115
|
+
if (preview.timedOut || (!preview.ok && !preview.stdout)) return preview;
|
|
116
|
+
if (!_enabled) return { skipped: "disabled" };
|
|
117
|
+
if (await externalAutoRunning()) return { skipped: "external-engine" };
|
|
118
|
+
invalidateClaudeAccountsCache();
|
|
119
|
+
chose = await chooseBeforeEngine().catch(() => ({ result: null, accounts: null }));
|
|
120
|
+
if (chose.result) return { chose: chose.result };
|
|
121
|
+
}
|
|
107
122
|
const out = await run(await cswapBin(), ["auto", "--once", "--json"], { timeout: TICK_TIMEOUT_MS });
|
|
108
123
|
return { ...out, accounts: chose.accounts };
|
|
109
124
|
});
|