@rikcodes/teamclaude 1.1.22-rik.5 → 1.1.22-rik.6
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/package.json +1 -1
- package/src/index.js +2 -2
- package/src/tui.js +36 -20
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rikcodes/teamclaude",
|
|
3
|
-
"version": "1.1.22-rik.
|
|
3
|
+
"version": "1.1.22-rik.6",
|
|
4
4
|
"description": "Multi-account proxy for Claude Code and Codex: pools Claude Max, ChatGPT/Codex, API-key and third-party backend accounts, and rotates on quota",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "src/index.js",
|
package/src/index.js
CHANGED
|
@@ -37,7 +37,7 @@ import { ResetCreditRedeemer } from './codex-reset-credits.js';
|
|
|
37
37
|
import { Warmer } from './warmer.js';
|
|
38
38
|
import { formatWarmupScheduleConfirmation, resolveWarmupConfig } from './warmup-schedule.js';
|
|
39
39
|
import { Sidecar, SIDECAR_DRAIN_GRACE_MS, SIDECAR_SHUTDOWN_GRACE_MS } from './sidecar.js';
|
|
40
|
-
import { TUI } from './tui.js';
|
|
40
|
+
import { TUI, ACCOUNT_SORTS } from './tui.js';
|
|
41
41
|
import { SessionTitles } from './session-titles.js';
|
|
42
42
|
import { captureEarlyConsole } from './early-log.js';
|
|
43
43
|
import { RemoteControl, createAttachSession } from './tui-remote.js';
|
|
@@ -535,7 +535,7 @@ async function serverCommand() {
|
|
|
535
535
|
// Read by the server per request and by the TUI per frame, so the reload
|
|
536
536
|
// is the whole application: the next request is timed, or is not.
|
|
537
537
|
config.throughputMeter = diskConfig.throughputMeter === true;
|
|
538
|
-
config.accountSort = diskConfig.accountSort
|
|
538
|
+
config.accountSort = ACCOUNT_SORTS.includes(diskConfig.accountSort) ? diskConfig.accountSort : 'arranged';
|
|
539
539
|
// Read by `run`/`env` from disk, but the TUI settings screen shows it live.
|
|
540
540
|
config.defaultClientMode = diskConfig.defaultClientMode === 'base-url' ? 'base-url' : 'mitm';
|
|
541
541
|
// The fleet switch for spending Codex reset credits. The redeemer reads it
|
package/src/tui.js
CHANGED
|
@@ -287,21 +287,36 @@ const PANE_MIN = 62;
|
|
|
287
287
|
const listRank = (/** @type {any} */ a) => (Number.isFinite(a?.displayOrder) ? a.displayOrder : Infinity);
|
|
288
288
|
|
|
289
289
|
// How the account list is ordered inside each provider group (`accountSort`).
|
|
290
|
-
// `arranged` is the operator's own order (listRank)
|
|
291
|
-
// account whose
|
|
290
|
+
// `arranged` is the operator's own order (listRank). Each of the others puts
|
|
291
|
+
// the account whose window ends soonest first, so quota that is about to
|
|
292
292
|
// expire unspent is at the top of the list.
|
|
293
|
-
|
|
293
|
+
//
|
|
294
|
+
// The window each sort reads. S7 and F7 are the family's own weekly bucket
|
|
295
|
+
// where the account has one, else the all-models weekly, which is what governs
|
|
296
|
+
// that family on such an account — the rule quota-summary.js resolves a
|
|
297
|
+
// family's window by.
|
|
298
|
+
/** @type {Record<string, (q: any) => any>} */
|
|
299
|
+
const SORT_RESET = {
|
|
300
|
+
'session-reset': q => q.unified5hReset,
|
|
301
|
+
'weekly-reset': q => q.unified7dReset,
|
|
302
|
+
'sonnet-reset': q => (q.unified7dSonnet != null ? q.unified7dSonnetReset : q.unified7dReset),
|
|
303
|
+
'fable-reset': q => (q.unified7dFable != null ? q.unified7dFableReset : q.unified7dReset),
|
|
304
|
+
};
|
|
305
|
+
export const ACCOUNT_SORTS = ['arranged', ...Object.keys(SORT_RESET)];
|
|
294
306
|
/** @type {Record<string, string>} */
|
|
295
|
-
const ACCOUNT_SORT_LABELS = {
|
|
307
|
+
const ACCOUNT_SORT_LABELS = {
|
|
308
|
+
arranged: 'arranged',
|
|
309
|
+
'session-reset': 'session reset',
|
|
310
|
+
'weekly-reset': 'weekly reset',
|
|
311
|
+
'sonnet-reset': 'S7 reset',
|
|
312
|
+
'fable-reset': 'F7 reset',
|
|
313
|
+
};
|
|
296
314
|
|
|
297
|
-
//
|
|
298
|
-
//
|
|
315
|
+
// The sort key: when the window resets. No reading (an API-key account, one
|
|
316
|
+
// that has not reported, a five-hour window nothing has opened) and a reset
|
|
299
317
|
// that has already passed both sort last: the second is a window that has just
|
|
300
318
|
// started over, so its next reset is the one furthest away.
|
|
301
|
-
const
|
|
302
|
-
const t = a?.quota?.unified7dReset;
|
|
303
|
-
return Number.isFinite(t) && t > now ? t : Infinity;
|
|
304
|
-
};
|
|
319
|
+
const resetRank = (/** @type {any} */ t, /** @type {number} */ now) => (Number.isFinite(t) && t > now ? t : Infinity);
|
|
305
320
|
|
|
306
321
|
// How long a reorder waits after the last move before it is written. Longer
|
|
307
322
|
// than a terminal's key-repeat interval, so a held arrow is one write; short
|
|
@@ -3034,16 +3049,16 @@ export class TUI {
|
|
|
3034
3049
|
* Which is also why the arrangement is a sort key rather than a permutation
|
|
3035
3050
|
* of `am.accounts`: see _doMoveAccount.
|
|
3036
3051
|
*
|
|
3037
|
-
* With
|
|
3038
|
-
*
|
|
3039
|
-
*
|
|
3052
|
+
* With a reset sort (`accountSort`) the soonest reset goes before the
|
|
3053
|
+
* arrangement, which then only breaks ties. Not on the reorder screen, and
|
|
3054
|
+
* not when `arranged` is asked for: the arrangement is what that screen
|
|
3040
3055
|
* edits, so it must see that order.
|
|
3041
3056
|
*
|
|
3042
3057
|
* @param {{ arranged?: boolean }} [opts]
|
|
3043
3058
|
*/
|
|
3044
3059
|
_displayOrder({ arranged = false } = {}) {
|
|
3045
|
-
const
|
|
3046
|
-
|
|
3060
|
+
const resetOf = arranged || (this.mode === 'select' && this.selAction === 'reorder')
|
|
3061
|
+
? null : SORT_RESET[this._accountSort()];
|
|
3047
3062
|
const now = Date.now();
|
|
3048
3063
|
return this.am.accounts
|
|
3049
3064
|
.map((/** @type {any} */ _, /** @type {number} */ i) => i)
|
|
@@ -3054,9 +3069,9 @@ export class TUI {
|
|
|
3054
3069
|
// Provider, then the sort, then the arrangement: the provider is what a
|
|
3055
3070
|
// row IS, so no sort and no number the operator set crosses it.
|
|
3056
3071
|
if (px !== py) return px - py;
|
|
3057
|
-
if (
|
|
3058
|
-
const tx =
|
|
3059
|
-
const ty =
|
|
3072
|
+
if (resetOf) {
|
|
3073
|
+
const tx = resetRank(resetOf(this.am.accounts[x].quota || {}), now);
|
|
3074
|
+
const ty = resetRank(resetOf(this.am.accounts[y].quota || {}), now);
|
|
3060
3075
|
if (tx !== ty) return tx < ty ? -1 : 1; // Infinity - Infinity is NaN, so compare
|
|
3061
3076
|
}
|
|
3062
3077
|
const rx = listRank(this.am.accounts[x]);
|
|
@@ -3695,8 +3710,9 @@ export class TUI {
|
|
|
3695
3710
|
if (byId('orderAccounts')) lines.push(row(byId('orderAccounts')));
|
|
3696
3711
|
if (byId('accountSort')) {
|
|
3697
3712
|
lines.push(row(byId('accountSort')));
|
|
3698
|
-
lines.push(dim('
|
|
3699
|
-
lines.push(dim(' the
|
|
3713
|
+
lines.push(dim(' A reset sort lists the account whose window ends soonest first;'));
|
|
3714
|
+
lines.push(dim(' S7/F7 read the weekly window on an account without one. The'));
|
|
3715
|
+
lines.push(dim(' arranged order breaks ties.'));
|
|
3700
3716
|
}
|
|
3701
3717
|
lines.push('');
|
|
3702
3718
|
// ── Network
|