## Documentation map
@@ -15,25 +15,28 @@ Multi-account OAuth rotation plugin for OpenCode with a local dashboard, force m
- 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.
+- Provides a localhost React/Vite dashboard to manage accounts, limits, rotation presets, force mode, re-auth, and sticky sessions.
- 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`).
+- Supports settings-driven rotation strategy (`round-robin`, `least-used`, `random`, `weighted-round-robin`) and account weights.
- Probes limits safely and keeps authoritative data quality rules.
-- Gates non-core Antigravity features behind a feature flag.
+- Gates non-core Antigravity and sticky-session features behind feature flags.
## 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.
+- The dashboard is a React/Vite app with dedicated Overview, Accounts, Configuration, Operations, and Sticky Session views.
+- Validation scripts are available for: unit, integration, web-headless, frontend, 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
+- Runtime UI/API coverage includes account re-auth, enabled/disabled gating, rotation presets, and sticky-session admin endpoints.
## 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.
+- Force mode is time-bound: it pins one alias for up to 24 hours and restores the previous strategy when cleared.
- 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:
@@ -41,6 +44,7 @@ Multi-account OAuth rotation plugin for OpenCode with a local dashboard, force m
- 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.
+- Sticky-session routing is opt-in and persisted separately from the main rotation settings.
## Rotation strategy reference
@@ -53,6 +57,7 @@ Multi-account OAuth rotation plugin for OpenCode with a local dashboard, force m
## Repository structure
- `src/` -> TypeScript source
+- `web/` -> React/Vite dashboard workspace
- `dist/` -> compiled output (`tsc` generated)
- `tests/unit/` -> unit tests
- `tests/integration/` -> integration tests
@@ -62,6 +67,7 @@ Multi-account OAuth rotation plugin for OpenCode with a local dashboard, force m
- `tests/sandbox/` -> sandbox isolation tests
- `tests/soak/` -> soak scaffolding
- `docs/` -> QA and phase documentation (see `docs/README.md` for canonical/historical split)
+- `openspec/` -> archived and current design/spec artifacts
- `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
@@ -70,9 +76,10 @@ Multi-account OAuth rotation plugin for OpenCode with a local dashboard, force m
## Requirements
- Node.js 20+
-- npm
+- pnpm 11.x (use Corepack or install pnpm directly)
- OpenCode CLI
- ChatGPT/Codex OAuth accounts
+- Python 3.9+ and Playwright if you use `auto-login/`
## Install and use
@@ -138,8 +145,9 @@ Update existing installs:
```bash
git clone https://github.com/guard22/opencode-multi-auth-codex.git
cd opencode-multi-auth-codex
-npm ci
-npm run build
+corepack enable
+pnpm install --frozen-lockfile
+pnpm run build
```
### Quick start
@@ -299,6 +307,10 @@ Outlook login often shows interstitial pages after password entry:
- `PUT /api/settings/feature-flags`
- `POST /api/settings/reset`
- `POST /api/settings/preset`
+- `GET /api/sticky-sessions/config` (feature-flag gated)
+- `PUT /api/sticky-sessions/config` (feature-flag gated)
+- `GET /api/sticky-sessions/status` (feature-flag gated)
+- `POST /api/sticky-sessions/cleanup` (feature-flag gated)
- `POST /api/antigravity/refresh` (feature-flag gated)
- `POST /api/antigravity/refresh-all` (feature-flag gated)
@@ -320,6 +332,7 @@ Outlook login often shows interstitial pages after password entry:
- `OPENCODE_MULTI_AUTH_TOKEN_FAILURE_COOLDOWN_MS`
- `OPENCODE_MULTI_AUTH_PROBE_EFFORT`
- `OPENCODE_MULTI_AUTH_LIMITS_PROBE_MODELS`
+- `OPENCODE_MULTI_AUTH_USAGE_BASE_URL`
### Model mapping and runtime behavior
@@ -391,6 +404,7 @@ See [docs/gpt-5.4-fast-benchmark.md](./docs/gpt-5.4-fast-benchmark.md) for a con
### Feature flags
- `OPENCODE_MULTI_AUTH_ANTIGRAVITY_ENABLED`
+- `OPENCODE_MULTI_AUTH_STICKY_SESSIONS_ENABLED`
### Notifications
@@ -412,18 +426,19 @@ See [docs/gpt-5.4-fast-benchmark.md](./docs/gpt-5.4-fast-benchmark.md) for a con
## Build and test
```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
+corepack enable
+pnpm install --frozen-lockfile
+pnpm run verify:static
+pnpm run build
+
+pnpm run test:unit
+pnpm run test:integration
+pnpm run test:web:headless
+pnpm run test:frontend
+pnpm run test:failure
+pnpm run test:stress
+pnpm run test:sandbox
+pnpm run test:soak:48h
```
Current test script surfaces are scaffolded and active. For true long soak, set a long duration and keep the run alive.
@@ -442,27 +457,28 @@ Use `codextesting.md` for the Codex CLI live-testing checklist and copy-paste co
## Development notes
-- Edit `src/*`, never hand-edit `dist/*`.
-- Run `npm run build` after source changes.
+- Edit `src/*` and `web/src/*`, never hand-edit `dist/*`.
+- Use pnpm scripts for local verification (`pnpm run verify:static`, `pnpm run test:unit`, `pnpm run test:frontend`).
- Keep manual/live tests sandboxed (temp HOME/store/auth paths).
## Release flow
-- This plugin is now intended to be installed from npm, so every shipped update should bump `package.json` version and publish a new package version. Reusing the same version on a new commit will leave users stuck on cached installs.
-- Prepare the next release by bumping the package version, rebuilding, and publishing:
+- Releases are published from `v*` tags through `.github/workflows/publish-npm.yml`.
+- The workflow uses pnpm for install/build/test, then publishes to npm with provenance.
+- Reusing the same version on a new commit will leave users stuck on cached installs, so bump `package.json` before tagging.
+- Prepare the next release by bumping the package version, rebuilding, and tagging:
```bash
-npm version 1.2.1 --no-git-tag-version
-npm install
-npm run build
-npm publish --access public
+pnpm version X.Y.Z --no-git-tag-version
+pnpm install --frozen-lockfile
+pnpm run build
```
- After that, cut the git release from `main`:
```bash
-git commit -m "chore: release v1.2.1"
-git tag v1.2.1
+git commit -m "chore: release vX.Y.Z"
+git tag vX.Y.Z
git push origin main --follow-tags
```
@@ -470,7 +486,7 @@ git push origin main --follow-tags
```json
{
- "plugin": ["npm:@guard22/opencode-multi-auth-codex@1.2.1"]
+ "plugin": ["npm:@guard22/opencode-multi-auth-codex@X.Y.Z"]
}
```
diff --git a/auto-login/auto_login.py b/auto-login/auto_login.py
index 8bb3e76..ad6da77 100755
--- a/auto-login/auto_login.py
+++ b/auto-login/auto_login.py
@@ -49,6 +49,21 @@
# Timing
BETWEEN_ACCOUNTS_DELAY = 5 # seconds between accounts
+ACCOUNT_METRIC_KEYS = {
+ "lastRefresh",
+ "lastSeenAt",
+ "lastActiveUntil",
+ "lastUsed",
+ "usageCount",
+ "rateLimits",
+ "rateLimitHistory",
+ "limitStatus",
+ "limitError",
+ "lastLimitProbeAt",
+ "lastLimitErrorAt",
+ "limitsConfidence",
+}
+
def find_system_browser():
override = os.environ.get("OPENCODE_MULTI_AUTH_BROWSER")
@@ -197,6 +212,10 @@ def fetch_userinfo_email(access_token):
return None
+def strip_metric_fields(account):
+ return {key: value for key, value in account.items() if key not in ACCOUNT_METRIC_KEYS}
+
+
# ── Account store (v2 format compatible with plugin) ───────────────────────
def load_store():
if not STORE_FILE.exists():
@@ -218,7 +237,7 @@ def save_store(store):
tmp = STORE_FILE.with_suffix(f".tmp-{os.getpid()}-{int(time.time() * 1000)}")
with open(tmp, "w") as f:
json.dump(store, f, indent=2)
- tmp.rename(STORE_FILE)
+ tmp.replace(STORE_FILE)
os.chmod(STORE_FILE, 0o600)
@@ -250,12 +269,9 @@ def add_account_to_store(tokens):
"accountId": account_id,
"expiresAt": expires_at,
"email": email,
- "lastRefresh": datetime.now(timezone.utc).isoformat(),
- "lastSeenAt": now,
"addedAt": now,
"source": "opencode",
"authInvalid": False,
- "usageCount": 0,
"enabled": True,
}
@@ -264,11 +280,9 @@ def add_account_to_store(tokens):
for i, acc in enumerate(store["accounts"]):
if acc.get("email") == email:
store["accounts"][i] = {
- **acc,
+ **strip_metric_fields(acc),
**new_account,
- "usageCount": acc.get("usageCount", 0),
"addedAt": acc.get("addedAt", now),
- "rateLimitHistory": acc.get("rateLimitHistory", []),
}
save_store(store)
return email, i, False
diff --git a/dist/auth-sync.d.ts b/dist/auth-sync.d.ts
deleted file mode 100644
index dd6ed90..0000000
--- a/dist/auth-sync.d.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-import type { Auth } from '@opencode-ai/sdk';
-export declare function syncAuthFromOpenCode(getAuth: () => Promise${email || 'Unknown email'}
-You can close this window.
- - - `); - finish(() => resolve(account)); - } - catch (err) { - res.writeHead(500); - res.end('Authentication failed'); - finish(() => reject(err)); - } - }); - try { - const 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 ${actualPort}...`); - } - catch (err) { - finish(() => reject(err)); - return; - } - timeout = setTimeout(() => { - finish(() => reject(new Error(`Login timeout after ${Math.round(timeoutMs / 1000)}s - no callback received`))); - }, timeoutMs); - }); -} -export async function refreshToken(alias) { - const store = loadStore(); - const account = store.accounts[alias]; - if (!account?.refreshToken) { - console.error(`[multi-auth] No refresh token for ${alias}`); - return null; - } - try { - const tokenRes = await fetch(TOKEN_URL, { - method: 'POST', - headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, - body: new URLSearchParams({ - grant_type: 'refresh_token', - client_id: CLIENT_ID, - refresh_token: account.refreshToken - }) - }); - if (!tokenRes.ok) { - console.error(`[multi-auth] Refresh failed for ${alias}: ${tokenRes.status}`); - if (tokenRes.status === 401 || tokenRes.status === 403) { - try { - updateAccount(alias, { - authInvalid: true, - authInvalidatedAt: Date.now() - }); - } - catch { - // ignore - } - } - return null; - } - const tokens = (await tokenRes.json()); - const accessClaims = decodeJwtPayload(tokens.access_token); - const idClaims = tokens.id_token ? decodeJwtPayload(tokens.id_token) : null; - const expiresAt = getExpiryFromClaims(accessClaims) || getExpiryFromClaims(idClaims) || Date.now() + tokens.expires_in * 1000; - const updates = { - accessToken: tokens.access_token, - refreshToken: tokens.refresh_token || account.refreshToken, - expiresAt, - lastRefresh: new Date().toISOString(), - idToken: tokens.id_token || account.idToken, - accountId: getAccountIdFromClaims(idClaims) || - getAccountIdFromClaims(accessClaims) || - account.accountId, - planType: getPlanTypeFromClaims(idClaims) || - getPlanTypeFromClaims(accessClaims) || - account.planType - }; - const updatedStore = updateAccount(alias, updates); - clearAuthInvalid(alias); - return updatedStore.accounts[alias]; - } - catch (err) { - console.error(`[multi-auth] Refresh error for ${alias}:`, err); - return null; - } -} -export async function ensureValidToken(alias) { - const store = loadStore(); - const account = store.accounts[alias]; - if (!account) - return null; - const bufferMs = 5 * 60 * 1000; - if (account.expiresAt < Date.now() + bufferMs) { - console.log(`[multi-auth] Refreshing token for ${alias}`); - const refreshed = await refreshToken(alias); - return refreshed?.accessToken || null; - } - return account.accessToken; -} -//# sourceMappingURL=auth.js.map \ No newline at end of file diff --git a/dist/auth.js.map b/dist/auth.js.map deleted file mode 100644 index 9b43592..0000000 --- a/dist/auth.js.map +++ /dev/null @@ -1 +0,0 @@ -{"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/cli.d.ts b/dist/cli.d.ts deleted file mode 100644 index faaadd5..0000000 --- a/dist/cli.d.ts +++ /dev/null @@ -1,3 +0,0 @@ -#!/usr/bin/env node -export {}; -//# sourceMappingURL=cli.d.ts.map \ No newline at end of file diff --git a/dist/cli.d.ts.map b/dist/cli.d.ts.map deleted file mode 100644 index f022439..0000000 --- a/dist/cli.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":""} \ No newline at end of file diff --git a/dist/cli.js b/dist/cli.js deleted file mode 100644 index 2b96a4f..0000000 --- a/dist/cli.js +++ /dev/null @@ -1,160 +0,0 @@ -#!/usr/bin/env node -import { fileURLToPath } from 'node:url'; -import { loginAccount } from './auth.js'; -import { removeAccount, listAccounts, getStorePath, loadStore } from './store.js'; -import { startWebConsole } from './web.js'; -import { disableService, installService, serviceStatus } from './systemd.js'; -const args = process.argv.slice(2); -const command = args[0]; -const alias = args[1]; -function getFlagValue(flag) { - const idx = args.indexOf(flag); - if (idx === -1) - return undefined; - return args[idx + 1]; -} -async function main() { - switch (command) { - case 'add': - case 'login': { - if (!alias) { - console.error('Usage: opencode-multi-auth add