From c8dafa3225a9d6495ecaf75349095405ced55ffb Mon Sep 17 00:00:00 2001 From: jorge guerrero Date: Sat, 21 Feb 2026 23:01:59 -0500 Subject: [PATCH 1/2] feat: harden rotation behavior and dashboard controls --- .env.example | 26 + .gitignore | 3 + IMPLEMENTATION_PLAN.md | 721 ++++ README.md | 449 +-- SANDBOX_QUICK_REF.md | 113 + TEST_EXECUTION_PLAN.md | 130 + codextesting.md | 196 + dist/auth.d.ts | 4 +- dist/auth.d.ts.map | 2 +- dist/auth.js | 93 +- dist/auth.js.map | 2 +- dist/codex-auth.d.ts.map | 2 +- dist/codex-auth.js | 10 +- dist/codex-auth.js.map | 2 +- dist/errors.d.ts | 17 + dist/errors.d.ts.map | 1 + dist/errors.js | 37 + dist/errors.js.map | 1 + dist/force-mode.d.ts | 24 + dist/force-mode.d.ts.map | 1 + dist/force-mode.js | 149 + dist/force-mode.js.map | 1 + dist/index.d.ts.map | 2 +- dist/index.js | 380 +- dist/index.js.map | 2 +- dist/limits-refresh.d.ts.map | 2 +- dist/limits-refresh.js | 36 +- dist/limits-refresh.js.map | 2 +- dist/probe-limits.d.ts | 7 + dist/probe-limits.d.ts.map | 2 +- dist/probe-limits.js | 95 +- dist/probe-limits.js.map | 2 +- dist/rate-limits.d.ts | 4 + dist/rate-limits.d.ts.map | 2 +- dist/rate-limits.js | 86 + dist/rate-limits.js.map | 2 +- dist/rotation.d.ts | 7 +- dist/rotation.d.ts.map | 2 +- dist/rotation.js | 197 +- dist/rotation.js.map | 2 +- dist/settings.d.ts | 28 + dist/settings.d.ts.map | 1 + dist/settings.js | 208 + dist/settings.js.map | 1 + dist/store.d.ts | 1 + dist/store.d.ts.map | 2 +- dist/store.js | 231 +- dist/store.js.map | 2 +- dist/types.d.ts | 47 +- dist/types.d.ts.map | 2 +- dist/types.js | 121 + dist/types.js.map | 2 +- dist/web.d.ts | 1 + dist/web.d.ts.map | 2 +- dist/web.js | 1299 ++++++- dist/web.js.map | 2 +- docs/ADMIN_MERGE_BRIEF.md | 77 + docs/PHASE_H_VALIDATION.md | 375 ++ docs/PHASE_REVIEW.md | 290 ++ docs/PRODUCTION_READINESS.md | 340 ++ docs/QA.md | 396 ++ jest.config.js | 24 + package-lock.json | 3973 +++++++++++++++++++- package.json | 14 +- src/auth.ts | 134 +- src/codex-auth.ts | 11 +- src/errors.ts | 64 + src/force-mode.ts | 194 + src/index.ts | 494 ++- src/limits-refresh.ts | 48 +- src/probe-limits.ts | 109 +- src/rate-limits.ts | 101 + src/rotation.ts | 233 +- src/settings.ts | 266 ++ src/store.ts | 265 +- src/types.ts | 205 +- src/web.ts | 1056 +++++- tests/failure/failure-injection.test.ts | 173 + tests/integration/web-server.test.ts | 116 + tests/sandbox/sandbox-paths.test.ts | 47 + tests/soak/soak-scaffold.test.ts | 61 + tests/stress/store-stress.test.ts | 69 + tests/unit/errors.test.ts | 43 + tests/unit/feature-flags.test.ts | 275 ++ tests/unit/force-mode.test.ts | 416 ++ tests/unit/localhost.test.ts | 39 + tests/unit/probe-limits.test.ts | 177 + tests/unit/rate-limits.test.ts | 39 + tests/unit/rotation-strategy.test.ts | 87 + tests/unit/settings.test.ts | 349 ++ tests/unit/store.test.ts | 136 + tests/web-headless/dashboard-smoke.test.ts | 103 + tsconfig.json | 2 +- 93 files changed, 14436 insertions(+), 1131 deletions(-) create mode 100644 .env.example create mode 100644 IMPLEMENTATION_PLAN.md create mode 100644 SANDBOX_QUICK_REF.md create mode 100644 TEST_EXECUTION_PLAN.md create mode 100644 codextesting.md create mode 100644 dist/errors.d.ts create mode 100644 dist/errors.d.ts.map create mode 100644 dist/errors.js create mode 100644 dist/errors.js.map create mode 100644 dist/force-mode.d.ts create mode 100644 dist/force-mode.d.ts.map create mode 100644 dist/force-mode.js create mode 100644 dist/force-mode.js.map create mode 100644 dist/settings.d.ts create mode 100644 dist/settings.d.ts.map create mode 100644 dist/settings.js create mode 100644 dist/settings.js.map create mode 100644 docs/ADMIN_MERGE_BRIEF.md create mode 100644 docs/PHASE_H_VALIDATION.md create mode 100644 docs/PHASE_REVIEW.md create mode 100644 docs/PRODUCTION_READINESS.md create mode 100644 docs/QA.md create mode 100644 jest.config.js create mode 100644 src/errors.ts create mode 100644 src/force-mode.ts create mode 100644 src/settings.ts create mode 100644 tests/failure/failure-injection.test.ts create mode 100644 tests/integration/web-server.test.ts create mode 100644 tests/sandbox/sandbox-paths.test.ts create mode 100644 tests/soak/soak-scaffold.test.ts create mode 100644 tests/stress/store-stress.test.ts create mode 100644 tests/unit/errors.test.ts create mode 100644 tests/unit/feature-flags.test.ts create mode 100644 tests/unit/force-mode.test.ts create mode 100644 tests/unit/localhost.test.ts create mode 100644 tests/unit/probe-limits.test.ts create mode 100644 tests/unit/rate-limits.test.ts create mode 100644 tests/unit/rotation-strategy.test.ts create mode 100644 tests/unit/settings.test.ts create mode 100644 tests/unit/store.test.ts create mode 100644 tests/web-headless/dashboard-smoke.test.ts diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..5199d38 --- /dev/null +++ b/.env.example @@ -0,0 +1,26 @@ +# GitHub push + PR settings (template) +# Copy this to .env and fill real values: +# cp .env.example .env + +# Required: token with repo scope (classic) or fine-grained repo contents:write + pull_requests:write. +GITHUB_TOKEN=ghp_replace_me + +# Required: your fork remote URL (the repo you own). +FORK_REMOTE_URL=https://github.com/your-username/opencode-multi-auth-codex.git + +# Optional: if you prefer a custom remote name. +FORK_REMOTE_NAME=fork + +# Required: branch to push. +PUSH_BRANCH=feature/multi-auth-admin-review + +# Required: base branch for PR. +PR_BASE_BRANCH=main + +# Optional git identity (used if your global git identity is not set). +GIT_AUTHOR_NAME=Your Name +GIT_AUTHOR_EMAIL=you@example.com + +# Optional PR metadata. +PR_TITLE=feat: improve rotation behavior, force mode, and dashboard strategy UX +PR_BODY_FILE=docs/ADMIN_MERGE_BRIEF.md diff --git a/.gitignore b/.gitignore index d7d1212..026c7f7 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,6 @@ node_modules/ *.log .npmrc node +.env +.env.* +!.env.example diff --git a/IMPLEMENTATION_PLAN.md b/IMPLEMENTATION_PLAN.md new file mode 100644 index 0000000..ec966d9 --- /dev/null +++ b/IMPLEMENTATION_PLAN.md @@ -0,0 +1,721 @@ +# OpenCode Multi-Auth Reliability Upgrade Plan + +## 1. Objective +Upgrade `guard22/opencode-multi-auth-codex` so it is reliable and low-maintenance for daily use, with strict pre-promotion validation. + +Primary goal: multi-account Codex linking + rotation that just works. + +## 1.1 Repository Location Requirement +- Repository location for implementation and tests: + - `/Users/jorgitin/Documents/projects/open_multi_auth` + +## 1.2 Baseline and Scope +- Baseline upstream: `https://github.com/guard22/opencode-multi-auth-codex` +- This work is a hardening/improvement pass on upstream plus custom behavior changes. +- Implement in source TypeScript (`src/*`), tests, and docs. Do not hand-edit `dist/*` for release. + +## 1.3 Custom Changes Included +- Account-level re-auth from dashboard/API. +- Account-level iOS-like `Enabled` switch from dashboard/API. +- Remove legacy disable control; `Enabled` switch becomes the disable mechanism. +- Keep force toggle separate from account `Enabled` switch behavior and UI. + +## 1.4 Known Live Issues to Permanently Fix +- Limits probe can fail from model/config incompatibility (for example `xhigh` with probe model). +- Failed probe runs may emit `token_count`; those must never overwrite authoritative limits. +- Weekly/five-hour values can look inconsistent if stale/error-derived snapshots are shown as fresh. + +## 1.5 Permanent Limits Accuracy Requirements +- Dashboard/API limits must come from the last successful authoritative probe only. +- Failed/incomplete probe runs must not mutate stored `weekly`/`fiveHour` values. +- If latest probe fails, expose error + freshness/confidence state. +- If no successful snapshot exists yet, show `unknown` (never synthetic `0%`). + +## 2. Independent Phase Execution Model (for multi-model implementation) +- Each phase below is an independent packet with its own markdown TODOs, verification, and handoff outputs. +- You can execute phases in separate model sessions and with different models. +- Recommended order is `A -> I`, but each phase can be completed and validated independently. +- A phase is considered complete only when its local verification checklist is green. +- If a phase changes shared contracts, rerun affected verification in prior completed phases. + +## 3. Locked Decisions +- Core connector reliability is first priority. +- Dashboard is localhost-only (`127.0.0.1` / loopback); no remote dashboard mode. +- Weighted scheduler is opt-in (`weighted-round-robin`). +- Force mode pins one account for 24h and auto-reverts to previous strategy. +- Antigravity remains in codebase but is off by default and hidden unless explicitly enabled. +- Promotion policy: canary -> weighted enablement -> 72h stability watch. +- Rollback trigger: any critical reliability/security incident. + +## 4. Shared Contracts (must remain valid across all phases) + +## 4.1 Store Contract +- [ ] Store supports versioned schema (`v2`) with deterministic migration from `v1`. +- [ ] Per-account fields include: `enabled`, `disabledAt`, `disabledBy`, `disableReason` (optional). +- [ ] Limits fields include: `rateLimits`, `rateLimitHistory`, `limitStatus`, `limitError`, `lastLimitProbeAt`, `lastLimitErrorAt`. +- [ ] Force fields include: `forcedAlias`, `forcedUntil`, `previousRotationStrategy`, `forcedBy`. + +## 4.2 API Contract +- [ ] Mutating endpoints return deterministic typed errors (`code`, `message`, optional `details`). +- [ ] Alias-scoped mutating endpoints must only mutate target alias. +- [ ] `GET /api/accounts` includes eligibility/health/cooldown + limits freshness/confidence metadata. + +## 4.3 Limits Data Quality Contract +- [ ] Probe sets compatible reasoning effort explicitly (`low` default, env-overridable). +- [ ] Probe retries/fallback handles `unsupported_value` / `reasoning.effort` failures. +- [ ] Failed/incomplete probe sessions are non-authoritative and cannot overwrite limits. +- [ ] No-authoritative-data state is represented as `unknown`. + +## 4.4 Observability Contract +- [ ] Decision logs include `requestId`, `strategy`, `selectedAlias`, `fallbackReason`, `forceState`, `enabledState`. +- [ ] Sensitive token material is redacted in all log paths. + +## 5. Independent Phase Packets + +## Phase A: Repository Bootstrap + Baseline Capture +### Todos +- [x] Clone upstream repo into `/Users/jorgitin/Documents/projects/open_multi_auth`. +- [x] Install dependencies and build baseline. +- [x] Capture baseline behavior (`status`, `web`, limits refresh, logs). +- [x] Record baseline in `docs/QA.md`. + +### Verification (Enhanced) +**L0: Repository Integrity** +- [x] Clone completes without corruption (`git status` clean) +- [x] All tracked files present (`git ls-files | wc -l` matches upstream) +- [x] No uncommitted changes in baseline + +**L1: Build Verification** +- [x] `npm ci` completes with zero exit code +- [x] `npm run build` produces `dist/` directory +- [x] `npx tsc --noEmit` passes with zero type errors +- [x] Entry point (`dist/cli.js`) exists and is executable + +**L2: Baseline Behavior Capture** +- [x] `node dist/cli.js status` executes without crash +- [x] `node dist/cli.js web --help` shows expected help text +- [x] Dashboard starts on port (manual check: `node dist/cli.js web --port 9999`) +- [x] Baseline limits refresh command executes +- [x] Log files generated in expected location + +**L3: Documentation** +- [x] `docs/QA.md` created with baseline metrics +- [x] Baseline command outputs captured +- [x] Known issues from upstream documented + +### Handoff Output +- [x] Baseline artifact paths + command results documented. +- [x] Baseline behavior snapshot stored for comparison. +- [x] QA.md baseline section complete. + +## Phase B: Core Runtime Reliability Hardening +### Todos +- [x] Replace recursive retries with bounded iterative attempts. +- [x] Enforce per-request max attempts (`<= eligible account count`). +- [x] Add deterministic fail-fast when no eligible account (`NO_ELIGIBLE_ACCOUNTS`). +- [x] Add top-level web route error guard. +- [x] Enforce localhost-only host binding. +- [x] Add store schema validation on load. +- [x] Add store migration framework for version upgrades. +- [x] Add in-process write lock around read-modify-write operations. +- [x] Harden persistence write (`tmp -> fsync(file) -> rename -> fsync(dir)`). +- [x] Add last-known-good snapshot + auto-restore on parse/validation failure. +- [x] Add explicit `OPENCODE_MULTI_AUTH_CODEX_AUTH_FILE` override. +- [x] Add OAuth callback redirect-port fallback behavior. +- [x] Add health hysteresis/cooldown to prevent account flapping. + +### Verification (Enhanced) +**L1: Retry & Fail-Fast Unit Tests** +- [x] Unit test: Recursive retry replaced with bounded iteration (max 3 attempts) +- [x] Unit test: Per-request attempts never exceed eligible account count +- [x] Unit test: `NO_ELIGIBLE_ACCOUNTS` error thrown deterministically when no accounts available +- [x] Unit test: Retry counter increments correctly per attempt +- [x] Unit test: Exponential backoff calculation (if implemented) + +**L2: Store Reliability Tests** +- [x] Unit test: Schema validation rejects malformed store files +- [x] Unit test: v1 to v2 migration executes deterministically +- [x] Unit test: Migration preserves existing account data +- [x] Unit test: Write lock prevents concurrent read-modify-write corruption +- [x] Unit test: Atomic write sequence (`tmp -> fsync -> rename -> fsync`) +- [x] Crash-recovery test: Interrupt during write, verify auto-restore from last-known-good +- [x] Crash-recovery test: Corrupted store file triggers auto-restore +- [x] Crash-recovery test: Empty store file triggers initialization + +**L3: Web & Security Tests** +- [x] Unit test: Localhost-only binding rejects non-loopback hosts +- [x] Integration test: Dashboard binds only to `127.0.0.1` +- [x] Unit test: Top-level error guard catches unhandled route errors +- [x] Integration test: OAuth callback handles port fallback correctly + +**L4: Health & Cooldown Tests** +- [x] Unit test: Account health hysteresis prevents rapid flapping +- [x] Unit test: Cooldown period respected after account marked unhealthy +- [x] Integration test: Account transitions through health states correctly + +**L5: Environment Override Tests** +- [x] Unit test: `OPENCODE_MULTI_AUTH_CODEX_AUTH_FILE` overrides default path +- [x] Integration test: Custom auth file path loads correctly + +### Handoff Output +- [x] Reliability change log + failing case reproductions now passing. +- [x] Test coverage report showing >80% on modified files. +- [x] Crash-recovery evidence documented in QA.md. + +## Phase C: Limits Accuracy Permanent Fix +### Todos +- [ ] Probe model compatibility hardening: + - [ ] pass `-c model_reasoning_effort="low"` in probe exec + - [ ] allow env override for probe effort + - [ ] probe model order prefers `gpt-5.3-codex` first + - [ ] fallback-retry on `unsupported_value` / `reasoning.effort` +- [ ] Probe authority hardening: + - [ ] accept limits only from successful completed probe sessions + - [ ] reject failed/incomplete/usage-limit sessions as data sources + - [ ] preserve prior limits on probe failure + - [ ] update only error metadata (`limitStatus`, `limitError`, `lastLimitErrorAt`) on failed probe +- [ ] Add freshness/confidence state (`fresh`, `stale`, `error`, `unknown`) to API/UI. +- [ ] Represent missing-authoritative-data as `unknown` (not `0%`). +- [ ] Add probe source diagnostics (model, source session/file, timestamp). + +### Verification (Enhanced - Must Pass 100%) +**Pre-Test Setup:** +- [ ] Sandbox environment isolated (`HOME=/tmp/oma-sandbox-limits`, separate auth file) +- [ ] Baseline snapshot captured of existing limits behavior + +**L1: Parser Authority Unit Tests** +- [ ] Unit test: Parser accepts only fully successful probe sessions as authoritative +- [ ] Unit test: Parser rejects sessions with `token_count` on error/failure +- [ ] Unit test: Parser rejects incomplete/crashed probe sessions +- [ ] Unit test: Parser correctly identifies `unsupported_value` / `reasoning.effort` errors +- [ ] Unit test: Probe fallback model ordering (`gpt-5.3-codex` prioritized) +- [ ] Unit test: Env override `OPENCODE_MULTI_AUTH_PROBE_EFFORT` takes precedence +- [ ] Unit test: Default probe effort is `low` when not specified + +**L2: Limits Mutation Integration Tests** +- [ ] Integration test: Failed probe cannot overwrite prior valid limits +- [ ] Integration test: Probe returning HTTP 200 but with error body does not mutate limits +- [ ] Integration test: Probe with partial `token_count` data on failure preserves prior limits +- [ ] Integration test: Interrupted probe (SIGTERM during exec) leaves limits unchanged +- [ ] Integration test: No successful snapshot exists -> display shows `unknown` +- [ ] Integration test: Successful probe updates limits AND appends to `rateLimitHistory` +- [ ] Integration test: Concurrent probes cannot cause race condition in limits update +- [ ] Integration test: Limits history maintains max 100 entries, FIFO eviction + +**L3: Freshness/Confidence State Tests** +- [ ] Unit test: `fresh` state when probe succeeded within last 5 minutes +- [ ] Unit test: `stale` state when probe succeeded 5-60 minutes ago +- [ ] Unit test: `error` state when last probe failed and < 60 min since success +- [ ] Unit test: `unknown` state when no successful probe ever OR last success > 60 min +- [ ] API test: `GET /api/accounts` includes `limitsConfidence` field with correct enum +- [ ] API test: `GET /api/accounts` includes `lastLimitProbeAt` ISO timestamp +- [ ] API test: `GET /api/accounts` includes `limitStatus` field + +**L4: Model Compatibility & Error Handling** +- [ ] Integration test: `xhigh` reasoning config does not break probe execution +- [ ] Integration test: `unsupported_value` error triggers retry with `low` effort +- [ ] Integration test: All retry attempts exhausted -> probe marked failed, limits preserved +- [ ] Integration test: Probe diagnostics include model name, timestamp, source log file + +**L5: Display Accuracy Tests** +- [ ] Headless UI test: Account with no data shows "unknown" (not "0%") +- [ ] Headless UI test: Stale limits show visual indicator (badge/color change) +- [ ] Headless UI test: Error state shows error icon + tooltip with last error +- [ ] Headless UI test: Weekly/five-hour percentages reflect actual authoritative data + +**L6: Regression Prevention** +- [ ] Test: Simulate old bug - probe with `token_count` on failure -> verify limits unchanged +- [ ] Test: Weekly and five-hour values never appear inconsistent after probe failure +- [ ] Test: Rapid successive probe failures don't corrupt stored limit history + +**L7: Contract Verification** +- [ ] Verify `Limits Data Quality Contract` (Section 4.3) all items pass +- [ ] Verify `Permanent Limits Accuracy Requirements` (Section 1.5) all items pass + +### Handoff Output +- [ ] Before/after evidence for weekly/five-hour consistency behavior. +- [ ] Test execution log with all 25+ test cases passing. +- [ ] QA entry in `docs/QA.md` with specific test commands and results. + +## Phase D: Account Lifecycle Controls (Enabled Switch + Re-auth) +### Todos +- [ ] Add persisted account availability fields (`enabled`, `disabledAt`, `disabledBy`, `disableReason`). +- [ ] Exclude disabled accounts from all eligibility checks. +- [ ] Add APIs: + - [ ] `GET /api/accounts` + - [ ] `PUT /api/accounts/:alias/enabled` + - [ ] `POST /api/accounts/:alias/reauth` +- [ ] Dashboard controls: + - [ ] iOS-like `Enabled` switch per account with states `off|on|updating|error` + - [ ] `Re-auth` action per account with states `idle|in-progress|success|error` + - [ ] disable toggle while request is in flight (double-submit safe) +- [ ] Remove legacy disable button/control from dashboard. +- [ ] Ensure `Enabled` switch is the only disable mechanism. +- [ ] Re-auth contract: only targeted alias credentials mutate. + +### Verification (Enhanced - DO NOT START PHASE D UNTIL ALL PASS) +**Pre-Test Setup:** +- [ ] Sandbox environment isolated (`HOME=/tmp/oma-sandbox-accounts`, separate auth file) +- [ ] Minimum 2 test accounts configured +- [ ] Legacy disable control removed and verified absent + +**L1: Store & Persistence Tests** +- [ ] Unit test: `enabled` field persists and survives restart +- [ ] Unit test: `disabledAt` timestamp set on disable +- [ ] Unit test: `disabledBy` captures actor identity +- [ ] Unit test: `disableReason` optional field stores correctly +- [ ] Unit test: Disabled accounts excluded from rotation eligibility +- [ ] Unit test: Schema validation accepts new account fields +- [ ] Integration test: Disable one account, verify other accounts still rotate +- [ ] Persistence test: Restart process, verify disabled state preserved + +**L2: Enable/Disable API Tests** +- [ ] API test: `PUT /api/accounts/:alias/enabled` with `true` enables account +- [ ] API test: `PUT /api/accounts/:alias/enabled` with `false` disables account +- [ ] API test: Disable returns deterministic error for unknown alias (404) +- [ ] API test: Disable returns deterministic error for already disabled alias (409) +- [ ] API test: Toggle response includes updated account state +- [ ] API test: `GET /api/accounts` includes `enabled` field for all accounts +- [ ] API test: `GET /api/accounts` includes eligibility metadata +- [ ] API test: Double-submit protection (concurrent toggles rejected) + +**L3: Re-auth API Tests** +- [ ] API test: `POST /api/accounts/:alias/reauth` targets only specified alias +- [ ] API test: Re-auth does not mutate other account credentials +- [ ] API test: Re-auth returns deterministic error for unknown alias +- [ ] API test: Re-auth returns deterministic error for disabled alias +- [ ] API test: Active alias re-auth maintains active auth pointer consistency +- [ ] API test: Re-auth progress state transitions correctly +- [ ] API test: Re-auth success updates credentials and metadata +- [ ] API test: Re-auth failure preserves previous credentials (no partial update) + +**L4: Dashboard UI Tests (Headless)** +- [ ] UI test: Accounts table renders all aliases with `Enabled` switch +- [ ] UI test: Switch state `off` displays correctly for disabled accounts +- [ ] UI test: Switch state `on` displays correctly for enabled accounts +- [ ] UI test: Switch state `updating` displays during toggle in-flight +- [ ] UI test: Switch state `error` displays on toggle failure +- [ ] UI test: Double-click prevention (switch disabled during request) +- [ ] UI test: Toggle persists across page reload +- [ ] UI test: Legacy disable button/control is completely absent +- [ ] UI test: Re-auth button shows `idle` state initially +- [ ] UI test: Re-auth button shows `in-progress` during re-auth +- [ ] UI test: Re-auth button shows `success` on completion +- [ ] UI test: Re-auth button shows `error` on failure +- [ ] UI test: `Enabled` switch is the ONLY disable mechanism in UI + +**L5: Eligibility & Rotation Tests** +- [ ] Integration test: Disabled account never selected by rotation +- [ ] Integration test: Rotation skips disabled accounts in round-robin +- [ ] Integration test: All accounts disabled -> `NO_ELIGIBLE_ACCOUNTS` error +- [ ] Integration test: Re-enabled account becomes eligible immediately +- [ ] Integration test: Health checks respect disabled state (no health checks for disabled) + +**L6: Contract Verification** +- [ ] Verify `Store Contract` Section 4.1 per-account fields pass +- [ ] Verify `API Contract` Section 4.2 alias-scoped mutation passes +- [ ] Verify Section 1.3 custom changes (Enabled switch only disable mechanism) pass + +**L7: Security & Edge Cases** +- [ ] Security test: Cannot disable last enabled account (prevent lockout) +- [ ] Security test: API rejects enable/disable for non-existent accounts +- [ ] Edge case: Rapid enable/disable toggles maintain consistency +- [ ] Edge case: Re-auth during active request handled gracefully + +### Handoff Output +- [ ] Screenshots/test artifacts for account controls. +- [ ] Test execution log with all 35+ test cases passing. +- [ ] QA entry in `docs/QA.md` with specific test commands and results. +- [ ] Evidence that legacy disable control is removed. + +## Phase E: Force Mode (Separate from Enabled Switch) +### Todos +- [ ] Persist force state (`forcedAlias`, `forcedUntil`, `previousRotationStrategy`, `forcedBy`). +- [ ] Force behavior: + - [ ] active + eligible forced alias always selected + - [ ] forced alias ineligible -> immediate clear + restore previous strategy + - [ ] forced alias manually disabled -> immediate clear + restore previous strategy + - [ ] forced alias removed -> auto-clear + restore + - [ ] expiry -> clear + restore + - [ ] TTL anchored to first activation (no extension on re-toggle) +- [ ] Force API: + - [ ] `GET /api/force` + - [ ] `POST /api/force` + - [ ] `POST /api/force/clear` +- [ ] Force dashboard toggle (iOS-like) with states `off|on|updating|error`. +- [ ] Keep force toggle visually/behaviorally separate from account `Enabled` switches. + +### Verification (Enhanced) +**Pre-Test Setup:** +- [ ] Sandbox environment isolated +- [ ] Minimum 3 test accounts configured +- [ ] Force toggle visually distinct from account `Enabled` switches + +**L1: Force State Persistence Tests** +- [ ] Unit test: `forcedAlias` persists and survives restart +- [ ] Unit test: `forcedUntil` TTL calculated correctly (24h from activation) +- [ ] Unit test: `previousRotationStrategy` stored correctly +- [ ] Unit test: `forcedBy` captures actor identity +- [ ] Integration test: Restart process, verify force state preserved + +**L2: Force Selection Logic Tests** +- [ ] Unit test: Active + eligible forced alias always selected +- [ ] Unit test: Forced alias ineligible -> immediate clear + restore strategy +- [ ] Unit test: Forced alias disabled -> immediate clear + restore strategy +- [ ] Unit test: Forced alias removed -> auto-clear + restore +- [ ] Unit test: Expired force (`forcedUntil` passed) -> clear + restore +- [ ] Unit test: TTL does NOT extend on re-toggle within 24h +- [ ] Unit test: Force cleared on new force activation (different alias) + +**L3: Force API Tests** +- [ ] API test: `GET /api/force` returns current force state +- [ ] API test: `POST /api/force` with alias activates force mode +- [ ] API test: Force activation requires existing, enabled alias +- [ ] API test: Force activation stores `forcedUntil` timestamp +- [ ] API test: Force activation stores `previousRotationStrategy` +- [ ] API test: `POST /api/force/clear` deactivates force and restores strategy +- [ ] API test: Clear returns current strategy after restoration +- [ ] API test: API returns deterministic errors for invalid operations + +**L4: Force Dashboard UI Tests (Headless)** +- [ ] UI test: Force toggle visually/behaviorally separate from account switches +- [ ] UI test: Force toggle state `off` when no force active +- [ ] UI test: Force toggle state `on` when force active +- [ ] UI test: Force toggle state `updating` during activation/clear +- [ ] UI test: Force toggle state `error` on operation failure +- [ ] UI test: Force toggle shows forced alias name when active +- [ ] UI test: Force toggle shows remaining TTL when active +- [ ] UI test: Expired force automatically shows `off` state + +**L5: Integration & Rotation Tests** +- [ ] Integration test: Rotation selects forced alias when active and eligible +- [ ] Integration test: Rotation returns to previous strategy after force cleared +- [ ] Integration test: Force survives across multiple requests +- [ ] Integration test: Decision logs include `forceState` field + +**L6: Contract Verification** +- [ ] Verify `Store Contract` Section 4.1 force fields pass +- [ ] Verify `Observability Contract` Section 4.4 decision logs include force state +- [ ] Verify Section 1.3 (force toggle separate from Enabled switch) passes + +**L7: Edge Cases & Lifecycle** +- [ ] Edge case: Force activated when no accounts exist +- [ ] Edge case: Force activated with expired TTL +- [ ] Edge case: Force cleared when no force active +- [ ] Lifecycle test: Complete force lifecycle observed (activate -> use -> expire) +- [ ] Lifecycle test: Force survives 48h soak (Phase H requirement) + +### Handoff Output +- [ ] Force lifecycle evidence including expiry/clear paths. +- [ ] Test execution log with all 30+ test cases passing. +- [ ] QA entry in `docs/QA.md` with specific test commands and results. + +## Phase F: Settings + Weighted Rotation +### Todos +- [ ] Add persisted settings model. +- [ ] Implement precedence: defaults -> persisted -> runtime config -> env. +- [ ] Implement `weighted-round-robin` strategy. +- [ ] Add weighted presets: Balanced, Conservative, Aggressive. +- [ ] Add advanced validation: + - [ ] thresholds in `0..100` + - [ ] `critical < low` + - [ ] weights in `(0,1]` + - [ ] minimum weight constraints +- [ ] Add settings API (`GET/PUT/reset`) and settings panel UI. + +### Verification (Enhanced) +**Pre-Test Setup:** +- [ ] Sandbox environment isolated +- [ ] Minimum 3 test accounts with varying weights + +**L1: Settings Persistence Tests** +- [ ] Unit test: Settings model persists and survives restart +- [ ] Unit test: Settings precedence: defaults -> persisted -> runtime -> env +- [ ] Unit test: Environment variables override persisted settings +- [ ] Unit test: Runtime config overrides persisted but not env +- [ ] Integration test: Restart process, verify settings preserved + +**L2: Settings Validation Tests** +- [ ] Unit test: Threshold must be in range `0..100` +- [ ] Unit test: `critical` threshold must be `< low` threshold +- [ ] Unit test: Weight must be in range `(0,1]` +- [ ] Unit test: Minimum weight constraints enforced +- [ ] Unit test: Invalid settings rejected with deterministic error +- [ ] API test: `PUT /api/settings` validates input and rejects invalid +- [ ] API test: Validation errors include specific field and constraint + +**L3: Weighted Rotation Tests** +- [ ] Unit test: Weighted distribution respects account weights +- [ ] Unit test: Higher weight accounts selected more frequently +- [ ] Unit test: All eligible accounts receive some traffic (no starvation) +- [ ] Unit test: Weighted calculation with 2+ accounts +- [ ] Unit test: Weighted calculation with 5+ accounts +- [ ] Integration test: Run 1000 rotations, verify distribution matches weights +- [ ] Integration test: Round-robin remains default unless explicitly changed + +**L4: Presets Tests** +- [ ] Unit test: Balanced preset applies equal weights +- [ ] Unit test: Conservative preset applies lower thresholds +- [ ] Unit test: Aggressive preset applies higher thresholds +- [ ] API test: Preset application validates and applies settings +- [ ] UI test: Preset selection updates settings correctly + +**L5: Settings API Tests** +- [ ] API test: `GET /api/settings` returns current settings +- [ ] API test: `PUT /api/settings` updates settings atomically +- [ ] API test: Settings update validates all constraints +- [ ] API test: `POST /api/settings/reset` restores defaults +- [ ] API test: Reset clears persisted settings +- [ ] API test: Settings changes logged to audit log + +**L6: Dashboard Settings Panel Tests (Headless)** +- [ ] UI test: Settings panel renders with current values +- [ ] UI test: Threshold inputs validate range `0..100` +- [ ] UI test: Weight inputs validate range `(0,1]` +- [ ] UI test: `critical < low` constraint enforced in UI +- [ ] UI test: Save button applies settings and shows success +- [ ] UI test: Reset button restores defaults with confirmation +- [ ] UI test: Validation errors displayed inline +- [ ] UI test: Settings persist across page reload + +**L7: Contract Verification** +- [ ] Verify round-robin remains default strategy +- [ ] Verify weighted strategy is opt-in only +- [ ] Verify settings precedence chain works correctly + +**L8: Edge Cases** +- [ ] Edge case: All weights equal -> uniform distribution +- [ ] Edge case: One account weight = 1.0, others minimal -> heavy skew +- [ ] Edge case: Settings update during active rotation handled gracefully + +### Handoff Output +- [ ] Weighted strategy behavior report with sample distributions. +- [ ] Test execution log with all 35+ test cases passing. +- [ ] QA entry in `docs/QA.md` with specific test commands and results. + +## Phase G: Non-Core Isolation +### Todos +- [ ] Gate antigravity functionality behind feature flag (default off). +- [ ] Hide antigravity UI/panel unless enabled. +- [ ] Ensure non-core paths cannot affect core rotation by default. + +### Verification (Enhanced) +**Pre-Test Setup:** +- [ ] Sandbox environment isolated +- [ ] Feature flag system implemented + +**L1: Feature Flag Unit Tests** +- [ ] Unit test: Antigravity feature flag defaults to `false` +- [ ] Unit test: Flag can be enabled via environment variable +- [ ] Unit test: Flag can be enabled via settings API +- [ ] Unit test: Flag change persists across restart + +**L2: Flag-Off Behavior Tests** +- [ ] Integration test: Core rotation works normally with flag off +- [ ] Integration test: No antigravity side effects on rotation decisions +- [ ] Integration test: No antigravity side effects on account selection +- [ ] Integration test: Store operations unaffected by antigravity code paths +- [ ] Integration test: Logs contain no antigravity-related entries when flag off + +**L3: Flag-On Behavior Tests** +- [ ] Integration test: Antigravity feature reachable when flag enabled +- [ ] Integration test: Antigravity UI/panel visible when flag enabled +- [ ] Integration test: Core rotation still works correctly with flag on +- [ ] Integration test: Account selection respects antigravity rules when enabled +- [ ] Integration test: No core regression when antigravity active + +**L4: UI Isolation Tests (Headless)** +- [ ] UI test: Antigravity panel absent when flag off +- [ ] UI test: Antigravity controls absent when flag off +- [ ] UI test: Antigravity panel present when flag on +- [ ] UI test: Flag toggle in settings works correctly +- [ ] UI test: No visual leakage of antigravity when flag off + +**L5: Security & Isolation Tests** +- [ ] Security test: Antigravity cannot modify core rotation when flag off +- [ ] Security test: Antigravity cannot access sensitive data when flag off +- [ ] Security test: Flag change requires appropriate permissions + +**L6: Contract Verification** +- [ ] Verify Section 3 Locked Decisions (antigravity off by default) +- [ ] Verify non-core paths do not affect core rotation by default + +**L7: Edge Cases** +- [ ] Edge case: Flag toggled during active request +- [ ] Edge case: Flag enabled then disabled, verify clean state + +### Handoff Output +- [ ] Feature-flag behavior matrix. +- [ ] Test execution log with all 20+ test cases passing. +- [ ] QA entry in `docs/QA.md` with specific test commands and results. + +## Phase H: Full Validation Matrix (Reliability + Security) +### Todos +- [ ] L0 Build/Type gates: + - [ ] `npm ci` + - [ ] `npm run lint` (if script exists; otherwise document N/A) + - [ ] `npm run build` + - [ ] `npx tsc --noEmit` +- [ ] L1 Unit coverage: + - [ ] rotation math/fairness + - [ ] retry bounds + - [ ] store migration/validation + - [ ] account enable/disable + - [ ] re-auth alias scope + - [ ] force lifecycle rules + - [ ] limits compatibility + integrity + `unknown` +- [ ] L2 Sandbox integration: + - [ ] isolated HOME/store/auth paths only + - [ ] account switch/re-auth/force workflows + - [ ] freshness/confidence behavior +- [ ] L3 Failure injection: + - [ ] 401/403 auth failures + - [ ] 429 rate limits + - [ ] 402 deactivated workspace + - [ ] 400 model unsupported + - [ ] probe session with token_count + final failure does not overwrite limits +- [ ] L4 Concurrency/stress: + - [ ] parallel bursts with no lost updates + - [ ] store remains consistent +- [ ] L5 Security/exposure: + - [ ] reject non-loopback bind + - [ ] deterministic errors for unknown/disabled alias mutations + - [ ] redaction in logs verified +- [ ] L6 Soak gate: + - [ ] 48h sandbox soak with periodic traffic + - [ ] no crashes, no stuck rotation, no corruption + - [ ] at least one full force lifecycle observed +- [ ] L7 Observability + SLO: + - [ ] required decision log schema present + - [ ] success rate >= 99.9% + - [ ] unhandled exceptions = 0 + - [ ] p95 latency regression <= 10% + - [ ] failed probes never mutate limits + +### Verification +- [ ] Run `TEST_EXECUTION_PLAN.md` end-to-end with artifacts. +- [ ] Repeat integration + headless runs 5 times to detect flakes. + +### Handoff Output +- [ ] Complete QA evidence in `docs/QA.md`. + +## Phase I: Docs, Promotion, and Rollback Readiness +### Todos +- [ ] Rewrite `README.md` (simple install/use). +- [ ] Update `docs/TESTING.md` with exact commands. +- [ ] Update `docs/OFFLINE_RECOVERY.md`. +- [ ] Update `docs/QA.md` troubleshooting matrix. +- [ ] Keep `TEST_EXECUTION_PLAN.md` current with scripts and gate order. +- [ ] Promotion steps: + - [ ] capture baseline metrics + - [ ] 24h canary on round-robin + - [ ] weighted enablement + - [ ] 72h stability watch +- [ ] Rollback drill: + - [ ] revert to last known-good + - [ ] restore settings snapshot + - [ ] verify `list/status/switch/refresh` + +### Verification (Enhanced) +**L1: Documentation Completeness** +- [ ] Doc review: `README.md` includes simple install/use instructions +- [ ] Doc review: `README.md` includes quickstart example +- [ ] Doc review: `docs/TESTING.md` lists all exact test commands +- [ ] Doc review: `docs/TESTING.md` explains test execution order +- [ ] Doc review: `docs/OFFLINE_RECOVERY.md` covers store corruption recovery +- [ ] Doc review: `docs/OFFLINE_RECOVERY.md` covers auth file recovery +- [ ] Doc review: `docs/QA.md` includes troubleshooting matrix +- [ ] Doc review: `docs/QA.md` includes all test execution results +- [ ] Doc review: `TEST_EXECUTION_PLAN.md` matches actual test scripts + +**L2: Script Availability Verification** +- [ ] Verify: `npm run lint` script exists and runs +- [ ] Verify: `npm run build` script exists and runs +- [ ] Verify: `npm run test:unit` script exists and runs +- [ ] Verify: `npm run test:integration` script exists and runs +- [ ] Verify: `npm run test:web:headless` script exists and runs +- [ ] Verify: `npm run test:failure` script exists and runs +- [ ] Verify: `npm run test:stress` script exists and runs +- [ ] Verify: `npm run test:sandbox` script exists and runs +- [ ] Verify: `npm run test:soak:48h` script exists and runs + +**L3: Canary Testing** +- [ ] Canary: 24h canary test started on round-robin strategy +- [ ] Canary: Metrics captured (success rate, latency, rotation distribution) +- [ ] Canary: Weighted strategy enablement test +- [ ] Canary: 72h stability watch initiated +- [ ] Canary: No critical errors during canary period +- [ ] Canary: Performance regression < 10% + +**L4: Rollback Drill** +- [ ] Rollback: Revert to last known-good version documented +- [ ] Rollback: Settings snapshot restore procedure tested +- [ ] Rollback: `list` command works after rollback +- [ ] Rollback: `status` command works after rollback +- [ ] Rollback: `switch` command works after rollback +- [ ] Rollback: `refresh` command works after rollback +- [ ] Rollback: Rollback completes within 5 minutes +- [ ] Rollback: Zero data loss during rollback + +**L5: Acceptance Criteria Verification** +- [ ] Verify: Every required phase packet is complete (A-I) +- [ ] Verify: Shared contracts (Section 4) remain valid +- [ ] Verify: Full validation matrix (Phase H) is green +- [ ] Verify: Permanent limits accuracy requirements met +- [ ] Verify: Account lifecycle controls complete +- [ ] Verify: Promotion and rollback readiness complete + +**L6: Final QA Evidence** +- [ ] Complete QA evidence collected in `docs/QA.md` +- [ ] All test execution logs archived +- [ ] All handoff outputs from phases A-I present +- [ ] Phase H: 5 consecutive integration runs all pass +- [ ] Phase H: 5 consecutive headless runs all pass +- [ ] Phase H: Stress test shows no lost updates +- [ ] Phase H: Soak test 48h completed successfully + +**L7: Release Readiness** +- [ ] Security review complete (no exposed credentials) +- [ ] Performance SLOs met (Section 3.7) +- [ ] Rollback procedure documented and tested +- [ ] Monitoring and alerting configured +- [ ] Team trained on new features + +### Handoff Output +- [ ] Release-readiness checklist signed off. +- [ ] Final QA evidence package in `docs/QA.md`. +- [ ] Test execution summary with all phases passing. +- [ ] Rollback procedure documented. +- [ ] Promotion metrics documented. + +## 6. Cross-Phase Handoff Template (use at end of every phase) +- [ ] Phase ID + date/time +- [ ] Files changed +- [ ] Commands run + pass/fail +- [ ] Known limitations/deferred items +- [ ] Risks introduced (if any) +- [ ] Next-phase recommendations + +## 7. Final Acceptance Criteria +- [ ] Every required phase packet is complete. +- [ ] Shared contracts (Section 4) remain valid. +- [ ] Full validation matrix (Phase H) is green. +- [ ] Permanent limits accuracy requirements are met (`unknown` + failed-probe-safe behavior). +- [ ] Account lifecycle controls are complete (`Enabled` switch replaces legacy disable; force remains separate). +- [ ] Promotion and rollback readiness complete. + +## 8. Suggested File Touch Map +- `src/index.ts` +- `src/rotation.ts` +- `src/store.ts` +- `src/types.ts` +- `src/web.ts` +- `src/auth.ts` +- `src/codex-auth.ts` +- `src/logger.ts` +- `test/` (unit + integration + stress + recovery + headless) +- `README.md` +- `docs/TESTING.md` +- `docs/OFFLINE_RECOVERY.md` +- `docs/QA.md` +- `TEST_EXECUTION_PLAN.md` diff --git a/README.md b/README.md index b9aba7b..f0e179b 100644 --- a/README.md +++ b/README.md @@ -1,34 +1,66 @@ # opencode-multi-auth-codex -Multi-account OAuth rotation for OpenAI Codex. Auto-rotates between your ChatGPT Plus/Pro accounts. +Multi-account OAuth rotation plugin for OpenCode with a local dashboard, force mode, weighted settings, limits probing, and reliability hardening. + +## What this project does + +- Rotates requests across multiple ChatGPT/Codex OAuth accounts. +- Keeps a local account store with migration, validation, and atomic writes. +- Provides a localhost dashboard to manage accounts and limits. +- Supports force mode (pin one alias), account enable/disable, and re-auth. +- Supports settings-driven rotation strategy (`round-robin`, `least-used`, `random`, `weighted-round-robin`). +- Probes limits safely and keeps authoritative data quality rules. +- Gates non-core Antigravity features behind a feature flag. + +## Current implementation status + +- Core phases A-G are implemented in this workspace. +- Validation scripts are available for: unit, integration, web-headless, failure, stress, sandbox, soak. +- Web hardening fixes are in place: + - localhost-only bind enforcement + - malformed JSON returns deterministic `400` without process crash + - dashboard client script parse issue fixed + +## Behavior guarantees (latest) + +- Rate-limit handling sleeps an alias until reset when reset timing is known (`Retry-After`, rate-limit window reset, or parsed provider reset text), instead of retrying that alias immediately. +- Force mode is strict: when enabled, requests stay pinned to the forced alias and do not silently fall back to other aliases. +- Rotation strategy control is shown next to Force Mode in the dashboard. +- Strategy changes from dashboard settings are applied to runtime selection logic (not just persisted state/UI display). +- Force Mode and strategy interaction is explicit: + - while Force Mode is ON, strategy changes are saved + - saved strategy becomes active when Force Mode is turned OFF +- Dashboard controls include mouseover help text for Force Mode and rotation strategy definitions. +- Account enable/disable toggle is authoritative for eligibility in rotation. + +## Repository structure + +- `src/` -> TypeScript source +- `dist/` -> compiled output (`tsc` generated) +- `tests/unit/` -> unit tests +- `tests/integration/` -> integration tests +- `tests/web-headless/` -> headless UI smoke tests +- `tests/failure/` -> failure-injection tests +- `tests/stress/` -> stress/concurrency tests +- `tests/sandbox/` -> sandbox isolation tests +- `tests/soak/` -> soak scaffolding +- `docs/` -> QA and phase documentation +- `IMPLEMENTATION_PLAN.md` -> full plan and contracts +- `TEST_EXECUTION_PLAN.md` -> required test order and gates +- `codextesting.md` -> live testing TODO for Codex CLI sessions -> **Based on [opencode-openai-codex-auth](https://github.com/numman-ali/opencode-openai-codex-auth) by [@nummanali](https://x.com/nummanali)**. Forked and modified to add multi-account rotation support. - -## Patched Build (Codex Backend Compatible) - -This fork patches the plugin to talk to **ChatGPT Codex backend** (`chatgpt.com/backend-api`) with the same headers and request shape as the official Codex OAuth plugin. - -**Install from GitHub (recommended for this fork):** - -```bash -bun add github:guard22/opencode-multi-auth-codex --cwd ~/.config/opencode -``` - -Then set the plugin entry in `~/.config/opencode/opencode.json`: - -```json -{ - "plugin": ["github:guard22/opencode-multi-auth-codex"] -} -``` +## Requirements -If you already installed an older build, re-run the GitHub install command above to override it. +- Node.js 20+ +- npm +- OpenCode CLI +- ChatGPT/Codex OAuth accounts -## Installation +## Install and use -### Via GitHub (Recommended) +### Plugin install (recommended) -Add to your `~/.config/opencode/opencode.json`: +In your OpenCode config (`~/.config/opencode/opencode.json`): ```json { @@ -36,283 +68,152 @@ Add to your `~/.config/opencode/opencode.json`: } ``` -OpenCode will auto-install on first run. - -### Manual Install - -If auto-install fails, install manually: - -```bash -bun add github:guard22/opencode-multi-auth-codex --cwd ~/.config/opencode -``` - -### From Source +### From source ```bash git clone https://github.com/guard22/opencode-multi-auth-codex.git cd opencode-multi-auth-codex -bun install -bun run build -bun link +npm ci +npm run build ``` -## Add Your Accounts +### Quick start ```bash -# Add each account (opens browser for OAuth) +# Add accounts opencode-multi-auth add personal -opencode-multi-auth add work -opencode-multi-auth add backup +opencode-multi-auth add work -# Each command opens your browser - log in with a different ChatGPT account each time -``` - -## Verify Setup - -```bash +# Check status opencode-multi-auth status -``` - -Output: -``` -[multi-auth] Account Status - -Strategy: round-robin -Accounts: 3 -Active: personal - - personal (active) - Email: you@personal.com - Uses: 12 - Token expires: 12/25/2025, 3:00:00 PM - - work - Email: you@work.com - Uses: 10 - Token expires: 12/25/2025, 3:00:00 PM - - backup - Email: you@backup.com - Uses: 8 - Token expires: 12/25/2025, 3:00:00 PM -``` - -## Web Dashboard (Local Only) - -Launch the local dashboard: - -```bash -opencode-multi-auth web --port 3434 --host 127.0.0.1 -``` - -Or from the repo: - -```bash -npm run web -``` - -Open `http://127.0.0.1:3434` to manage Codex CLI tokens from `~/.codex/auth.json`: -- Sync current auth.json token into your local list -- See which token is active on the device -- Switch auth.json to a stored token -- Refresh OAuth tokens (per-token or all) -- Refresh 5-hour and weekly limits manually (probe-run per alias) -- Search/filter by alias/email/tags/notes -- Sort by remaining limits, expiry, or alias; recommended token badge -- Tag and annotate tokens (notes) -- Queue-based refresh with progress + stop -- Limit history sparklines and trend rate -- Built-in log view - -The dashboard watches `~/.codex/auth.json` and will add new tokens as you log in via Codex CLI. - -Limit refresh runs `codex exec` in a per-alias sandbox (`~/.codex-multi/`) so you can -update limits for any stored token without switching the active device token. - -### Optional Store Encryption - -Set `CODEX_SOFT_STORE_PASSPHRASE` to encrypt `~/.config/opencode-multi-auth/accounts.json` at rest: - -```bash -export CODEX_SOFT_STORE_PASSPHRASE="your-passphrase" -``` - -If the store is encrypted and the passphrase is missing, the UI will show a locked status and refuse to overwrite. - -### Systemd Autostart (user service) - -Install and enable the user service: - -```bash -opencode-multi-auth service install --port 3434 --host 127.0.0.1 -``` - -Check status or disable: - -```bash -opencode-multi-auth service status -opencode-multi-auth service disable -``` - -### Logs - -The dashboard writes logs to `~/.config/opencode-multi-auth/logs/codex-soft.log` by default. -Override with `CODEX_SOFT_LOG_PATH` if you want a custom path. - -## Configure OpenCode - -Add to your `~/.config/opencode/opencode.json`: - -```json -{ - "plugin": ["github:guard22/opencode-multi-auth-codex"] -} -``` - -Or with other plugins: - -```json -{ - "plugin": [ - "oh-my-opencode", - "github:guard22/opencode-multi-auth-codex" - ] -} -``` - - -## Background Notifications (macOS) - - -### iPhone notifications via ntfy (click to open session) - -If you want push notifications on iOS (with a clickable link to the OpenCode web session), use `ntfy`. - -1) Install the **ntfy** app on iPhone and subscribe to a topic. - -2) Set these env vars on the Mac where OpenCode runs: +# Start dashboard +opencode-multi-auth web --host 127.0.0.1 --port 3434 +``` + +Open `http://127.0.0.1:3434`. + +## CLI commands + +- `opencode-multi-auth add ` -> add account via OAuth +- `opencode-multi-auth remove ` -> remove account +- `opencode-multi-auth list` -> list configured accounts +- `opencode-multi-auth status` -> full status +- `opencode-multi-auth path` -> print store path +- `opencode-multi-auth web --host 127.0.0.1 --port 3434` -> run dashboard +- `opencode-multi-auth service install|disable|status` -> systemd user service helpers + +## Dashboard/API endpoints + +- `GET /api/state` +- `GET /api/logs` +- `POST /api/sync` +- `POST /api/auth/start` +- `POST /api/switch` +- `POST /api/remove` +- `POST /api/account/meta` +- `POST /api/token/refresh` +- `POST /api/limits/refresh` +- `POST /api/limits/stop` +- `GET /api/accounts` +- `PUT /api/accounts/:alias/enabled` +- `POST /api/accounts/:alias/reauth` +- `GET /api/force` +- `POST /api/force` +- `POST /api/force/clear` +- `GET /api/settings` +- `PUT /api/settings` +- `GET /api/settings/feature-flags` +- `PUT /api/settings/feature-flags` +- `POST /api/settings/reset` +- `POST /api/settings/preset` +- `POST /api/antigravity/refresh` (feature-flag gated) +- `POST /api/antigravity/refresh-all` (feature-flag gated) + +## Environment variables + +### Storage and auth + +- `OPENCODE_MULTI_AUTH_STORE_DIR` -> override store directory +- `OPENCODE_MULTI_AUTH_STORE_FILE` -> override store file path +- `OPENCODE_MULTI_AUTH_CODEX_AUTH_FILE` -> override Codex `auth.json` +- `CODEX_SOFT_STORE_PASSPHRASE` -> encrypt account store at rest +- `CODEX_SOFT_LOG_PATH` -> override dashboard log path + +### Rotation and limits + +- `OPENCODE_MULTI_AUTH_ROTATION_STRATEGY` (settings source override; runtime rotation follows persisted dashboard settings) +- `OPENCODE_MULTI_AUTH_CRITICAL_THRESHOLD` +- `OPENCODE_MULTI_AUTH_LOW_THRESHOLD` +- `OPENCODE_MULTI_AUTH_TOKEN_FAILURE_COOLDOWN_MS` +- `OPENCODE_MULTI_AUTH_PROBE_EFFORT` +- `OPENCODE_MULTI_AUTH_LIMITS_PROBE_MODELS` + +### Model mapping and runtime behavior + +- `OPENCODE_MULTI_AUTH_PREFER_CODEX_LATEST` +- `OPENCODE_MULTI_AUTH_CODEX_LATEST_MODEL` +- `OPENCODE_MULTI_AUTH_INJECT_MODELS` +- `OPENCODE_MULTI_AUTH_TRUNCATION` +- `OPENCODE_MULTI_AUTH_DEBUG` + +### Feature flags + +- `OPENCODE_MULTI_AUTH_ANTIGRAVITY_ENABLED` + +### Notifications + +- `OPENCODE_MULTI_AUTH_NOTIFY` +- `OPENCODE_MULTI_AUTH_NOTIFY_SOUND` +- `OPENCODE_MULTI_AUTH_NOTIFY_MAC_OPEN` - `OPENCODE_MULTI_AUTH_NOTIFY_NTFY_URL` - Example: `https://ntfy.sh/` (or your self-hosted ntfy URL) +- `OPENCODE_MULTI_AUTH_NOTIFY_NTFY_TOKEN` - `OPENCODE_MULTI_AUTH_NOTIFY_UI_BASE_URL` - Base URL of your OpenCode web UI reachable from iPhone. - Example (Tailscale): `http://100.x.y.z:4096` -- Optional: `OPENCODE_MULTI_AUTH_NOTIFY_NTFY_TOKEN` (Bearer token) - -The plugin sends notifications for: - -- `session.idle` (finished): priority `3` -- `session.status` with `retry`: priority `4` -- `session.error`: priority `5` - -When possible, the notification body includes `Project` + session `Title`, plus the `sessionID`. -It also attaches a `Click:` URL like `/session/` so tapping the push opens the session. - -This plugin can send a **macOS notification + sound** when a session finishes work. -It listens for OpenCode events (`session.status` and `session.idle`). - -Defaults: -- Enabled by default -- Sound: `/System/Library/Sounds/Glass.aiff` -Environment variables: -- `OPENCODE_MULTI_AUTH_NOTIFY=0` disables notifications -- `OPENCODE_MULTI_AUTH_NOTIFY_SOUND=/path/to/sound.aiff` overrides the sound -- `OPENCODE_MULTI_AUTH_NOTIFY_MAC_OPEN=0` disables click-to-open on macOS (when available) +## Security rules -Clickable macOS notifications require `terminal-notifier` (optional). If installed, clicking the banner opens the session URL. +- Dashboard host is loopback-only (`127.0.0.1`, `::1`, `localhost`). +- Non-loopback host bind is rejected. +- Sensitive token patterns are redacted in logs. +- Store file permissions are restricted (`0o600`). +- Antigravity APIs are blocked when feature flag is off. -If OpenCode seems to only make progress when the window is focused, macOS may be throttling it. -Try disabling App Nap for OpenCode.app (Finder -> Get Info -> Prevent App Nap), -or run the server from a terminal under `caffeinate`. - -## Codex Latest Model Mapping - -OpenCode may not list the newest Codex model yet (it keeps an internal allowlist). -This plugin can still use the newest model by **mapping** the selected Codex model -to the latest backend model on ChatGPT. - -Default behavior: -- If you select `openai/gpt-5.2-codex` (or `openai/gpt-5-codex`), the plugin will send requests as `gpt-5.3-codex`. - -Environment variables: -- `OPENCODE_MULTI_AUTH_PREFER_CODEX_LATEST=0` disables the mapping (use exact model). -- `OPENCODE_MULTI_AUTH_CODEX_LATEST_MODEL=gpt-5.3-codex` overrides the target model. -- `OPENCODE_MULTI_AUTH_DEBUG=1` prints mapping logs like: `model map: gpt-5.2-codex -> gpt-5.3-codex`. - -## Troubleshooting - -### BunInstallFailedError (DependencyLoop) - -If OpenCode fails to boot with: - -``` -BunInstallFailedError -{ "pkg": "github:guard22/opencode-multi-auth-codex", "version": "latest" } -``` - -It usually means an older `@a3fckx/opencode-multi-auth` dependency is still present. - -Fix: - -1) Remove the old dependency from `~/.config/opencode/package.json`: - -```json -{ - "dependencies": { - "@a3fckx/opencode-multi-auth": "^1.0.4" - } -} -``` - -2) Reinstall: +## Build and test ```bash -bun add github:guard22/opencode-multi-auth-codex --cwd ~/.config/opencode +npm ci +npm run lint +npm run build +npx tsc --noEmit + +npm run test:unit +npm run test:integration +npm run test:web:headless +npm run test:failure +npm run test:stress +npm run test:sandbox +npm run test:soak:48h ``` -Optional fallback: use a file path plugin entry if installs are blocked: +Current test script surfaces are scaffolded and active. For true long soak, set a long duration and keep the run alive. -```json -{ - "plugin": [ - "file:///Users//.config/opencode/node_modules/@guard22/opencode-multi-auth-codex/dist/index.js" - ] -} -``` +## Live validation runbook -## How It Works - -| Feature | Behavior | -|---------|----------| -| **Rotation** | Round-robin across all accounts per API call | -| **Rate Limits** | Auto-skips rate-limited account for 5 min, uses next | -| **Token Refresh** | Auto-refreshes tokens before expiry | -| **Models** | Auto-discovers GPT-5.x models from OpenAI API | -| **Storage** | `~/.config/opencode-multi-auth/accounts.json` | - -## CLI Commands - -| Command | Description | -|---------|-------------| -| `add ` | Add new account via OAuth (opens browser) | -| `remove ` | Remove an account | -| `list` | List all configured accounts | -| `status` | Detailed status with usage counts | -| `path` | Show config file location | -| `web` | Launch local Codex auth.json dashboard | -| `service` | Install/disable systemd user service | -| `help` | Show help message | +Use `codextesting.md` for the Codex CLI live-testing checklist and copy-paste command flow. -## Requirements +## Troubleshooting -- ChatGPT Plus/Pro subscription(s) -- OpenCode CLI +- If dashboard start fails with localhost error, check `--host` and use loopback only. +- If a request returns `INVALID_JSON`, verify payload body is valid JSON. +- If an alias action returns `ACCOUNT_NOT_FOUND`, refresh account list first. +- If re-auth is blocked with `ACCOUNT_DISABLED`, enable the account before re-auth. +- If encrypted store appears locked, export `CODEX_SOFT_STORE_PASSPHRASE` before launching. -## Credits +## Development notes -- Original OAuth implementation: [numman-ali/opencode-openai-codex-auth](https://github.com/numman-ali/opencode-openai-codex-auth) -- Multi-account rotation: [@a3fckx](https://github.com/a3fckx) +- Edit `src/*`, never hand-edit `dist/*`. +- Run `npm run build` after source changes. +- Keep manual/live tests sandboxed (temp HOME/store/auth paths). ## License diff --git a/SANDBOX_QUICK_REF.md b/SANDBOX_QUICK_REF.md new file mode 100644 index 0000000..dc3ccbd --- /dev/null +++ b/SANDBOX_QUICK_REF.md @@ -0,0 +1,113 @@ +# Sandbox Quick Ref (Offline) + +Use this to manually test without touching your live OpenCode/Codex setup. + +## 1) One-time setup (inside required folder) +```bash +cd /Users/jorgitin/Documents/projects/open_multi_auth +git clone https://github.com/guard22/opencode-multi-auth-codex.git . +npm ci +npm run build +``` + +If this folder is not empty, clone to a temporary location and copy the repo contents into `/Users/jorgitin/Documents/projects/open_multi_auth` before running tests. + +## 2) Isolated sandbox env +```bash +export HOME=/tmp/oma-sandbox-home +export OPENCODE_MULTI_AUTH_STORE_DIR=/tmp/oma-sandbox-store +export OPENCODE_MULTI_AUTH_CODEX_AUTH_FILE=/tmp/oma-sandbox-home/.codex/auth.json + +mkdir -p "$HOME/.codex" "$OPENCODE_MULTI_AUTH_STORE_DIR" +``` + +## 3) Invoke sandbox version (manual testing) +Status: +```bash +node dist/cli.js status +``` + +Run dashboard locally: +```bash +node dist/cli.js web --host 127.0.0.1 --port 4343 +``` +Open: `http://127.0.0.1:4343` + +## 4) Fast safety checks (must stay sandboxed) +```bash +node dist/cli.js path +echo "$HOME" +echo "$OPENCODE_MULTI_AUTH_STORE_DIR" +echo "$OPENCODE_MULTI_AUTH_CODEX_AUTH_FILE" +``` + +Expected: +- store path under `/tmp/oma-sandbox-store` +- auth path under `/tmp/oma-sandbox-home/.codex/auth.json` + +## 5) Single-command sandbox invocation (no persistent exports) +```bash +HOME=/tmp/oma-sandbox-home \ +OPENCODE_MULTI_AUTH_STORE_DIR=/tmp/oma-sandbox-store \ +OPENCODE_MULTI_AUTH_CODEX_AUTH_FILE=/tmp/oma-sandbox-home/.codex/auth.json \ +node dist/cli.js web --host 127.0.0.1 --port 4343 +``` + +## 6) Quick troubleshooting + +`EADDRINUSE` (port busy): +```bash +node dist/cli.js web --host 127.0.0.1 --port 4344 +``` + +Store looks wrong/corrupt: +```bash +ls -la /tmp/oma-sandbox-store +``` +Delete only sandbox store: +```bash +rm -rf /tmp/oma-sandbox-store +mkdir -p /tmp/oma-sandbox-store +``` + +Need clean sandbox reset: +```bash +rm -rf /tmp/oma-sandbox-home /tmp/oma-sandbox-store +mkdir -p /tmp/oma-sandbox-home/.codex /tmp/oma-sandbox-store +``` + +`spawn codex ENOENT` during limits refresh: +- `codex` binary is missing from PATH in that shell. +- Fix PATH or skip limits-refresh tests in that environment. + +Probe run fails with usage-limit/model/config error: +- Expected hardened behavior: account `limitStatus` becomes `error` and prior `rateLimits` remain unchanged. +- Dashboard/API should expose the failure state instead of silently replacing limits with error-session values. + +Limits confidence quick check (after feature is implemented): +- Trigger a successful limits refresh and verify account shows `fresh` confidence. +- Trigger a known failing probe and verify: + - confidence switches to `error` + - prior limits are preserved + - `lastLimitErrorAt` updates. + +Force mode quick check (after feature is implemented): +- In dashboard, enable "Force this account for 24h" on one alias. +- Send multiple requests and confirm that alias is always selected while eligible. +- Clear force mode and confirm scheduler returns to previous strategy. + +Account enable/disable quick check (after feature is implemented): +- Use the account `Enabled` iOS-style switch to turn one alias off and confirm it is never selected. +- Turn the same alias back on and confirm it returns to eligibility. +- Turn off the currently forced alias and confirm force clears immediately and previous strategy is restored. +- Confirm legacy disable button/control is removed from the dashboard (switch is the only disable mechanism). + +Re-auth quick check (after feature is implemented): +- Trigger re-auth for one alias from dashboard. +- Confirm only that alias credentials update. +- If that alias is active, confirm auth pointer remains consistent after re-auth. + +## 7) Promotion guard reminder +Never point sandbox env vars to real `~/.codex` or real store paths until all validation gates are green. +Dashboard policy for hardened build: localhost-only (no remote dashboard mode). +Use `TEST_EXECUTION_PLAN.md` as the full post-implementation runbook. diff --git a/TEST_EXECUTION_PLAN.md b/TEST_EXECUTION_PLAN.md new file mode 100644 index 0000000..95054ef --- /dev/null +++ b/TEST_EXECUTION_PLAN.md @@ -0,0 +1,130 @@ +# Post-Implementation Test Execution Plan + +This runbook defines exactly how to validate the implementation after coding is complete. + +## 1) Goal +- Prove correctness, safety, and reliability of multi-auth core behavior before main usage. +- Catch regressions in rotation, account lifecycle controls, force mode, and limits reporting. +- Ensure the weekly-limit inconsistency class is permanently prevented. + +## 2) Required Test Surfaces +- `Unit`: deterministic logic (rotation/store/limits parsing/force rules). +- `Integration`: API behavior and state transitions. +- `Headless UI E2E`: dashboard behavior without manual browser usage. +- `Failure injection`: forced 401/403/429/402/400 + probe failures. +- `Reliability`: stress + crash recovery + soak. + +## 3) Required Scripts (must exist by implementation complete) +- `npm run lint` +- `npm run build` +- `npm run test:unit` +- `npm run test:integration` +- `npm run test:web:headless` +- `npm run test:failure` +- `npm run test:stress` +- `npm run test:sandbox` +- `npm run test:soak:48h` + +If a script is missing, add it as part of implementation before declaring test-complete. + +## 4) Execution Order (No Skips) +1. Static + build gates. +2. Unit suites. +3. Integration suites. +4. Headless UI suites. +5. Failure injection suites. +6. Stress and concurrency suites. +7. Crash-recovery suites. +8. 48h soak. + +If any stage fails, fix and restart from the failed stage; if fix touches shared core paths (`rotation`, `store`, `web`, `limits`), rerun from stage 1. + +## 5) Detailed Coverage Checklist + +## 5.1 Account Enabled Switch (new disable mechanism) +- API: `PUT /api/accounts/:alias/enabled` toggles state with deterministic errors. +- Rotation: disabled accounts are never selected. +- Persistence: enabled/disabled state survives restart. +- UI headless: + - iOS-style switch renders per account. + - switch states: `off`, `on`, `updating`, `error`. + - in-flight toggles are non-reentrant (double click safe). +- Legacy control removal: + - old disable button/control is absent. + - only source of disablement is the `Enabled` switch. + +## 5.2 Force Mode (separate from account enable) +- Force toggle remains separate from account `Enabled` switches. +- Enable force pins forced alias while eligible. +- Clear force restores prior strategy. +- Disable forced alias auto-clears force and restores prior strategy. +- TTL behavior: 24h anchor does not extend on repeated force toggles. + +## 5.3 Re-auth per Account +- `POST /api/accounts/:alias/reauth` updates only target alias credentials. +- Active-alias re-auth keeps active auth pointer consistent. +- UI headless verifies `idle -> in-progress -> success/error` transitions. + +## 5.4 Limits Accuracy (permanent fix requirements) +- Probe compatibility: + - global `xhigh` config does not break limits probe. + - fallback works on `unsupported_value` / `reasoning.effort` errors. +- Failed-probe-safe behavior: + - failed/incomplete probes never overwrite stored `rateLimits`. + - `limitStatus=error`, `lastLimitErrorAt` updated, prior values preserved. +- No-data behavior: + - accounts with no successful snapshot report `unknown` (not `0%`). +- Freshness behavior: + - API/UI provides confidence state (`fresh`, `stale`, `error`, `unknown`). + +## 5.5 Crash Safety + Recovery +- Interrupt process during store write and restart. +- Verify store can be loaded or auto-restored from last-known-good snapshot. +- Verify no partial JSON corruption causes undefined runtime behavior. + +## 5.6 Security and Exposure +- Dashboard rejects non-loopback host binding. +- Mutating actions reject unknown aliases and disabled aliases with deterministic errors. +- Log redaction covers tokens/credentials. + +## 6) Headless UI Test Cases (minimum) +- Accounts table renders all aliases. +- Account `Enabled` switch toggles and persists across reload. +- Force switch works independently of account `Enabled` switch. +- Re-auth action starts and resolves with correct status state. +- Limits badge/text reflects `fresh/stale/error/unknown` correctly. +- Legacy disable control is not present. + +## 7) Reliability and Flake Control +- Repeat `test:integration` and `test:web:headless` 5 consecutive runs; all must pass. +- Stress test must show no lost updates, deadlocks, or corrupted store state. +- Soak gate (48h): no crashes, no stuck rotation, no corruption, at least one force lifecycle. + +## 8) Command Runbook +```bash +npm ci +npm run lint +npm run build +npx tsc --noEmit + +npm run test:unit +npm run test:integration +npm run test:web:headless +npm run test:failure +npm run test:stress +npm run test:sandbox +npm run test:soak:48h +``` + +## 9) Pass/Fail Criteria +- All commands exit zero. +- All required feature checklists in section 5 are validated. +- No blocker/high severity defects open. +- SLO gates from `IMPLEMENTATION_PLAN.md` are met. + +## 10) Evidence and Artifacts +- Store results in `docs/QA.md`: + - command, timestamp, pass/fail + - failing output (if any) and remediation + - links/paths to logs, traces, and headless test reports +- Keep artifacts for the canary + 72h watch window. diff --git a/codextesting.md b/codextesting.md new file mode 100644 index 0000000..c72ad3e --- /dev/null +++ b/codextesting.md @@ -0,0 +1,196 @@ +# Codex CLI Live Testing TODO + +This checklist is for live validation with your OpenCode + Codex workflow after backing up your current `guard22` config. + +Use this file as your step-by-step TODO. Check each box as you complete it. + +## 1) Preflight (Do first) + +- [ ] Backup current config and plugin state (`~/.config/opencode`, `~/.codex`, current plugin refs). +- [ ] Confirm this repo is built from latest local source: + +```bash +npm run lint +npm run build +``` + +- [ ] Run the full automated validation once before manual/live testing: + +```bash +npm run test:unit +npm run test:integration +npm run test:web:headless +npm run test:failure +npm run test:stress +npm run test:sandbox +npm run test:soak:48h +``` + +## 2) Start Dashboard + Basic Health + +- [ ] Start dashboard on loopback: + +```bash +node dist/cli.js web --host 127.0.0.1 --port 3434 +``` + +- [ ] Open `http://127.0.0.1:3434` and confirm UI renders (no blank page, no JS syntax errors). +- [ ] Verify state endpoint responds: + +```bash +curl -s http://127.0.0.1:3434/api/state +``` + +- [ ] Verify non-loopback bind is blocked: + +```bash +node dist/cli.js web --host 0.0.0.0 --port 3434 +``` + +Expected: fails with `LOCALHOST_ONLY`. + +## 3) API Safety/Crash-Proof Checks + +- [ ] Malformed JSON returns 400 and server stays alive: + +```bash +curl -i -X POST http://127.0.0.1:3434/api/switch -H 'Content-Type: application/json' --data '{bad json' +curl -i -X POST http://127.0.0.1:3434/api/switch -H 'Content-Type: application/json' --data '{}' +``` + +Expected: first is `400` (`INVALID_JSON`), second returns normal API error but process is still up. + +## 4) Account Lifecycle (Core) + +- [ ] Add at least 2 test accounts: + +```bash +node dist/cli.js add test1 +node dist/cli.js add test2 +``` + +- [ ] Confirm accounts present: + +```bash +node dist/cli.js status +curl -s http://127.0.0.1:3434/api/accounts +``` + +- [ ] Disable one account from UI and confirm it shows disabled. +- [ ] Re-enable the same account and confirm immediate recovery. +- [ ] Try disabling the last enabled account and verify API/UI blocks with 409. +- [ ] Verify unknown alias toggle returns deterministic error: + +```bash +curl -i -X PUT http://127.0.0.1:3434/api/accounts/does-not-exist/enabled -H 'Content-Type: application/json' --data '{"enabled":false}' +``` + +Expected: `404` with `ACCOUNT_NOT_FOUND`. + +- [ ] Re-auth enabled account from UI and confirm OAuth flow starts. +- [ ] Re-auth disabled account and verify blocked (409 `ACCOUNT_DISABLED`). + +## 5) Force Mode + +- [ ] Enable force mode for one alias in UI. +- [ ] Verify force state endpoint: + +```bash +curl -s http://127.0.0.1:3434/api/force +``` + +- [ ] Toggle force for same alias twice and verify TTL does not extend unexpectedly. +- [ ] Disable forced alias and verify force auto-clears. +- [ ] Clear force manually and verify previous strategy is restored. + +## 6) Settings + Weighted Rotation + +- [ ] Get settings: + +```bash +curl -s http://127.0.0.1:3434/api/settings +``` + +- [ ] Set weighted strategy + weights: + +```bash +curl -i -X PUT http://127.0.0.1:3434/api/settings -H 'Content-Type: application/json' --data '{"rotationStrategy":"weighted-round-robin","criticalThreshold":10,"lowThreshold":30,"accountWeights":{"test1":0.7,"test2":0.3}}' +``` + +- [ ] Confirm settings persisted across restart of dashboard. +- [ ] Apply preset and verify response: + +```bash +curl -i -X POST http://127.0.0.1:3434/api/settings/preset -H 'Content-Type: application/json' --data '{"preset":"balanced"}' +``` + +## 7) Limits Refresh + Confidence + +- [ ] Trigger refresh all: + +```bash +curl -i -X POST http://127.0.0.1:3434/api/limits/refresh -H 'Content-Type: application/json' --data '{}' +``` + +- [ ] Verify queue/state updates in UI (`queued` -> `running` -> `success/error`). +- [ ] Verify accounts show confidence badge states (`fresh/stale/error/unknown`). +- [ ] Confirm no-data accounts show `unknown` (not fake `0%`). + +## 8) Feature Flag / Antigravity Gate + +- [ ] With Antigravity disabled, verify endpoint blocked: + +```bash +curl -i -X POST http://127.0.0.1:3434/api/antigravity/refresh -H 'Content-Type: application/json' --data '{}' +``` + +Expected: `403 FEATURE_DISABLED`. + +- [ ] Enable feature flag via settings API only if you want to test Antigravity paths. + +## 9) OpenCode + Codex Live Flow + +- [ ] Run OpenCode with this plugin config. +- [ ] Send at least 20 real requests through OpenCode using mixed prompts/models. +- [ ] Verify no request-loop failures and no process crashes. +- [ ] Confirm active alias rotates when expected and respects enabled/disabled/force rules. +- [ ] Monitor logs for deterministic, redacted errors: + +```bash +tail -f ~/.config/opencode-multi-auth/logs/codex-soft.log +``` + +## 10) Fast Regression Loop (when something fails) + +- [ ] Capture failing command/API call. +- [ ] Capture exact response code + body. +- [ ] Capture relevant log lines. +- [ ] Reproduce with smallest possible case. +- [ ] Fix in `src/*`, rebuild, rerun only impacted suites first, then full runbook. + +## 11) Final Exit Criteria + +- [ ] Dashboard stable, no parse/runtime crashes. +- [ ] localhost-only bind enforced. +- [ ] Account lifecycle works (enable/disable/reauth) with deterministic errors. +- [ ] Force mode lifecycle works and clears correctly. +- [ ] Settings persist and are used by live rotation. +- [ ] Limits refresh works and confidence states are correct. +- [ ] All automated scripts pass. + +## Issue Log Template + +Use this format while testing live: + +```text +Issue ID: +When: +Command / API: +Expected: +Actual: +HTTP/code: +Logs: +Repro steps: +Fix commit/path: +Retest result: +``` diff --git a/dist/auth.d.ts b/dist/auth.d.ts index a6a3ebe..5f9ba93 100644 --- a/dist/auth.d.ts +++ b/dist/auth.d.ts @@ -6,8 +6,10 @@ interface AuthorizationFlow { }; state: string; url: string; + redirectUri: string; + port: number; } -export declare function createAuthorizationFlow(): Promise; +export declare function createAuthorizationFlow(port?: number): Promise; export declare function loginAccount(alias: string, flow?: AuthorizationFlow): Promise; export declare function refreshToken(alias: string): Promise; export declare function ensureValidToken(alias: string): Promise; diff --git a/dist/auth.d.ts.map b/dist/auth.d.ts.map index b6ffce9..5ddd79f 100644 --- a/dist/auth.d.ts.map +++ b/dist/auth.d.ts.map @@ -1 +1 @@ -{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAA;AAmBpD,UAAU,iBAAiB;IACzB,IAAI,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAA;IAC7C,KAAK,EAAE,MAAM,CAAA;IACb,GAAG,EAAE,MAAM,CAAA;CACZ;AAED,wBAAsB,uBAAuB,IAAI,OAAO,CAAC,iBAAiB,CAAC,CAiB1E;AAED,wBAAsB,YAAY,CAChC,KAAK,EAAE,MAAM,EACb,IAAI,CAAC,EAAE,iBAAiB,GACvB,OAAO,CAAC,kBAAkB,CAAC,CA8I7B;AAED,wBAAsB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC,CA+DpF;AAED,wBAAsB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAe5E"} \ No newline at end of file +{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAA;AAqBpD,UAAU,iBAAiB;IACzB,IAAI,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAA;IAC7C,KAAK,EAAE,MAAM,CAAA;IACb,GAAG,EAAE,MAAM,CAAA;IACX,WAAW,EAAE,MAAM,CAAA;IACnB,IAAI,EAAE,MAAM,CAAA;CACb;AAED,wBAAsB,uBAAuB,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAoBvF;AAkCD,wBAAsB,YAAY,CAChC,KAAK,EAAE,MAAM,EACb,IAAI,CAAC,EAAE,iBAAiB,GACvB,OAAO,CAAC,kBAAkB,CAAC,CAsJ7B;AAED,wBAAsB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC,CA6DpF;AAED,wBAAsB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAc5E"} \ No newline at end of file diff --git a/dist/auth.js b/dist/auth.js index cd603fa..8ef7326 100644 --- a/dist/auth.js +++ b/dist/auth.js @@ -5,20 +5,23 @@ import * as url from 'url'; import { addAccount, updateAccount, loadStore } from './store.js'; import { clearAuthInvalid } from './rotation.js'; import { decodeJwtPayload, getAccountIdFromClaims, getEmailFromClaims, getExpiryFromClaims } from './codex-auth.js'; -// OpenAI OAuth endpoints (same as official Codex CLI) const OPENAI_ISSUER = 'https://auth.openai.com'; const AUTHORIZE_URL = `${OPENAI_ISSUER}/oauth/authorize`; const TOKEN_URL = `${OPENAI_ISSUER}/oauth/token`; const CLIENT_ID = 'app_EMoamEEZ73f0CkXaXp7hrann'; -const REDIRECT_PORT = 1455; -const REDIRECT_URI = `http://localhost:${REDIRECT_PORT}/auth/callback`; +const DEFAULT_REDIRECT_PORTS = [1455, 1456, 1457, 1458, 1459]; const SCOPES = ['openid', 'profile', 'email', 'offline_access']; -export async function createAuthorizationFlow() { +function getRedirectUri(port) { + return `http://localhost:${port}/auth/callback`; +} +export async function createAuthorizationFlow(port) { const pkce = await generatePKCE(); const state = randomBytes(16).toString('hex'); + const redirectPort = port || DEFAULT_REDIRECT_PORTS[0]; + const redirectUri = getRedirectUri(redirectPort); const authUrl = new URL(AUTHORIZE_URL); authUrl.searchParams.set('client_id', CLIENT_ID); - authUrl.searchParams.set('redirect_uri', REDIRECT_URI); + authUrl.searchParams.set('redirect_uri', redirectUri); authUrl.searchParams.set('response_type', 'code'); authUrl.searchParams.set('scope', SCOPES.join(' ')); authUrl.searchParams.set('code_challenge', pkce.challenge); @@ -28,13 +31,42 @@ export async function createAuthorizationFlow() { authUrl.searchParams.set('id_token_add_organizations', 'true'); authUrl.searchParams.set('codex_cli_simplified_flow', 'true'); authUrl.searchParams.set('originator', 'codex_cli_rs'); - return { pkce, state, url: authUrl.toString() }; + return { pkce, state, url: authUrl.toString(), redirectUri, port: redirectPort }; } -export async function loginAccount(alias, flow) { - const activeFlow = flow ?? await createAuthorizationFlow(); - const { pkce, state } = activeFlow; +function tryListenOnPort(server, port) { return new Promise((resolve, reject) => { - let server = null; + const onError = (err) => { + server.off('error', onError); + reject(err); + }; + server.on('error', onError); + server.listen(port, () => { + server.off('error', onError); + resolve(); + }); + }); +} +async function findAvailablePort(server, ports) { + for (const port of ports) { + try { + await tryListenOnPort(server, port); + return port; + } + catch (err) { + if (err.code === 'EADDRINUSE') { + continue; + } + throw err; + } + } + throw new Error(`All ports ${ports.join(', ')} are in use. Stop Codex CLI if running.`); +} +export async function loginAccount(alias, flow) { + const ports = DEFAULT_REDIRECT_PORTS; + let activeFlow = flow; + let server = null; + let actualPort; + return new Promise(async (resolve, reject) => { const cleanup = () => { if (server) { server.close(); @@ -47,6 +79,13 @@ export async function loginAccount(alias, flow) { res.end('Not found'); return; } + if (!activeFlow) { + res.writeHead(500); + res.end('No active flow'); + cleanup(); + reject(new Error('No active flow')); + return; + } const parsedUrl = url.parse(req.url, true); const code = parsedUrl.query.code; const returnedState = parsedUrl.query.state; @@ -57,7 +96,7 @@ export async function loginAccount(alias, flow) { reject(new Error('No authorization code')); return; } - if (returnedState && returnedState !== state) { + if (returnedState && returnedState !== activeFlow.state) { res.writeHead(400); res.end('Invalid state'); cleanup(); @@ -65,7 +104,6 @@ export async function loginAccount(alias, flow) { return; } try { - // Exchange code for tokens const tokenRes = await fetch(TOKEN_URL, { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, @@ -73,8 +111,8 @@ export async function loginAccount(alias, flow) { grant_type: 'authorization_code', client_id: CLIENT_ID, code, - code_verifier: pkce.verifier, - redirect_uri: REDIRECT_URI + code_verifier: activeFlow.pkce.verifier, + redirect_uri: activeFlow.redirectUri }) }); if (!tokenRes.ok) { @@ -137,21 +175,21 @@ export async function loginAccount(alias, flow) { reject(err); } }); - server.listen(REDIRECT_PORT, () => { + try { + actualPort = await findAvailablePort(server, ports); + if (!activeFlow || activeFlow.port !== actualPort) { + activeFlow = await createAuthorizationFlow(actualPort); + } console.log(`\n[multi-auth] Login for account "${alias}"`); console.log(`[multi-auth] Open this URL in your browser:\n`); console.log(` ${activeFlow.url}\n`); - console.log(`[multi-auth] Waiting for callback on port ${REDIRECT_PORT}...`); - }); - server.on('error', (err) => { - if (err.code === 'EADDRINUSE') { - reject(new Error(`Port ${REDIRECT_PORT} is in use. Stop Codex CLI if running.`)); - } - else { - reject(err); - } - }); - // Timeout after 5 minutes + console.log(`[multi-auth] Waiting for callback on port ${actualPort}...`); + } + catch (err) { + cleanup(); + reject(err); + return; + } setTimeout(() => { cleanup(); reject(new Error('Login timeout - no callback received')); @@ -177,8 +215,6 @@ export async function refreshToken(alias) { }); if (!tokenRes.ok) { console.error(`[multi-auth] Refresh failed for ${alias}: ${tokenRes.status}`); - // If the refresh token is invalid/expired, mark this account invalid so - // rotation can keep working without repeatedly selecting a broken account. if (tokenRes.status === 401 || tokenRes.status === 403) { try { updateAccount(alias, { @@ -220,7 +256,6 @@ export async function ensureValidToken(alias) { const account = store.accounts[alias]; if (!account) return null; - // Refresh if expiring within 5 minutes const bufferMs = 5 * 60 * 1000; if (account.expiresAt < Date.now() + bufferMs) { console.log(`[multi-auth] Refreshing token for ${alias}`); diff --git a/dist/auth.js.map b/dist/auth.js.map index b769a52..c5bff1c 100644 --- a/dist/auth.js.map +++ b/dist/auth.js.map @@ -1 +1 @@ -{"version":3,"file":"auth.js","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"auth.js","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/codex-auth.d.ts.map b/dist/codex-auth.d.ts.map index 3bf5094..4947157 100644 --- a/dist/codex-auth.d.ts.map +++ b/dist/codex-auth.d.ts.map @@ -1 +1 @@ -{"version":3,"file":"codex-auth.d.ts","sourceRoot":"","sources":["../src/codex-auth.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,MAAM,CAAA;IAChB,YAAY,EAAE,MAAM,CAAA;IACpB,aAAa,EAAE,MAAM,CAAA;IACrB,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB;AAED,MAAM,WAAW,aAAa;IAC5B,cAAc,EAAE,MAAM,GAAG,IAAI,CAAA;IAC7B,MAAM,EAAE,eAAe,CAAA;IACvB,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB;AAQD,wBAAgB,gBAAgB,IAAI,MAAM,CAEzC;AAQD,wBAAgB,iBAAiB,IAAI,aAAa,GAAG,IAAI,CAWxD;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,aAAa,GAAG,IAAI,CAK5D;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI,CAW1E;AAED,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI,GAAG,MAAM,GAAG,SAAS,CAMzF;AAED,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI,GAAG,MAAM,GAAG,SAAS,CAI7F;AAED,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI,GAAG,MAAM,GAAG,SAAS,CAK1F;AAkCD,wBAAgB,iBAAiB,IAAI;IAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,KAAK,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,CA2C9F;AAED,wBAAgB,kBAAkB,IAAI;IAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAE7D;AAED,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CA8B1D"} \ No newline at end of file +{"version":3,"file":"codex-auth.d.ts","sourceRoot":"","sources":["../src/codex-auth.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,MAAM,CAAA;IAChB,YAAY,EAAE,MAAM,CAAA;IACpB,aAAa,EAAE,MAAM,CAAA;IACrB,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB;AAED,MAAM,WAAW,aAAa;IAC5B,cAAc,EAAE,MAAM,GAAG,IAAI,CAAA;IAC7B,MAAM,EAAE,eAAe,CAAA;IACvB,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB;AAiBD,wBAAgB,gBAAgB,IAAI,MAAM,CAEzC;AAQD,wBAAgB,iBAAiB,IAAI,aAAa,GAAG,IAAI,CAWxD;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,aAAa,GAAG,IAAI,CAK5D;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI,CAW1E;AAED,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI,GAAG,MAAM,GAAG,SAAS,CAMzF;AAED,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI,GAAG,MAAM,GAAG,SAAS,CAI7F;AAED,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI,GAAG,MAAM,GAAG,SAAS,CAK1F;AAkCD,wBAAgB,iBAAiB,IAAI;IAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,KAAK,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,CA2C9F;AAED,wBAAgB,kBAAkB,IAAI;IAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAE7D;AAED,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CA8B1D"} \ No newline at end of file diff --git a/dist/codex-auth.js b/dist/codex-auth.js index 2ebc65a..06ce215 100644 --- a/dist/codex-auth.js +++ b/dist/codex-auth.js @@ -2,8 +2,16 @@ import * as fs from 'fs'; import * as os from 'os'; import * as path from 'path'; import { addAccount, loadStore, setActiveAlias, updateAccount } from './store.js'; +const CODEX_AUTH_FILE_ENV = 'OPENCODE_MULTI_AUTH_CODEX_AUTH_FILE'; +function getCodexAuthFilePath() { + const override = process.env[CODEX_AUTH_FILE_ENV]; + if (override && override.trim()) + return path.resolve(override.trim()); + const CODEX_DIR = path.join(os.homedir(), '.codex'); + return path.join(CODEX_DIR, 'auth.json'); +} const CODEX_DIR = path.join(os.homedir(), '.codex'); -const CODEX_AUTH_FILE = path.join(CODEX_DIR, 'auth.json'); +const CODEX_AUTH_FILE = getCodexAuthFilePath(); let lastFingerprint = null; let lastAuthError = null; export function getCodexAuthPath() { diff --git a/dist/codex-auth.js.map b/dist/codex-auth.js.map index 2ed76bc..5b8852d 100644 --- a/dist/codex-auth.js.map +++ b/dist/codex-auth.js.map @@ -1 +1 @@ -{"version":3,"file":"codex-auth.js","sourceRoot":"","sources":["../src/codex-auth.ts"],"names":[],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"codex-auth.js","sourceRoot":"","sources":["../src/codex-auth.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/errors.d.ts b/dist/errors.d.ts new file mode 100644 index 0000000..223cee1 --- /dev/null +++ b/dist/errors.d.ts @@ -0,0 +1,17 @@ +export type ErrorCode = 'NO_ELIGIBLE_ACCOUNTS' | 'ACCOUNT_NOT_FOUND' | 'ACCOUNT_DISABLED' | 'TOKEN_REFRESH_FAILED' | 'STORE_LOCKED' | 'STORE_CORRUPTED' | 'STORE_MIGRATION_FAILED' | 'VALIDATION_ERROR' | 'RATE_LIMITED' | 'AUTH_INVALID' | 'MODEL_UNSUPPORTED' | 'WORKSPACE_DEACTIVATED' | 'MAX_RETRIES_EXCEEDED' | 'INVALID_REQUEST' | 'LOCALHOST_ONLY'; +export interface DeterministicError { + code: ErrorCode; + message: string; + details?: Record; +} +export declare function createError(code: ErrorCode, message: string, details?: Record): DeterministicError; +export declare function errorResponse(error: DeterministicError, status?: number): Response; +export declare const Errors: { + noEligibleAccounts: (reason?: string) => DeterministicError; + accountNotFound: (alias: string) => DeterministicError; + accountDisabled: (alias: string) => DeterministicError; + maxRetriesExceeded: (attempts: number, aliasesTried: string[]) => DeterministicError; + storeLocked: (reason?: string) => DeterministicError; + localhostOnly: (host: string) => DeterministicError; +}; +//# sourceMappingURL=errors.d.ts.map \ No newline at end of file diff --git a/dist/errors.d.ts.map b/dist/errors.d.ts.map new file mode 100644 index 0000000..6f13e42 --- /dev/null +++ b/dist/errors.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,SAAS,GACjB,sBAAsB,GACtB,mBAAmB,GACnB,kBAAkB,GAClB,sBAAsB,GACtB,cAAc,GACd,iBAAiB,GACjB,wBAAwB,GACxB,kBAAkB,GAClB,cAAc,GACd,cAAc,GACd,mBAAmB,GACnB,uBAAuB,GACvB,sBAAsB,GACtB,iBAAiB,GACjB,gBAAgB,CAAA;AAEpB,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,SAAS,CAAA;IACf,OAAO,EAAE,MAAM,CAAA;IACf,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAClC;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,kBAAkB,CAEnH;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,kBAAkB,EAAE,MAAM,GAAE,MAAY,GAAG,QAAQ,CAKvF;AAED,eAAO,MAAM,MAAM;kCACa,MAAM,KAAG,kBAAkB;6BAIhC,MAAM,KAAG,kBAAkB;6BAK3B,MAAM,KAAG,kBAAkB;mCAKrB,MAAM,gBAAgB,MAAM,EAAE,KAAG,kBAAkB;2BAK3D,MAAM,KAAG,kBAAkB;0BAI5B,MAAM,KAAG,kBAAkB;CAKlD,CAAA"} \ No newline at end of file diff --git a/dist/errors.js b/dist/errors.js new file mode 100644 index 0000000..cc2b886 --- /dev/null +++ b/dist/errors.js @@ -0,0 +1,37 @@ +export function createError(code, message, details) { + return { code, message, details }; +} +export function errorResponse(error, status = 500) { + return new Response(JSON.stringify({ error }), { status, headers: { 'Content-Type': 'application/json' } }); +} +export const Errors = { + noEligibleAccounts: (reason) => ({ + code: 'NO_ELIGIBLE_ACCOUNTS', + message: reason || 'No eligible accounts available for rotation', + }), + accountNotFound: (alias) => ({ + code: 'ACCOUNT_NOT_FOUND', + message: `Account not found: ${alias}`, + details: { alias }, + }), + accountDisabled: (alias) => ({ + code: 'ACCOUNT_DISABLED', + message: `Account is disabled: ${alias}`, + details: { alias }, + }), + maxRetriesExceeded: (attempts, aliasesTried) => ({ + code: 'MAX_RETRIES_EXCEEDED', + message: `Exhausted all ${attempts} retry attempts`, + details: { attempts, aliasesTried }, + }), + storeLocked: (reason) => ({ + code: 'STORE_LOCKED', + message: reason || 'Store is locked and cannot be modified', + }), + localhostOnly: (host) => ({ + code: 'LOCALHOST_ONLY', + message: 'Dashboard can only bind to localhost (127.0.0.1 or ::1)', + details: { attemptedHost: host }, + }), +}; +//# sourceMappingURL=errors.js.map \ No newline at end of file diff --git a/dist/errors.js.map b/dist/errors.js.map new file mode 100644 index 0000000..e8a61cb --- /dev/null +++ b/dist/errors.js.map @@ -0,0 +1 @@ +{"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAuBA,MAAM,UAAU,WAAW,CAAC,IAAe,EAAE,OAAe,EAAE,OAAiC;IAC7F,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,CAAA;AACnC,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,KAAyB,EAAE,SAAiB,GAAG;IAC3E,OAAO,IAAI,QAAQ,CACjB,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,CAAC,EACzB,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE,EAAE,CAC5D,CAAA;AACH,CAAC;AAED,MAAM,CAAC,MAAM,MAAM,GAAG;IACpB,kBAAkB,EAAE,CAAC,MAAe,EAAsB,EAAE,CAAC,CAAC;QAC5D,IAAI,EAAE,sBAAsB;QAC5B,OAAO,EAAE,MAAM,IAAI,6CAA6C;KACjE,CAAC;IACF,eAAe,EAAE,CAAC,KAAa,EAAsB,EAAE,CAAC,CAAC;QACvD,IAAI,EAAE,mBAAmB;QACzB,OAAO,EAAE,sBAAsB,KAAK,EAAE;QACtC,OAAO,EAAE,EAAE,KAAK,EAAE;KACnB,CAAC;IACF,eAAe,EAAE,CAAC,KAAa,EAAsB,EAAE,CAAC,CAAC;QACvD,IAAI,EAAE,kBAAkB;QACxB,OAAO,EAAE,wBAAwB,KAAK,EAAE;QACxC,OAAO,EAAE,EAAE,KAAK,EAAE;KACnB,CAAC;IACF,kBAAkB,EAAE,CAAC,QAAgB,EAAE,YAAsB,EAAsB,EAAE,CAAC,CAAC;QACrF,IAAI,EAAE,sBAAsB;QAC5B,OAAO,EAAE,iBAAiB,QAAQ,iBAAiB;QACnD,OAAO,EAAE,EAAE,QAAQ,EAAE,YAAY,EAAE;KACpC,CAAC;IACF,WAAW,EAAE,CAAC,MAAe,EAAsB,EAAE,CAAC,CAAC;QACrD,IAAI,EAAE,cAAc;QACpB,OAAO,EAAE,MAAM,IAAI,wCAAwC;KAC5D,CAAC;IACF,aAAa,EAAE,CAAC,IAAY,EAAsB,EAAE,CAAC,CAAC;QACpD,IAAI,EAAE,gBAAgB;QACtB,OAAO,EAAE,yDAAyD;QAClE,OAAO,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE;KACjC,CAAC;CACH,CAAA"} \ No newline at end of file diff --git a/dist/force-mode.d.ts b/dist/force-mode.d.ts new file mode 100644 index 0000000..94b70d2 --- /dev/null +++ b/dist/force-mode.d.ts @@ -0,0 +1,24 @@ +export interface ForceState { + forcedAlias: string | null; + forcedUntil: number | null; + previousRotationStrategy: string | null; + forcedBy: string | null; +} +export declare function getForceState(): ForceState; +export declare function isForceActive(): boolean; +export declare function activateForce(alias: string, actor?: string): { + success: boolean; + error?: string; + state?: ForceState; +}; +export declare function clearForce(): { + success: boolean; + restoredStrategy?: string | null; +}; +export declare function checkAndAutoClearForce(): { + wasCleared: boolean; + reason?: string; +}; +export declare function getRemainingForceTimeMs(): number; +export declare function formatForceDuration(ms: number): string; +//# sourceMappingURL=force-mode.d.ts.map \ No newline at end of file diff --git a/dist/force-mode.d.ts.map b/dist/force-mode.d.ts.map new file mode 100644 index 0000000..fd74deb --- /dev/null +++ b/dist/force-mode.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"force-mode.d.ts","sourceRoot":"","sources":["../src/force-mode.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,UAAU;IACzB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B,wBAAwB,EAAE,MAAM,GAAG,IAAI,CAAA;IACvC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;CACxB;AAcD,wBAAgB,aAAa,IAAI,UAAU,CAQ1C;AAED,wBAAgB,aAAa,IAAI,OAAO,CAwBvC;AAED,wBAAgB,aAAa,CAC3B,KAAK,EAAE,MAAM,EACb,KAAK,GAAE,MAAiB,GACvB;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,UAAU,CAAA;CAAE,CA+C1D;AAED,wBAAgB,UAAU,IAAI;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAiCnF;AAED,wBAAgB,sBAAsB,IAAI;IAAE,UAAU,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CA6BjF;AAED,wBAAgB,uBAAuB,IAAI,MAAM,CAOhD;AAED,wBAAgB,mBAAmB,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAQtD"} \ No newline at end of file diff --git a/dist/force-mode.js b/dist/force-mode.js new file mode 100644 index 0000000..9d09b4c --- /dev/null +++ b/dist/force-mode.js @@ -0,0 +1,149 @@ +import { loadStore, saveStore } from './store.js'; +const FORCE_TTL_MS = 24 * 60 * 60 * 1000; // 24 hours +const ROTATION_STRATEGIES = new Set([ + 'round-robin', + 'least-used', + 'random', + 'weighted-round-robin' +]); +function isRotationStrategy(value) { + return typeof value === 'string' && ROTATION_STRATEGIES.has(value); +} +export function getForceState() { + const store = loadStore(); + return { + forcedAlias: store.forcedAlias ?? null, + forcedUntil: store.forcedUntil ?? null, + previousRotationStrategy: store.previousRotationStrategy ?? null, + forcedBy: store.forcedBy ?? null + }; +} +export function isForceActive() { + const state = getForceState(); + if (!state.forcedAlias || !state.forcedUntil) { + return false; + } + const now = Date.now(); + if (now > state.forcedUntil) { + return false; + } + // Check if forced alias still exists and is eligible + const store = loadStore(); + const forcedAccount = store.accounts[state.forcedAlias]; + if (!forcedAccount) { + return false; + } + // Check if account is disabled + if (forcedAccount.enabled === false) { + return false; + } + return true; +} +export function activateForce(alias, actor = 'system') { + const store = loadStore(); + // Validate alias exists + if (!store.accounts[alias]) { + return { success: false, error: `Account '${alias}' not found` }; + } + // Validate alias is enabled + if (store.accounts[alias].enabled === false) { + return { success: false, error: `Account '${alias}' is disabled` }; + } + const now = Date.now(); + const keepExistingTtl = store.forcedAlias === alias && + typeof store.forcedUntil === 'number' && + store.forcedUntil > now; + const forcedUntil = keepExistingTtl ? store.forcedUntil : now + FORCE_TTL_MS; + const currentStrategy = store.settings?.rotationStrategy || + store.rotationStrategy || + 'round-robin'; + // Store previous rotation strategy if not already forcing + const previousStrategy = (store.forcedAlias ? store.previousRotationStrategy : currentStrategy) ?? null; + const newStore = { + ...store, + forcedAlias: alias, + forcedUntil, + previousRotationStrategy: previousStrategy, + forcedBy: actor + }; + saveStore(newStore); + return { + success: true, + state: { + forcedAlias: alias, + forcedUntil, + previousRotationStrategy: previousStrategy, + forcedBy: actor + } + }; +} +export function clearForce() { + const store = loadStore(); + const restoredStrategy = store.previousRotationStrategy; + const currentStrategy = store.settings?.rotationStrategy || + store.rotationStrategy || + 'round-robin'; + const nextStrategy = isRotationStrategy(restoredStrategy) + ? restoredStrategy + : currentStrategy; + const newStore = { + ...store, + forcedAlias: null, + forcedUntil: null, + rotationStrategy: nextStrategy, + previousRotationStrategy: null, + forcedBy: null + }; + if (store.settings) { + newStore.settings = { + ...store.settings, + rotationStrategy: nextStrategy + }; + } + saveStore(newStore); + return { + success: true, + restoredStrategy + }; +} +export function checkAndAutoClearForce() { + const state = getForceState(); + if (!state.forcedAlias) { + return { wasCleared: false }; + } + const store = loadStore(); + const now = Date.now(); + // Check expiry + if (state.forcedUntil && now > state.forcedUntil) { + clearForce(); + return { wasCleared: true, reason: 'expired' }; + } + // Check if alias still exists + if (!store.accounts[state.forcedAlias]) { + clearForce(); + return { wasCleared: true, reason: 'account_removed' }; + } + // Check if alias is disabled + if (store.accounts[state.forcedAlias].enabled === false) { + clearForce(); + return { wasCleared: true, reason: 'account_disabled' }; + } + return { wasCleared: false }; +} +export function getRemainingForceTimeMs() { + const state = getForceState(); + if (!state.forcedUntil) { + return 0; + } + const remaining = state.forcedUntil - Date.now(); + return Math.max(0, remaining); +} +export function formatForceDuration(ms) { + const hours = Math.floor(ms / (60 * 60 * 1000)); + const minutes = Math.floor((ms % (60 * 60 * 1000)) / (60 * 1000)); + if (hours > 0) { + return `${hours}h ${minutes}m`; + } + return `${minutes}m`; +} +//# sourceMappingURL=force-mode.js.map \ No newline at end of file diff --git a/dist/force-mode.js.map b/dist/force-mode.js.map new file mode 100644 index 0000000..323af91 --- /dev/null +++ b/dist/force-mode.js.map @@ -0,0 +1 @@ +{"version":3,"file":"force-mode.js","sourceRoot":"","sources":["../src/force-mode.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/index.d.ts.map b/dist/index.d.ts.map index 48fe73c..7b6e1cc 100644 --- a/dist/index.d.ts.map +++ b/dist/index.d.ts.map @@ -1 +1 @@ -{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAe,MAAM,qBAAqB,CAAA;AAiM9D;;;;GAIG;AACH,QAAA,MAAM,eAAe,EAAE,MA0oBtB,CAAA;AAED,eAAe,eAAe,CAAA"} \ No newline at end of file +{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAe,MAAM,qBAAqB,CAAA;AA+O9D;;;;GAIG;AACH,QAAA,MAAM,eAAe,EAAE,MA4rBtB,CAAA;AAED,eAAe,eAAe,CAAA"} \ No newline at end of file diff --git a/dist/index.js b/dist/index.js index d77a84a..5e1d1da 100644 --- a/dist/index.js +++ b/dist/index.js @@ -1,10 +1,13 @@ import fs from 'node:fs'; import { syncAuthFromOpenCode } from './auth-sync.js'; import { createAuthorizationFlow, loginAccount } from './auth.js'; -import { extractRateLimitUpdate, mergeRateLimits } from './rate-limits.js'; +import { extractRateLimitUpdate, getBlockingRateLimitResetAt, mergeRateLimits, parseRateLimitResetFromError, parseRetryAfterHeader } from './rate-limits.js'; import { getNextAccount, markAuthInvalid, markModelUnsupported, markRateLimited, markWorkspaceDeactivated } from './rotation.js'; -import { listAccounts, updateAccount } from './store.js'; +import { getForceState, isForceActive } from './force-mode.js'; +import { getRuntimeSettings } from './settings.js'; +import { listAccounts, updateAccount, loadStore } from './store.js'; import { DEFAULT_CONFIG } from './types.js'; +import { Errors } from './errors.js'; const PROVIDER_ID = 'openai'; const CODEX_BASE_URL = 'https://chatgpt.com/backend-api'; const REDIRECT_PORT = 1455; @@ -122,6 +125,30 @@ function ensureContentType(headers) { } return responseHeaders; } +function extractErrorMessage(payload, fallbackText = '') { + if (!payload || typeof payload !== 'object') { + return fallbackText; + } + const detailMessage = typeof payload?.detail?.message === 'string' + ? payload.detail.message + : typeof payload?.detail === 'string' + ? payload.detail + : ''; + const errorMessage = typeof payload?.error?.message === 'string' + ? payload.error.message + : ''; + const topLevelMessage = typeof payload?.message === 'string' + ? payload.message + : ''; + return detailMessage || errorMessage || topLevelMessage || fallbackText; +} +function resolveRateLimitedUntil(rateLimits, headers, errorText, fallbackCooldownMs, now = Date.now()) { + const retryAfterUntil = parseRetryAfterHeader(headers.get('retry-after'), now) || 0; + const windowResetUntil = getBlockingRateLimitResetAt(rateLimits, now) || 0; + const messageResetUntil = parseRateLimitResetFromError(errorText, now) || 0; + const fallbackUntil = now + fallbackCooldownMs; + return Math.max(fallbackUntil, retryAfterUntil, windowResetUntil, messageResetUntil); +} function parseSseStream(sseText) { const lines = sseText.split('\n'); for (const line of lines) { @@ -488,188 +515,219 @@ const MultiAuthPlugin = async ({ client, $, serverUrl, project, directory }) => console.log('[multi-auth] No accounts configured. Run: opencode-multi-auth add '); return {}; } - // Custom fetch with multi-account rotation const customFetch = async (input, init) => { await syncAuthFromOpenCode(getAuth); - const rotation = await getNextAccount(pluginConfig); - if (!rotation) { - return new Response(JSON.stringify({ error: { message: 'No available accounts' } }), { status: 503, headers: { 'Content-Type': 'application/json' } }); - } - const { account, token } = rotation; - const decoded = decodeJWT(token); - const accountId = decoded?.[JWT_CLAIM_PATH]?.chatgpt_account_id; - if (!accountId) { - return new Response(JSON.stringify({ error: { message: '[multi-auth] Failed to extract accountId from token' } }), { status: 401, headers: { 'Content-Type': 'application/json' } }); - } - const originalUrl = extractRequestUrl(input); - const url = toCodexBackendUrl(originalUrl); - let body = {}; - try { - body = init?.body ? JSON.parse(init.body) : {}; - } - catch { - body = {}; - } - const isStreaming = body?.stream === true; - const normalizedModel = normalizeModel(body.model); - const reasoningMatch = body.model?.match(/-(none|low|medium|high|xhigh)$/); - const payload = { - ...body, - model: normalizedModel, - store: false - }; - // Note: The ChatGPT Codex backend does not currently accept - // `truncation`. Keep this opt-in and default off. - if (payload.truncation === undefined) { - const truncationRaw = (process.env.OPENCODE_MULTI_AUTH_TRUNCATION || '').trim(); - if (truncationRaw && truncationRaw !== 'disabled' && truncationRaw !== 'false' && truncationRaw !== '0') { - payload.truncation = truncationRaw; - } - } - if (payload.input) { - payload.input = filterInput(payload.input); - } - if (reasoningMatch?.[1]) { - payload.reasoning = { - ...(payload.reasoning || {}), - effort: reasoningMatch[1], - summary: payload.reasoning?.summary || 'auto' + const store = loadStore(); + const forceState = getForceState(); + const forcePinned = isForceActive() && !!forceState.forcedAlias; + const eligibleCount = Object.values(store.accounts).filter(acc => { + const now = Date.now(); + return (!acc.rateLimitedUntil || acc.rateLimitedUntil < now) && + (!acc.modelUnsupportedUntil || acc.modelUnsupportedUntil < now) && + (!acc.workspaceDeactivatedUntil || acc.workspaceDeactivatedUntil < now) && + !acc.authInvalid && + acc.enabled !== false; + }).length; + const maxAttempts = forcePinned ? 1 : Math.max(1, eligibleCount); + const triedAliases = new Set(); + let attempt = 0; + while (attempt < maxAttempts) { + attempt++; + const settings = getRuntimeSettings(); + const effectiveConfig = { + ...pluginConfig, + rotationStrategy: settings.settings.rotationStrategy }; - } - delete payload.reasoning_effort; - try { - const headers = new Headers(init?.headers || {}); - headers.delete('x-api-key'); - headers.set('Content-Type', 'application/json'); - headers.set('Authorization', `Bearer ${token}`); - headers.set(OPENAI_HEADERS.ACCOUNT_ID, accountId); - headers.set(OPENAI_HEADERS.BETA, OPENAI_HEADER_VALUES.BETA_RESPONSES); - headers.set(OPENAI_HEADERS.ORIGINATOR, OPENAI_HEADER_VALUES.ORIGINATOR_CODEX); - const cacheKey = payload?.prompt_cache_key; - if (cacheKey) { - headers.set(OPENAI_HEADERS.CONVERSATION_ID, cacheKey); - headers.set(OPENAI_HEADERS.SESSION_ID, cacheKey); - } - else { - headers.delete(OPENAI_HEADERS.CONVERSATION_ID); - headers.delete(OPENAI_HEADERS.SESSION_ID); + const rotation = await getNextAccount(effectiveConfig); + if (!rotation) { + if (forcePinned && forceState.forcedAlias) { + const forced = loadStore().accounts[forceState.forcedAlias]; + const now = Date.now(); + if (forced?.rateLimitedUntil && forced.rateLimitedUntil > now) { + return new Response(JSON.stringify({ + error: { + code: 'RATE_LIMITED', + message: `Forced account '${forced.alias}' is rate-limited until ${new Date(forced.rateLimitedUntil).toISOString()}`, + details: { alias: forced.alias, rateLimitedUntil: forced.rateLimitedUntil } + } + }), { status: 429, headers: { 'Content-Type': 'application/json' } }); + } + } + return new Response(JSON.stringify({ + error: Errors.noEligibleAccounts('No available accounts after filtering') + }), { status: 503, headers: { 'Content-Type': 'application/json' } }); } - headers.set('accept', 'text/event-stream'); - const res = await fetch(url, { - method: init?.method || 'POST', - headers, - body: JSON.stringify(payload) - }); - const limitUpdate = extractRateLimitUpdate(res.headers); - if (limitUpdate) { - updateAccount(account.alias, { - rateLimits: mergeRateLimits(account.rateLimits, limitUpdate) - }); + const { account, token } = rotation; + if (triedAliases.has(account.alias)) { + continue; } - // Handle rate limiting with automatic rotation - if (res.status === 401 || res.status === 403) { - const errorData = await res.clone().json().catch(() => ({})); - const message = errorData?.error?.message || ''; - if (message.toLowerCase().includes('invalidated') || res.status === 401) { - markAuthInvalid(account.alias); - } - const retryRotation = await getNextAccount(pluginConfig); - if (retryRotation && retryRotation.account.alias !== account.alias) { - return customFetch(input, init); - } + triedAliases.add(account.alias); + const decoded = decodeJWT(token); + const accountId = decoded?.[JWT_CLAIM_PATH]?.chatgpt_account_id; + if (!accountId) { return new Response(JSON.stringify({ error: { - message: `[multi-auth][acc=${account.alias}] Unauthorized on all accounts. ${message}`.trim() + code: 'TOKEN_PARSE_ERROR', + message: '[multi-auth] Failed to extract accountId from token' } - }), { status: res.status, headers: { 'Content-Type': 'application/json' } }); + }), { status: 401, headers: { 'Content-Type': 'application/json' } }); + } + const originalUrl = extractRequestUrl(input); + const url = toCodexBackendUrl(originalUrl); + let body = {}; + try { + body = init?.body ? JSON.parse(init.body) : {}; } - if (res.status === 429) { - markRateLimited(account.alias, pluginConfig.rateLimitCooldownMs); - // Try another account - const retryRotation = await getNextAccount(pluginConfig); - if (retryRotation && retryRotation.account.alias !== account.alias) { - return customFetch(input, init); + catch { + body = {}; + } + const isStreaming = body?.stream === true; + const normalizedModel = normalizeModel(body.model); + const reasoningMatch = body.model?.match(/-(none|low|medium|high|xhigh)$/); + const payload = { + ...body, + model: normalizedModel, + store: false + }; + if (payload.truncation === undefined) { + const truncationRaw = (process.env.OPENCODE_MULTI_AUTH_TRUNCATION || '').trim(); + if (truncationRaw && truncationRaw !== 'disabled' && truncationRaw !== 'false' && truncationRaw !== '0') { + payload.truncation = truncationRaw; } - // All accounts exhausted - const errorData = await res.json().catch(() => ({})); - return new Response(JSON.stringify({ - error: { - message: `[multi-auth][acc=${account.alias}] Rate limited on all accounts. ${errorData.error?.message || ''}` - } - }), { status: 429, headers: { 'Content-Type': 'application/json' } }); } - if (res.status === 402) { - // Some accounts can temporarily be in a deactivated workspace state. - // Rotate to the next account instead of hard-failing the request. - const errorData = await res.clone().json().catch(() => null); - const errorText = await res.clone().text().catch(() => ''); - const code = (typeof errorData?.detail?.code === 'string' && errorData.detail.code) || - (typeof errorData?.error?.code === 'string' && errorData.error.code) || - ''; - const message = (typeof errorData?.detail?.message === 'string' && errorData.detail.message) || - (typeof errorData?.detail === 'string' && errorData.detail) || - (typeof errorData?.error?.message === 'string' && errorData.error.message) || - (typeof errorData?.message === 'string' && errorData.message) || - errorText || - ''; - const isDeactivatedWorkspace = code === 'deactivated_workspace' || - message.toLowerCase().includes('deactivated_workspace') || - message.toLowerCase().includes('deactivated workspace'); - if (isDeactivatedWorkspace) { - markWorkspaceDeactivated(account.alias, pluginConfig.workspaceDeactivatedCooldownMs, { - error: message || code + if (payload.input) { + payload.input = filterInput(payload.input); + } + if (reasoningMatch?.[1]) { + payload.reasoning = { + ...(payload.reasoning || {}), + effort: reasoningMatch[1], + summary: payload.reasoning?.summary || 'auto' + }; + } + delete payload.reasoning_effort; + try { + const headers = new Headers(init?.headers || {}); + headers.delete('x-api-key'); + headers.set('Content-Type', 'application/json'); + headers.set('Authorization', `Bearer ${token}`); + headers.set(OPENAI_HEADERS.ACCOUNT_ID, accountId); + headers.set(OPENAI_HEADERS.BETA, OPENAI_HEADER_VALUES.BETA_RESPONSES); + headers.set(OPENAI_HEADERS.ORIGINATOR, OPENAI_HEADER_VALUES.ORIGINATOR_CODEX); + const cacheKey = payload?.prompt_cache_key; + if (cacheKey) { + headers.set(OPENAI_HEADERS.CONVERSATION_ID, cacheKey); + headers.set(OPENAI_HEADERS.SESSION_ID, cacheKey); + } + else { + headers.delete(OPENAI_HEADERS.CONVERSATION_ID); + headers.delete(OPENAI_HEADERS.SESSION_ID); + } + headers.set('accept', 'text/event-stream'); + const res = await fetch(url, { + method: init?.method || 'POST', + headers, + body: JSON.stringify(payload) + }); + const limitUpdate = extractRateLimitUpdate(res.headers); + const mergedRateLimits = limitUpdate + ? mergeRateLimits(account.rateLimits, limitUpdate) + : account.rateLimits; + if (limitUpdate) { + updateAccount(account.alias, { + rateLimits: mergedRateLimits }); - const retryRotation = await getNextAccount(pluginConfig); - if (retryRotation && retryRotation.account.alias !== account.alias) { - return customFetch(input, init); + } + if (res.status === 401 || res.status === 403) { + const errorData = await res.clone().json().catch(() => ({})); + const message = errorData?.error?.message || ''; + if (message.toLowerCase().includes('invalidated') || res.status === 401) { + markAuthInvalid(account.alias); + } + if (attempt < maxAttempts) { + continue; } return new Response(JSON.stringify({ - error: { - message: `[multi-auth][acc=${account.alias}] Workspace deactivated on all accounts. ${message || code}`.trim() - } - }), { status: 402, headers: { 'Content-Type': 'application/json' } }); + error: Errors.maxRetriesExceeded(attempt, Array.from(triedAliases)) + }), { status: res.status, headers: { 'Content-Type': 'application/json' } }); } - } - if (res.status === 400) { - // Some accounts get staged access to newer Codex models (e.g. gpt-5.3-codex). - // If the backend says the model isn't supported for this account, temporarily - // skip it instead of trapping the whole rotation on a permanent 400 loop. - const errorData = await res.clone().json().catch(() => ({})); - const message = (typeof errorData?.detail === 'string' && errorData.detail) || - (typeof errorData?.error?.message === 'string' && errorData.error.message) || - (typeof errorData?.message === 'string' && errorData.message) || - ''; - const isModelUnsupported = typeof message === 'string' && - message.toLowerCase().includes('model is not supported') && - message.toLowerCase().includes('chatgpt account'); - if (isModelUnsupported) { - markModelUnsupported(account.alias, pluginConfig.modelUnsupportedCooldownMs, { - model: normalizedModel, - error: message - }); - const retryRotation = await getNextAccount(pluginConfig); - if (retryRotation && retryRotation.account.alias !== account.alias) { - return customFetch(input, init); + if (res.status === 429) { + const errorData = await res.clone().json().catch(() => ({})); + const errorText = extractErrorMessage(errorData); + const rateLimitedUntil = resolveRateLimitedUntil(mergedRateLimits, res.headers, errorText, pluginConfig.rateLimitCooldownMs); + markRateLimited(account.alias, rateLimitedUntil); + if (attempt < maxAttempts) { + continue; } return new Response(JSON.stringify({ - error: { - message: `[multi-auth] Model not supported on all accounts. ${message}`.trim() + error: Errors.maxRetriesExceeded(attempt, Array.from(triedAliases)) + }), { status: 429, headers: { 'Content-Type': 'application/json' } }); + } + if (res.status === 402) { + const errorData = await res.clone().json().catch(() => null); + const errorText = await res.clone().text().catch(() => ''); + const code = (typeof errorData?.detail?.code === 'string' && errorData.detail.code) || + (typeof errorData?.error?.code === 'string' && errorData.error.code) || + ''; + const message = (typeof errorData?.detail?.message === 'string' && errorData.detail.message) || + (typeof errorData?.detail === 'string' && errorData.detail) || + (typeof errorData?.error?.message === 'string' && errorData.error.message) || + (typeof errorData?.message === 'string' && errorData.message) || + errorText || + ''; + const isDeactivatedWorkspace = code === 'deactivated_workspace' || + message.toLowerCase().includes('deactivated_workspace') || + message.toLowerCase().includes('deactivated workspace'); + if (isDeactivatedWorkspace) { + markWorkspaceDeactivated(account.alias, pluginConfig.workspaceDeactivatedCooldownMs, { + error: message || code + }); + if (attempt < maxAttempts) { + continue; } - }), { status: 400, headers: { 'Content-Type': 'application/json' } }); + return new Response(JSON.stringify({ + error: Errors.maxRetriesExceeded(attempt, Array.from(triedAliases)) + }), { status: 402, headers: { 'Content-Type': 'application/json' } }); + } + } + if (res.status === 400) { + const errorData = await res.clone().json().catch(() => ({})); + const message = (typeof errorData?.detail === 'string' && errorData.detail) || + (typeof errorData?.error?.message === 'string' && errorData.error.message) || + (typeof errorData?.message === 'string' && errorData.message) || + ''; + const isModelUnsupported = typeof message === 'string' && + message.toLowerCase().includes('model is not supported') && + message.toLowerCase().includes('chatgpt account'); + if (isModelUnsupported) { + markModelUnsupported(account.alias, pluginConfig.modelUnsupportedCooldownMs, { + model: normalizedModel, + error: message + }); + if (attempt < maxAttempts) { + continue; + } + return new Response(JSON.stringify({ + error: Errors.maxRetriesExceeded(attempt, Array.from(triedAliases)) + }), { status: 400, headers: { 'Content-Type': 'application/json' } }); + } + } + if (!res.ok) { + return res; + } + const responseHeaders = ensureContentType(res.headers); + if (!isStreaming && responseHeaders.get('content-type')?.includes('text/event-stream')) { + return await convertSseToJson(res, responseHeaders); } - } - if (!res.ok) { return res; } - const responseHeaders = ensureContentType(res.headers); - if (!isStreaming && responseHeaders.get('content-type')?.includes('text/event-stream')) { - return await convertSseToJson(res, responseHeaders); + catch (err) { + return new Response(JSON.stringify({ error: { code: 'REQUEST_FAILED', message: `[multi-auth] Request failed: ${err}` } }), { status: 500, headers: { 'Content-Type': 'application/json' } }); } - return res; - } - catch (err) { - return new Response(JSON.stringify({ error: { message: `[multi-auth] Request failed: ${err}` } }), { status: 500, headers: { 'Content-Type': 'application/json' } }); } + return new Response(JSON.stringify({ + error: Errors.maxRetriesExceeded(attempt, Array.from(triedAliases)) + }), { status: 503, headers: { 'Content-Type': 'application/json' } }); }; // Return SDK configuration with custom fetch for rotation return { diff --git a/dist/index.js.map b/dist/index.js.map index 0b6da60..b180cbe 100644 --- a/dist/index.js.map +++ b/dist/index.js.map @@ -1 +1 @@ -{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/limits-refresh.d.ts.map b/dist/limits-refresh.d.ts.map index 67cc148..69af0bb 100644 --- a/dist/limits-refresh.d.ts.map +++ b/dist/limits-refresh.d.ts.map @@ -1 +1 @@ -{"version":3,"file":"limits-refresh.d.ts","sourceRoot":"","sources":["../src/limits-refresh.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAA;AAEpD,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,MAAM,CAAA;IACb,OAAO,EAAE,OAAO,CAAA;IAChB,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED,wBAAsB,2BAA2B,CAAC,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAyB1G;AAED,wBAAsB,iBAAiB,CACrC,QAAQ,EAAE,kBAAkB,EAAE,EAC9B,KAAK,CAAC,EAAE,MAAM,GACb,OAAO,CAAC,kBAAkB,EAAE,CAAC,CAkB/B"} \ No newline at end of file +{"version":3,"file":"limits-refresh.d.ts","sourceRoot":"","sources":["../src/limits-refresh.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAA;AAEpD,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,MAAM,CAAA;IACb,OAAO,EAAE,OAAO,CAAA;IAChB,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED,wBAAsB,2BAA2B,CAAC,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAmD1G;AAED,wBAAsB,iBAAiB,CACrC,QAAQ,EAAE,kBAAkB,EAAE,EAC9B,KAAK,CAAC,EAAE,MAAM,GACb,OAAO,CAAC,kBAAkB,EAAE,CAAC,CAkB/B"} \ No newline at end of file diff --git a/dist/limits-refresh.js b/dist/limits-refresh.js index 4399d00..91849a6 100644 --- a/dist/limits-refresh.js +++ b/dist/limits-refresh.js @@ -1,30 +1,50 @@ -import { mergeRateLimits } from './rate-limits.js'; +import { getBlockingRateLimitResetAt, isRateLimitErrorText, mergeRateLimits, parseRateLimitResetFromError } from './rate-limits.js'; import { loadStore, updateAccount } from './store.js'; import { probeRateLimitsForAccount } from './probe-limits.js'; import { logError, logInfo } from './logger.js'; +import { calculateLimitsConfidence } from './types.js'; export async function refreshRateLimitsForAccount(account) { updateAccount(account.alias, { limitStatus: 'running', limitError: undefined }); logInfo(`Refreshing limits for ${account.alias}`); const probe = await probeRateLimitsForAccount(account); - if (!probe.rateLimits) { + // Phase C: Only accept authoritative limits from successful completed sessions + if (!probe.isAuthoritative || !probe.rateLimits) { logError(`Limit probe failed for ${account.alias}: ${probe.error || 'Probe failed'}`); - updateAccount(account.alias, { + const now = Date.now(); + const errorText = probe.error || 'Probe failed'; + const likelyRateLimit = isRateLimitErrorText(errorText); + const parsedResetAt = parseRateLimitResetFromError(errorText, now); + const fallbackResetAt = likelyRateLimit + ? getBlockingRateLimitResetAt(account.rateLimits, now) + : undefined; + const rateLimitedUntil = parsedResetAt ?? fallbackResetAt; + // Phase C: Update only error metadata, preserve prior limits + const updates = { limitStatus: 'error', - limitError: probe.error || 'Probe failed', - lastLimitErrorAt: Date.now() - }); + limitError: errorText, + lastLimitErrorAt: now, + limitsConfidence: calculateLimitsConfidence(account.lastLimitProbeAt, now, 'error') + }; + if (typeof rateLimitedUntil === 'number' && rateLimitedUntil > now) { + updates.rateLimitedUntil = rateLimitedUntil; + } + updateAccount(account.alias, updates); return { alias: account.alias, updated: false, - error: probe.error || 'Probe failed' + error: errorText }; } + // Phase C: Only merge authoritative limits from successful probe + const now = Date.now(); updateAccount(account.alias, { rateLimits: mergeRateLimits(account.rateLimits, probe.rateLimits), limitStatus: 'success', limitError: undefined, - lastLimitProbeAt: Date.now() + lastLimitProbeAt: now, + limitsConfidence: calculateLimitsConfidence(now, account.lastLimitErrorAt, 'success') }); + logInfo(`Limits refreshed for ${account.alias} using model ${probe.probeModel || 'unknown'}, effort ${probe.probeEffort || 'default'}`); return { alias: account.alias, updated: true }; } export async function refreshRateLimits(accounts, alias) { diff --git a/dist/limits-refresh.js.map b/dist/limits-refresh.js.map index cb06676..665b9b2 100644 --- a/dist/limits-refresh.js.map +++ b/dist/limits-refresh.js.map @@ -1 +1 @@ -{"version":3,"file":"limits-refresh.js","sourceRoot":"","sources":["../src/limits-refresh.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAA;AAClD,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AACrD,OAAO,EAAE,yBAAyB,EAAE,MAAM,mBAAmB,CAAA;AAC7D,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,aAAa,CAAA;AAS/C,MAAM,CAAC,KAAK,UAAU,2BAA2B,CAAC,OAA2B;IAC3E,aAAa,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,WAAW,EAAE,SAAS,EAAE,UAAU,EAAE,SAAS,EAAE,CAAC,CAAA;IAC/E,OAAO,CAAC,yBAAyB,OAAO,CAAC,KAAK,EAAE,CAAC,CAAA;IACjD,MAAM,KAAK,GAAG,MAAM,yBAAyB,CAAC,OAAO,CAAC,CAAA;IACtD,IAAI,CAAC,KAAK,CAAC,UAAU,EAAE,CAAC;QACtB,QAAQ,CAAC,0BAA0B,OAAO,CAAC,KAAK,KAAK,KAAK,CAAC,KAAK,IAAI,cAAc,EAAE,CAAC,CAAA;QACrF,aAAa,CAAC,OAAO,CAAC,KAAK,EAAE;YAC3B,WAAW,EAAE,OAAO;YACpB,UAAU,EAAE,KAAK,CAAC,KAAK,IAAI,cAAc;YACzC,gBAAgB,EAAE,IAAI,CAAC,GAAG,EAAE;SAC7B,CAAC,CAAA;QACF,OAAO;YACL,KAAK,EAAE,OAAO,CAAC,KAAK;YACpB,OAAO,EAAE,KAAK;YACd,KAAK,EAAE,KAAK,CAAC,KAAK,IAAI,cAAc;SACrC,CAAA;IACH,CAAC;IAED,aAAa,CAAC,OAAO,CAAC,KAAK,EAAE;QAC3B,UAAU,EAAE,eAAe,CAAC,OAAO,CAAC,UAAU,EAAE,KAAK,CAAC,UAAU,CAAC;QACjE,WAAW,EAAE,SAAS;QACtB,UAAU,EAAE,SAAS;QACrB,gBAAgB,EAAE,IAAI,CAAC,GAAG,EAAE;KAC7B,CAAC,CAAA;IACF,OAAO,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,CAAA;AAChD,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,QAA8B,EAC9B,KAAc;IAEd,IAAI,KAAK,EAAE,CAAC;QACV,MAAM,OAAO,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,KAAK,KAAK,KAAK,CAAC,CAAA;QAC3D,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,OAAO,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,eAAe,EAAE,CAAC,CAAA;QAC5D,CAAC;QACD,OAAO,CAAC,MAAM,2BAA2B,CAAC,OAAO,CAAC,CAAC,CAAA;IACrD,CAAC;IAED,MAAM,KAAK,GAAG,SAAS,EAAE,CAAA;IACzB,MAAM,OAAO,GAAyB,EAAE,CAAA;IACxC,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC/B,OAAO,CAAC,IAAI,CAAC,MAAM,2BAA2B,CAAC,OAAO,CAAC,CAAC,CAAA;IAC1D,CAAC;IACD,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC;QAC/C,OAAO,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,wBAAwB,EAAE,CAAC,CAAA;IAC/E,CAAC;IACD,OAAO,OAAO,CAAA;AAChB,CAAC"} \ No newline at end of file +{"version":3,"file":"limits-refresh.js","sourceRoot":"","sources":["../src/limits-refresh.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/probe-limits.d.ts b/dist/probe-limits.d.ts index 431392a..3ff2c96 100644 --- a/dist/probe-limits.d.ts +++ b/dist/probe-limits.d.ts @@ -3,8 +3,15 @@ export interface ProbeResult { rateLimits?: AccountRateLimits; eventTs?: number; sourceFile?: string; + probeModel?: string; + probeEffort?: string; + probeDurationMs?: number; error?: string; + isAuthoritative?: boolean; } +export declare function shouldRetryWithFallback(error?: string): boolean; +export declare function getProbeEffort(): string; +export declare function getProbeModels(): string[]; export declare function probeRateLimitsForAccount(account: AccountCredentials): Promise; export declare function getProbeHomeRoot(): string; //# sourceMappingURL=probe-limits.d.ts.map \ No newline at end of file diff --git a/dist/probe-limits.d.ts.map b/dist/probe-limits.d.ts.map index 7a77deb..a96be6d 100644 --- a/dist/probe-limits.d.ts.map +++ b/dist/probe-limits.d.ts.map @@ -1 +1 @@ -{"version":3,"file":"probe-limits.d.ts","sourceRoot":"","sources":["../src/probe-limits.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAA;AASvE,MAAM,WAAW,WAAW;IAC1B,UAAU,CAAC,EAAE,iBAAiB,CAAA;IAC9B,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AA2HD,wBAAsB,yBAAyB,CAAC,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,WAAW,CAAC,CA2CjG;AAED,wBAAgB,gBAAgB,IAAI,MAAM,CAEzC"} \ No newline at end of file +{"version":3,"file":"probe-limits.d.ts","sourceRoot":"","sources":["../src/probe-limits.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAA;AAWvE,MAAM,WAAW,WAAW;IAC1B,UAAU,CAAC,EAAE,iBAAiB,CAAA;IAC9B,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,UAAU,CAAC,EAAE,MAAM,CAAA;IAEnB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,KAAK,CAAC,EAAE,MAAM,CAAA;IAEd,eAAe,CAAC,EAAE,OAAO,CAAA;CAC1B;AA4CD,wBAAgB,uBAAuB,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAa/D;AAGD,wBAAgB,cAAc,IAAI,MAAM,CAMvC;AAED,wBAAgB,cAAc,IAAI,MAAM,EAAE,CASzC;AAoED,wBAAsB,yBAAyB,CAAC,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,WAAW,CAAC,CAwFjG;AAED,wBAAgB,gBAAgB,IAAI,MAAM,CAEzC"} \ No newline at end of file diff --git a/dist/probe-limits.js b/dist/probe-limits.js index 2b72efd..aae24c5 100644 --- a/dist/probe-limits.js +++ b/dist/probe-limits.js @@ -7,7 +7,9 @@ const CODEX_HOME_ROOT = path.join(os.homedir(), '.codex-multi'); const CODEX_CONFIG_PATH = path.join(os.homedir(), '.codex', 'config.toml'); const DEFAULT_PROMPT = 'Reply ONLY with OK. Do not run any commands.'; const EXEC_TIMEOUT_MS = 120_000; -const DEFAULT_PROBE_MODELS = ['gpt-5-codex', 'gpt-5.2-codex', 'gpt-5.3-codex']; +// Reordered to prefer gpt-5.3-codex first (Phase C requirement) +const DEFAULT_PROBE_MODELS = ['gpt-5.3-codex', 'gpt-5.2-codex', 'gpt-5-codex']; +const DEFAULT_PROBE_EFFORT = 'low'; function ensureDir(dir) { if (!fs.existsSync(dir)) { fs.mkdirSync(dir, { recursive: true, mode: 0o700 }); @@ -47,16 +49,28 @@ function copyConfigToml(dir) { // ignore config copy errors } } -function shouldRetryWithFallback(error) { +export function shouldRetryWithFallback(error) { if (!error) return false; const text = error.toLowerCase(); return (text.includes('model_not_found') || text.includes('model is not supported') || text.includes('requested model') || - text.includes('does not exist')); + text.includes('does not exist') || + // Phase C: Handle reasoning.effort and unsupported_value errors + text.includes('unsupported_value') || + text.includes('reasoning.effort') || + text.includes('reasoning effort')); } -function getProbeModels() { +// Phase C: Get probe effort from environment or default to 'low' +export function getProbeEffort() { + const envEffort = process.env.OPENCODE_MULTI_AUTH_PROBE_EFFORT; + if (envEffort && ['low', 'medium', 'high'].includes(envEffort.toLowerCase())) { + return envEffort.toLowerCase(); + } + return DEFAULT_PROBE_EFFORT; +} +export function getProbeModels() { const raw = (process.env.OPENCODE_MULTI_AUTH_LIMITS_PROBE_MODELS || '').trim(); const fromEnv = raw .split(',') @@ -65,7 +79,7 @@ function getProbeModels() { const candidates = fromEnv.length > 0 ? fromEnv : DEFAULT_PROBE_MODELS; return Array.from(new Set(candidates)); } -async function runCodexExec(codexHome, model) { +async function runCodexExec(codexHome, model, effort) { return new Promise((resolve) => { const args = [ 'exec', @@ -78,16 +92,22 @@ async function runCodexExec(codexHome, model) { if (model) { args.push('-m', model); } + // Phase C: Add reasoning effort configuration + if (effort) { + args.push('-c', `model_reasoning_effort="${effort}"`); + } args.push(DEFAULT_PROMPT); let stderr = ''; let stdout = ''; + const startTime = Date.now(); const child = spawn('codex', args, { env: { ...process.env, CODEX_HOME: codexHome }, stdio: ['ignore', 'pipe', 'pipe'] }); const timer = setTimeout(() => { child.kill('SIGTERM'); - resolve({ ok: false, error: 'codex exec timed out' }); + const durationMs = Date.now() - startTime; + resolve({ ok: false, error: 'codex exec timed out', durationMs }); }, EXEC_TIMEOUT_MS); child.stdout.on('data', (data) => { stdout += data.toString(); @@ -101,16 +121,18 @@ async function runCodexExec(codexHome, model) { }); child.on('error', (err) => { clearTimeout(timer); - resolve({ ok: false, error: String(err) }); + const durationMs = Date.now() - startTime; + resolve({ ok: false, error: String(err), durationMs }); }); child.on('close', (code) => { clearTimeout(timer); + const durationMs = Date.now() - startTime; if (code === 0) { - resolve({ ok: true }); + resolve({ ok: true, durationMs }); } else { const message = stderr.trim() || stdout.trim() || `codex exec failed (code ${code})`; - resolve({ ok: false, error: message }); + resolve({ ok: false, error: message, durationMs }); } }); }); @@ -122,37 +144,76 @@ export async function probeRateLimitsForAccount(account) { copyConfigToml(codexHome); const sessionsDir = path.join(codexHome, 'sessions'); const probeModels = getProbeModels(); + const probeEffort = getProbeEffort(); let lastError = 'No token_count events found in alias sessions'; const attemptErrors = []; for (let idx = 0; idx < probeModels.length; idx++) { const probeModel = probeModels[idx]; const startedAt = Date.now(); - const execResult = await runCodexExec(codexHome, probeModel); + // Phase C: Pass effort config and track duration + const execResult = await runCodexExec(codexHome, probeModel, probeEffort); const latest = findLatestSessionRateLimits({ sessionsDir, sinceMs: startedAt - 5_000 }); - if (latest?.rateLimits) { + // Phase C: Only accept authoritative data from successful completions + if (execResult.ok && latest?.rateLimits) { return { rateLimits: latest.rateLimits, eventTs: latest.eventTs, - sourceFile: latest.sourceFile + sourceFile: latest.sourceFile, + probeModel, + probeEffort, + probeDurationMs: execResult.durationMs, + isAuthoritative: true }; } if (execResult.error) { lastError = execResult.error; - attemptErrors.push(`[model=${probeModel}] ${execResult.error}`); + attemptErrors.push(`[model=${probeModel}, effort=${probeEffort}] ${execResult.error}`); } const hasNext = idx < probeModels.length - 1; if (!hasNext) break; - if (!shouldRetryWithFallback(execResult.error)) - break; + // Phase C: Retry with fallback on unsupported_value / reasoning.effort errors + if (shouldRetryWithFallback(execResult.error)) { + // Try with 'low' effort explicitly if current effort failed + if (probeEffort !== 'low' && execResult.error?.toLowerCase().includes('reasoning')) { + const lowEffortResult = await runCodexExec(codexHome, probeModel, 'low'); + const lowEffortLatest = findLatestSessionRateLimits({ + sessionsDir, + sinceMs: Date.now() - 5_000 + }); + if (lowEffortResult.ok && lowEffortLatest?.rateLimits) { + return { + rateLimits: lowEffortLatest.rateLimits, + eventTs: lowEffortLatest.eventTs, + sourceFile: lowEffortLatest.sourceFile, + probeModel, + probeEffort: 'low', + probeDurationMs: lowEffortResult.durationMs, + isAuthoritative: true + }; + } + if (lowEffortResult.error) { + attemptErrors.push(`[model=${probeModel}, effort=low] ${lowEffortResult.error}`); + } + } + continue; + } + // Don't retry if it's not a fallback-eligible error + break; } if (attemptErrors.length > 0) { - return { error: attemptErrors[attemptErrors.length - 1] }; + return { + error: attemptErrors[attemptErrors.length - 1], + isAuthoritative: false + }; } - return { error: lastError }; + return { + error: lastError, + isAuthoritative: false + }; } export function getProbeHomeRoot() { return CODEX_HOME_ROOT; diff --git a/dist/probe-limits.js.map b/dist/probe-limits.js.map index 6c6145e..c7e9311 100644 --- a/dist/probe-limits.js.map +++ b/dist/probe-limits.js.map @@ -1 +1 @@ -{"version":3,"file":"probe-limits.js","sourceRoot":"","sources":["../src/probe-limits.ts"],"names":[],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"probe-limits.js","sourceRoot":"","sources":["../src/probe-limits.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/rate-limits.d.ts b/dist/rate-limits.d.ts index 4f2be1b..ca9f877 100644 --- a/dist/rate-limits.d.ts +++ b/dist/rate-limits.d.ts @@ -2,5 +2,9 @@ import type { AccountRateLimits } from './types.js'; type RateLimitUpdate = AccountRateLimits; export declare function extractRateLimitUpdate(headers: Headers): RateLimitUpdate | null; export declare function mergeRateLimits(existing: AccountRateLimits | undefined, update: RateLimitUpdate): AccountRateLimits; +export declare function parseRetryAfterHeader(retryAfter: string | null, now?: number): number | undefined; +export declare function parseRateLimitResetFromError(text: string, now?: number): number | undefined; +export declare function isRateLimitErrorText(text: string): boolean; +export declare function getBlockingRateLimitResetAt(rateLimits: AccountRateLimits | undefined, now?: number): number | undefined; export {}; //# sourceMappingURL=rate-limits.d.ts.map \ No newline at end of file diff --git a/dist/rate-limits.d.ts.map b/dist/rate-limits.d.ts.map index 665e7fe..9157549 100644 --- a/dist/rate-limits.d.ts.map +++ b/dist/rate-limits.d.ts.map @@ -1 +1 @@ -{"version":3,"file":"rate-limits.d.ts","sourceRoot":"","sources":["../src/rate-limits.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAmB,MAAM,YAAY,CAAA;AAEpE,KAAK,eAAe,GAAG,iBAAiB,CAAA;AAoDxC,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,OAAO,GAAG,eAAe,GAAG,IAAI,CA0D/E;AAED,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,iBAAiB,GAAG,SAAS,EACvC,MAAM,EAAE,eAAe,GACtB,iBAAiB,CAKnB"} \ No newline at end of file +{"version":3,"file":"rate-limits.d.ts","sourceRoot":"","sources":["../src/rate-limits.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAmB,MAAM,YAAY,CAAA;AAEpE,KAAK,eAAe,GAAG,iBAAiB,CAAA;AA6DxC,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,OAAO,GAAG,eAAe,GAAG,IAAI,CA0D/E;AAED,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,iBAAiB,GAAG,SAAS,EACvC,MAAM,EAAE,eAAe,GACtB,iBAAiB,CAKnB;AAED,wBAAgB,qBAAqB,CACnC,UAAU,EAAE,MAAM,GAAG,IAAI,EACzB,GAAG,GAAE,MAAmB,GACvB,MAAM,GAAG,SAAS,CAapB;AAED,wBAAgB,4BAA4B,CAC1C,IAAI,EAAE,MAAM,EACZ,GAAG,GAAE,MAAmB,GACvB,MAAM,GAAG,SAAS,CAqBpB;AAED,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAW1D;AAED,wBAAgB,2BAA2B,CACzC,UAAU,EAAE,iBAAiB,GAAG,SAAS,EACzC,GAAG,GAAE,MAAmB,GACvB,MAAM,GAAG,SAAS,CA8BpB"} \ No newline at end of file diff --git a/dist/rate-limits.js b/dist/rate-limits.js index 381f4c8..a16c88b 100644 --- a/dist/rate-limits.js +++ b/dist/rate-limits.js @@ -34,6 +34,15 @@ function parseTimestamp(value) { return parsed; return undefined; } +function parseHumanDate(value) { + const normalized = value + .replace(/\b(\d{1,2})(st|nd|rd|th)\b/gi, '$1') + .trim(); + const parsed = Date.parse(normalized); + if (!Number.isNaN(parsed)) + return parsed; + return undefined; +} function matchWindowKey(headerName) { for (const entry of WINDOW_PATTERNS) { if (entry.patterns.some((pattern) => headerName.includes(pattern))) { @@ -114,4 +123,81 @@ export function mergeRateLimits(existing, update) { weekly: { ...(existing?.weekly || {}), ...(update.weekly || {}) } }; } +export function parseRetryAfterHeader(retryAfter, now = Date.now()) { + if (!retryAfter) + return undefined; + const trimmed = retryAfter.trim(); + if (!trimmed) + return undefined; + const asNumber = Number(trimmed); + if (Number.isFinite(asNumber) && asNumber >= 0) { + return now + asNumber * 1000; + } + const asDate = Date.parse(trimmed); + if (!Number.isNaN(asDate)) + return asDate; + return undefined; +} +export function parseRateLimitResetFromError(text, now = Date.now()) { + if (!text) + return undefined; + const retryAfterMatch = text.match(/(?:retry[\s-]*after|try again in)\s*(\d+)\s*(seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h)\b/i); + if (retryAfterMatch) { + const amount = Number(retryAfterMatch[1]); + const unit = retryAfterMatch[2].toLowerCase(); + if (Number.isFinite(amount) && amount >= 0) { + if (unit.startsWith('h')) + return now + amount * 60 * 60 * 1000; + if (unit.startsWith('m')) + return now + amount * 60 * 1000; + return now + amount * 1000; + } + } + const tryAgainAtMatch = text.match(/try again at\s+([^\n.]+)/i); + if (tryAgainAtMatch?.[1]) { + const resetAt = parseHumanDate(tryAgainAtMatch[1]); + if (resetAt !== undefined) + return resetAt; + } + return undefined; +} +export function isRateLimitErrorText(text) { + if (!text) + return false; + const normalized = text.toLowerCase(); + return (normalized.includes('rate limit') || + normalized.includes('usage limit') || + normalized.includes("you've hit your usage limit") || + normalized.includes('too many requests') || + normalized.includes('try again at') || + normalized.includes('retry after')); +} +export function getBlockingRateLimitResetAt(rateLimits, now = Date.now()) { + if (!rateLimits) + return undefined; + const windows = [ + rateLimits.fiveHour, + rateLimits.weekly + ]; + const exhaustedResets = []; + const futureResets = []; + for (const window of windows) { + if (!window || typeof window.resetAt !== 'number' || window.resetAt <= now) { + continue; + } + futureResets.push(window.resetAt); + if (typeof window.remaining === 'number' && window.remaining <= 0) { + exhaustedResets.push(window.resetAt); + } + } + if (exhaustedResets.length > 0) { + // If multiple windows are exhausted, wait for the last one to reset. + return Math.max(...exhaustedResets); + } + if (futureResets.length > 0) { + // Conservative fallback when backend says limited but remaining counters are absent. + return Math.max(...futureResets); + } + return undefined; +} //# sourceMappingURL=rate-limits.js.map \ No newline at end of file diff --git a/dist/rate-limits.js.map b/dist/rate-limits.js.map index 7ce074f..32c5c84 100644 --- a/dist/rate-limits.js.map +++ b/dist/rate-limits.js.map @@ -1 +1 @@ -{"version":3,"file":"rate-limits.js","sourceRoot":"","sources":["../src/rate-limits.ts"],"names":[],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"rate-limits.js","sourceRoot":"","sources":["../src/rate-limits.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/rotation.d.ts b/dist/rotation.d.ts index 6d03bd8..9b61a03 100644 --- a/dist/rotation.d.ts +++ b/dist/rotation.d.ts @@ -2,9 +2,14 @@ import type { AccountCredentials, DEFAULT_CONFIG } from './types.js'; export interface RotationResult { account: AccountCredentials; token: string; + forceState?: { + active: boolean; + alias: string | null; + remainingMs: number; + }; } export declare function getNextAccount(config: typeof DEFAULT_CONFIG): Promise; -export declare function markRateLimited(alias: string, cooldownMs: number): void; +export declare function markRateLimited(alias: string, rateLimitedUntil: number): void; export declare function clearRateLimit(alias: string): void; export declare function markModelUnsupported(alias: string, cooldownMs: number, info?: { model?: string; diff --git a/dist/rotation.d.ts.map b/dist/rotation.d.ts.map index 32a6cf6..e125a1c 100644 --- a/dist/rotation.d.ts.map +++ b/dist/rotation.d.ts.map @@ -1 +1 @@ -{"version":3,"file":"rotation.d.ts","sourceRoot":"","sources":["../src/rotation.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AAEpE,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,kBAAkB,CAAA;IAC3B,KAAK,EAAE,MAAM,CAAA;CACd;AAWD,wBAAsB,cAAc,CAClC,MAAM,EAAE,OAAO,cAAc,GAC5B,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,CA0GhC;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,IAAI,CAKvE;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAIlD;AAED,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,MAAM,EACb,UAAU,EAAE,MAAM,EAClB,IAAI,CAAC,EAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,GACxC,IAAI,CAWN;AAED,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAOzD;AAED,wBAAgB,wBAAwB,CACtC,KAAK,EAAE,MAAM,EACb,UAAU,EAAE,MAAM,EAClB,IAAI,CAAC,EAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,GACxB,IAAI,CASN;AAED,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAM7D;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAMnD;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAKpD"} \ No newline at end of file +{"version":3,"file":"rotation.d.ts","sourceRoot":"","sources":["../src/rotation.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AAEpE,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,kBAAkB,CAAA;IAC3B,KAAK,EAAE,MAAM,CAAA;IACb,UAAU,CAAC,EAAE;QACX,MAAM,EAAE,OAAO,CAAA;QACf,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;QACpB,WAAW,EAAE,MAAM,CAAA;KACpB,CAAA;CACF;AAgED,wBAAsB,cAAc,CAClC,MAAM,EAAE,OAAO,cAAc,GAC5B,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,CA0OhC;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAQ7E;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAIlD;AAED,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,MAAM,EACb,UAAU,EAAE,MAAM,EAClB,IAAI,CAAC,EAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,GACxC,IAAI,CAWN;AAED,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAOzD;AAED,wBAAgB,wBAAwB,CACtC,KAAK,EAAE,MAAM,EACb,UAAU,EAAE,MAAM,EAClB,IAAI,CAAC,EAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,GACxB,IAAI,CASN;AAED,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAM7D;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAMnD;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAKpD"} \ No newline at end of file diff --git a/dist/rotation.js b/dist/rotation.js index 00b4eb0..97e0c3d 100644 --- a/dist/rotation.js +++ b/dist/rotation.js @@ -1,5 +1,9 @@ import { getStoreDiagnostics, loadStore, saveStore, updateAccount } from './store.js'; import { ensureValidToken } from './auth.js'; +import { isForceActive, checkAndAutoClearForce, getForceState, clearForce } from './force-mode.js'; +import { getRuntimeSettings, calculateWeightedSelection } from './settings.js'; +const HEALTH_HYSTERESIS_MS = 10_000; +const RECENT_FAILURE_WINDOW_MS = 60_000; function shuffled(input) { const a = [...input]; for (let i = a.length - 1; i > 0; i -= 1) { @@ -8,7 +12,54 @@ function shuffled(input) { } return a; } +function evaluateAccountHealth(acc, now) { + const wasRateLimited = !!(acc.rateLimitedUntil && acc.rateLimitedUntil > now - HEALTH_HYSTERESIS_MS); + const wasModelUnsupported = !!(acc.modelUnsupportedUntil && acc.modelUnsupportedUntil > now - HEALTH_HYSTERESIS_MS); + const wasWorkspaceDeactivated = !!(acc.workspaceDeactivatedUntil && acc.workspaceDeactivatedUntil > now - HEALTH_HYSTERESIS_MS); + // Phase D: Check if account is disabled + const isDisabled = acc.enabled === false; + const currentlyBlocked = !!(acc.rateLimitedUntil && acc.rateLimitedUntil > now) || + !!(acc.modelUnsupportedUntil && acc.modelUnsupportedUntil > now) || + !!(acc.workspaceDeactivatedUntil && acc.workspaceDeactivatedUntil > now) || + !!acc.authInvalid || + isDisabled; // Phase D: Exclude disabled accounts + const isInProbation = !currentlyBlocked && (wasRateLimited || wasModelUnsupported || wasWorkspaceDeactivated); + let recentFailures = 0; + if (acc.lastLimitErrorAt && acc.lastLimitErrorAt > now - RECENT_FAILURE_WINDOW_MS) { + recentFailures++; + } + if (acc.authInvalidatedAt && acc.authInvalidatedAt > now - RECENT_FAILURE_WINDOW_MS) { + recentFailures++; + } + let priority = 100; + if (isInProbation) + priority -= 30; + if (recentFailures > 0) + priority -= recentFailures * 10; + if (acc.usageCount === 0) + priority -= 5; + if (currentlyBlocked) + priority = 0; + // Phase D: Disabled accounts get lowest priority + if (isDisabled) + priority = -1; + return { + alias: acc.alias, + isHealthy: !currentlyBlocked && !acc.authInvalid && !isDisabled, + isInProbation, + recentFailures, + priority + }; +} export async function getNextAccount(config) { + // Phase E: Check and auto-clear expired/invalid force state + const autoClear = checkAndAutoClearForce(); + if (autoClear.wasCleared) { + console.log(`[multi-auth] Force mode auto-cleared: ${autoClear.reason}`); + } + // Phase E: Check if force mode is active + const forceActive = isForceActive(); + const forceState = getForceState(); let store = loadStore(); const aliases = Object.keys(store.accounts); if (aliases.length === 0) { @@ -21,13 +72,58 @@ export async function getNextAccount(config) { return null; } const now = Date.now(); - const availableAliases = aliases.filter(alias => { + // Phase E: If force mode is active, never fall back to another alias. + if (forceActive && forceState.forcedAlias) { + const forcedAlias = forceState.forcedAlias; + const forcedAccount = store.accounts[forcedAlias]; + if (forcedAccount) { + const health = evaluateAccountHealth(forcedAccount, now); + if (health.isHealthy) { + const token = await ensureValidToken(forcedAlias); + if (token) { + store = updateAccount(forcedAlias, { + usageCount: (forcedAccount.usageCount || 0) + 1, + lastUsed: now, + limitError: undefined + }); + store.activeAlias = forcedAlias; + store.lastRotation = now; + saveStore(store); + console.log(`[multi-auth] Force mode: using ${forcedAlias}`); + return { + account: store.accounts[forcedAlias], + token, + forceState: { + active: true, + alias: forcedAlias, + remainingMs: forceState.forcedUntil ? forceState.forcedUntil - now : 0 + } + }; + } + else { + console.warn(`[multi-auth] Force mode: ${forcedAlias} token unavailable; refusing fallback`); + return null; + } + } + else { + console.warn(`[multi-auth] Force mode: ${forcedAlias} currently blocked; refusing fallback`); + return null; + } + } + else { + // Forced account no longer exists - clear force and proceed normally. + console.warn(`[multi-auth] Force mode: ${forcedAlias} not found, clearing force`); + clearForce(); + } + } + const healthMap = new Map(); + for (const alias of aliases) { const acc = store.accounts[alias]; - const notRateLimited = !acc.rateLimitedUntil || acc.rateLimitedUntil < now; - const notModelUnsupported = !acc.modelUnsupportedUntil || acc.modelUnsupportedUntil < now; - const notWorkspaceDeactivated = !acc.workspaceDeactivatedUntil || acc.workspaceDeactivatedUntil < now; - const notInvalidated = !acc.authInvalid; - return notRateLimited && notModelUnsupported && notWorkspaceDeactivated && notInvalidated; + healthMap.set(alias, evaluateAccountHealth(acc, now)); + } + const availableAliases = aliases.filter(alias => { + const health = healthMap.get(alias); + return health?.isHealthy === true; }); if (availableAliases.length === 0) { console.warn('[multi-auth] No available accounts (rate-limited or invalidated).'); @@ -40,12 +136,19 @@ export async function getNextAccount(config) { return parsed; return 60_000; })(); + const runtimeSettings = getRuntimeSettings(); + const rotationStrategy = runtimeSettings.settings.rotationStrategy || config.rotationStrategy; const buildCandidates = () => { - switch (config.rotationStrategy) { + switch (rotationStrategy) { case 'least-used': { const sorted = [...availableAliases].sort((a, b) => { const aa = store.accounts[a]; const bb = store.accounts[b]; + const healthA = healthMap.get(a); + const healthB = healthMap.get(b); + const priorityDiff = (healthB?.priority || 0) - (healthA?.priority || 0); + if (priorityDiff !== 0) + return priorityDiff; const usageDiff = (aa?.usageCount || 0) - (bb?.usageCount || 0); if (usageDiff !== 0) return usageDiff; @@ -57,17 +160,65 @@ export async function getNextAccount(config) { return { aliases: sorted }; } case 'random': { - return { aliases: shuffled(availableAliases) }; + const sorted = [...availableAliases].sort((a, b) => { + const healthA = healthMap.get(a); + const healthB = healthMap.get(b); + return (healthB?.priority || 0) - (healthA?.priority || 0); + }); + const topPriority = sorted.slice(0, Math.ceil(sorted.length / 2)); + return { aliases: shuffled(topPriority.length > 0 ? topPriority : sorted) }; + } + // Phase F: Weighted round-robin + case 'weighted-round-robin': { + const weights = runtimeSettings.settings.accountWeights; + // Filter to healthy accounts with weights + const weightedAliases = availableAliases.filter(alias => (weights[alias] || 0) > 0); + if (weightedAliases.length === 0) { + // Fallback to round-robin if no weights defined + const sorted = [...availableAliases].sort((a, b) => { + const healthA = healthMap.get(a); + const healthB = healthMap.get(b); + return (healthB?.priority || 0) - (healthA?.priority || 0); + }); + const start = store.rotationIndex % sorted.length; + const rr = sorted.map((_, i) => sorted[(start + i) % sorted.length]); + const nextIndex = (selected) => { + const idx = sorted.indexOf(selected); + if (idx < 0) + return store.rotationIndex; + return (idx + 1) % sorted.length; + }; + return { aliases: rr, nextIndex }; + } + // Use weighted selection + const selected = calculateWeightedSelection(weightedAliases, weights); + if (!selected) { + // Fallback to round-robin + const sorted = [...availableAliases].sort((a, b) => { + const healthA = healthMap.get(a); + const healthB = healthMap.get(b); + return (healthB?.priority || 0) - (healthA?.priority || 0); + }); + const start = store.rotationIndex % sorted.length; + const rr = sorted.map((_, i) => sorted[(start + i) % sorted.length]); + return { aliases: rr }; + } + return { aliases: [selected] }; } case 'round-robin': default: { - const start = store.rotationIndex % availableAliases.length; - const rr = availableAliases.map((_, i) => availableAliases[(start + i) % availableAliases.length]); + const sorted = [...availableAliases].sort((a, b) => { + const healthA = healthMap.get(a); + const healthB = healthMap.get(b); + return (healthB?.priority || 0) - (healthA?.priority || 0); + }); + const start = store.rotationIndex % sorted.length; + const rr = sorted.map((_, i) => sorted[(start + i) % sorted.length]); const nextIndex = (selected) => { - const idx = availableAliases.indexOf(selected); + const idx = sorted.indexOf(selected); if (idx < 0) return store.rotationIndex; - return (idx + 1) % availableAliases.length; + return (idx + 1) % sorted.length; }; return { aliases: rr, nextIndex }; } @@ -77,8 +228,6 @@ export async function getNextAccount(config) { for (const candidate of candidates) { const token = await ensureValidToken(candidate); if (!token) { - // Don't hard-fail the whole system on a single broken account. - // Put it on a short cooldown so rotation can keep working. store = updateAccount(candidate, { rateLimitedUntil: now + tokenFailureCooldownMs, limitError: '[multi-auth] Token unavailable (refresh failed?)', @@ -97,16 +246,28 @@ export async function getNextAccount(config) { store.rotationIndex = nextIndex(candidate); } saveStore(store); - return { account: store.accounts[candidate], token }; + const currentForceState = getForceState(); + return { + account: store.accounts[candidate], + token, + forceState: { + active: isForceActive(), + alias: currentForceState.forcedAlias, + remainingMs: currentForceState.forcedUntil ? currentForceState.forcedUntil - now : 0 + } + }; } console.error('[multi-auth] No available accounts (token refresh failed on all candidates).'); return null; } -export function markRateLimited(alias, cooldownMs) { +export function markRateLimited(alias, rateLimitedUntil) { + const now = Date.now(); + const safeUntil = Math.max(rateLimitedUntil, now + 1000); + const seconds = Math.max(1, Math.ceil((safeUntil - now) / 1000)); updateAccount(alias, { - rateLimitedUntil: Date.now() + cooldownMs + rateLimitedUntil: safeUntil }); - console.warn(`[multi-auth] Account ${alias} marked rate-limited for ${cooldownMs / 1000}s`); + console.warn(`[multi-auth] Account ${alias} marked rate-limited for ${seconds}s`); } export function clearRateLimit(alias) { updateAccount(alias, { diff --git a/dist/rotation.js.map b/dist/rotation.js.map index c6ff123..a8684ef 100644 --- a/dist/rotation.js.map +++ b/dist/rotation.js.map @@ -1 +1 @@ -{"version":3,"file":"rotation.js","sourceRoot":"","sources":["../src/rotation.ts"],"names":[],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"rotation.js","sourceRoot":"","sources":["../src/rotation.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/settings.d.ts b/dist/settings.d.ts new file mode 100644 index 0000000..0815ebe --- /dev/null +++ b/dist/settings.d.ts @@ -0,0 +1,28 @@ +import { type RotationSettings, type WeightPreset, type SettingsValidationError } from './types.js'; +export interface SettingsResult { + settings: RotationSettings; + source: 'default' | 'persisted' | 'runtime' | 'env'; + errors?: SettingsValidationError[]; +} +export declare function getSettings(): SettingsResult; +export declare function getRuntimeSettings(): SettingsResult; +export declare function updateSettings(updates: Partial, actor?: string): { + success: boolean; + settings?: RotationSettings; + errors?: SettingsValidationError[]; +}; +export declare function resetSettings(actor?: string): RotationSettings; +export declare function applyPreset(preset: WeightPreset, actor?: string): { + success: boolean; + settings?: RotationSettings; + errors?: SettingsValidationError[]; +}; +export declare function calculateWeightedSelection(aliases: string[], weights: Record): string | null; +export declare function getSettingsWithInfo(): { + settings: RotationSettings; + source: string; + preset?: WeightPreset; + canReset: boolean; +}; +export declare function isFeatureEnabled(flag: keyof NonNullable): boolean; +//# sourceMappingURL=settings.d.ts.map \ No newline at end of file diff --git a/dist/settings.d.ts.map b/dist/settings.d.ts.map new file mode 100644 index 0000000..46ef79d --- /dev/null +++ b/dist/settings.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"settings.d.ts","sourceRoot":"","sources":["../src/settings.ts"],"names":[],"mappings":"AAEA,OAAO,EAIL,KAAK,gBAAgB,EACrB,KAAK,YAAY,EACjB,KAAK,uBAAuB,EAC7B,MAAM,YAAY,CAAA;AAInB,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,gBAAgB,CAAA;IAC1B,MAAM,EAAE,SAAS,GAAG,WAAW,GAAG,SAAS,GAAG,KAAK,CAAA;IACnD,MAAM,CAAC,EAAE,uBAAuB,EAAE,CAAA;CACnC;AAmED,wBAAgB,WAAW,IAAI,cAAc,CAE5C;AAGD,wBAAgB,kBAAkB,IAAI,cAAc,CAEnD;AAGD,wBAAgB,cAAc,CAC5B,OAAO,EAAE,OAAO,CAAC,gBAAgB,CAAC,EAClC,KAAK,GAAE,MAAiB,GACvB;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,EAAE,gBAAgB,CAAC;IAAC,MAAM,CAAC,EAAE,uBAAuB,EAAE,CAAA;CAAE,CA2BvF;AAGD,wBAAgB,aAAa,CAAC,KAAK,GAAE,MAAiB,GAAG,gBAAgB,CAQxE;AAGD,wBAAgB,WAAW,CACzB,MAAM,EAAE,YAAY,EACpB,KAAK,GAAE,MAAiB,GACvB;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,EAAE,gBAAgB,CAAC;IAAC,MAAM,CAAC,EAAE,uBAAuB,EAAE,CAAA;CAAE,CAyDvF;AAGD,wBAAgB,0BAA0B,CACxC,OAAO,EAAE,MAAM,EAAE,EACjB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAC9B,MAAM,GAAG,IAAI,CAuBf;AAGD,wBAAgB,mBAAmB,IAAI;IACrC,QAAQ,EAAE,gBAAgB,CAAA;IAC1B,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,CAAC,EAAE,YAAY,CAAA;IACrB,QAAQ,EAAE,OAAO,CAAA;CAClB,CAwBA;AAGD,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,WAAW,CAAC,gBAAgB,CAAC,cAAc,CAAC,CAAC,GAAG,OAAO,CAGnG"} \ No newline at end of file diff --git a/dist/settings.js b/dist/settings.js new file mode 100644 index 0000000..4eea87a --- /dev/null +++ b/dist/settings.js @@ -0,0 +1,208 @@ +import { loadStore, saveStore } from './store.js'; +import { logInfo, logError } from './logger.js'; +import { DEFAULT_ROTATION_SETTINGS, WEIGHTED_PRESETS, validateSettings } from './types.js'; +function resolveSettings(includeEnvOverrides) { + const store = loadStore(); + // Start with defaults + let settings = { ...DEFAULT_ROTATION_SETTINGS }; + let source = 'default'; + // Layer 1: Persisted settings from store + if (store.settings) { + settings = { + ...settings, + ...store.settings + }; + source = 'persisted'; + } + // Layer 2: Environment variables override (optional for runtime behavior) + if (includeEnvOverrides) { + const envStrategy = process.env.OPENCODE_MULTI_AUTH_ROTATION_STRATEGY; + if (envStrategy && ['round-robin', 'least-used', 'random', 'weighted-round-robin'].includes(envStrategy)) { + settings.rotationStrategy = envStrategy; + source = 'env'; + } + const envCriticalThreshold = process.env.OPENCODE_MULTI_AUTH_CRITICAL_THRESHOLD; + if (envCriticalThreshold) { + const parsed = parseFloat(envCriticalThreshold); + if (!isNaN(parsed) && parsed >= 0 && parsed <= 100) { + settings.criticalThreshold = parsed; + source = 'env'; + } + } + const envLowThreshold = process.env.OPENCODE_MULTI_AUTH_LOW_THRESHOLD; + if (envLowThreshold) { + const parsed = parseFloat(envLowThreshold); + if (!isNaN(parsed) && parsed >= 0 && parsed <= 100) { + settings.lowThreshold = parsed; + source = 'env'; + } + } + // Phase G: Feature flag environment overrides + const envAntigravity = process.env.OPENCODE_MULTI_AUTH_ANTIGRAVITY_ENABLED; + if (envAntigravity) { + const enabled = envAntigravity.toLowerCase() === 'true' || envAntigravity === '1'; + settings.featureFlags = { + ...(settings.featureFlags || {}), + antigravityEnabled: enabled + }; + source = 'env'; + } + } + // Validate final settings + const errors = validateSettings(settings); + if (errors.length > 0) { + logError(`Settings validation errors: ${errors.map(e => e.message).join(', ')}`); + } + return { settings, source, errors: errors.length > 0 ? errors : undefined }; +} +// Phase F: Get settings with proper precedence (including env overrides) +export function getSettings() { + return resolveSettings(true); +} +// Runtime behavior should use persisted settings so dashboard changes take effect immediately. +export function getRuntimeSettings() { + return resolveSettings(false); +} +// Phase F: Update settings with validation +export function updateSettings(updates, actor = 'system') { + const current = getRuntimeSettings(); + // Merge updates with current settings + const newSettings = { + ...current.settings, + ...updates, + updatedAt: Date.now(), + updatedBy: actor + }; + // Validate new settings + const errors = validateSettings(newSettings); + if (errors.length > 0) { + logError(`Settings update failed validation: ${errors.map(e => e.message).join(', ')}`); + return { success: false, errors }; + } + // Save to store + const store = loadStore(); + store.settings = newSettings; + // Keep legacy field in sync for force-mode compatibility. + store.rotationStrategy = newSettings.rotationStrategy; + saveStore(store); + logInfo(`Settings updated by ${actor}: ${JSON.stringify(updates)}`); + return { success: true, settings: newSettings }; +} +// Phase F: Reset settings to defaults +export function resetSettings(actor = 'system') { + const store = loadStore(); + delete store.settings; + store.rotationStrategy = DEFAULT_ROTATION_SETTINGS.rotationStrategy; + saveStore(store); + logInfo(`Settings reset to defaults by ${actor}`); + return { ...DEFAULT_ROTATION_SETTINGS }; +} +// Phase F: Apply a preset +export function applyPreset(preset, actor = 'system') { + const store = loadStore(); + const accounts = Object.keys(store.accounts); + const presetConfig = WEIGHTED_PRESETS[preset]; + let accountWeights = {}; + if (preset === 'balanced') { + // Equal weights for all accounts + const weight = accounts.length > 0 ? 1 / accounts.length : 0; + accounts.forEach(alias => { + accountWeights[alias] = weight; + }); + } + else if (preset === 'conservative') { + // Weights based on limit health + accounts.forEach(alias => { + const account = store.accounts[alias]; + const fiveHourRemaining = account.rateLimits?.fiveHour?.remaining ?? 50; + const weeklyRemaining = account.rateLimits?.weekly?.remaining ?? 50; + const health = (fiveHourRemaining + weeklyRemaining) / 2; + accountWeights[alias] = health / 100; + }); + // Normalize to sum to 1 + const total = Object.values(accountWeights).reduce((sum, w) => sum + w, 0); + if (total > 0) { + accounts.forEach(alias => { + accountWeights[alias] = accountWeights[alias] / total; + }); + } + } + else if (preset === 'aggressive') { + // Favor accounts with high usage (lower remaining) + accounts.forEach(alias => { + const account = store.accounts[alias]; + const fiveHourRemaining = account.rateLimits?.fiveHour?.remaining ?? 50; + const weeklyRemaining = account.rateLimits?.weekly?.remaining ?? 50; + const health = (fiveHourRemaining + weeklyRemaining) / 2; + // Inverse: lower health = higher weight + accountWeights[alias] = (100 - health) / 100; + }); + // Normalize to sum to 1 + const total = Object.values(accountWeights).reduce((sum, w) => sum + w, 0); + if (total > 0) { + accounts.forEach(alias => { + accountWeights[alias] = accountWeights[alias] / total; + }); + } + } + const updates = { + rotationStrategy: 'weighted-round-robin', + criticalThreshold: presetConfig.thresholds.critical, + lowThreshold: presetConfig.thresholds.low, + accountWeights + }; + return updateSettings(updates, actor); +} +// Phase F: Calculate weighted selection +export function calculateWeightedSelection(aliases, weights) { + if (aliases.length === 0) + return null; + // Filter to only available aliases + const available = aliases.filter(alias => weights[alias] > 0); + if (available.length === 0) + return null; + // Calculate total weight + const totalWeight = available.reduce((sum, alias) => sum + (weights[alias] || 0), 0); + if (totalWeight === 0) + return null; + // Weighted random selection + let random = Math.random() * totalWeight; + for (const alias of available) { + random -= weights[alias] || 0; + if (random <= 0) { + return alias; + } + } + // Fallback to last + return available[available.length - 1]; +} +// Phase F: Get settings with environment info +export function getSettingsWithInfo() { + const result = getSettings(); + const store = loadStore(); + // Detect if using a preset + let preset; + if (result.settings.rotationStrategy === 'weighted-round-robin') { + // Check if weights match a preset pattern + for (const [presetName, config] of Object.entries(WEIGHTED_PRESETS)) { + if (presetName !== 'custom' && + Math.abs(result.settings.criticalThreshold - config.thresholds.critical) < 0.01 && + Math.abs(result.settings.lowThreshold - config.thresholds.low) < 0.01) { + preset = presetName; + break; + } + } + } + return { + settings: result.settings, + source: result.source, + preset, + canReset: !!store.settings + }; +} +// Phase G: Check if a feature flag is enabled +export function isFeatureEnabled(flag) { + const settings = getSettings(); + return settings.settings.featureFlags?.[flag] ?? false; +} +//# sourceMappingURL=settings.js.map \ No newline at end of file diff --git a/dist/settings.js.map b/dist/settings.js.map new file mode 100644 index 0000000..08fc48d --- /dev/null +++ b/dist/settings.js.map @@ -0,0 +1 @@ +{"version":3,"file":"settings.js","sourceRoot":"","sources":["../src/settings.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/store.d.ts b/dist/store.d.ts index 8c6a8bf..1fe1ab5 100644 --- a/dist/store.d.ts +++ b/dist/store.d.ts @@ -1,6 +1,7 @@ import type { AccountStore, AccountCredentials } from './types.js'; export declare function loadStore(): AccountStore; export declare function saveStore(store: AccountStore): void; +export declare function withWriteLock(fn: () => T): Promise; export declare function getStoreDiagnostics(): { storeDir: string; storeFile: string; diff --git a/dist/store.d.ts.map b/dist/store.d.ts.map index 1fa3ae7..80490ad 100644 --- a/dist/store.d.ts.map +++ b/dist/store.d.ts.map @@ -1 +1 @@ -{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../src/store.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACV,YAAY,EACZ,kBAAkB,EAGnB,MAAM,YAAY,CAAA;AAyInB,wBAAgB,SAAS,IAAI,YAAY,CAmCxC;AAED,wBAAgB,SAAS,CAAC,KAAK,EAAE,YAAY,GAAG,IAAI,CAqEnD;AAED,wBAAgB,mBAAmB,IAAI;IACrC,QAAQ,EAAE,MAAM,CAAA;IAChB,SAAS,EAAE,MAAM,CAAA;IACjB,MAAM,EAAE,OAAO,CAAA;IACf,SAAS,EAAE,OAAO,CAAA;IAClB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;CACrB,CAQA;AAGD,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,CAAC,kBAAkB,EAAE,OAAO,GAAG,YAAY,CAAC,GAAG,YAAY,CAc/G;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,YAAY,CASzD;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,kBAAkB,CAAC,GAAG,YAAY,CAe/F;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,YAAY,CA+BjE;AAED,wBAAgB,gBAAgB,IAAI,kBAAkB,GAAG,IAAI,CAI5D;AAED,wBAAgB,YAAY,IAAI,kBAAkB,EAAE,CAGnD;AAED,wBAAgB,YAAY,IAAI,MAAM,CAErC;AAED,wBAAgB,cAAc,IAAI;IAAE,MAAM,EAAE,OAAO,CAAC;IAAC,SAAS,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAG9F"} \ No newline at end of file +{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../src/store.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACV,YAAY,EACZ,kBAAkB,EAGnB,MAAM,YAAY,CAAA;AA0UnB,wBAAgB,SAAS,IAAI,YAAY,CAsExC;AAED,wBAAgB,SAAS,CAAC,KAAK,EAAE,YAAY,GAAG,IAAI,CAiFnD;AAED,wBAAsB,aAAa,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAO9D;AAED,wBAAgB,mBAAmB,IAAI;IACrC,QAAQ,EAAE,MAAM,CAAA;IAChB,SAAS,EAAE,MAAM,CAAA;IACjB,MAAM,EAAE,OAAO,CAAA;IACf,SAAS,EAAE,OAAO,CAAA;IAClB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;CACrB,CAQA;AAGD,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,CAAC,kBAAkB,EAAE,OAAO,GAAG,YAAY,CAAC,GAAG,YAAY,CAc/G;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,YAAY,CASzD;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,kBAAkB,CAAC,GAAG,YAAY,CAe/F;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,YAAY,CA+BjE;AAED,wBAAgB,gBAAgB,IAAI,kBAAkB,GAAG,IAAI,CAI5D;AAED,wBAAgB,YAAY,IAAI,kBAAkB,EAAE,CAGnD;AAED,wBAAgB,YAAY,IAAI,MAAM,CAErC;AAED,wBAAgB,cAAc,IAAI;IAAE,MAAM,EAAE,OAAO,CAAC;IAAC,SAAS,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAG9F"} \ No newline at end of file diff --git a/dist/store.js b/dist/store.js index 9f9e007..4ea5612 100644 --- a/dist/store.js +++ b/dist/store.js @@ -19,10 +19,12 @@ function getStoreFile() { return path.join(getStoreDir(), DEFAULT_STORE_FILE); } const STORE_ENV_PASSPHRASE = 'CODEX_SOFT_STORE_PASSPHRASE'; -const STORE_VERSION = 1; +const CURRENT_STORE_VERSION = 2; let storeLocked = false; let lastStoreError = null; let lastStoreEncrypted = false; +let writeLock = false; +let writeLockQueue = []; function ensureDir() { const dir = getStoreDir(); if (!fs.existsSync(dir)) { @@ -31,6 +33,7 @@ function ensureDir() { } function emptyStore() { return { + version: CURRENT_STORE_VERSION, accounts: {}, activeAlias: null, rotationIndex: 0, @@ -57,7 +60,7 @@ function encryptStore(store, passphrase) { const tag = cipher.getAuthTag(); return { encrypted: true, - version: STORE_VERSION, + version: CURRENT_STORE_VERSION, salt: salt.toString('base64'), iv: iv.toString('base64'), tag: tag.toString('base64'), @@ -75,6 +78,166 @@ function decryptStore(file, passphrase) { const decrypted = Buffer.concat([decipher.update(data), decipher.final()]).toString('utf8'); return JSON.parse(decrypted); } +function validateAccount(acc, alias) { + if (!acc || typeof acc !== 'object') + return null; + if (typeof acc.accessToken !== 'string' || !acc.accessToken) + return null; + if (typeof acc.refreshToken !== 'string' || !acc.refreshToken) + return null; + if (typeof acc.expiresAt !== 'number') + return null; + return { + alias, + accessToken: acc.accessToken, + refreshToken: acc.refreshToken, + idToken: typeof acc.idToken === 'string' ? acc.idToken : undefined, + accountId: typeof acc.accountId === 'string' ? acc.accountId : undefined, + expiresAt: acc.expiresAt, + email: typeof acc.email === 'string' ? acc.email : undefined, + lastRefresh: typeof acc.lastRefresh === 'string' ? acc.lastRefresh : undefined, + lastSeenAt: typeof acc.lastSeenAt === 'number' ? acc.lastSeenAt : undefined, + lastActiveUntil: typeof acc.lastActiveUntil === 'number' ? acc.lastActiveUntil : undefined, + lastUsed: typeof acc.lastUsed === 'number' ? acc.lastUsed : undefined, + usageCount: typeof acc.usageCount === 'number' ? acc.usageCount : 0, + rateLimitedUntil: typeof acc.rateLimitedUntil === 'number' ? acc.rateLimitedUntil : undefined, + modelUnsupportedUntil: typeof acc.modelUnsupportedUntil === 'number' ? acc.modelUnsupportedUntil : undefined, + modelUnsupportedAt: typeof acc.modelUnsupportedAt === 'number' ? acc.modelUnsupportedAt : undefined, + modelUnsupportedModel: typeof acc.modelUnsupportedModel === 'string' ? acc.modelUnsupportedModel : undefined, + modelUnsupportedError: typeof acc.modelUnsupportedError === 'string' ? acc.modelUnsupportedError : undefined, + workspaceDeactivatedUntil: typeof acc.workspaceDeactivatedUntil === 'number' ? acc.workspaceDeactivatedUntil : undefined, + workspaceDeactivatedAt: typeof acc.workspaceDeactivatedAt === 'number' ? acc.workspaceDeactivatedAt : undefined, + workspaceDeactivatedError: typeof acc.workspaceDeactivatedError === 'string' ? acc.workspaceDeactivatedError : undefined, + authInvalid: typeof acc.authInvalid === 'boolean' ? acc.authInvalid : undefined, + authInvalidatedAt: typeof acc.authInvalidatedAt === 'number' ? acc.authInvalidatedAt : undefined, + // Phase D: Account availability fields + enabled: typeof acc.enabled === 'boolean' ? acc.enabled : undefined, + disabledAt: typeof acc.disabledAt === 'number' ? acc.disabledAt : undefined, + disabledBy: typeof acc.disabledBy === 'string' ? acc.disabledBy : undefined, + disableReason: typeof acc.disableReason === 'string' ? acc.disableReason : undefined, + rateLimits: acc.rateLimits || undefined, + rateLimitHistory: Array.isArray(acc.rateLimitHistory) ? acc.rateLimitHistory : undefined, + limitStatus: typeof acc.limitStatus === 'string' ? acc.limitStatus : undefined, + limitError: typeof acc.limitError === 'string' ? acc.limitError : undefined, + lastLimitProbeAt: typeof acc.lastLimitProbeAt === 'number' ? acc.lastLimitProbeAt : undefined, + lastLimitErrorAt: typeof acc.lastLimitErrorAt === 'number' ? acc.lastLimitErrorAt : undefined, + limitsConfidence: acc.limitsConfidence === 'fresh' || + acc.limitsConfidence === 'stale' || + acc.limitsConfidence === 'error' || + acc.limitsConfidence === 'unknown' + ? acc.limitsConfidence + : undefined, + tags: Array.isArray(acc.tags) ? acc.tags : undefined, + notes: typeof acc.notes === 'string' ? acc.notes : undefined, + source: acc.source === 'opencode' || acc.source === 'codex' ? acc.source : undefined + }; +} +function validateStore(data) { + if (!data || typeof data !== 'object') + return null; + const accounts = {}; + const rawAccounts = data.accounts; + if (rawAccounts && typeof rawAccounts === 'object') { + for (const [alias, acc] of Object.entries(rawAccounts)) { + const validated = validateAccount(acc, alias); + if (validated) { + accounts[alias] = validated; + } + } + } + return { + version: typeof data.version === 'number' ? data.version : undefined, + accounts, + activeAlias: typeof data.activeAlias === 'string' ? data.activeAlias : null, + rotationIndex: typeof data.rotationIndex === 'number' ? data.rotationIndex : 0, + lastRotation: typeof data.lastRotation === 'number' ? data.lastRotation : Date.now(), + // Phase E: Preserve force mode fields + forcedAlias: data.forcedAlias ?? null, + forcedUntil: data.forcedUntil ?? null, + previousRotationStrategy: data.previousRotationStrategy ?? null, + forcedBy: data.forcedBy ?? null, + // Phase F: Preserve rotation strategy and settings + rotationStrategy: data.rotationStrategy ?? 'round-robin', + settings: data.settings ?? undefined + }; +} +function migrateV1toV2(data) { + return { + ...data, + version: 2, + settings: { + rotationStrategy: 'round-robin' + }, + force: { + forcedAlias: null, + forcedUntil: null, + previousRotationStrategy: null, + forcedBy: null + } + }; +} +function migrateStore(data) { + if (!data || typeof data !== 'object') + return null; + const version = typeof data.version === 'number' ? data.version : 1; + if (version > CURRENT_STORE_VERSION) { + console.warn(`[multi-auth] Store version ${version} is newer than supported ${CURRENT_STORE_VERSION}. Proceeding with caution.`); + return validateStore(data); + } + let migrated = data; + if (version === 1) { + migrated = migrateV1toV2(data); + console.log('[multi-auth] Migrated store from v1 to v2'); + } + return validateStore(migrated); +} +function getLastKnownGoodPath() { + return `${getStoreFile()}.lkg`; +} +function saveLastKnownGood(store) { + // Avoid writing plaintext snapshots when store encryption is enabled. + if (getPassphrase()) { + return; + } + const lkgPath = getLastKnownGoodPath(); + try { + fs.writeFileSync(lkgPath, JSON.stringify(store, null, 2), { mode: 0o600 }); + } + catch { + // ignore + } +} +function loadLastKnownGood() { + const lkgPath = getLastKnownGoodPath(); + if (!fs.existsSync(lkgPath)) + return null; + try { + const data = fs.readFileSync(lkgPath, 'utf-8'); + const parsed = JSON.parse(data); + return validateStore(parsed); + } + catch { + return null; + } +} +async function acquireWriteLock() { + if (!writeLock) { + writeLock = true; + return; + } + return new Promise((resolve) => { + writeLockQueue.push(resolve); + }); +} +function releaseWriteLock() { + const next = writeLockQueue.shift(); + if (next) { + next(); + } + else { + writeLock = false; + } +} function buildSnapshot(window) { if (!window) return undefined; @@ -130,7 +293,20 @@ export function loadStore() { return emptyStore(); } try { - return decryptStore(parsed, passphrase); + const decrypted = decryptStore(parsed, passphrase); + const validated = validateStore(decrypted); + if (validated) { + saveLastKnownGood(validated); + return validated; + } + storeLocked = true; + lastStoreError = 'Store validation failed after decryption.'; + const lkg = loadLastKnownGood(); + if (lkg) { + console.warn('[multi-auth] Restored from last-known-good snapshot'); + return lkg; + } + return emptyStore(); } catch (err) { storeLocked = true; @@ -139,12 +315,30 @@ export function loadStore() { return emptyStore(); } } - return parsed; + const migrated = migrateStore(parsed); + if (migrated) { + saveLastKnownGood(migrated); + return migrated; + } + storeLocked = true; + lastStoreError = 'Store validation failed.'; + console.error('[multi-auth] Store validation failed'); + const lkg = loadLastKnownGood(); + if (lkg) { + console.warn('[multi-auth] Restored from last-known-good snapshot'); + return lkg; + } + return emptyStore(); } - catch { + catch (err) { storeLocked = true; lastStoreError = 'Failed to parse store. Store locked until fixed.'; - console.error('[multi-auth] Failed to parse store, resetting'); + console.error('[multi-auth] Failed to parse store:', err); + const lkg = loadLastKnownGood(); + if (lkg) { + console.warn('[multi-auth] Restored from last-known-good snapshot'); + return lkg; + } } } return emptyStore(); @@ -159,7 +353,6 @@ export function saveStore(store) { const passphrase = getPassphrase(); const payload = passphrase ? encryptStore(store, passphrase) : store; const json = JSON.stringify(payload, null, 2); - // Best-effort backup to help recover from crashes/corruption. try { if (fs.existsSync(file)) { fs.copyFileSync(file, `${file}.bak`); @@ -195,7 +388,6 @@ export function saveStore(store) { fs.renameSync(tmp, file); } catch (err) { - // Windows can fail to rename over an existing file. if (err?.code === 'EPERM' || err?.code === 'EEXIST') { try { fs.unlinkSync(file); @@ -215,12 +407,35 @@ export function saveStore(store) { throw err; } } + try { + const dirFd = fs.openSync(getStoreDir(), 'r'); + try { + fs.fsyncSync(dirFd); + } + catch { + // ignore + } + fs.closeSync(dirFd); + } + catch { + // ignore + } try { fs.chmodSync(file, 0o600); } catch { // ignore } + saveLastKnownGood(store); +} +export async function withWriteLock(fn) { + await acquireWriteLock(); + try { + return fn(); + } + finally { + releaseWriteLock(); + } } export function getStoreDiagnostics() { return { diff --git a/dist/store.js.map b/dist/store.js.map index 4ffb891..5860343 100644 --- a/dist/store.js.map +++ b/dist/store.js.map @@ -1 +1 @@ -{"version":3,"file":"store.js","sourceRoot":"","sources":["../src/store.ts"],"names":[],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"store.js","sourceRoot":"","sources":["../src/store.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/types.d.ts b/dist/types.d.ts index ee68578..f226401 100644 --- a/dist/types.d.ts +++ b/dist/types.d.ts @@ -21,12 +21,17 @@ export interface AccountCredentials { workspaceDeactivatedError?: string; authInvalid?: boolean; authInvalidatedAt?: number; + enabled?: boolean; + disabledAt?: number; + disabledBy?: string; + disableReason?: string; rateLimits?: AccountRateLimits; rateLimitHistory?: RateLimitHistoryEntry[]; limitStatus?: LimitStatus; limitError?: string; lastLimitProbeAt?: number; lastLimitErrorAt?: number; + limitsConfidence?: LimitsConfidence; tags?: string[]; notes?: string; source?: 'opencode' | 'codex'; @@ -52,11 +57,20 @@ export interface RateLimitHistoryEntry { weekly?: RateLimitSnapshot; } export type LimitStatus = 'idle' | 'queued' | 'running' | 'success' | 'error' | 'stopped'; +export type LimitsConfidence = 'fresh' | 'stale' | 'error' | 'unknown'; +export declare function calculateLimitsConfidence(lastProbeAt: number | undefined, lastErrorAt: number | undefined, limitStatus: LimitStatus | undefined): LimitsConfidence; export interface AccountStore { + version?: number; accounts: Record; activeAlias: string | null; rotationIndex: number; lastRotation: number; + forcedAlias?: string | null; + forcedUntil?: number | null; + previousRotationStrategy?: string | null; + forcedBy?: string | null; + rotationStrategy?: 'round-robin' | 'least-used' | 'random' | 'weighted-round-robin'; + settings?: RotationSettings; } export interface OpenAIModel { id: string; @@ -65,7 +79,7 @@ export interface OpenAIModel { owned_by: string; } export interface PluginConfig { - rotationStrategy: 'round-robin' | 'least-used' | 'random'; + rotationStrategy: 'round-robin' | 'least-used' | 'random' | 'weighted-round-robin'; autoRefreshTokens: boolean; rateLimitCooldownMs: number; modelUnsupportedCooldownMs: number; @@ -91,4 +105,35 @@ export interface ProviderModel { }; } export declare const DEFAULT_CONFIG: PluginConfig; +export interface RotationSettings { + rotationStrategy: 'round-robin' | 'least-used' | 'random' | 'weighted-round-robin'; + criticalThreshold: number; + lowThreshold: number; + accountWeights: Record; + featureFlags?: FeatureFlags; + updatedAt?: number; + updatedBy?: string; +} +export interface FeatureFlags { + antigravityEnabled: boolean; +} +export declare const DEFAULT_FEATURE_FLAGS: FeatureFlags; +export type WeightPreset = 'balanced' | 'conservative' | 'aggressive' | 'custom'; +export interface WeightedPresetConfig { + name: WeightPreset; + description: string; + defaultWeights: Record; + thresholds: { + critical: number; + low: number; + }; +} +export declare const DEFAULT_ROTATION_SETTINGS: RotationSettings; +export declare const WEIGHTED_PRESETS: Record; +export interface SettingsValidationError { + field: string; + message: string; + constraint: string; +} +export declare function validateSettings(settings: Partial): SettingsValidationError[]; //# sourceMappingURL=types.d.ts.map \ No newline at end of file diff --git a/dist/types.d.ts.map b/dist/types.d.ts.map index df56c0c..6226190 100644 --- a/dist/types.d.ts.map +++ b/dist/types.d.ts.map @@ -1 +1 @@ -{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/types.js b/dist/types.js index 4186038..1dc86f2 100644 --- a/dist/types.js +++ b/dist/types.js @@ -1,3 +1,31 @@ +// Phase C: Calculate limits confidence based on probe timestamps +export function calculateLimitsConfidence(lastProbeAt, lastErrorAt, limitStatus) { + const now = Date.now(); + const FRESH_THRESHOLD_MS = 5 * 60 * 1000; // 5 minutes + const STALE_THRESHOLD_MS = 60 * 60 * 1000; // 60 minutes + // If we have an error more recent than last success, show error + if (lastErrorAt && (!lastProbeAt || lastErrorAt > lastProbeAt)) { + // If we have some successful data, show stale with error + if (lastProbeAt && now - lastProbeAt < STALE_THRESHOLD_MS) { + return 'error'; + } + } + // No successful probe ever + if (!lastProbeAt) { + return 'unknown'; + } + const ageMs = now - lastProbeAt; + if (ageMs < FRESH_THRESHOLD_MS) { + return 'fresh'; + } + else if (ageMs < STALE_THRESHOLD_MS) { + return 'stale'; + } + else { + // Data is too old, treat as unknown + return 'unknown'; + } +} export const DEFAULT_CONFIG = { rotationStrategy: 'round-robin', autoRefreshTokens: true, @@ -6,4 +34,97 @@ export const DEFAULT_CONFIG = { workspaceDeactivatedCooldownMs: 30 * 60 * 1000, // 30 minutes modelFilter: /^gpt-5/ }; +// Phase G: Default feature flags +export const DEFAULT_FEATURE_FLAGS = { + antigravityEnabled: false +}; +// Phase F: Default settings +export const DEFAULT_ROTATION_SETTINGS = { + rotationStrategy: 'round-robin', + criticalThreshold: 10, + lowThreshold: 30, + accountWeights: {}, + featureFlags: { ...DEFAULT_FEATURE_FLAGS } +}; +// Phase F: Preset configurations +export const WEIGHTED_PRESETS = { + balanced: { + name: 'balanced', + description: 'Equal distribution across all accounts', + defaultWeights: {}, // Calculated dynamically as 1/n + thresholds: { critical: 10, low: 30 } + }, + conservative: { + name: 'conservative', + description: 'Prefer accounts with higher remaining limits', + defaultWeights: {}, // Calculated based on limit health + thresholds: { critical: 20, low: 40 } + }, + aggressive: { + name: 'aggressive', + description: 'Maximize throughput, accept higher risk', + defaultWeights: {}, // Favor accounts with high usage + thresholds: { critical: 5, low: 20 } + }, + custom: { + name: 'custom', + description: 'User-defined weights and thresholds', + defaultWeights: {}, + thresholds: { critical: 10, low: 30 } + } +}; +export function validateSettings(settings) { + const errors = []; + // Validate thresholds are in 0-100 range + if (settings.criticalThreshold !== undefined) { + if (settings.criticalThreshold < 0 || settings.criticalThreshold > 100) { + errors.push({ + field: 'criticalThreshold', + message: 'Critical threshold must be between 0 and 100', + constraint: '0 <= criticalThreshold <= 100' + }); + } + } + if (settings.lowThreshold !== undefined) { + if (settings.lowThreshold < 0 || settings.lowThreshold > 100) { + errors.push({ + field: 'lowThreshold', + message: 'Low threshold must be between 0 and 100', + constraint: '0 <= lowThreshold <= 100' + }); + } + } + // Validate critical < low + if (settings.criticalThreshold !== undefined && settings.lowThreshold !== undefined) { + if (settings.criticalThreshold >= settings.lowThreshold) { + errors.push({ + field: 'thresholds', + message: 'Critical threshold must be less than low threshold', + constraint: 'criticalThreshold < lowThreshold' + }); + } + } + // Validate weights are in (0, 1] range + if (settings.accountWeights) { + for (const [alias, weight] of Object.entries(settings.accountWeights)) { + if (weight <= 0 || weight > 1) { + errors.push({ + field: `accountWeights.${alias}`, + message: `Weight for ${alias} must be between 0 and 1`, + constraint: '0 < weight <= 1' + }); + } + } + // Validate weights sum to approximately 1 + const totalWeight = Object.values(settings.accountWeights).reduce((sum, w) => sum + w, 0); + if (totalWeight > 0 && Math.abs(totalWeight - 1) > 0.01) { + errors.push({ + field: 'accountWeights', + message: 'Total weights must sum to 1.0', + constraint: 'sum(weights) ≈ 1.0' + }); + } + } + return errors; +} //# sourceMappingURL=types.js.map \ No newline at end of file diff --git a/dist/types.js.map b/dist/types.js.map index 2cae3bf..4fa56d5 100644 --- a/dist/types.js.map +++ b/dist/types.js.map @@ -1 +1 @@ -{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AA+GA,MAAM,CAAC,MAAM,cAAc,GAAiB;IAC1C,gBAAgB,EAAE,aAAa;IAC/B,iBAAiB,EAAE,IAAI;IACvB,mBAAmB,EAAE,CAAC,GAAG,EAAE,GAAG,IAAI,EAAE,YAAY;IAChD,0BAA0B,EAAE,EAAE,GAAG,EAAE,GAAG,IAAI,EAAE,aAAa;IACzD,8BAA8B,EAAE,EAAE,GAAG,EAAE,GAAG,IAAI,EAAE,aAAa;IAC7D,WAAW,EAAE,QAAQ;CACtB,CAAA"} \ No newline at end of file +{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/web.d.ts b/dist/web.d.ts index 4fce8be..b7205bf 100644 --- a/dist/web.d.ts +++ b/dist/web.d.ts @@ -1,4 +1,5 @@ import * as http from 'node:http'; +export declare function isLocalhostHost(host: string): boolean; export declare function startWebConsole(options?: { port?: number; host?: string; diff --git a/dist/web.d.ts.map b/dist/web.d.ts.map index 336f1d9..ffee376 100644 --- a/dist/web.d.ts.map +++ b/dist/web.d.ts.map @@ -1 +1 @@ -{"version":3,"file":"web.d.ts","sourceRoot":"","sources":["../src/web.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,IAAI,MAAM,WAAW,CAAA;AA4sDjC,wBAAgB,eAAe,CAAC,OAAO,CAAC,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAAC,MAAM,CA2NvF"} \ No newline at end of file +{"version":3,"file":"web.d.ts","sourceRoot":"","sources":["../src/web.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,IAAI,MAAM,WAAW,CAAA;AAwBjC,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAErD;AA4uED,wBAAgB,eAAe,CAAC,OAAO,CAAC,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAAC,MAAM,CA2oBvF"} \ No newline at end of file diff --git a/dist/web.js b/dist/web.js index 528d149..27fefd3 100644 --- a/dist/web.js +++ b/dist/web.js @@ -11,11 +11,18 @@ import { getCodexAuthPath, getCodexAuthStatus, syncCodexAuthFile, writeCodexAuth import { getStoreStatus, listAccounts, loadStore, removeAccount, updateAccount } from './store.js'; import { getRefreshQueueState, startRefreshQueue, stopRefreshQueue } from './refresh-queue.js'; import { getLogPath, logError, logInfo, readLogTail } from './logger.js'; +import { getForceState, activateForce, clearForce, isForceActive, getRemainingForceTimeMs, formatForceDuration } from './force-mode.js'; +import { getSettings, getRuntimeSettings, isFeatureEnabled } from './settings.js'; +import { Errors } from './errors.js'; const DEFAULT_HOST = '127.0.0.1'; const DEFAULT_PORT = 3434; +const LOCALHOST_HOST_PATTERN = /^(127\.0\.0\.1|::1|localhost)$/i; const SYNC_INTERVAL_MS = 3000; const SYNC_DEBOUNCE_MS = 600; const ANTIGRAVITY_ACCOUNTS_FILE = path.join(os.homedir(), '.config', 'opencode', 'antigravity-accounts.json'); +export function isLocalhostHost(host) { + return LOCALHOST_HOST_PATTERN.test(host.trim()); +} const execAsync = promisify(exec); let lastSyncAt = 0; let lastSyncError = null; @@ -248,6 +255,88 @@ const HTML = ` .status-success { background: rgba(55, 211, 153, 0.15); color: var(--success); } .status-error { background: rgba(255, 107, 107, 0.18); color: var(--danger); } .status-stopped { background: rgba(249, 115, 22, 0.2); color: var(--warning); } + /* Phase C: Confidence badge styles */ + .confidence-badge { + font-size: 9px; + text-transform: uppercase; + letter-spacing: 0.08em; + padding: 2px 6px; + border-radius: 6px; + font-weight: 700; + margin-left: 6px; + } + .confidence-fresh { background: rgba(55, 211, 153, 0.15); color: var(--success); } + .confidence-stale { background: rgba(255, 181, 71, 0.2); color: var(--accent); } + .confidence-error { background: rgba(255, 107, 107, 0.18); color: var(--danger); } + .confidence-unknown { background: rgba(255,255,255,0.08); color: var(--muted); } + + /* Phase D: iOS-style toggle switch */ + .toggle-switch { + position: relative; + display: inline-flex; + align-items: center; + gap: 8px; + cursor: pointer; + } + .toggle-switch input { + opacity: 0; + width: 0; + height: 0; + } + .toggle-slider { + position: relative; + width: 44px; + height: 24px; + background: rgba(255,255,255,0.1); + border-radius: 24px; + transition: background 0.2s; + } + .toggle-slider:before { + content: ''; + position: absolute; + height: 20px; + width: 20px; + left: 2px; + bottom: 2px; + background: white; + border-radius: 50%; + transition: transform 0.2s; + } + .toggle-switch input:checked + .toggle-slider { + background: var(--success); + } + .toggle-switch input:checked + .toggle-slider:before { + transform: translateX(20px); + } + .toggle-switch input:disabled + .toggle-slider { + opacity: 0.5; + cursor: not-allowed; + } + .toggle-switch.updating .toggle-slider { + background: var(--accent); + animation: pulse 1s infinite; + } + .toggle-switch.error .toggle-slider { + background: var(--danger); + } + @keyframes pulse { + 0%, 100% { opacity: 1; } + 50% { opacity: 0.5; } + } + .toggle-label { + font-size: 13px; + color: var(--text); + font-weight: 500; + } + .account-controls { + display: flex; + flex-wrap: wrap; + gap: 10px; + align-items: center; + padding: 12px 0; + border-top: 1px solid rgba(255,255,255,0.06); + border-bottom: 1px solid rgba(255,255,255,0.06); + } .account-meta { display: grid; gap: 6px; @@ -409,6 +498,103 @@ const HTML = ` grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); margin: 12px 0; } + /* Phase E: Force Mode Toggle Styles */ + .force-toggle-container { + display: flex; + align-items: center; + gap: 12px; + } + .force-mode-controls { + display: flex; + align-items: center; + gap: 12px; + flex-wrap: wrap; + justify-content: flex-end; + } + .force-strategy-inline { + display: flex; + align-items: center; + gap: 8px; + } + .force-strategy-inline label { + font-size: 12px; + color: var(--muted); + } + .strategy-help { + width: 18px; + height: 18px; + border-radius: 50%; + border: 1px solid rgba(255,255,255,0.2); + display: inline-flex; + align-items: center; + justify-content: center; + font-size: 11px; + color: var(--muted); + cursor: help; + } + .toggle-switch { + display: flex; + align-items: center; + gap: 10px; + cursor: pointer; + } + .toggle-switch input { + display: none; + } + .toggle-slider { + width: 44px; + height: 24px; + background: rgba(255,255,255,0.1); + border-radius: 12px; + position: relative; + transition: background 0.2s; + } + .toggle-slider::before { + content: ''; + position: absolute; + width: 20px; + height: 20px; + background: var(--text); + border-radius: 50%; + top: 2px; + left: 2px; + transition: transform 0.2s; + } + .toggle-switch input:checked + .toggle-slider { + background: var(--accent); + } + .toggle-switch input:checked + .toggle-slider::before { + transform: translateX(20px); + } + .toggle-switch input:disabled + .toggle-slider { + opacity: 0.5; + cursor: not-allowed; + } + .toggle-label { + font-size: 13px; + color: var(--muted); + } + .toggle-switch input:checked ~ .toggle-label { + color: var(--accent); + } + #forceAliasSelect { + background: var(--panel-2); + border: 1px solid rgba(255,255,255,0.1); + border-radius: 8px; + padding: 8px 12px; + color: var(--text); + font-family: inherit; + font-size: 13px; + } + #rotationStrategySelect { + background: var(--panel-2); + border: 1px solid rgba(255,255,255,0.1); + border-radius: 8px; + padding: 8px 12px; + color: var(--text); + font-family: inherit; + font-size: 13px; + } @media (max-width: 720px) { header { padding: 26px 18px 10px; } .container { padding: 0 16px 28px; } @@ -457,7 +643,44 @@ const HTML = `
+ +
+
+
+
Force Mode
+
Pin rotation to a specific account for 24 hours
+
+
+
+ + ? + +
+
+ + + ? +
+
+
+
+
+
+ + +
+ +
+
+
+
Force Mode
+
Pin rotation to a specific account for 24 hours
+
+
+
+ + ? + +
+
+ + + ? +
+
+
+
+
+
+ + +