Skip to content

feat(providers): add Qwen Cloud individual token-plan provider - #2361

Merged
steipete merged 24 commits into
steipete:mainfrom
umutkeltek:feat/qwen-cloud-provider
Jul 28, 2026
Merged

feat(providers): add Qwen Cloud individual token-plan provider#2361
steipete merged 24 commits into
steipete:mainfrom
umutkeltek:feat/qwen-cloud-provider

Conversation

@umutkeltek

@umutkeltek umutkeltek commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds Qwen Cloud's individual Token Plan as a first-class CodexBar provider.

  • Shows the 5-hour and weekly usage windows, reset times, tier limits, and active plan.
  • Integrates with the menu card, configurable menu-bar layout, CLI, widget, and provider settings.
  • Uses provider ID .qwencloud and CLI name qwen-cloud (qwencloud, qwen, and
    qwen-token-plan are aliases).

Current request flow

  1. Resolve the Qwen session from a Chrome cookie import, a manual Cookie header, or
    QWEN_CLOUD_COOKIE.
  2. Load home.qwencloud.com to resolve sec_token, rejecting login pages and stale sessions.
  3. POST form-encoded requests to
    https://cs-data.qwencloud.com/data/api.json?action=IntlBroadScopeAspnGateway&product=sfm_bailian.
  4. Read the current dashboard APIs:
    • zeldaHttp.apikeyMgr./tokenplan/personal/api/v2/usage
    • zeldaHttp.apikeyMgr./tokenplan/personal/api/v2/subscription
    • zeldaHttp.apikeyMgr./tokenplan/personal/api/v2/quota-config
  5. Parse the nested/stringified OneConsole envelopes into CodexBar's standard primary and
    secondary rate windows.

Automatic browser import intentionally defaults to Chrome only, avoiding unrelated browser and
Keychain prompts. Sessions from other browsers can still be supplied through a manual Cookie
header or QWEN_CLOUD_COOKIE.

Shared OneConsole hardening

The final head consolidates the OneConsole behavior shared by Qwen Cloud, Alibaba Coding Plan,
and Alibaba Token Plan while retaining provider-specific authentication and endpoint rules.

  • Extracts shared cookie import, cookie-header, JSON traversal, and sec_token helpers.
  • Passes each provider's authentication predicate through the Chromium fallback.
  • Keeps redirect behavior Qwen-local instead of changing the generic HTTP client.
  • Requires HTTPS, rejects URL userinfo and untrusted origins/ports, strips cross-origin
    credentials, and blocks cross-origin 307/308 body forwarding.
  • Preserves cookies on trusted overridden-host redirects.
  • Treats login HTML and a missing sec_token as loginRequired.
  • Preserves JSON key priority and skips invalid values while continuing nested traversal.
  • Allows valid environment/manual Qwen cookies through the non-macOS CLI web-support gate.

Verification on final head b5f9b6cf

  • make check — passed; SwiftFormat reports 0/1,601 files requiring changes and strict
    SwiftLint reports 0 violations across 1,600 files.
  • swift test --filter 'AlibabaCodingPlan|AlibabaTokenPlan|QwenCloud|OneConsole'
    127 tests in 24 suites passed; the environment-guarded live Qwen smoke test was skipped.
  • swift test --filter 'QwenCloud|sourceModeRequiresWebSupportAllowsQwenCookiesOnLinuxGate'
    29 Qwen tests in 7 suites plus the focused CLI gate test passed.
  • git diff --check — passed.
  • Public added-lines and commit-message redact scans — no findings.

A full make test run was also attempted with the Xcode toolchain and SDK pinned coherently.
It reached 49/61 passing shards. Shard 50 then failed only in untouched SpendDashboard suites
with date-window assertions where totalCost was nil; the standalone
SpendDashboardControllerTests reproduces 10 of those failures outside this provider diff.
This PR does not modify SpendDashboard.

No live provider request, browser-cookie import, or real Keychain read was run during this
hardening pass.

Historical real-account proof

The live endpoint contract was verified on July 22, 2026 at head 6026fd0a with a packaged,
Developer ID-signed build and the contributor's Qwen Cloud account. The build:

  • selected the contributor's cached Brave session;
  • loaded the Qwen dashboard and resolved sec_token;
  • received HTTP 200 JSON responses from the usage, subscription, and quota-config APIs on
    cs-data.qwencloud.com;
  • parsed both the 300-minute and 10,080-minute windows and their plan limits; and
  • rendered the result in CodexBar without repeated Safe Storage prompts after one
    Always Allow approval.

Redacted CLI receipt:

$ CodexBarCLI usage --provider qwen-cloud --source web --json-only --log-level info
exit=0
provider=qwencloud
source=web
primary.windowMinutes=300
primary.usedPercent=<nonzero live value redacted>
primary.limit=3,000 credits
primary.resetsAt=<future account timestamp redacted>
secondary.windowMinutes=10080
secondary.usedPercent=<nonzero live value redacted>
secondary.limit=10,000 credits
secondary.resetsAt=<future account timestamp redacted>

Redacted request-path receipt from the same run:

home.qwencloud.com dashboard -> 200 text/html
Qwen user-info -> 200 application/json; sec_token resolved
cs-data.qwencloud.com .../tokenplan/personal/api/v2/usage -> 200 application/json
cs-data.qwencloud.com .../tokenplan/personal/api/v2/subscription -> 200 application/json
cs-data.qwencloud.com .../tokenplan/personal/api/v2/quota-config -> 200 application/json

Cookie values and names, account identity, request IDs, exact usage, reset timestamps, and raw
response bodies remain redacted. The unredacted 495-byte JSON result recorded at the time had
SHA-256 68c4b1aa77a568c4661ca90d8e1b16d99aafb903157bf6c2f4e63d2a5b580b49.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 99a25394e8

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment on lines +54 to +57
return cookies.contains { cookie in
guard Self.recognizedSessionCookies.contains(cookie.name) else { return false }
let domain = cookie.domain.lowercased().trimmingCharacters(in: CharacterSet(charactersIn: "."))
return domain.hasSuffix("qwencloud.com")

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Do not treat locale cookies as sessions

With automatic import, this returns true for any recognized cookie on qwencloud.com; because the recognized set includes non-auth cookies like intl_locale (and account-id cookies without a ticket), a browser profile that merely visited Qwen Cloud can be selected before a later profile that is actually logged in. The fetch then sends only those cookies, gets loginRequired, clears/reimports the same profile, and the provider never reaches the valid session. Require an actual auth ticket/session cookie before returning true.

Useful? React with 👍 / 👎.

Comment on lines +18 to +21
if let scheme = URL(string: raw)?.scheme {
return scheme.lowercased() == "https" ? raw : nil
}
return raw

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Normalize bare QWEN_CLOUD_HOST values

When QWEN_CLOUD_HOST is configured as a bare host (for example qwen-cloud.test, the form accepted by QWEN_CLOUD_QUOTA_URL and the Alibaba token-plan host override), this returns the bare string. dashboardURL and defaultQuotaURL then build qwen-cloud.test/... URLs with no scheme/host, so endpoint-override tests or local proxies fail before making a request; normalize bare hosts to HTTPS before returning.

Useful? React with 👍 / 👎.

umutkeltek added a commit to umutkeltek/CodexBar that referenced this pull request Jul 21, 2026
…alize bare host overrides

Review follow-ups for steipete#2361:

- Cookie import now treats only login_aliyunid_ticket / qwen_sso_ticket as
  proof of an authenticated session. Locale prefs, account-id markers, and
  CSRF cookies scoped to qwencloud.com no longer select browser profiles
  that merely visited the site, which previously caused ticketless requests,
  loginRequired responses, and re-import loops.
- QWEN_CLOUD_HOST now accepts bare hosts (e.g. qwen-cloud.test or
  qwen-cloud.test:8443) and normalizes them to HTTPS via the shared
  endpoint-override validator, matching the Alibaba token-plan host
  override, so dashboard/quota URLs and the Origin header stay valid.
- Adds regression tests for both paths and documents the bare-host form.
@clawsweeper clawsweeper Bot added rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. P3 Low-risk cleanup, docs, polish, ergonomics, or speculative feature. merge-risk: 🚨 auth-provider 🚨 Merging this PR could break OAuth, tokens, provider routing, model choice, or credentials. labels Jul 21, 2026
@clawsweeper

clawsweeper Bot commented Jul 21, 2026

Copy link
Copy Markdown

Codex review: needs real behavior proof before merge. Reviewed July 28, 2026, 10:56 AM ET / 14:56 UTC.

ClawSweeper review

What this changes

This PR adds Qwen Cloud Token Plan usage tracking to CodexBar’s menu bar, CLI, widget, settings, and documentation, while extracting shared Aliyun OneConsole authentication and parsing helpers used by Qwen and Alibaba providers.

Merge readiness

Blocked until stronger real behavior proof is added - 5 items remain

Keep this PR open for maintainer review. The prior SEC-token transport-failure finding appears addressed at the current head, and the branch contains focused regression coverage, but this is still a large new provider plus shared authentication refactor without final-head real-account proof after the later redirect, importer, and token-error changes.

Priority: P2
Reviewed head: 2b44b6b1cef09d0eaec12ca9c524f0427cb64065
Owner decision: Required. See Decision needed.

Review scores

Measure Result What it means
Overall readiness 🦐 gold shrimp (3/6) The patch has strong focused test and review-follow-up signal, but merge readiness is capped by stale real-account proof for an authenticated provider integration.
Proof confidence 🦐 gold shrimp (3/6) Needs stronger real behavior proof before merge: The PR includes a convincing redacted real-account CLI receipt from July 22, 2026, but it predates later shared authentication, redirect, Chrome-only importer, and SEC-token failure changes; add redacted current-head terminal output, logs, or a recording before merge. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.
Patch quality 🐚 platinum hermit (4/6) No actionable review findings were identified.

Verification

Check Result Evidence
Real behavior Needs proof Needs stronger real behavior proof before merge: The PR includes a convincing redacted real-account CLI receipt from July 22, 2026, but it predates later shared authentication, redirect, Chrome-only importer, and SEC-token failure changes; add redacted current-head terminal output, logs, or a recording before merge. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.
Evidence reviewed 5 items Final-head follow-up: The current PR head is 2b44b6b, whose commit message and review response state that SEC-token dashboard timeout and HTTP 503 failures are retained as retryable network failures rather than becoming loginRequired and clearing cached cookies.
Prior finding addressed: The latest review thread identifies the prior P2 defect—collapsing dashboard transport or 5xx failures into loginRequired—and the author reports focused timeout and 503 regression coverage at the current head. No remaining line-level defect is established from the provided final-head review context.
Shared compatibility surface: The branch changes 55 files (+3,900/-761) and introduces shared Aliyun OneConsole cookie import, redirect routing, SEC-token resolution, and JSON traversal that Qwen Cloud and existing Alibaba providers use.
Findings None None.
Security None None.

How this fits together

CodexBar obtains provider usage from authenticated browser/manual credentials, converts provider responses into common usage windows, then exposes those windows through the menu bar, CLI, widget, and settings UI. This PR adds Qwen Cloud to that pipeline and moves common Aliyun OneConsole cookie, redirect, SEC-token, and JSON logic into shared provider infrastructure.

flowchart LR
    A[Browser or manual Qwen cookie] --> B[Qwen session import]
    B --> C[SEC token resolution]
    C --> D[Qwen Token Plan APIs]
    D --> E[Usage window parser]
    E --> F[Provider registry]
    F --> G[Menu bar CLI widget settings]
    H[Alibaba providers] --> I[Shared OneConsole helpers]
    I --> C
Loading

Decision needed

Question Recommendation
Should CodexBar accept Qwen Cloud Token Plan as a first-class supported provider, including ongoing ownership of the shared Aliyun OneConsole authentication surface? Sponsor the Qwen provider: Request final-head redacted live proof, then continue normal compatibility review with Qwen Cloud as a supported provider.

Why: The implementation adds new provider and credential configuration surface while also widening shared code used by Alibaba providers; technical review cannot determine whether that support commitment fits the maintainers’ product scope.

Before merge

  • Add real behavior proof - Needs stronger real behavior proof before merge: The PR includes a convincing redacted real-account CLI receipt from July 22, 2026, but it predates later shared authentication, redirect, Chrome-only importer, and SEC-token failure changes; add redacted current-head terminal output, logs, or a recording before merge. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.
  • Resolve merge risk (P1) - Merging changes shared OneConsole cookie, redirect, token, and parsing behavior used by existing Alibaba providers; the supplied focused tests reduce but do not eliminate compatibility risk.
  • Resolve merge risk (P1) - The only real-account receipt predates the later shared authentication, redirect, Chrome-only import, and SEC-token failure changes, so current-head authenticated behavior remains unproven.
  • Resolve merge risk (P1) - Adding a first-class Qwen Cloud provider and new credential configuration is a product-support commitment that needs maintainer sponsorship beyond patch correctness.
Agent review details

Security

None.

Review metrics

Metric Value Why it matters
Patch scope 55 files affected; 3,900 added, 761 removed The feature reaches every provider surface and refactors shared OneConsole behavior used by existing Alibaba providers.
Focused validation 127 focused Alibaba/Qwen/OneConsole tests reported The stated suite covers the new provider and adjacent shared-provider behavior, though it is supplemental to live proof.

Merge-risk options

Maintainer options:

  1. Add final-head live proof (recommended)
    Provide a redacted terminal receipt, runtime logs, or packaged-app recording from 2b44b6b that shows authenticated Qwen usage parsing after the final shared-authentication changes.
  2. Accept the proof gap
    Maintainers may merge based on the historical July 22 receipt and focused regressions while explicitly accepting that the final head was not rechecked against a live Qwen session.
  3. Pause provider support
    Close or defer the PR if maintainers do not want to take on the shared Aliyun OneConsole compatibility surface.

Technical review

Best possible solution:

If maintainers want Qwen Cloud as a supported core provider, retain the provider-specific boundaries and land it only after a redacted current-head authenticated CLI or packaged-app receipt confirms successful 5-hour and weekly window parsing without exposing cookies, account identity, request IDs, IP addresses, or private endpoints.

Do we have a high-confidence way to reproduce the issue?

Not applicable: this PR introduces an optional provider rather than fixing an established broken behavior. The supplied current-head test evidence is source-level validation, while real authenticated Qwen behavior is only evidenced at an earlier July 22, 2026 head.

Is this the best way to solve the issue?

Unclear: the provider follows CodexBar’s existing descriptor, settings, CLI, widget, and provider-documentation patterns, but the broad shared OneConsole refactor and the product decision to support Qwen Cloud require maintainer confirmation before this is the best long-term path.

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning high; reviewed against 02b4ba278c81.

Labels

Label justifications:

  • P2: This is a useful optional provider addition with bounded but cross-provider compatibility implications.
  • merge-risk: 🚨 compatibility: Shared OneConsole importer, cookie-header, redirect, token, and JSON helpers now affect existing Alibaba provider paths.
  • merge-risk: 🚨 auth-provider: The diff handles browser cookie selection, manual cookies, SEC tokens, credential forwarding, login classification, and cached-session recovery.
  • rating: 🦐 gold shrimp: Overall readiness is 🦐 gold shrimp; proof is 🦐 gold shrimp and patch quality is 🐚 platinum hermit.
  • status: 📣 needs proof: The PR needs real behavior proof before ClawSweeper can clear the contributor ask. Needs stronger real behavior proof before merge: The PR includes a convincing redacted real-account CLI receipt from July 22, 2026, but it predates later shared authentication, redirect, Chrome-only importer, and SEC-token failure changes; add redacted current-head terminal output, logs, or a recording before merge. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.

Evidence

What I checked:

Likely related people:

  • steipete: The project owner is present in the PR timeline, authored the branch’s merge-from-main integration commit, and is the best available decision owner for accepting a new first-class provider and its shared authentication surface. (role: recent reviewer and integration contributor; confidence: medium; commits: 7d1d43deec6d; files: Sources/CodexBarCore/Providers/Shared/AliyunOneConsole/OneConsoleSECTokenResolver.swift, Sources/CodexBarCore/Providers/QwenCloud/QwenCloudProviderDescriptor.swift)
  • umutkeltek: Authored the Qwen provider and the shared OneConsole changes across the PR, including the current SEC-token failure-preservation follow-up. (role: feature implementer; confidence: high; commits: df2366945464, b5f9b6cfaeb1, 2b44b6b1cef0; files: Sources/CodexBarCore/Providers/QwenCloud/QwenCloudUsageFetcher.swift, Sources/CodexBarCore/Providers/Shared/AliyunOneConsole/OneConsoleSECTokenResolver.swift)

Rank-up moves

Optional improvements that raise the rating; they are not merge blockers.

  • Add redacted real-account evidence from the current head showing the Qwen 5-hour and weekly windows.
  • Obtain maintainer confirmation that Qwen Cloud belongs in CodexBar’s supported provider set.

Rating scale

Score Internal tier Crab rank Meaning
6/6 S 🦀 challenger crab Exceptional readiness
5/6 A 🦞 diamond lobster Very strong readiness
4/6 B 🐚 platinum hermit Good normal PR; ordinary maintainer review
3/6 C 🦐 gold shrimp Useful, but confidence is limited
2/6 D 🦪 silver shellfish Proof or implementation needs work
1/6 F 🧂 unranked krab Not merge-ready
N/A NA 🌊 off-meta tidepool Rating does not apply

Overall follows the weaker of proof and patch quality.
Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics.

Workflow

  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.

History

Review history (3 earlier review cycles)
  • reviewed 2026-07-21T02:36:05.788Z sha a266bc3 :: needs real behavior proof before merge. :: none
  • reviewed 2026-07-28T01:22:58.680Z sha 529cc6c :: needs real behavior proof before merge. :: none
  • reviewed 2026-07-28T07:18:39.933Z sha 7d1d43d :: needs real behavior proof before merge. :: [P2] Propagate sec-token transport failures

Add a fully-wired "Qwen Cloud" provider that tracks the individual token
plan subscription on https://home.qwencloud.com/billing/subscription/token-plan-individual
(the plan that grants hosted Claude access), alongside all existing settings.

Qwen Cloud shares the Aliyun one-console auth + BssOpenAPI gateway used by
the Alibaba token plan, so it reuses that parser/cookie plumbing:

- New provider `.qwencloud` (CLI name `qwen-cloud`, aliases qwencloud/qwen/
  qwen-token-plan) with descriptor, web fetch strategy, monochrome icon, and
  a curated confetti palette.
- QwenCloudUsageFetcher posts form-encoded GetSubscriptionSummary
  (BssOpenAPI-V3, productCode sfm_tokenplansolo_public_intl) after resolving
  sec_token from the dashboard HTML, the sec_token cookie, or /tool/user/info.json.
- URL-scoped cookie headers for qwencloud.com plus a browser cookie importer
  over the qwencloud/alibabacloud/aliyun passport domains.
- Settings UI (cookie source picker + manual Cookie header + "Open Token Plan"
  link), CLI (`codexbar usage --provider qwen-cloud`), diagnostics, widget,
  and docs (docs/qwen-cloud.md, README, providers.md, configuration.md).
- Generalized AlibabaCodingPlanCookieImporter.importSession to accept a
  provider-specific domain list + session validator so Qwen Cloud can reuse it;
  the existing Alibaba behavior is unchanged (delegates with its own defaults).
- Extended the Alibaba token-plan parser to read nested EquityList quota fields
  (CycleTotalValue/CycleSurplusValue/EndTime) without changing existing results.

Tests: parser/snapshot/cookie-header/stub-fetch/import-validation suites plus
an opt-in live smoke test (disabled by default; gated on QWEN_CLOUD_LIVE_TEST=1
and QWEN_CLOUD_COOKIE) so CI never touches the network or Keychain.
…alize bare host overrides

Review follow-ups for steipete#2361:

- Cookie import now treats only login_aliyunid_ticket / qwen_sso_ticket as
  proof of an authenticated session. Locale prefs, account-id markers, and
  CSRF cookies scoped to qwencloud.com no longer select browser profiles
  that merely visited the site, which previously caused ticketless requests,
  loginRequired responses, and re-import loops.
- QWEN_CLOUD_HOST now accepts bare hosts (e.g. qwen-cloud.test or
  qwen-cloud.test:8443) and normalizes them to HTTPS via the shared
  endpoint-override validator, matching the Alibaba token-plan host
  override, so dashboard/quota URLs and the Origin header stay valid.
- Adds regression tests for both paths and documents the bare-host form.
…ption response

Captures a real-world subscription-summary response from
home.qwencloud.com for an authenticated account with no active
individual token-plan subscription (TotalCount=0, zeroed quota fields).
The API returns HTTP 200 with Success=true rather than an error, so the
parser must not report a false subscription or synthesize a 100% bar.

Documents the actual contract encountered in production so future
parser changes can be checked against it. Verified end-to-end:

    $ codexbar usage --provider qwen-cloud --source web --log-level verbose
    -> Cookie cache hit
    -> dashboard HTML 200 (18 kB)
    -> /tool/user/info.json 200 (sec_token resolved)
    -> GetSubscriptionSummary 200 (451 B, TotalCount=0)

Parser yields an empty primary window (no false quota) and an identity
loginMethod of "TOKEN PLAN", matching the user-visible label.

Complements the existing TotalCount=1 / TotalValue>0 fixtures.
@umutkeltek
umutkeltek force-pushed the feat/qwen-cloud-provider branch from a266bc3 to d6a1184 Compare July 21, 2026 16:28
@umutkeltek

Copy link
Copy Markdown
Contributor Author

Redacted verbose log (codexbar usage --provider qwen-cloud --source web --log-level verbose)

2026-07-21T18:15:33+0300 debug com.steipete.codexbar.cookie-cache: provider=qwencloud [CodexBarCore] Cookie cache hit
2026-07-21T18:15:33+0300 debug com.steipete.codexbar.cookie-cache: provider=qwencloud [CodexBarCore] Cookie cache hit
2026-07-21T18:15:33+0300 info com.steipete.codexbar.qwen-cloud: apiCookieNames=<REDACTED> dashboardCookieNames=<REDACTED> hasSecToken=0 source=Brave Default [CodexBarCore] Qwen Cloud using cached browser cookie header
2026-07-21T18:15:34+0300 info com.steipete.codexbar.qwen-cloud: bodyBytes=18198 contentType=text/html;charset=UTF-8 status=200 [CodexBarCore] Qwen Cloud HTTP response
2026-07-21T18:15:34+0300 info com.steipete.codexbar.qwen-cloud: bodyBytes=317 contentType=application/json status=200 [CodexBarCore] Qwen Cloud HTTP response
2026-07-21T18:15:34+0300 info com.steipete.codexbar.qwen-cloud: [CodexBarCore] Resolved Qwen Cloud sec_token from user info
2026-07-21T18:15:34+0300 info com.steipete.codexbar.qwen-cloud: apiCookieNames=<REDACTED> apiHost=home.qwencloud.com hasCSRF=0 secTokenSource=user-info [CodexBarCore] Fetching Qwen Cloud usage
2026-07-21T18:15:34+0300 info com.steipete.codexbar.qwen-cloud: bodyBytes=451 contentType=application/json status=200 [CodexBarCore] Qwen Cloud HTTP response
== Qwen Cloud (web) ==
Plan: Token Plan

Redacted raw subscription-summary response

{"requestId":"<REDACTED>","code":"200","message":null,"action":null,"apiName":null,"data":{"RequestId":"<REDACTED>","Message":"Successful!","Data":{"Uid":<REDACTED>,"TotalSurplusValue":"0","TotalCount":0,"TotalValue":"0","ProductCode":"sfm_tokenplansolo_public_intl"},"Code":"Success","Success":true},"httpStatusCode":"200","accessDeniedDetail":null,"extendedCode":null,"successResponse":true}```

Copy link
Copy Markdown
Contributor Author

@codex review
@clawsweeper re-review

Updated head 9085e05f replaces the obsolete Qwen subscription-summary usage path with the current 5-hour/weekly token-plan APIs, adds tier limits and customizable menu-bar window support, and records final-head Qwen, MenuBarLayout, ProvidersPane, AlibabaTokenPlan, make check, packaging, and redaction evidence in the PR body.

@clawsweeper

clawsweeper Bot commented Jul 22, 2026

Copy link
Copy Markdown

🦞🧹
ClawSweeper re-review requested.

I asked ClawSweeper to review this item again.
Action: item re-review queued (workflow sweep.yml, event repository_dispatch).
Result: the existing ClawSweeper review comment will be edited in place when the review finishes.

Re-review progress:

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 9085e05f21

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment on lines +14 to +19
.chromeBeta,
.brave,
.edge,
.arc,
.firefox,
.safari,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Keep Qwen auto imports Chrome-only by default

In Auto mode this default import order probes Chrome Beta/Brave/Edge/Arc/Firefox/Safari as soon as Chrome lacks a usable Qwen cookie, which can trigger extra browser/Keychain prompts for a new provider. The repo guidance says cookie imports should default Chrome-only when possible; please keep Qwen to Chrome by default and make broader browser lists opt-in.

AGENTS.md reference: AGENTS.md:L48-L48

Useful? React with 👍 / 👎.

Comment on lines 222 to 225
guard let fallbackSession = try AlibabaChromiumCookieFallbackImporter.importSession(
browser: browser,
domains: self.cookieDomains,
domains: domains,
logger: logger)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Use Qwen auth rules in Chromium fallback

When the generic importer falls back to the locked Chromium DB path, this call still uses AlibabaChromiumCookieFallbackImporter.importSession, whose own private session check requires both login_aliyunid_ticket and an Aliyun account cookie before it returns. For Qwen SSO profiles that only have qwen_sso_ticket (accepted by QwenCloudCookieImport.authTicketCookies), the fallback returns nil before the provider-specific predicate below can accept it, so Auto import fails even though a valid Qwen session is present; pass the provider auth predicate into the fallback importer or return candidate cookies for the outer check.

Useful? React with 👍 / 👎.

supportsTokenCost: false,
noDataMessage: { "Qwen Cloud cost summary is not supported." }),
fetchPlan: ProviderFetchPlan(
sourceModes: [.auto, .web],

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Allow cookie-supplied Qwen CLI on non-macOS

With this provider registered as web-only here, the CLI's non-macOS preflight treats auto/web as requiring browser support and returns the unsupported-web response before QwenCloudWebFetchStrategy.isAvailable can use QWEN_CLOUD_COOKIE or a manual cookie. That makes codexbar usage qwen-cloud unusable on Linux/CI even when the user supplies the cookie that the fetcher explicitly supports; add a sourceModeRequiresWebSupport exception like the other manual-cookie providers.

Useful? React with 👍 / 👎.

@umutkeltek

Copy link
Copy Markdown
Contributor Author

Fixed the Qwen Cloud DataV2 runtime failure at head 008dc97.

Root cause: the request sent cornerstoneParam.consoleSite=MODELSTUDIO_ALBABACLOUD, while Qwen Cloud's current public dashboard client requires QWENCLOUD. The gateway still returned HTTP 200 with a DataV2 envelope, but without the token-plan usage fields, which produced the reported “Missing token plan data” error.

Added a request-contract regression at the public fetchUsage seam and changed the production context to QWENCLOUD.

Verification:

  • swift test --filter QwenCloud — 26 tests passed; guarded live smoke skipped
  • swift test --filter 'MenuBarLayout|ProvidersPaneCoverageTests|AlibabaTokenPlan' — 85 tests passed
  • make check — passed, including SwiftFormat and strict SwiftLint with 0 violations
  • package_app.sh — passed; fresh bundle launched from this branch checkout
  • redact scan — no findings

No live provider probe, browser-cookie import, or Keychain read was run.

@codex review
@clawsweeper re-review

@clawsweeper

clawsweeper Bot commented Jul 22, 2026

Copy link
Copy Markdown

🦞🧹
ClawSweeper re-review requested.

I asked ClawSweeper to review this item again.
Action: item re-review queued (workflow sweep.yml, event repository_dispatch).
Result: the existing ClawSweeper review comment will be edited in place when the review finishes.

Re-review progress:

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 008dc97428

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

guard url.scheme?.lowercased() == "https" else { return nil }

var mutable = request
let originalHost = self.dashboardURL.host ?? "home.qwencloud.com"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P3 Badge Preserve cookies across overridden-host redirects

When fetchUsage is exercised with QWEN_CLOUD_HOST/QWEN_CLOUD_QUOTA_URL pointing at a test or proxy host, any same-host HTTPS redirect is compared against the process-default dashboard host instead of the host from the current fetch environment/request. In those override runs, the redirect helper treats the redirected request as cross-host and strips the Cookie header, so a harmless canonical/locale redirect on the overridden endpoint can make the sec-token preflight or API call look logged out.

Useful? React with 👍 / 👎.

@umutkeltek

Copy link
Copy Markdown
Contributor Author

Follow-up fix pushed in 6026fd0 after testing against the current Brave session shape.

  • Brave stores the authenticated Qwen session as login_qwencloud_ticket on .qwencloud.com; the importer now accepts it alongside the legacy/federated ticket names.
  • Token-plan API calls now use https://cs-data.qwencloud.com/data/api.json; dashboard requests remain on home.qwencloud.com.
  • swift test --filter QwenCloud: 27 tests passed across 7 suites.
  • make check: passed; SwiftFormat clean and SwiftLint reported 0 violations.
  • make test: 48 shards passed. Shard 49 reproduced the same 10 date-sensitive SpendDashboardControllerTests failures already confirmed on unchanged origin/main; Qwen tests were not implicated.
  • Public diff redaction scan: no findings.

@umutkeltek

Copy link
Copy Markdown
Contributor Author

Live real-account proof is now included in the PR body.

The final packaged, stable-signed PR build successfully used the current Brave session, resolved the Qwen sec_token, received HTTP 200 JSON responses from the live usage/subscription/quota-config APIs on cs-data.qwencloud.com, and parsed both the 300-minute and 10,080-minute rate windows with their tier limits. The contributor also confirmed the menu result and that the Safe Storage prompt stopped repeating after one Always Allow approval.

Exact account usage, reset timestamps, cookie data, identity, request IDs, and response bodies remain redacted. The final-head shared Alibaba path was rechecked: 37 tests in 8 suites passed.

@clawsweeper re-review

@clawsweeper

clawsweeper Bot commented Jul 22, 2026

Copy link
Copy Markdown

🦞🧹
ClawSweeper re-review requested.

I asked ClawSweeper to review this item again.
Action: item re-review queued (workflow sweep.yml, event repository_dispatch).
Result: the existing ClawSweeper review comment will be edited in place when the review finishes.

Re-review progress:

… shared OneConsole type

The Qwen Cloud provider already piggybacks on AlibabaCodingPlanCookieImporter's generic importSession(browserDetection:domains:isAuthenticatedSession:logPrefix:sessionLabel:logger:) entry point. Today that generic overload lives inside the Alibaba module path, which makes the shared-ness implicit and forces Qwen to reach into a sibling provider's namespace.

Move the generic implementation -- SessionInfo, importSession, hasSession, cookieImportCandidates, matchesCookieDomain, normalizeCookieDomain -- into a new Providers/Shared/AliyunOneConsole/AliyunOneConsoleCookieImporter.swift. Keep AlibabaCodingPlanCookieImporter as a thin Alibaba-specific wrapper that declares the cookie domains and ticket predicate, and re-export SessionInfo as a typealias so existing call sites compile unchanged.

QwenCloudCookieImporter now calls AliyunOneConsoleCookieImporter directly instead of going through the Alibaba namespace.

The Alibaba-specific Chromium fallback importer (AlibabaChromiumCookieFallbackImporter) stays in the Alibaba module because it carries Alibaba ticket-name knowledge. AliyunOneConsoleCookieImporter delegates to it.

No behavior change.

Verified:
- swift test --filter AlibabaCodingPlan: 58 tests passed
- swift test --filter AlibabaTokenPlan: 37 tests passed
- swift test --filter QwenCloud: 27 tests passed
- make check: 0 violations
…ba + Qwen copies

AlibabaTokenPlanCookieHeaders and QwenCloudCookieHeaders are byte-for-byte identical apart from the two cached-header name constants. The HTTPCookie -> scoped-Cookie-header builder (matchesRequestURL, cookieSortKey, by-name merge) and the duplicated '[String].uniquedSorted()' extension also live in both provider files.

Promote a generic OneConsoleCookieHeaders and OneConsoleCookieHeaderBuilder under Providers/Shared/AliyunOneConsole/. Each provider declares its cache namespace (alibaba_token_plan, qwen_cloud) via a typed initializer on the shared struct and routes cached-header round-trips through it.

AlibabaTokenPlanCookieHeaders and QwenCloudCookieHeaders become typealiases of OneConsoleCookieHeaders, so all existing call sites continue to compile. The cached-header initializer argument is now namespaced (alibabaTokenPlanCachedHeader:, qwenCloudCachedHeader:) to avoid the collision that would otherwise require the same init? across two extensions.

Drop the three duplicate '[String].uniquedSorted()' fileprivate extensions (AlibabaTokenPlanProviderDescriptor, AlibabaTokenPlanUsageFetcher, QwenCloudProviderDescriptor, QwenCloudUsageFetcher) now that the shared type owns one copy.

No behavior change.

Verified:
- swift test --filter AlibabaCodingPlan: 58 tests passed
- swift test --filter AlibabaTokenPlan: 37 tests passed
- swift test --filter QwenCloud: 27 tests passed
- make check: 0 violations
expandEmbeddedJSON, findObject, number, percentagePoints, and date parsing live as private statics in QwenCloudUsageFetcher, with near-identical implementations duplicated in AlibabaCodingPlanUsageFetcher and AlibabaTokenPlanUsageFetcher.

Pull them into Providers/Shared/AliyunOneConsole/OneConsoleJSON.swift and route QwenCloudUsageFetcher through the shared helpers. AlibabaCodingPlan and AlibabaTokenPlan migrate in follow-up commits so this one stays a pure refactor.

This commit only refactors QwenCloudUsageFetcher; it preserves the existing recursive shape (findObject returns the first dictionary whose keys overlap any of the search set) so all 27 QwenCloud tests continue to pass without modification.

No behavior change.

Verified:
- swift test --filter QwenCloud: 27 tests passed
- make check: 0 violations
Dashboard HTML extraction, user-info JSON fallback, and sec_token cookie lookup live as private statics in QwenCloudUsageFetcher (172 lines) with near-identical logic in AlibabaCodingPlanUsageFetcher (90+ lines).

Pull the chain into Providers/Shared/AliyunOneConsole/OneConsoleSECTokenResolver.swift. Providers configure the chain via Configuration: dashboardURL closure, userInfoPath, loginPageSniffers, and any extra HTML regex patterns they want to try.

QwenCloudUsageFetcher now declares a single static resolver and routes through it. The previous 172-line block (resolveSECSessionToken + fetchSECSessionTokenFromDashboard + fetchSECSessionTokenFromUserInfo + extractSECSessionToken + matchFirstGroup + secTokenCookieValue + looksLikeLoginPage) collapses to one call. The source label (dashboard-html / cookie / user-info) is preserved so existing log metadata is unchanged.

AlibabaCodingPlan and AlibabaTokenPlan migrate in follow-up commits so this one stays a pure refactor.

No behavior change.

Verified:
- swift test --filter AlibabaCodingPlan: 58 tests passed
- swift test --filter AlibabaTokenPlan: 37 tests passed
- swift test --filter QwenCloud: 27 tests passed
- make check: 0 violations
Move the five Qwen Cloud parser-response JSON blobs into Tests/CodexBarTests/Fixtures/QwenCloud/*.json so reviewers can replay the captured payloads offline and the test file no longer carries inline 60-line response fixtures.

Fixture loader uses Bundle.module.url(forResource:withExtension:subdirectory:), the same pattern already in use by AgentSessionParserTests and ModelsDevPricingTests.

The no_active_subscription.json fixture is the live captured response from PR steipete#2361; it guards against the parser reporting a false 100% remaining bar on authenticated accounts without an active token plan.

Verified:
- swift test --filter QwenCloud: 27 tests passed
- make check: 0 violations
Add an Aliyun OneConsole family section to docs/providers.md that lists the
shared plumbing under Sources/CodexBarCore/Providers/Shared/AliyunOneConsole/
and explains what each provider still owns vs what it reuses.

This gives the next OneConsole-based provider (Tongyi, Bailian China, …) a
single place to learn the integration shape.

No code change.

Verified:
- make check: 0 violations
@umutkeltek

Copy link
Copy Markdown
Contributor Author

Final head b5f9b6cf is pushed and the PR body now records the current implementation and evidence.

All six prior actionable review threads are addressed:

  • authenticated-ticket validation;
  • bare-host HTTPS normalization;
  • Chrome-only automatic imports;
  • provider-specific auth rules in the Chromium fallback;
  • environment/manual cookie support through the non-macOS CLI gate; and
  • override-aware trusted redirect routing.

Additional hardening covers cross-origin credential/body forwarding, login-page and missing-token
classification, JSON key priority, provider-neutral importer errors, fixture sanitization, and the
shared OneConsole extraction.

Final-head verification:

  • make check passed with 0 format changes and 0 SwiftLint violations;
  • 127 Alibaba/Qwen/OneConsole tests in 24 suites passed;
  • the focused Qwen plus non-macOS CLI gate run passed;
  • git diff --check passed; and
  • public redaction scans reported no findings.

The full-suite SpendDashboard host-baseline failure is documented precisely in the PR body and is
outside this provider diff.

@codex review
@clawsweeper re-review

@clawsweeper

clawsweeper Bot commented Jul 28, 2026

Copy link
Copy Markdown

🦞👀
ClawSweeper picked this up.

Command router queued. I will update this comment with the next step.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: b5f9b6cfae

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment on lines +73 to +77
static let browserOrder: BrowserCookieImportOrder = [
.chrome,
.chromeBeta,
.brave,
.edge,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Restrict Qwen automatic imports to Chrome

Because this browserOrder is passed to QwenCloudCookieImport.importSession, an automatic Qwen refresh still falls through to Chrome Beta/Brave/Edge/Arc/Firefox/Safari whenever Chrome has no valid session, even though the descriptor advertises Chrome-only import. In that scenario users can still get prompted for other browser cookie stores, which is the behavior the Chrome-only hardening was meant to avoid; keep the automatic order to [.chrome] unless an explicit override supplies more browsers.

AGENTS.md reference: AGENTS.md:L48-L48

Useful? React with 👍 / 👎.

@umutkeltek

Copy link
Copy Markdown
Contributor Author

Latest Codex P2 is fixed at head 529cc6c2.

  • Qwen automatic cookie refresh now uses Chrome only, matching the provider metadata and avoiding fallback prompts from Chrome Beta, Brave, Edge, Arc, Firefox, or Safari.
  • Explicit importer overrides can still opt into a broader browser order; manual and QWEN_CLOUD_COOKIE flows are unchanged.
  • Added a regression assertion for QwenCloudWebFetchStrategy.browserOrder == [.chrome] and verified it red-to-green.
  • swift test --filter QwenCloud: 29 tests in 7 suites passed.
  • make check: clean; SwiftLint reported 0 violations across 1,600 files.
  • make test: reproduced only the already-documented unrelated SpendDashboard baseline failure (13 issues in untouched SpendDashboard suites).

@codex review
@clawsweeper re-review

@clawsweeper

clawsweeper Bot commented Jul 28, 2026

Copy link
Copy Markdown

🦞👀
ClawSweeper picked this up.

Command router queued. I will update this comment with the next step.

@clawsweeper clawsweeper Bot added rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. P2 Normal priority bug or improvement with limited blast radius. merge-risk: 🚨 compatibility 🚨 Merging this PR could break existing users, config, migrations, defaults, or upgrades. and removed rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. P3 Low-risk cleanup, docs, polish, ergonomics, or speculative feature. labels Jul 28, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 529cc6c248

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

@clawsweeper clawsweeper Bot added rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. and removed rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. labels Jul 28, 2026
@clawsweeper clawsweeper Bot added rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. and removed rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. labels Jul 28, 2026
@steipete
steipete merged commit 83a7fd3 into steipete:main Jul 28, 2026
9 checks passed
@steipete

Copy link
Copy Markdown
Owner

Merged after full verification. Qwen Cloud Individual Token Plan lands as a first-class provider (owner decision), with the shared OneConsole parser repaired during review: date-only yyyy-MM-dd parsing and numeric-0-as-nil sentinel behavior were restored with regressions, so existing Alibaba Token Plan behavior is preserved (138 focused tests + full Alibaba/Qwen/OneConsole suites green). Host-scoped cookie handling was verified — no cross-host cookie unions. The contributor changelog edit was dropped per repo policy. Exact-head CI fully green (https://github.com/steipete/CodexBar/actions/runs/30387148051). Live proof: the author's earlier real-account run plus a second user's browser-schema confirmation on #2328; exact-head live confirmation requested from users on the next release. Thanks @umutkeltek — excellent first contribution!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

merge-risk: 🚨 auth-provider 🚨 Merging this PR could break OAuth, tokens, provider routing, model choice, or credentials. merge-risk: 🚨 compatibility 🚨 Merging this PR could break existing users, config, migrations, defaults, or upgrades. P2 Normal priority bug or improvement with limited blast radius. rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants