Skip to content

feat: add ClinePass usage provider#1888

Closed
JagravNaik wants to merge 2 commits into
steipete:mainfrom
JagravNaik:feat/clinepass-provider
Closed

feat: add ClinePass usage provider#1888
JagravNaik wants to merge 2 commits into
steipete:mainfrom
JagravNaik:feat/clinepass-provider

Conversation

@JagravNaik

Copy link
Copy Markdown

Summary

Adds a new ClinePass provider to CodexBar, surfacing Cline's flat-rate subscription usage as three rolling percentage bars (5-hour, weekly, monthly) with reset countdowns, plus plan name and account email.

Data source

Three Cline account API endpoints behind a single CLINE_API_KEY (Bearer auth, {success,data,error} envelope):

  • GET /api/v1/users/me → account email
  • GET /api/v1/users/me/plan → plan displayName
  • GET /api/v1/users/me/plan/usage-limits → server-computed { type, percentUsed, resetsAt } per window (five_hour / weekly / monthly)

The /plan and /plan/usage-limits endpoints are dashboard-derived (extracted from the Cline web dashboard's JavaScript bundle — not in Cline's published Enterprise API Reference). The usage-limits fetch is best-effort: a 404 or transient failure degrades to showing plan name + email without usage windows rather than failing the whole fetch.

Concurrency

The three reads are independent (all use the literal me path) and run concurrently via withThrowingTaskGroup, collapsing three serialized round trips into one (~0.7s → ~0.25s). The user and plan fetches are required; limits catches its own errors without aborting the group.

Wiring

Follows the CrossModel/OpenRouter pattern: custom ClinePassUsageSnapshot field on UsageSnapshot (6 Codable sites), ProviderDescriptor registry, ProviderImplementationRegistry, ProviderTokenResolver, ProviderConfigEnvironment, ProviderDiagnosticExport, CostUsageScanner, LogCategories, TokenAccountSupportCatalog, widget display name/color, CLI diagnose, and docs/providers.md (count 57 → 58).

Hardening

  • parseTimestamp uses a two-formatter approach (withFractionalSeconds then plain) to handle timezone offsets (Z, +HH:mm, +HHmm) that the original truncating parser silently dropped.
  • ClinePassUserDTO drops the unused id field (fetched but never consumed — every endpoint uses literal me).
  • ClinePassUsageError.networkError removed (dead code, never thrown).
  • Endpoint override validation rejects non-HTTPS/non-loopback URLs before attaching credentials; same-origin validation on every response rejects cross-origin redirects.

Commands run

  • swift build -c release — clean
  • swift build — clean (after rebasing onto latest main with ClawRouter provider)
  • ./Scripts/regenerate-codex-parser-hash.sh — hash updated to 75eb44533cdd6d4c
  • App packaged via ./Scripts/package_app.sh and launched — confirmed running

Tests

13 core tests (ClinePassUsageStatsTests): snapshot mapping, full fetch flow, pagination, 401/envelope-error/cross-origin rejection, Codable round-trip, timestamp parsing. Plus menu descriptor, CLI output, CLI diagnose, config env, diagnostic export, icon resources, providers pane, token account precedence, and debug log coverage.

Note: swift test hits a known Sparkle @rpath dlopen environmental quirk (documented in prior sessions). Tests pass when run via xcrun xctest with the framework rpath resolved. Two parallel code reviewers (core layer + app layer) both returned APPROVE with no blockers.

Screenshots

Enable ClinePass in Settings → Providers → ClinePass, paste your API key (created at app.cline.bot → Settings → API Keys). The menu bar shows the 5-hour window percentage; the menu card shows all three windows with reset countdowns, plan name, and account email.

Add support for ClinePass, Cline's flat-rate subscription, surfacing
its three rolling usage windows (5-hour, weekly, monthly) as percentage
bars with reset countdowns, plus plan name and account email.

Data source: three Cline account API endpoints behind a single
CLINE_API_KEY (Bearer auth, {success,data,error} envelope):
  - GET /api/v1/users/me           -> account email
  - GET /api/v1/users/me/plan      -> plan displayName
  - GET /api/v1/users/me/plan/usage-limits -> server-computed
    { type, percentUsed, resetsAt } per window (five_hour/weekly/monthly)

The /plan and /plan/usage-limits endpoints are dashboard-derived (not
in Cline's published Enterprise API Reference); usage-limits is fetched
best-effort so a 404 or transient failure degrades to showing plan name
+ email without usage windows rather than failing the whole fetch.

The three reads are independent (all use the literal 'me' path) and run
concurrently via withThrowingTaskGroup, collapsing three serialized
round trips into one (~0.7s -> ~0.25s). The user and plan fetches are
required; limits catches its own errors without aborting the group.

Wiring follows the CrossModel/OpenRouter pattern: custom
ClinePassUsageSnapshot field on UsageSnapshot (6 Codable sites),
ProviderDescriptor registry, ProviderImplementationRegistry,
ProviderTokenResolver, ProviderConfigEnvironment,
ProviderDiagnosticExport, CostUsageScanner, LogCategories,
TokenAccountSupportCatalog, widget display name/color, CLI diagnose,
and docs/providers.md (count 57 -> 58).

Additional hardening vs the initial implementation:
  - parseTimestamp uses a two-formatter approach (withFractionalSeconds
    then plain) to handle timezone offsets (Z, +HH:mm, +HHmm) that the
    original truncating parser silently dropped.
  - ClinePassUserDTO drops the unused 'id' field (fetched but never
    consumed — every endpoint uses literal 'me').
  - ClinePassUsageError.networkError removed (dead code, never thrown).
  - Endpoint override validation rejects non-HTTPS/non-loopback URLs
    before attaching credentials; same-origin validation on every
    response rejects cross-origin redirects.

Tests: 13 core tests (snapshot mapping, full fetch flow, pagination,
401/envelope-error/cross-origin rejection, Codable round-trip, timestamp
parsing) plus menu descriptor, CLI output, CLI diagnose, config env,
diagnostic export, icon resources, providers pane, token account
precedence, and debug log coverage.

Docs: docs/clinepass.md, docs/providers.md updated.
@clawsweeper

clawsweeper Bot commented Jul 4, 2026

Copy link
Copy Markdown

Codex review: needs maintainer review before merge. Reviewed July 4, 2026, 11:34 AM ET / 15:34 UTC.

Summary
The PR adds a ClinePass API-key provider with Cline account usage fetching, provider/CLI/menu/widget/docs wiring, and focused tests.

Reproducibility: not applicable. as a feature PR. For the prior PR bug, source and test inspection show the versioned base URL path now normalizes and has regression coverage.

Review metrics: 2 noteworthy metrics.

  • Diff surface: 36 files, +1388/-6. The provider touches core, app, widget, CLI, docs, and tests, so merge review needs to cover end-to-end wiring.
  • New account reads: 3 Cline GET endpoints. All three requests use the same bearer token and depend on the Cline account endpoint contract.

Root-cause cluster
Relationship: fixed_by_candidate
Canonical: #1786
Summary: This PR is a candidate implementation for the open ClinePass provider feature request, whose remaining blocker is maintainer acceptance of the ClinePass auth and quota endpoint contract.

Members:

Proposal only: this assessment does not dispatch repair, suppress jobs, mutate sibling items, close, or merge anything.

Merge readiness
Overall: 🐚 platinum hermit
Proof: 🦞 diamond lobster
Patch quality: 🐚 platinum hermit
Result: ready for maintainer review.

Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch.

Rank-up moves:

  • [P2] Add or link maintainer-visible confirmation that /plan/usage-limits is supported for third-party API-key use.

Mantis proof suggestion
A short redacted desktop proof would help because the PR adds visible provider settings, menu bar, and menu-card behavior beyond the CLI output. A maintainer can ask Mantis to capture proof by posting this exact PR comment:

@openclaw-mantis visual task: verify enabling ClinePass with a redacted test key shows the 5-hour menu bar metric and all three usage windows in the menu card.

Risk before merge

  • [P1] The implementation depends on dashboard-derived /plan and /plan/usage-limits endpoints that the linked owner comment has not accepted as a supported third-party quota contract.
  • [P1] Merging adds new CLINE_API_KEY and CLINE_API_BASE_URL credential routing plus persisted API-key settings, so maintainers should explicitly accept the auth/provider surface before users rely on it.

Maintainer options:

  1. Confirm the ClinePass quota contract (recommended)
    Get maintainer-visible acceptance or upstream confirmation that these quota endpoints and API-key scopes are supported enough for CodexBar core before merge.
  2. Accept the endpoint dependency explicitly
    Maintainers can choose to own the dashboard-derived endpoint risk now that the implementation has live proof and focused tests.
  3. Pause until the contract is public
    If the undocumented quota API is not acceptable in core, pause or close this branch and keep the linked feature request as the canonical tracker.

Next step before merge

  • [P2] Human review is needed because the remaining blocker is endpoint/auth product acceptance, not an automatable code repair.

Security
Cleared: No concrete supply-chain or credential-exfiltration defect was found; the remaining concern is auth/provider product acceptance rather than a security bug.

Review details

Best possible solution:

Land the provider only after maintainers accept ClinePass's API-key quota endpoint contract, or keep the linked feature request open until Cline documents or supports that third-party contract.

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

Not applicable as a feature PR. For the prior PR bug, source and test inspection show the versioned base URL path now normalizes and has regression coverage.

Is this the best way to solve the issue?

Unclear until maintainers accept the endpoint contract. The implementation is narrow and follows provider patterns, but the linked owner direction requested supported quota endpoints before merging dashboard-derived API use.

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning high; reviewed against 3191f129f994.

Label changes

Label changes:

  • add rating: 🐚 platinum hermit: Overall readiness is 🐚 platinum hermit; proof is 🦞 diamond lobster and patch quality is 🐚 platinum hermit.
  • add status: 👀 ready for maintainer look: ClawSweeper has no concrete contributor-facing blocker left for this PR. Sufficient (live_output): Sufficient live output: the contributor posted redacted CLI output showing all three ClinePass windows and later posted live verification for the versioned-base fix.
  • remove status: ⏳ waiting on author: Current PR status label is status: 👀 ready for maintainer look.
  • remove rating: 🦐 gold shrimp: Current PR rating is rating: 🐚 platinum hermit, so this older rating label is no longer current.

Label justifications:

  • P3: This is an optional new provider feature, not a regression or blocked core workflow.
  • merge-risk: 🚨 auth-provider: The PR adds new Cline API-key resolution, endpoint override handling, bearer-token account reads, and provider selection behavior.
  • rating: 🐚 platinum hermit: Overall readiness is 🐚 platinum hermit; proof is 🦞 diamond lobster and patch quality is 🐚 platinum hermit.
  • status: 👀 ready for maintainer look: ClawSweeper has no concrete contributor-facing blocker left for this PR. Sufficient (live_output): Sufficient live output: the contributor posted redacted CLI output showing all three ClinePass windows and later posted live verification for the versioned-base fix.
  • proof: sufficient: Contributor real behavior proof is sufficient. Sufficient live output: the contributor posted redacted CLI output showing all three ClinePass windows and later posted live verification for the versioned-base fix.
Evidence reviewed

What I checked:

Likely related people:

  • steipete: He gave the ClinePass contract requirements on the related feature request and recently added ClawRouter/provider registry wiring in the same area. (role: repository owner/product direction commenter and recent provider contributor; confidence: high; commits: efb7839ddf99, f84a171bca1b; files: Sources/CodexBarCore/Providers/ProviderDescriptor.swift, Sources/CodexBarCore/Config/ProviderConfigEnvironment.swift, Sources/CodexBar/Providers/Shared/ProviderImplementationRegistry.swift)
  • JC: JC introduced the CrossModel provider pattern that this PR explicitly follows for API-key fetching, usage snapshots, endpoint validation, and descriptor wiring. (role: adjacent provider-pattern author; confidence: medium; commits: 0a18391e1838; files: Sources/CodexBarCore/Providers/CrossModel/CrossModelUsageStats.swift, Sources/CodexBarCore/Providers/CrossModel/CrossModelProviderDescriptor.swift)
What the crustacean ranks mean
  • 🦀 challenger crab: rare, exceptional readiness with strong proof, clean implementation, and convincing validation.
  • 🦞 diamond lobster: very strong readiness with only minor maintainer review expected.
  • 🐚 platinum hermit: good normal PR, likely mergeable with ordinary maintainer review.
  • 🦐 gold shrimp: useful signal, but proof or patch confidence is still limited.
  • 🦪 silver shellfish: thin signal; proof, validation, or implementation needs work.
  • 🧂 unranked krab: not merge-ready because proof is missing/unusable or there are serious correctness or safety concerns.
  • 🌊 off-meta tidepool: rating does not apply to this item.

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.

How this review workflow works
  • 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.
Review history (2 earlier review cycles)
  • reviewed 2026-07-04T14:02:35.252Z sha f4a81bb :: needs real behavior proof before merge. :: none
  • reviewed 2026-07-04T14:23:34.466Z sha f4a81bb :: found issues before merge. :: [P2] Normalize the Cline base path before appending endpoints

@clawsweeper clawsweeper Bot added rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. 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 4, 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: f4a81bb9f4

ℹ️ 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".

}
let prefix = components.percentEncodedPath
let trimmedPrefix = prefix.hasSuffix("/") ? String(prefix.dropLast()) : prefix
components.percentEncodedPath = trimmedPrefix + encodedSuffix

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 Cline API base path before appending endpoints

When CLINE_API_BASE_URL is set to Cline's documented API base such as https://api.cline.bot/api/v1 (their examples call /api/v1/...: https://docs.cline.bot/api/getting-started), this preserves that path and then appends another /api/v1, so the provider requests /api/v1/api/v1/users/me and all account reads fail. Either treat the override as the versioned API root and append /users/me, or strip an existing /api/v1 before adding these suffixes.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Fixed in 3b737da. endpoint() now normalizes the base path — it strips a trailing slash and a trailing /api/v1 (case-insensitive) before appending the versioned suffix, so both the bare host (https://api.cline.bot) and Cline's documented versioned root (https://api.cline.bot/api/v1) resolve to a single /api/v1/... path instead of doubling it. Host-level prefixes (e.g. a reverse-proxy /gateway) are preserved. Verified live against api.cline.bot with a versioned CLINE_API_BASE_URL, and added normalizedBasePath unit tests plus an integration test asserting no doubled /api/v1.

@JagravNaik

Copy link
Copy Markdown
Author

Behavior Proof

CLI output (swift run CodexBarCLI --provider clinepass --no-color)

== ClinePass (api) ==
5-hour: 0% left [------------]
Resets in 4h 29m
Weekly: 25% left [===---------]
Resets in 6d 5h
Monthly: 63% left [=======-----]
Resets in 29d 5h
Account: [REDACTED]
Plan: Cline Pass (Monthly)

Verification

  • All three Cline API endpoints return 200 with real usage windows (verified against a live ClinePass account at api.cline.bot)
  • GET /api/v1/users/me → account email
  • GET /api/v1/users/me/planCline Pass (Monthly)
  • GET /api/v1/users/me/plan/usage-limits → server-computed five_hour / weekly / monthly windows with percentUsed and resetsAt
  • The three fetches run concurrently via withThrowingTaskGroup (~0.4s for all three vs sequential)
  • App is running with ClinePass as the selected menu bar provider (PID 56610), showing the 5-hour window percentage in the menu bar

@JagravNaik

Copy link
Copy Markdown
Author

Proof: PR builds, compiles, and runs clean against live ClinePass API.

  • swift build — clean
  • swift run CodexBarCLI --provider clinepass --no-color — shows all 3 windows with reset countdowns
  • ✓ App packaged via ./Scripts/package_app.sh, launched, and confirmed running with ClinePass as the selected provider
  • ✓ Code review passed: 2 parallel reviewers (core layer + app layer) both returned APPROVE

@clawsweeper re-review

@clawsweeper

clawsweeper Bot commented Jul 4, 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.

@clawsweeper clawsweeper Bot added proof: sufficient Contributor real behavior proof is sufficient. rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. and removed rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. labels Jul 4, 2026
Addresses PR steipete#1888 review (Codex + ClawSweeper): when CLINE_API_BASE_URL is
set to Cline's documented versioned root (https://api.cline.bot/api/v1), the
endpoint builder preserved that path and appended another /api/v1, producing
/api/v1/api/v1/users/me so every account read 404'd.

endpoint() now strips a trailing slash and a trailing /api/v1 (case-insensitive)
from the base path before appending the versioned suffix, so both the bare host
and the versioned root resolve to the same URL. Host-level prefixes (e.g. a
reverse-proxy /gateway) are preserved.

Adds unit coverage for normalizedBasePath edge cases and an integration test
asserting a versioned base URL never yields a doubled /api/v1 path.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@JagravNaik

Copy link
Copy Markdown
Author

Addressed the sole blocking review finding (doubled /api/v1 when CLINE_API_BASE_URL is set to Cline's versioned root) in 3b737da.

Fix: endpoint() normalizes the base path — strips a trailing slash and a trailing /api/v1 (case-insensitive) before appending the versioned suffix. Both https://api.cline.bot and https://api.cline.bot/api/v1 now resolve to a single /api/v1/...; host-level prefixes are preserved.

Verification:

  • ✓ Live against api.cline.bot with CLINE_API_BASE_URL=https://api.cline.bot/api/v1 — all 3 endpoints 200, windows render correctly (previously 404'd on the doubled path).
  • ✓ Default (no override) still works.
  • ✓ 17 ClinePass unit/integration tests pass, incl. new normalizedBasePath edge-case coverage and a doubled-path regression test.
  • swift build clean, swiftformat clean.

@clawsweeper re-review

@clawsweeper

clawsweeper Bot commented Jul 4, 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.

@clawsweeper clawsweeper Bot added rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. and removed rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. labels Jul 4, 2026
@JagravNaik JagravNaik closed this Jul 4, 2026
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. P3 Low-risk cleanup, docs, polish, ergonomics, or speculative feature. proof: sufficient Contributor real behavior proof is sufficient. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant