Skip to content

Add Alibaba Coding Plan provider with web/API support#453

Closed
jnd0 wants to merge 7 commits intosteipete:mainfrom
jnd0:feature/alibaba-coding-plan-provider
Closed

Add Alibaba Coding Plan provider with web/API support#453
jnd0 wants to merge 7 commits intosteipete:mainfrom
jnd0:feature/alibaba-coding-plan-provider

Conversation

@jnd0
Copy link
Contributor

@jnd0 jnd0 commented Mar 1, 2026

Summary

  • Add a new Alibaba provider (displayed as Alibaba / CLI alibaba-coding-plan) with full registry wiring, settings UI, icon, docs, and test coverage.
  • Implement Alibaba Coding Plan usage fetching via console RPC web flow (cookie session + sec_token + form-encoded params) with API-key fallback, intl/cn region handling, and resilient payload parsing for nested DataV2 structures.
  • Fix a root-cause bug in CookieHeaderNormalizer where -b regex matching could trigger inside cookie values (e.g. ...-Br...), truncating manual Cookie headers and causing false ConsoleNeedLogin failures.

What changed

  • New provider implementation
    • Added Alibaba provider core + app integration:
      • Sources/CodexBarCore/Providers/Alibaba/*
      • Sources/CodexBar/Providers/Alibaba/*
    • Registered provider in descriptor/implementation registries and enums:
      • UsageProvider.alibaba, IconStyle.alibaba
      • provider descriptor + settings snapshot + token resolver + env override wiring.
  • Fetch strategy + parsing
    • Added web strategy (auto/manual cookie) and API strategy.
    • Implemented console RPC request shape for intl/cn:
      • host/action/product/api query pattern (bailian-*-cs* host)
      • form body: params, region, sec_token
      • cornerstoneParam fields to mirror console calls.
    • Added SEC token resolution from dashboard HTML and /tool/user/info.json fallback.
    • Added robust response parsing for nested wrappers (data.DataV2.data.data) and quota fields.
    • Added conservative reset-date normalization for the 5-hour window to avoid immediate “resets now” churn when backend returns near-now timestamps.
    • Tightened inactive-plan behavior: synthetic fallback windows are no longer emitted for explicitly inactive statuses (e.g. EXPIRED).
  • Settings / UX
    • Added Alibaba settings fields/pickers (region, cookie source, manual cookie, API key).
    • Auto-enable provider when Alibaba token already exists at startup or when API key is set.
    • Ensured availability gating does not hide .auto cookie setups.
    • Added provider icon + docs (docs/alibaba-coding-plan.md, docs/providers.md).
  • Bug fix included in this PR
    • CookieHeaderNormalizer now anchors --cookie/-b pattern matching to command boundaries so cookie-value substrings no longer get misparsed.

Testing

  • swift test --filter AlibabaCodingPlan

  • ./Scripts/compile_and_run.sh

  • Manual validation against a live Alibaba Coding Plan account:

    • verified successful usage fetch (5-hour / weekly / monthly windows)
    • validated intl console RPC request/response alignment.

    Visual representation:

image

Implement Alibaba provider settings, region-aware console RPC parsing, tests, and docs; also fix cookie header normalization to avoid truncating values containing '-b', which caused false login-required failures for valid manual cookies.
Copy link

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

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: eb2cd354ea

ℹ️ 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 +39 to +43
let hasToken = !context.settings.alibabaCodingPlanAPIToken.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty
let hasManualCookie =
context.settings.alibabaCodingPlanCookieSource == .manual &&
!context.settings.alibabaCodingPlanCookieHeader.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty
return hasToken || hasManualCookie

Choose a reason for hiding this comment

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

P1 Badge Treat auto-cookie Alibaba setups as available

This availability check only returns true for API tokens, env cookies, or manual-cookie mode, so users who enable Alibaba with the default .auto cookie source and rely on browser cookie import are filtered out by enabledProviders() and never fetched. In that common setup the new web flow cannot run unless users also set an API key or manual cookie, which breaks the provider’s advertised auto web mode.

Useful? React with 👍 / 👎.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Addressed in 55d90b2: removed the strict app-side availability gate so Alibaba no longer gets filtered out for default .auto cookie mode. Auto-import setups now remain available and can fetch via web strategy as intended.

{
let source = instanceInfo ?? payload
let status = self.anyString(for: ["status", "instanceStatus"], in: source)?.uppercased()
guard status == "VALID" || status == "ACTIVE" || instanceInfo != nil else { return nil }

Choose a reason for hiding this comment

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

P2 Badge Require active status before creating fallback quota window

The fallback guard accepts any non-nil instanceInfo (|| instanceInfo != nil), so payloads with inactive plans (for example status: EXPIRED) still produce a synthetic fiveHourUsedQuota=0/fiveHourTotalQuota=100 snapshot when quota fields are missing. That reports an active-looking quota window for inactive plans instead of failing parsing, which can show incorrect usage state.

Useful? React with 👍 / 👎.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Addressed in 55d90b2: fallback now only synthesizes a quota window for active/valid (or unspecified) status, and no longer does so for explicitly inactive statuses like EXPIRED.

@jnd0
Copy link
Contributor Author

jnd0 commented Mar 1, 2026

Follow-up pushed in 352ea6b with final UX polish based on live validation:\n\n- keep countdown reset text (e.g. ) for Alibaba windows\n- show request usage detail under each bar ()\n- normalize 5-hour reset timestamps when backend returns near-now/stale values so we avoid incorrect \n- improve auto cookie import reliability for Alibaba by prioritizing Safari and filtering for authenticated cookie sets\n\nRe-tested with a live Alibaba Coding Plan account; menu now shows stable countdowns + request usage values across 5-hour/weekly/monthly windows.

@jnd0
Copy link
Contributor Author

jnd0 commented Mar 1, 2026

Follow-up pushed in 352ea6b with final UX polish based on live validation:

  • keep countdown reset text (for example: Resets in 5h) for Alibaba windows
  • show request usage detail under each bar (used / total used)
  • normalize 5-hour reset timestamps when backend returns near-now/stale values so we avoid incorrect reset-now behavior
  • improve auto cookie import reliability for Alibaba by prioritizing Safari and filtering for authenticated cookie sets

Re-tested with a live Alibaba Coding Plan account; menu now shows stable countdowns plus request usage values across 5-hour, weekly, and monthly windows.

@jnd0
Copy link
Contributor Author

jnd0 commented Mar 7, 2026

Fixed the remaining Alibaba web/session fetch issues and pushed 4ec2f52.

Why this changed:

  • I noticed Alibaba had updated the Coding Plan console flow and request shape, which is why I updated the web bootstrap and cookie/session handling to match the new behavior

Summary:

  • updated the Alibaba web request bootstrap for the new console detail route and referer shape
  • improved strategy/error propagation so auto/web mode surfaces concrete cookie failures instead of a generic no-strategy error
  • added an Alibaba-specific Chromium cookie fallback that correctly decrypts Brave cookies, including the host-bound prefix in Alibaba's stored cookie values
  • kept Safari-first behavior intact, while falling back cleanly to Brave/Chrome when Safari cookie access is blocked by Full Disk Access restrictions

Validation:

  • swift run CodexBarCLI usage --provider alibaba-coding-plan --source web --format json --verbose
  • swift test --filter AlibabaCodingPlan
  • ./Scripts/compile_and_run.sh
    EOF && gh auth status

@ratulsarna
Copy link
Collaborator

@codex review

Copy link

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

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: 4ec2f52db7

ℹ️ About Codex in GitHub

Your team has set up Codex to 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 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +111 to +113
if httpResponse.statusCode == 401 || httpResponse.statusCode == 403 {
throw AlibabaCodingPlanUsageError.loginRequired
}

Choose a reason for hiding this comment

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

P1 Badge Throw invalidCredentials for API 401/403 responses

In the API-key fetch path, HTTP 401/403 is currently mapped to .loginRequired, but that error message tells users to sign in via browser cookies rather than fix their API key; this misclassifies the failure mode and sends users to the wrong remediation when keys are expired/invalid. Because this branch is only used for bearer/API-key requests, it should return .invalidCredentials so production failures are diagnosed correctly.

Useful? React with 👍 / 👎.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Addressed in 63cd143: API-key fetches now map HTTP 401/403 to AlibabaCodingPlanUsageError.invalidCredentials (not loginRequired), so the remediation matches API auth failures.

Comment on lines +316 to +318
if let override = AlibabaCodingPlanSettingsReader.hostOverride(environment: environment),
let hostURL = URL(string: override),
hostURL.scheme != nil

Choose a reason for hiding this comment

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

P2 Badge Accept bare host overrides when resolving SEC token URL

resolveConsoleSECToken only honors ALIBABA_CODING_PLAN_HOST when the override already includes a URL scheme, but AlibabaCodingPlanSettingsReader.hostOverride accepts bare hosts and the documented usage uses that form. With ALIBABA_CODING_PLAN_HOST=custom.aliyun.com, this branch falls back to region.dashboardURL, so web-mode token refresh ignores the override and can fail against non-default environments.

Useful? React with 👍 / 👎.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Addressed in 63cd143: resolveConsoleSECToken now accepts bare ALIBABA_CODING_PLAN_HOST values by normalizing them to an HTTPS dashboard URL via resolveConsoleDashboardURL/dashboardURL(from:region:), so token refresh honors host overrides without requiring a scheme.

URLQueryItem(name: "action", value: "zeldaEasy.broadscope-bailian.codingPlan.queryCodingPlanInstanceInfoV2"),
URLQueryItem(name: "product", value: "broadscope-bailian"),
URLQueryItem(name: "api", value: "queryCodingPlanInstanceInfoV2"),
URLQueryItem(name: "currentRegionId", value: AlibabaCodingPlanAPIRegion.international.currentRegionID),

Choose a reason for hiding this comment

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

P2 Badge Use selected region in host-override quota query

When ALIBABA_CODING_PLAN_HOST is set, resolveQuotaURL builds the request via url(from:), but that helper hard-codes currentRegionId to the international region. If users select China mainland and also use a host override, requests still carry ap-southeast-1, which can query the wrong regional quota context and return incorrect/empty usage.

Useful? React with 👍 / 👎.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Addressed in 63cd143: host-override quota URL resolution is now region-aware (url(from:region:)) and uses the selected region for currentRegionId (including cn-beijing). Added regression coverage in AlibabaCodingPlanProviderTests.

@ratulsarna
Copy link
Collaborator

@jnd0 Possible to address these comments?

@jnd0
Copy link
Contributor Author

jnd0 commented Mar 12, 2026

@jnd0 Possible to address these comments?

Done :)

@goodtiger
Copy link

I tested this PR locally on macOS arm64 and found a couple of concrete issues with the Alibaba/Bailian Coding Plan provider in a China mainland setup.

What I verified

  • Provider is enabled successfully.
  • Region selection persists correctly to config (region: cn).
  • An API key is present in config for the alibaba provider.

Repro / observed behavior

1) auto source only attempts web and fails early

Running:

codexbar usage --provider alibaba-coding-plan --format json --pretty -v

showed:

  • alibaba-coding-plan.web (web) available
  • then failed with:
    • A TLS error caused the secure connection to fail.

It did not successfully use API fallback in this state.

2) forcing api still returns console-login-required

Running with an API key and forcing API mode:

codexbar usage --provider alibaba-coding-plan --source api --format json --pretty

returned:

  • Alibaba Coding Plan console login is required. Sign in to Model Studio in a supported browser or paste a Cookie header.

That suggests the current so-called API path is still hitting a flow that effectively requires console login/session state, at least for this cn setup.

Likely problems

  1. Configured apiKey did not appear to participate correctly in fetch availability / fallback.
  2. Web failure in auto mode did not recover into a usable API path.
  3. In cn mode, the API path still seems tied to a console-authenticated flow instead of a true API-key-only path.

Extra note

There may also be some intl bias in the current provider wiring / dashboard defaults, which could be confusing when debugging cn mode, although the config itself does persist region: cn correctly.

If useful, I can provide more detailed reproduction steps, but the short version is:

  • region=cn is definitely persisted
  • web path errors with TLS
  • --source api still reports console login required

So right now the provider compiles, but the cn + api-key path still doesn't look functionally complete.

@jnd0
Copy link
Contributor Author

jnd0 commented Mar 16, 2026

Thanks @goodtiger for the CN repro details. I pushed a follow-up in 249c5a5 that addresses the concrete issues you called out.

What changed:

  • fixed auto fallback behavior for Alibaba web transport/TLS failures, so auto now falls through to API strategy instead of stopping early
  • updated API-mode response mapping so login-style payloads (ConsoleNeedLogin) are surfaced as an API-path limitation error (not web cookie-login messaging)
  • improved SEC token extraction fallbacks and accepted token key variants (secToken / sec_token)
  • improved Alibaba cookie-header assembly to dedupe by cookie name and prefer non-expired/latest values
  • added regression tests for:
    • TLS fallback behavior in auto vs forced web
    • API-mode mapping for ConsoleNeedLogin
  • documented known CN limitation in docs/alibaba-coding-plan.md

Validation run:

  • swift test --filter AlibabaCodingPlan
  • ./Scripts/compile_and_run.sh

Known limitation (still explicit):

  • for some CN accounts/endpoints, the Alibaba /data/api.json coding-plan path can still require console session state even with an API key (ConsoleNeedLogin). In that case API-key-only mode is not fully available upstream, and web session mode is required.

@ratulsarna
Copy link
Collaborator

ratulsarna commented Mar 19, 2026

Opened replacement PR #574 that supersedes #453.

Thanks again @jnd0 for the original Alibaba provider implementation and follow-up fixes.

@ratulsarna ratulsarna closed this Mar 19, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants