Skip to content

fix(cli): preserve absent OAuth plan fields - #4996

Merged
lidge-jun merged 1 commit into
lidge-jun:devfrom
luvs01:agent/cli-oauth-plan-fields-20260918
Sep 18, 2026
Merged

lidge-jun merged 1 commit into
lidge-jun:devfrom
luvs01:agent/cli-oauth-plan-fields-20260918

Conversation

@luvs01

@luvs01 luvs01 commented Sep 18, 2026

Copy link
Copy Markdown
Contributor

Summary

The ocx account list --json OAuth projection collapsed two different wire states into one: an absent plan key (proxies that predate tier reporting) and an explicit plan: null (the proxy checked and found no tier) both came out as plan: null. Downstream version-detection and automation read the absent key as the old-proxy signal, so synthesizing null for it reports the wrong thing.

  • fetchOAuthRows in src/cli/account-api.ts now forwards plan only when the response object actually owns the property (Object.hasOwn), so absent stays absent while null and reported tiers pass through verbatim — matching the row type's own contract (plan?: string | null, [Feature]: expose the Anthropic account subscription tier (plan) like the OpenAI provider does #3777).
  • Regression coverage lives in tests/cli/cli-dto-fidelity.test.ts — the file that already covers "the CLI discarded fields the API already returned" — because tests/cli/cli-account.test.ts sits exactly at its file-size-ratchet cap and cannot grow.

Verification

Exact head: e5c3e3419781a97c5ce95cd6ed150c9bb4cef8e9 (tree e606e4ad524de0430d103d62d75bfc7ecdb6df95), based on dev ad9eab393b1125ca7bdfa3e83ed4fa0e0b0475e9.

  • bun x tsc --noEmit — clean.
  • bun run structure:check — passed.
  • bun run privacy:scan — passed.
  • bun scripts/file-size-ratchet.ts — passed.
  • bun test tests/cli/cli-dto-fidelity.test.ts — 22/22 pass.
  • bun test tests/cli/cli-account.test.ts — 153/153 pass.
  • Regression proof: the new absent-key case fails against the unfixed projection (synthesizes plan: null), passes with the fix.

Remaining gates

Review readiness checklist

  • All CI tests are green on my local testing. Local gates passed (see Verification); fork run 35290314706 dispatched on the exact head.
  • I pushed my PR to the latest dev commit. The branch is cut from dev ad9eab3; the maintainer absorbs any newer dev at landing.
  • I resolved all correct Codex and CodeRabbit findings. No review rounds yet on this head; the branch is new.
  • My PR is ready for review.

Summary by CodeRabbit

  • Bug Fixes

    • OAuth account data now accurately preserves whether plan information was unavailable, explicitly empty, or reported with a tier.
    • Prevents missing plan details from being incorrectly displayed as null.
  • Tests

    • Added coverage for absent, empty, and populated plan values.

An absent plan key means the proxy predates tier reporting while plan: null means it checked and found no tier. The CLI projection collapsed absent to null, erasing the distinction. Forward the key only when the response owns it.
@coderabbitai

coderabbitai Bot commented Sep 18, 2026

Copy link
Copy Markdown
Contributor

Review Change StackReview Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Advanced

Run ID: cd8a3e79-109b-442d-9688-1268219853f4

📥 Commits

Reviewing files that changed from the base of the PR and between 6467235 and e5c3e34.

📒 Files selected for processing (2)
  • src/cli/account-api.ts
  • tests/cli/cli-dto-fidelity.test.ts

Included review availability: Your plan provides up to 10 included reviews per hour; 7 remain after this review.


📝 Walkthrough

Walkthrough

The OAuth account projection now preserves the distinction between an absent plan field and an explicit null. Tests cover absent, null, and reported plan values.

Changes

OAuth plan field fidelity

Layer / File(s) Summary
Preserve OAuth plan presence
src/cli/account-api.ts, tests/cli/cli-dto-fidelity.test.ts
fetchOAuthRows includes plan only when the server response has that key. Tests verify that absent, null, and "max" values reach the projected row correctly.

Priority: ⬇️ Low

Estimated code review effort: 1 (Trivial) | ~5 minutes

Change: Bug fix

Merge Risk: ⚪ Minimal · up to e5c3e

The OAuth account JSON projection preserves the intended distinction between unavailable tier data and an explicit no-tier result. No actionable merge risk remains.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 1 functions across 2 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: preserving absent OAuth plan fields in the CLI projection.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
  • Fix all pre-merge checks with AI
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create a new PR

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions

Copy link
Copy Markdown
Contributor

Deterministic PR hygiene checks passed.

@github-actions github-actions Bot added bug Something isn't working review-ready labels Sep 18, 2026
@github-actions
github-actions Bot marked this pull request as ready for review September 18, 2026 00:25
@github-actions

github-actions Bot commented Sep 18, 2026

Copy link
Copy Markdown
Contributor

✅ READY

  • all PR quality gates passed; the review readiness checklist is complete.

Review readiness checklist

  • ✅ All CI tests are green on my local testing.
  • ✅ I pushed my PR to the latest dev commit.
  • ✅ I resolved all correct Codex and CodeRabbit findings.
  • ✅ My PR is ready for review.

4/4 boxes ticked.

This pull request is already Ready for Review.
The review-ready label marks this PR as ready; review automation runs independently.
Maintainers: @lidge-jun @Ingwannu

@lidge-jun

Copy link
Copy Markdown
Owner

리뷰 · 우선순위 72 / 80

이 PR은 ocx account list --json OAuth 투영이 plan 키의 “없음”과 “명시적 null”을 한쪽으로 뭉개던 버그를 고칩니다. 지금 dev(e80e571f63, package 2.59.0, tip #4984)의 src/cli/account-api.ts fetchOAuthRowsplan: a.plan ?? null로 씁니다. 프록시가 tier를 아예 안 보내던 옛 응답(키 부재)과, tier를 조회했는데 값이 없는 응답(plan: null)이 둘 다 JSON에 "plan": null로 나갑니다. 다운스트림이 “키 없음 = 옛 프록시”로 버전을 가늠하면 잘못된 신호를 읽습니다. 행 타입 자체는 이미 plan?: string | null(#3777)이라 부재를 허용합니다.

고침은 한 줄 계약입니다. Object.hasOwn(a, "plan")일 때만 { plan: a.plan }을 펼치고, 없으면 키를 만들지 않습니다. null"max" 같은 실제 값은 그대로 통과합니다. Object.hasOwn은 tip의 adapters/vision 등에서 이미 쓰는 존재 검사라 런타임 전제와 맞습니다. 회귀는 tests/cli/cli-dto-fidelity.test.ts에 넣었습니다. 본문 설명대로 tests/cli/cli-account.test.ts는 file-size-ratchet 상한에 걸려 키울 수 없고, “API가 준 필드를 CLI가 버린다” 계열 결함의 집이 이 fidelity 파일입니다. fetchRows/AccountDeps는 이미 export되어 있어 테스트 import도 tip과 맞습니다.

types.ts/config.ts 스플릿과 무관하고, 같은 주제의 열린 중복 PR은 보이지 않습니다. review-ready 라벨이 붙어 있고 checklist도 채워져 있습니다. 점수는 높게 잡되 80 근처는 아닙니다. 변경량이 작고 정확하지만, tip보다 앞선 base(ad9eab393)라 랜딩 시 tip 흡수·fork CI(macos #4905)만 보면 됩니다. Preview deploy는 계획에 없습니다.

src/cli/account-api.ts (fetchOAuthRows plan 투영) - a.plan ?? null → hasOwn 스프레드. tip 버그 경로와 정확히 대응합니다. 다른 family(codex/api-key) plan 필드는 이 경로가 아니니 범위도 맞습니다.
tests/cli/cli-dto-fidelity.test.ts - absent / null / tier 세 갈래를 한 describe에 묶었습니다. stub fetchImplResponse.json({ activeAccountId: null, accounts })만 돌려 네트워크 없이도 재현됩니다.
경로/심볼 AccountRow.plan - 타입은 optional+null 허용. 수정 후 “키 없음”이 타입·JSON 양쪽에서 유지되는지, 테이블 렌더(formatAccountTable)가 undefined plan을 깨지 않는지만 랜딩 전 smoke로 보면 충분합니다.

메인테이너의 판단이 필요한 지점

  • tip rebase를 기여자에게 맡길지, 랜딩 기차에서 흡수할지(충돌 표면은 사실상 이 한 줄).
  • JSON 출력 계약 변경(없던 키가 생기던 버그 수정)을 changelog에 한 줄 넣을지.

너의 추천

머지하세요. 작은 정정이고 테스트가 계약을 잠급니다. tip에 올린 뒤 Cross-platform/로컬 게이트만 확인하면 됩니다. 라벨은 바꾸지 마세요.

이 댓글은 grok-bot이 작성했습니다

@lidge-jun

Copy link
Copy Markdown
Owner

Merging with one macOS red that is a known dev regression rather than anything in this change.

The only failure at this head is Codex history injection preflight on a WAL store with no live writer > reaches a verdict on a cleanly-closed WAL store rather than the catch-all refusal, an 8ms assertion on macos 1/2. It comes from #4957, which landed with full Linux and all-nine-Windows-shard evidence and a macOS gap in its one platform-dependent case. A dedicated lane owns the fix. Everything else at this head is green.

That failure is deterministic and fast, so it is distinguishable from the timeout and cancellation pattern tracked in #4956; I am treating fast assertions as real results and timeouts as the known defect, rather than waving both through.

@lidge-jun
lidge-jun merged commit 4c0124a into lidge-jun:dev Sep 18, 2026
28 of 31 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working review-ready

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants