release: v2.2.0 stable + post-audit hardening - #504
Conversation
Promote the v2.1.13-beta line to a stable 2.2.0 release and fold in the remaining LOW findings from the deep post-merge audit. Release: - Version 2.1.13-beta.3 -> 2.2.0 across package.json, .codex-plugin/plugin.json, AGENTS.md, package-lock.json. - Rename docs/releases/v2.1.13-beta.3.md -> v2.2.0.md, rewrite as a STABLE release (install `npm i -g codex-multi-auth`, no @beta), add a #501/#502 quota section, and document the post-audit hardening. Update the docs-portal + root README pointers from "current prerelease (beta)" to "current stable" v2.2.0. Fixes (from the deep audit's LOW findings): - codex-manager.ts styleAccountDetailText: test `failed|error` (danger) BEFORE the `unavailable|not available` warning keywords in both the suffix and compact paths, so a real failure whose text contains "not available" renders red, not a soft yellow warning. - storage/paths.ts resolvePath: reject a path containing a NUL byte up front (defense in depth) rather than letting it reach the fs layer. - codex-manager/commands/switch.ts: require a strict integer index; "1.5"/"2abc" no longer silently truncate to a valid account — they error. Tests: strict-index rejection cases for `switch`, and a NUL-byte rejection case for `resolvePath`. Not changed: the quota-probe transient-vs-unsupported precedence (CodeRabbit LOW-2) was intentionally left as-is — existing tests (quota-probe "does not throw CodexUnavailableError when a non-unsupported failure is mixed in" / "does not mask an instruction-fetch failure") deliberately keep a real transient surfacing rather than masking an outage behind the friendly note. typecheck + lint + audit:ci clean; full suite 4278 passed / 2 skipped.
|
Codex usage limits have been reached for code reviews. Please check with the admins of this repo to increase the limits by adding credits. |
|
@coderabbitai full review |
✅ Actions performedFull review triggered. |
📝 WalkthroughWalkthroughv2.2.0 promoted to stable. adds nul-byte rejection in lib/storage/paths.ts:445, strict digits-only switch index validation in lib/codex-manager/commands/switch.ts:39, and an error-tone precedence fix in lib/codex-manager.ts:425,442. docs and version metadata updated. Changesrelease and input validation hardening
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~18 minutes
Possibly related PRs
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
✨ Simplify code
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@lib/codex-manager.ts`:
- Around line 442-444: Add a focused unit test for styleAccountDetailText to
assert that when a detail string contains overlapping keywords (e.g., both
"error"/"failed" and "unavailable"/"not available") the tone precedence yields
"danger" (matching the compact-path change that checks /failed|error/i before
the unavailable regex). Locate the function under test styleAccountDetailText in
lib/codex-manager.ts and write a vitest unit test (e.g., alongside
test/codex-manager-cli.test.ts or a new file under test/) that passes a string
containing both keywords (and normalized whitespace/newlines) and asserts the
returned/styled output uses the danger style (same outcome as stylePromptText
when matching /failed|error/i); make the assertion mirror existing tests that
check CODEX_UNAVAILABLE_PROBE_NOTE but expect "danger" instead of "warning".
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: 6914fa6e-7439-4edb-a594-5d012950f99a
⛔ Files ignored due to path filters (1)
package-lock.jsonis excluded by!**/package-lock.json
📒 Files selected for processing (12)
.codex-plugin/plugin.json.gitignoreAGENTS.mdREADME.mddocs/README.mddocs/releases/v2.2.0.mdlib/codex-manager.tslib/codex-manager/commands/switch.tslib/storage/paths.tspackage.jsontest/codex-manager-switch-command.test.tstest/paths.test.ts
📜 Review details
🧰 Additional context used
📓 Path-based instructions (17)
package.json
📄 CodeRabbit inference engine (SECURITY.md)
package.json: Pinhonoto4.12.18or higher (but below4.12.0-4.12.1) to avoid GHSA-xh87-mx6m-69f3 authentication bypass vulnerability
Pinrollupto^4.59.0or higher to avoid vulnerable versions below4.59.0in Vite and Vitest transitive dependencies
Files:
package.json
docs/{README.md,docs/**/*.md}
📄 CodeRabbit inference engine (docs/DOCUMENTATION.md)
docs/{README.md,docs/**/*.md}: Use canonical package namecodex-multi-authin all documentation
Verify internal links in documentation are valid before merge
Ensure no conflicting guidance exists between README, docs, and governance files before merge
Files:
docs/README.md
docs/{README.md,docs/getting-started.md}
📄 CodeRabbit inference engine (docs/DOCUMENTATION.md)
Update
README.mdanddocs/getting-started.mdfirst when runtime behavior changes
Files:
docs/README.md
docs/{README.md,docs/getting-started.md,docs/configuration.md,docs/troubleshooting.md,docs/reference/**/*.md}
📄 CodeRabbit inference engine (docs/DOCUMENTATION.md)
Verify every documented command is executable as written before merge
Files:
docs/README.md
docs/{docs/**/*.md,README.md}
📄 CodeRabbit inference engine (docs/DOCUMENTATION.md)
Verify paths in documentation match runtime modules (
lib/runtime-paths.ts,lib/storage.ts,lib/config.ts)
Files:
docs/README.md
docs/{README.md,docs/index.md,docs/README.md}
📄 CodeRabbit inference engine (docs/DOCUMENTATION.md)
Use accurate discoverability terms in public landing pages without keyword stuffing or ranking promises
Root README and docs landing pages should naturally include
Codex CLI,multi-account OAuth,account switching,health checks,runtime rotation,diagnostics, andrecoverywhen those topics are in scope
Files:
docs/README.md
docs/**/*.md
📄 CodeRabbit inference engine (docs/STYLE_GUIDE.md)
docs/**/*.md: User-facing documentation should follow the page template: Title and one-line lead, Quick path commands, Core operational workflow, Troubleshooting or failure handling, and Related links
Use short sections and scan-friendly tables in documentation where they improve clarity
Prefer direct, actionable language in documentation
Use runnable command examples in documentation
Explain expected outcomes after critical commands in documentation
Keep terminology consistent with runtime names in documentation
Avoid speculative language when behavior is deterministic in documentation
Put the user problem in the first paragraph before implementation detail
Use descriptive page titles such ascodex-multi-auth Featuresinstead of generic titles on public docs
Do not repeat keyword lists in every section; search terms should appear only where they help a developer understand the page
Canonical command family iscodex-multi-auth ...
Canonical runtime root is~/.codex/multi-auth
Runtime rotation must be described as default-on unless the release policy changes
Legacy command/path references belong only in migration contexts in documentation
Compatibility aliases (codex multi auth,codex multi-auth,codex multiauth) belong only in command reference, troubleshooting, or migration contexts
Keep command flags aligned with runtime usage text in documentation
Avoid non-runnable command snippets in documentation
Avoid conflicting path guidance across documentation
Avoid legacy-first onboarding language in documentationMaintain complete documentation including: getting-started guide, features overview, configuration reference, troubleshooting guide, command reference, public API contract, error contracts, settings reference, storage paths, upgrade guide, privacy policy, and release notes
Files:
docs/README.mddocs/releases/v2.2.0.md
docs/{README.md,package.json,docs/development/GITHUB_DISCOVERABILITY.md}
📄 CodeRabbit inference engine (docs/STYLE_GUIDE.md)
Keep the repository description, package description, README lead, and
docs/development/GITHUB_DISCOVERABILITY.mdaligned
Files:
docs/README.md
docs/**
⚙️ CodeRabbit configuration file
keep README, SECURITY, and docs consistent with actual CLI flags and workflows. whenever behavior changes, require updated upgrade notes and mention new npm scripts.
Files:
docs/README.mddocs/releases/v2.2.0.md
lib/**/*.ts
📄 CodeRabbit inference engine (lib/AGENTS.md)
lib/**/*.ts: All public exports should flow throughlib/index.tsor documented package subpaths
Never import fromdist/in source tests or library code
Never suppress type errors
Files:
lib/storage/paths.tslib/codex-manager.tslib/codex-manager/commands/switch.ts
lib/storage/**/*.ts
📄 CodeRabbit inference engine (lib/AGENTS.md)
lib/storage/**/*.ts: Worktree storage usesresolveProjectStorageIdentityRoot; never derive project pools from raw worktree paths
Never use bare recursive cleanup in Windows-sensitive paths without retry handling
Files:
lib/storage/paths.ts
**/*.ts
📄 CodeRabbit inference engine (AGENTS.md)
Do not use
as any,@ts-ignore, or@ts-expect-errortype assertionsDo not bypass the official Codex CLI by reimplementing general Codex commands in the wrapper
Do not patch official Codex app binaries; use app bind or launcher helpers for desktop app integration
Do not expose account emails or tokens in runtime proxy client response headers or logs
Do not key project storage by worktree path; use
resolveProjectStorageIdentityRootfor storage path resolutionUse ESM only with
"type": "module"; Node >= 18 is requiredEmail dedup must be case-insensitive via
normalizeEmailKey()function (trim + lowercase)
Files:
lib/storage/paths.tstest/codex-manager-switch-command.test.tslib/codex-manager.tslib/codex-manager/commands/switch.tstest/paths.test.ts
**/*.{ts,tsx,js,mjs,cjs}
📄 CodeRabbit inference engine (README.md)
Install and use
codex-multi-authas a global npm package withnpm i -g codex-multi-authto manage multi-account OAuth for Codex CLIImplement OAuth account credential handling for personal development use only; include clear documentation that this is not an official OpenAI product and users are responsible for policy compliance
Implement stateless
store=falserouting as default; enable statefulstore=truebackground response mode only via explicitCODEX_AUTH_BACKGROUND_RESPONSES=1or settings configuration for callers that sendbackground: trueImplement Responses request/prompt compatibility with strict runtime handling and documented error contracts; support configurable timeout overrides via
CODEX_AUTH_FETCH_TIMEOUT_MSandCODEX_AUTH_STREAM_STALL_TIMEOUT_MS
Files:
lib/storage/paths.tstest/codex-manager-switch-command.test.tslib/codex-manager.tslib/codex-manager/commands/switch.tstest/paths.test.ts
lib/**
⚙️ CodeRabbit configuration file
focus on auth rotation, windows filesystem IO, and concurrency. verify every change cites affected tests (vitest) and that new queues handle EBUSY/429 scenarios. check for logging that leaks tokens or emails.
Files:
lib/storage/paths.tslib/codex-manager.tslib/codex-manager/commands/switch.ts
test/**/*.test.ts
📄 CodeRabbit inference engine (test/AGENTS.md)
test/**/*.test.ts: Vitest globals (describe,it,expect) are enabled and should be used without explicit imports
Maintain 80% coverage threshold across statements, branches, functions, and lines
UseremoveWithRetryfor Windows filesystem cleanup instead of barefs.rmto handle EBUSY/EPERM/ENOTEMPTY backoff
Use source files in tests, not compileddist/files; test the source directly
Do not skip tests without justification; include rationale if a test must be skipped
Relax ESLint rules for test files as specified ineslint.config.js
Files:
test/codex-manager-switch-command.test.tstest/paths.test.ts
test/**/*.ts
📄 CodeRabbit inference engine (AGENTS.md)
Use Vitest for test suites; include property tests and chaos tests for core functionality
Files:
test/codex-manager-switch-command.test.tstest/paths.test.ts
test/**
⚙️ CodeRabbit configuration file
tests must stay deterministic and use vitest. demand regression cases that reproduce concurrency bugs, token refresh races, and windows filesystem behavior. reject changes that mock real secrets or skip assertions.
Files:
test/codex-manager-switch-command.test.tstest/paths.test.ts
🧠 Learnings (1)
📓 Common learnings
Learnt from: CR
Repo: ndycode/codex-multi-auth
Timestamp: 2026-06-02T11:45:09.291Z
Learning: Runtime rotation is default-on through `codexRuntimeRotationProxy`; users can opt out with `codex-multi-auth rotation disable` or `CODEX_MULTI_AUTH_RUNTIME_ROTATION_PROXY=0`
Learnt from: CR
Repo: ndycode/codex-multi-auth
Timestamp: 2026-06-02T11:45:09.291Z
Learning: Keep runtime rotation default-on behavior aligned with explicit release and migration documentation
Learnt from: CR
Repo: ndycode/codex-multi-auth
Timestamp: 2026-06-02T11:45:09.291Z
Learning: OAuth callback port remains 1455
Learnt from: CR
Repo: ndycode/codex-multi-auth
Timestamp: 2026-06-02T11:45:09.291Z
Learning: The runtime proxy is loopback-only and uses a per-process client token; it forwards only Responses API and model discovery requests
Learnt from: CR
Repo: ndycode/codex-multi-auth
Timestamp: 2026-06-02T11:45:09.291Z
Learning: The persistent desktop app bind is reversible and edits user config/startup metadata, not official app binaries
Learnt from: CR
Repo: ndycode/codex-multi-auth
Timestamp: 2026-06-02T11:45:09.291Z
Learning: The package does not publish a global `codex` bin; `codex-multi-auth-codex` is the explicit wrapper with auth commands running locally and non-auth commands forwarding to official Codex
Learnt from: CR
Repo: ndycode/codex-multi-auth
Timestamp: 2026-06-02T11:45:09.291Z
Learning: Settings Q hotkey = cancel without save; theme live-preview restores baseline on cancel
Learnt from: CR
Repo: ndycode/codex-multi-auth
Timestamp: 2026-06-02T11:45:40.404Z
Learning: Keep `codex` binary owned by the official OpenAI install path; use `codex-multi-auth-codex` wrapper only when intentionally choosing wrapper-launched sessions instead of direct Codex CLI usage
Learnt from: CR
Repo: ndycode/codex-multi-auth
Timestamp: 2026-06-02T11:45:40.404Z
Learning: Design for personal development workflows where credentials stay local, runtime rotation is loopback-only, and account state remains visible and recoverable
Learnt from: CR
Repo: ndycode/codex-multi-auth
Timestamp: 2026-06-02T11:45:40.404Z
Learning: Ensure that experimental features in Settings menu are non-destructive by default: sync previews before apply, preserve destination-only accounts, and fail safely on filename collisions
Learnt from: CR
Repo: ndycode/codex-multi-auth
Timestamp: 2026-06-02T11:45:49.834Z
Learning: Documentation files should be organized by category: Start Here, Daily Use, Release History, Repair, Reference, Maintainer Docs, and Governance
Learnt from: CR
Repo: ndycode/codex-multi-auth
Timestamp: 2026-06-02T11:45:49.834Z
Learning: Documentation governance is defined in DOCUMENTATION.md and establishes the contract for documentation standards and practices
🔇 Additional comments (12)
.codex-plugin/plugin.json (1)
3-3: LGTM!package.json (1)
3-3: LGTM!AGENTS.md (1)
6-6: LGTM!README.md (1)
386-388: LGTM!docs/README.md (1)
35-36: LGTM!docs/releases/v2.2.0.md (1)
1-9: LGTM!Also applies to: 14-14, 95-110
.gitignore (1)
36-37: LGTM!lib/storage/paths.ts (1)
445-450: LGTM!test/paths.test.ts (1)
775-781: LGTM!lib/codex-manager/commands/switch.ts (1)
39-45: LGTM!test/codex-manager-switch-command.test.ts (1)
70-80: LGTM!lib/codex-manager.ts (1)
419-432: LGTM!
…ntDetailText CodeRabbit (#504) flagged missing coverage for the tone-precedence fix: a failure detail containing both /failed|error/i and an unavailable keyword must render danger (red), not be downgraded to warning (yellow). - Export styleAccountDetailText (behavior-neutral) for direct unit testing - Add test/codex-manager-detail-tone.test.ts: 5 cases covering compact path, 'not available' variant, whitespace/newline normalization, warning-only control, and the quota-suffix branch Forces legacy ANSI (v2 off) + TTY so danger=red / warning=yellow are deterministic. Full suite: 4283 passed.
|
Addressed the actionable review comment in Finding: missing coverage for Fix: exported
Forces legacy ANSI (v2 off) + TTY so @coderabbitai full review |
🧩 Analysis chain🏁 Script executed: #!/bin/bash
# Check the new test file
fd 'codex-manager-detail-tone.test.ts' --exec cat {}
# Check the export change in lib/codex-manager.ts around styleAccountDetailText
rg -n 'styleAccountDetailText' --type ts -C 3Length of output: 11602
full review triggered for the updated branch. ✅ Actions performedFull review triggered. |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@lib/codex-manager.ts`:
- Around line 406-409: The export styleAccountDetailText is intentionally
exposed for unit tests; add an explicit JSDoc `@internal` tag above its
declaration to signal it’s test-only (keep the existing explanatory comment
about tone precedence/security). Locate the exported function named
styleAccountDetailText and prepend a JSDoc block containing `@internal` (and a
brief one-line summary if desired) so the intent is clear while preserving the
current comment and behavior.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: b8e8cfff-eca7-43ff-a4a1-3f6b2b932e96
📒 Files selected for processing (2)
lib/codex-manager.tstest/codex-manager-detail-tone.test.ts
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: Greptile Review
🧰 Additional context used
📓 Path-based instructions (7)
test/**/*.test.ts
📄 CodeRabbit inference engine (test/AGENTS.md)
test/**/*.test.ts: Vitest globals (describe,it,expect) are enabled and should be used without explicit imports
Maintain 80% coverage threshold across statements, branches, functions, and lines
UseremoveWithRetryfor Windows filesystem cleanup instead of barefs.rmto handle EBUSY/EPERM/ENOTEMPTY backoff
Use source files in tests, not compileddist/files; test the source directly
Do not skip tests without justification; include rationale if a test must be skipped
Relax ESLint rules for test files as specified ineslint.config.js
Files:
test/codex-manager-detail-tone.test.ts
**/*.ts
📄 CodeRabbit inference engine (AGENTS.md)
Do not use
as any,@ts-ignore, or@ts-expect-error- maintain proper type safety
Files:
test/codex-manager-detail-tone.test.tslib/codex-manager.ts
**/*.{ts,js}
📄 CodeRabbit inference engine (AGENTS.md)
Use ESM only (
"type": "module"), target Node >= 18
Files:
test/codex-manager-detail-tone.test.tslib/codex-manager.ts
test/**/*.ts
📄 CodeRabbit inference engine (AGENTS.md)
Use Vitest for test suites with support for property tests and chaos tests
Files:
test/codex-manager-detail-tone.test.ts
test/**
⚙️ CodeRabbit configuration file
tests must stay deterministic and use vitest. demand regression cases that reproduce concurrency bugs, token refresh races, and windows filesystem behavior. reject changes that mock real secrets or skip assertions.
Files:
test/codex-manager-detail-tone.test.ts
lib/**/*.ts
📄 CodeRabbit inference engine (lib/AGENTS.md)
lib/**/*.ts: All public exports should flow throughlib/index.tsor documented package subpaths
Never import fromdist/in source tests or library code
Never suppress type errorsStore core runtime logic following the lib/ directory structure: auth/, runtime/, request/, storage/, codex-cli/, codex-manager/, prompts/, recovery/, tools/, ui/
Files:
lib/codex-manager.ts
lib/**
⚙️ CodeRabbit configuration file
focus on auth rotation, windows filesystem IO, and concurrency. verify every change cites affected tests (vitest) and that new queues handle EBUSY/429 scenarios. check for logging that leaks tokens or emails.
Files:
lib/codex-manager.ts
🧠 Learnings (1)
📓 Common learnings
Learnt from: CR
Repo: ndycode/codex-multi-auth
Timestamp: 2026-06-02T12:08:50.198Z
Learning: Canonical package name is `codex-multi-auth` and canonical command family is `codex-multi-auth ...`
Learnt from: CR
Repo: ndycode/codex-multi-auth
Timestamp: 2026-06-02T12:08:50.198Z
Learning: The package does not publish a global `codex` bin; `codex-multi-auth-codex` is the explicit wrapper: auth commands run locally, non-auth commands forward to official Codex
Learnt from: CR
Repo: ndycode/codex-multi-auth
Timestamp: 2026-06-02T12:08:50.198Z
Learning: Runtime rotation is default-on through `codexRuntimeRotationProxy`; users can opt out with `codex-multi-auth rotation disable` or `CODEX_MULTI_AUTH_RUNTIME_ROTATION_PROXY=0`
Learnt from: CR
Repo: ndycode/codex-multi-auth
Timestamp: 2026-06-02T12:08:50.198Z
Learning: The runtime proxy is loopback-only and uses a per-process client token, forwarding only Responses API and model discovery requests
Learnt from: CR
Repo: ndycode/codex-multi-auth
Timestamp: 2026-06-02T12:08:50.198Z
Learning: The persistent desktop app bind is reversible and edits user config/startup metadata, not official app binaries
Learnt from: CR
Repo: ndycode/codex-multi-auth
Timestamp: 2026-06-02T12:08:50.198Z
Learning: Do not bypass the official Codex CLI by reimplementing general Codex commands in the wrapper
Learnt from: CR
Repo: ndycode/codex-multi-auth
Timestamp: 2026-06-02T12:08:50.198Z
Learning: Keep runtime rotation default-on behavior aligned with explicit release and migration documentation
Learnt from: CR
Repo: ndycode/codex-multi-auth
Timestamp: 2026-06-02T12:08:50.198Z
Learning: Do not expose account emails or tokens in runtime proxy client response headers or logs
Learnt from: CR
Repo: ndycode/codex-multi-auth
Timestamp: 2026-06-02T12:09:02.503Z
Learning: Store accounts in JSON format at `~/.codex/multi-auth/openai-codex-accounts.json` or in project-scoped paths under `~/.codex/multi-auth/projects/<project-key>/openai-codex-accounts.json`
Learnt from: CR
Repo: ndycode/codex-multi-auth
Timestamp: 2026-06-02T12:09:02.503Z
Learning: Store settings in JSON format at `~/.codex/multi-auth/settings.json` or at the path specified by `CODEX_MULTI_AUTH_CONFIG_PATH`
Learnt from: CR
Repo: ndycode/codex-multi-auth
Timestamp: 2026-06-02T12:09:02.503Z
Learning: Use `CODEX_MULTI_AUTH_DIR` environment variable to allow override of settings and accounts root directory
Learnt from: CR
Repo: ndycode/codex-multi-auth
Timestamp: 2026-06-02T12:09:02.503Z
Learning: Implement health-aware account selection that considers quota state, cooldown state, and runtime metrics before rotating to a different account
Learnt from: CR
Repo: ndycode/codex-multi-auth
Timestamp: 2026-06-02T12:09:02.503Z
Learning: Use bounded outbound request budgets to prevent a single prompt from exhausting the entire account pool during rotation
Learnt from: CR
Repo: ndycode/codex-multi-auth
Timestamp: 2026-06-02T12:09:02.503Z
Learning: Keep credentials local and ensure runtime rotation is loopback-only with no external request forwarding outside the local machine
Learnt from: CR
Repo: ndycode/codex-multi-auth
Timestamp: 2026-06-02T12:09:02.503Z
Learning: Use JSON format for all configuration files including settings, accounts, quota cache, policies, routing profiles, and budget guards
Learnt from: CR
Repo: ndycode/codex-multi-auth
Timestamp: 2026-06-02T12:09:02.503Z
Learning: Implement OAuth callback handling on port `1455` for the default login flow, with fallback to device-auth and manual callback-paste flows when port is unavailable
Learnt from: CR
Repo: ndycode/codex-multi-auth
Timestamp: 2026-06-02T12:09:02.503Z
Learning: Log all activity to `~/.codex/multi-auth/logs/codex-plugin/` with structured logging that supports runtime observability and diagnostics
Learnt from: CR
Repo: ndycode/codex-multi-auth
Timestamp: 2026-06-02T12:09:02.503Z
Learning: Respect `CODEX_MODE`, `CODEX_MULTI_AUTH_RUNTIME_ROTATION_PROXY`, `CODEX_MULTI_AUTH_APP_ROTATION_IDLE_MS`, and other feature-gate environment variables to allow runtime configuration of package behavior
Learnt from: CR
Repo: ndycode/codex-multi-auth
Timestamp: 2026-06-02T12:09:02.503Z
Learning: Provide machine-readable JSON output for diagnostic commands like `status`, `report`, `check`, and `doctor` to support automation and tooling integration
Learnt from: CR
Repo: ndycode/codex-multi-auth
Timestamp: 2026-06-02T12:09:35.895Z
Learning: Maintain a comprehensive test suite (4,200+ tests) with green results and pass all security audits (`npm run audit:ci`), typecheck, and lint validation
Learnt from: CR
Repo: ndycode/codex-multi-auth
Timestamp: 2026-06-02T12:09:35.895Z
Learning: Apply defensive security hardening across all layers (runtime, storage, prompt caching, path handling) to prevent common attack vectors like shell injection, path traversal, token exposure, and unauthorized network access
🔇 Additional comments (2)
lib/codex-manager.ts (1)
410-451: LGTM!test/codex-manager-detail-tone.test.ts (1)
6-72: test coverage for tone precedence is solid.the suite pins the danger-before-warning invariant in both compact (lib/codex-manager.ts:444-447) and quota-suffix (lib/codex-manager.ts:427-435) branches. forcing
isTTY=trueandv2Enabled=falseon lines 24-28 makes ansi assertions deterministic.five cases cover the key scenarios:
- "failed" + "unavailable" → danger (test 1)
- "error" + "not available" → danger (test 2)
- whitespace/newline normalization → danger (test 3)
- "unavailable" alone → warning, not danger (test 4, control)
- quota-suffix with both keywords → danger (test 5)
this directly resolves the past review comment on lib/codex-manager.ts:445-447 that flagged missing regression coverage for overlapping keywords.
|
@coderabbitai the only actionable comment (tone-precedence test for styleAccountDetailText) is addressed in 51d9a06 and you confirmed it ("✅ Addressed in commits d8f714c to 51d9a06"). Resolved the thread. Please re-evaluate and clear the stale CHANGES_REQUESTED from the prior commit. |
|
✅ Actions performedComments resolved and changes approved. |
Summary
Cuts the v2.2.0 stable release (promoting the v2.1.13-beta line) and folds in the remaining LOW findings from the deep post-merge audit of
main.Per the maintainer decision, this is a minor stable release → npm
latest(drops the-betaprerelease tag).Release
2.1.13-beta.3→2.2.0acrosspackage.json,.codex-plugin/plugin.json,AGENTS.md,package-lock.json.docs/releases/v2.1.13-beta.3.md→v2.2.0.md, rewritten as a stable release (npm i -g codex-multi-auth, no@beta), with a [bug]codex-multi-auth checkno longer works due to using GPT-5-Codex for quota fetching? #501/fix(quota): detect unsupported Codex model from detail shape (#501) #502 quota section + post-audit hardening notes. Docs-portal + README pointers moved from "current prerelease (beta)" → "current stable" v2.2.0..omc/to.gitignore(session scratch, never published).Fixes (deep-audit LOW findings)
styleAccountDetailText(codex-manager.ts): testfailed|error(danger) beforeunavailable|not available(warning) in both the suffix and compact paths — a real failure whose text contains "not available" now renders red, not a soft yellow warning.resolvePath(storage/paths.ts): reject a NUL-byte path up front (defense in depth) instead of letting it reach the fs layer.switch <index>: require a strict integer —1.5/2abcno longer silently truncate to a valid account; they error.Tests: strict-index rejection for
switch, NUL-byte rejection forresolvePath.Deliberately NOT changed
The quota-probe transient-vs-unsupported precedence (a CodeRabbit LOW suggestion) was left as-is: existing tests ("does not throw CodexUnavailableError when a non-unsupported failure is mixed in" / "does not mask an instruction-fetch failure") intentionally keep a real transient surfacing rather than masking a possible outage behind the friendly "Codex unavailable" note. Changing it would regress that safety contract.
Audit confidence (this release)
Deep multi-arm audit of merged
main(the basis for 2.2.0):audit:ciexit 0 (vitest GHSA cleared), vendor verified, no secrets in tarball, all 4 bins present, Node-18 clean, version parity.Verification
typecheck + lint +
audit:ciclean · full suite 4278 passed / 2 skipped.🤖 Generated with Claude Code
note: greptile review for oc-chatgpt-multi-auth. cite files like
lib/foo.ts:123. confirm regression tests + windows concurrency/token redaction coverage.Greptile Summary
promotes the v2.1.13-beta line to a stable 2.2.0 release and folds in the remaining LOW audit findings: tone-precedence fix in
styleAccountDetailText, NUL-byte rejection inresolvePath, and strict-integer guard inswitch. all three fixes ship with targeted vitest coverage (the previously-noted gap for the tone fix is now closed bytest/codex-manager-detail-tone.test.ts).styleAccountDetailText(lib/codex-manager.ts):failed|errornow checked beforeunavailable|not availableon both the compact path and the quota-suffix path, so a 5xx "service not available" renders danger (red) instead of warning (yellow). exported for direct unit testing.resolvePath(lib/storage/paths.ts): NUL-byte (\x00) check added as the very first guard, before tilde expansion orpath.resolve, giving a clear error rather than a deep fs-layer throw on windows or posix.switch <index>(lib/codex-manager/commands/switch.ts):^\d+$regex rejects floats (1.5), scientific notation (1e0), hex (0x2), and sign-prefixed strings (+1,-1) beforeparseIntis called, preventing silent truncation to a valid account index.Confidence Score: 5/5
all three code changes are narrow, well-scoped hardening fixes with direct vitest coverage; version bump and docs are mechanical.
the tone-precedence fix, NUL-byte guard, and strict-integer check each have no side-effects beyond the intended behavior change, and each is pinned by new tests. the previous audit gap (missing tone test) is now closed. no concurrency-sensitive paths are touched, no token or filesystem safety regressions are introduced.
no files require special attention.
Important Files Changed
Flowchart
%%{init: {'theme': 'neutral'}}%% flowchart TD A["switch index arg"] --> B{"^\\d+$ test on trimmed arg"} B -- fail --> E["logError: Invalid index\nreturn 1"] B -- pass --> C{"isFinite && >= 1"} C -- fail --> E C -- pass --> F["loadAccounts()"] F --> G{"targetIndex in range?"} G -- no --> H["logError: out of range\nreturn 1"] G -- yes --> I["persistAndSyncSelectedAccount()"] I --> J["return 0"] R["resolvePath(filePath)"] --> R1{"contains NUL byte?"} R1 -- yes --> R2["throw: Invalid path: contains a NUL byte"] R1 -- no --> R3["tilde expand / path.resolve"] R3 --> R4["lookalike-sibling + root checks"] R4 --> R5["return resolved path"] S["styleAccountDetailText(detail)"] --> S1{"quota pattern match?"} S1 -- yes --> S2{"suffix: /failed|error/?"} S2 -- yes --> SD["danger (red)"] S2 -- no --> S3{"suffix: unavailable/stale?"} S3 -- yes --> SW["warning (yellow)"] S3 -- no --> SM["muted"] S1 -- no --> S4{"compact: /rate-limited/?"} S4 -- yes --> SD2["danger"] S4 -- no --> S5{"compact: /failed|error/?"} S5 -- yes --> SD3["danger"] S5 -- no --> S6{"compact: unavailable/stale?"} S6 -- yes --> SW2["warning"] S6 -- no --> SF["fallback tone"]Comments Outside Diff (1)
lib/codex-manager.ts, line 424-448 (link)styleAccountDetailTextpriority fixthe priority-swap is the core correctness fix in this PR, but there's no unit test verifying the new ordering.
styleAccountDetailTextis only referenced in tests via a pass-through mock inrepair-commands.test.ts— so a regression (e.g. the suffix branch reverting to the old order) would pass the full suite undetected. a targeted test for a suffix like"service not available – error"asserting"danger"output would close this gap.Prompt To Fix With AI
Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!
Reviews (2): Last reviewed commit: "test(codex-manager): pin danger>warning ..." | Re-trigger Greptile