Skip to content

fix(opencode): read pay-as-you-go usage instead of failing with HTTP 500 - #2504

Open
epoch-chrono wants to merge 5 commits into
steipete:mainfrom
epoch-chrono:fix/opencode-pay-as-you-go-usage
Open

fix(opencode): read pay-as-you-go usage instead of failing with HTTP 500#2504
epoch-chrono wants to merge 5 commits into
steipete:mainfrom
epoch-chrono:fix/opencode-pay-as-you-go-usage

Conversation

@epoch-chrono

@epoch-chrono epoch-chrono commented Jul 29, 2026

Copy link
Copy Markdown

Fixes the OpenCode API error: HTTP 500: HTTPError reported in #706 and #273. I traced it to a schema change on opencode.ai rather than a transient server fault, and it turns out to be fixable client-side — the usage data is still served, under different field names.

What breaks today

OpenCodeUsageFetcher resolves the workspace, then asks the subscription server function (7abeebee…) for usage. For a workspace that bills per request, that object no longer exists. I replayed the exact three calls the provider makes, with the same server IDs, headers and cookie:

1) GET  /_server?id=def3997…ba0234f                     -> 200  workspace resolved
2) GET  /_server?id=7abeebee…d691b4&args=["wrk_…"]      -> 200  payload is null
3) POST /_server  (X-Server-Id: 7abeebee…d691b4)        -> 500  {"status":500,"unhandled":true,"message":"HTTPError"}

Auth is fine (no 401/403) and the workspace lookup works — the failure is isolated to the subscription function. Two details matter:

  1. The account is pay-as-you-go, so its billing object has subscription: null, and the subscription function has nothing to return.
  2. rollingUsage / usagePercent no longer appear anywhere in the billing data (0 occurrences). The current fields are monthlyUsage, monthlyLimit and balance. So both the parseSubscription regex and the subscription call target a shape opencode.ai has replaced.

There is also a smaller issue: a server function that resolves to null answers with …["server-fn:<uuid>"]=[],null), which isExplicitNullPayload does not recognize. That is why the POST retry is sent at all, and it is the request that returns HTTP 500.

What this changes

When the subscription lookup fails in a subscription-shaped way, I fall back to the customer/billing server function (c83b78a6…) — the same one OpenCodeGoUsageFetcher already reads the Zen balance from — and derive usage from what opencode.ai serves today:

  • usedPercent = monthlyUsage / monthlyLimit, rendered as the primary window
  • monthlyUsage, monthlyLimit and the remaining prepaid balance, rendered as provider cost

Deliberately conservative:

  • Workspaces that still return a subscription keep the existing path untouched; the new code never runs for them.
  • The fallback only triggers on apiError / parseFailed. Credential and network failures propagate as before, and an expired session detected during the fallback still surfaces as invalidCredentials.
  • When the billing payload has no usage either, the existing "no subscription usage data" error is raised — the raw HTTP 500 is no longer what the user sees.
  • The billing object carries no cycle boundary, so resetsAt stays nil rather than guessing one.

On the unit scale: balance and monthlyUsage arrive as integers scaled by 1e8, while monthlyLimit / reloadAmount / reloadTrigger are whole USD. I did not pick that divisor myself — OpenCodeGoZenBalanceParser.billingScale already uses it for the balance this app renders today, and my live values are consistent with it (spend matches the cycle, and the balance sits above the configured auto-reload trigger, which had not fired). It is isolated in a single named constant.

Parsing is tolerant of both shapes: the billing function replies with SolidStart's $R[...] JavaScript payload, so I try JSON first and fall back to a field scan that requires customerID before trusting any number.

Tests

  • New OpenCodeZenBillingParserTests plus a redacted billing fixture (Tests/CodexBarTests/Fixtures/Providers/OpenCode/billing-pay-as-you-go.txt): $R[...] payload, JSON payload, missing limit, legacy workspace that still has a subscription, and payloads that must be rejected.
  • New cases in OpenCodeUsageFetcherErrorTests: pay-as-you-go workspace now yields a snapshot instead of an error, the POST that returns 500 is no longer sent, a POST failure still recovers through billing, and a signed-out billing response maps to invalidCredentials. The existing null-payload test now asserts the graceful error after the billing attempt.
  • New OpenCodeMenuCardCostTests for the menu card itself: a workspace with a limit renders the percentage, and one without a limit still renders spend and balance instead of an empty card.
  • New toUsageSnapshot cases in OpenCodeUsageParserTests for the monthly window, the cost snapshot, the no-limit case, and clamping above 100%.

Evidence from a real pay-as-you-go workspace

Captured today against a live opencode.ai account. Workspace/customer IDs are redacted; the session cookie was read from a file and never printed, and the account values below are my own.

Before — main (this PR reverted), same account, same cookie. A small executable linking CodexBarCore from main and calling OpenCodeUsageFetcher.fetchUsage directly:

codebase: steipete/CodexBar main (no fix)
error com.steipete.codexbar.opencode-usage: [CodexBarCore] OpenCode subscription payload missing after GET; retrying with POST.
error com.steipete.codexbar.opencode-usage: [CodexBarCore] OpenCode returned 500 (type=application/json;charset=UTF-8 length=53)
  result: OpenCode API error: HTTP 500: HTTPError

The three requests the provider makes, replayed at the HTTP level with the same server IDs and headers:

=== 1) workspace GET -> HTTP 200 (len=223) ===
((self.$R=self.$R||{})["server-fn:<uuid>"]=[],($R=>$R[0]=[$R[1]={id:"wrk_<redacted>",name:"<redacted>",slug:null}])(...))

=== 2) subscription GET -> HTTP 200 (len=93) ===
((self.$R=self.$R||{})["server-fn:<uuid>"]=[],null)

=== 3) subscription POST (retry) -> HTTP 500 (len=53) ===
{"status":500,"unhandled":true,"message":"HTTPError"}

Step 2 is the payload isExplicitNullPayload did not recognize, which is why step 3 is sent at all. Step 3 is the request that produces the reported error.

What the billing data actually contains for that same workspace, from the customer/billing server function this PR falls back to:

...reloadTrigger:5,reloadTriggerMin:5,monthlyLimit:20,monthlyUsage:1556267684,timeMonthlyUsageUpdated:...
...paymentMethodLast4:null,balance:1326177004,reload:!0,reloadAmount:10,reloadAmountMin:10,...

This is also the concrete check on the fixed-point semantics: monthlyUsage 1556267684 / 1e8 = $15.56 against a monthlyLimit of 20 already in whole USD, and balance 1326177004 / 1e8 = $13.26, which is above the reloadTrigger of 5 — consistent with auto-reload not having fired. rollingUsage / usagePercent appear zero times anywhere in this payload.

After — this branch, same account, same cookie, through the full fetch path (workspace lookup, subscription attempt, billing fallback, snapshot conversion):

case: live account (cookie loaded, not printed)
  ok   monthly spend $15.56 of $20.00 (77.8%), balance $13.26
  ok   primary window usedPercent 77.8%

So where the provider previously surfaced HTTP 500: HTTPError, it now reports the monthly spend, the limit and the remaining prepaid balance, and the values line up with the raw payload above.

One thing this proof does not cover: I could not run make test or launch the packaged app, since this machine has Command Line Tools but no full Xcode (the app target needs the #Preview macro plugin, and SwiftLint needs sourcekitd). The run above links CodexBarCore from this branch directly, so it exercises the fetch and snapshot path but not the SwiftUI rendering; the menu-card branch is covered by OpenCodeMenuCardCostTests instead. The CI run on this PR is still awaiting maintainer approval, so the suite has not executed yet.

Refs #706, #273

opencode.ai retired the payload the OpenCode provider parses. Workspaces that
bill per request have `subscription: null`, so the subscription server function
answers with an empty payload on GET and HTTP 500 on the POST retry, which
surfaces as "OpenCode API error: HTTP 500: HTTPError" and leaves the provider
without any usage to show. `rollingUsage.usagePercent` no longer appears in the
billing data at all.

I fall back to the customer/billing server function, the same one the OpenCode
Go provider already reads the Zen balance from, and derive usage from the fields
opencode.ai serves today: monthly spend against the configured monthly limit,
plus the remaining prepaid balance. Workspaces that still carry a subscription
keep the existing path untouched, and the fallback only runs for
subscription-shaped failures so credential errors still surface as such.

I also treat a server function that resolves to null as an explicit null
payload, so the POST retry that answers HTTP 500 is never sent.

Refs steipete#706, steipete#273

@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: d56479cf1a

ℹ️ 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 cost = ProviderCostSnapshot(
used: usage.monthlyUsageUSD,
limit: usage.monthlyLimitUSD ?? 0,

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 Render no-limit OpenCode pay-as-you-go spend

When the billing payload has monthlyLimit: null, this converts it to limit: 0 while primary is also nil, and the existing menu model drops OpenCode provider-cost sections with nonpositive limits (MenuCardView+Costs.swift:485). In that no-limit pay-as-you-go case the fetch now succeeds but the card still has no metric or cost section, so the parsed monthly spend/balance is effectively hidden; please add an OpenCode no-limit rendering path or otherwise keep the spend displayable.

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.

Good catch — fixed in 5dd30e7.

You are right that the no-limit case fell through to guard cost.limit > 0 and left the card with nothing on it, even though the spend and balance had been parsed. I added an OpenCode branch for limit <= 0 in MenuCardView+Costs.swift, following the shape OpenAI and ClawRouter already use for limitless spend: monthly spend as the spend line, remaining prepaid balance underneath, no percentage. Workspaces that do have a limit keep the existing percentage rendering.

I kept limit: 0 as the signal rather than making the cost snapshot optional, since that is the convention those providers already rely on, and documented it where the snapshot is built. New OpenCodeMenuCardCostTests covers all three cases through Model.make: with a limit, without a limit, and without a limit or balance.

A pay-as-you-go workspace with no monthly limit produced an empty card: the
fetch succeeded, but the snapshot has no primary window (no limit means no
percentage) and its provider cost carries limit 0, which the shared cost
section drops. The monthly spend and the prepaid balance were parsed and then
never shown.

I add an OpenCode branch for that case, matching the one OpenAI and ClawRouter
already use for limitless spend: monthly spend as the spend line, remaining
balance underneath. Workspaces that do have a limit keep the existing
percentage rendering.
@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. P2 Normal priority bug or improvement with limited blast radius. labels Jul 29, 2026
@clawsweeper

clawsweeper Bot commented Jul 29, 2026

Copy link
Copy Markdown

Codex review: needs changes before merge. Reviewed August 7, 2026, 1:08 PM ET / 17:08 UTC.

ClawSweeper review

What this changes

This PR adds a billing-data fallback for OpenCode pay-as-you-go workspaces and displays monthly spend, an optional limit, and balance instead of a subscription-endpoint HTTP 500.

Merge readiness

⚠️ Needs maintainer review before merge - 2 items remain

Keep open: the OpenCode fallback remains needed and has credible live proof, but the current head is dirty against main and retains a provider-specific menu-card branch that conflicts with main’s descriptor-selected presentation architecture.

Priority: P2
Reviewed head: 34974731d75839f61807f0fe396245878654402d

Review scores

Measure Result What it means
Overall readiness 🦐 gold shrimp (3/6) The live provider evidence is strong, but the current dirty head has one concrete integration blocker against main.
Proof confidence 🦞 diamond lobster (5/6) Sufficient (live_output): The PR body includes redacted live before/after output showing the prior HTTP 500 and a recovered pay-as-you-go usage snapshot through the full fetch path.
Patch quality 🦐 gold shrimp (3/6) 1 actionable review finding remain.

Verification

Check Result Evidence
Real behavior Verified Sufficient (live_output): The PR body includes redacted live before/after output showing the prior HTTP 500 and a recovered pay-as-you-go usage snapshot through the full fetch path.
Evidence reviewed 5 items Current main still lacks the fallback: Current main fetches and parses only subscription usage after resolving the workspace, so the reported pay-as-you-go path remains unhandled.
Current presentation boundary: Main now selects provider cost rendering through a descriptor-provided style; the PR’s direct OpenCode branch uses the superseded provider argument path.
PR merge blocker: GitHub reports this head as dirty; the retained direct OpenCode card branch is the concrete conflicting presentation change.
Findings 1 actionable finding [P1] Move the OpenCode card rule to the descriptor
Security None None.

How this fits together

CodexBar’s OpenCode provider converts browser-authenticated workspace responses into a usage snapshot for the menu-bar card. The subscription lookup is the normal input; this PR introduces billing data as the fallback input when pay-as-you-go accounts have no subscription usage.

flowchart LR
A[OpenCode session cookie] --> B[Workspace lookup]
B --> C[Subscription usage lookup]
C --> D{Subscription data available?}
D -->|Yes| E[Usage snapshot]
D -->|No| F[Billing usage fallback]
F --> E
E --> G[Menu-bar cost card]
Loading

Before merge

  • Move the OpenCode card rule to the descriptor (P1) - This still branches on .opencode inside the old provider-argument renderer. Main now supplies a descriptor-selected cost style to this renderer, and GitHub marks the head dirty; rebase this no-limit presentation onto that boundary so the fallback can merge without restoring parallel routing.
  • Resolve merge risk (P1) - Merging the current dirty head would conflict with the shipped descriptor cost-style refactor; preserving the old provider-specific branch would create a second presentation-routing path.

Findings

  • [P1] Move the OpenCode card rule to the descriptor — Sources/CodexBar/MenuCardView+Costs.swift:447-449
Agent review details

Security

None.

Review metrics

Metric Value Why it matters
Patch surface production +358, tests/fixtures +383, changelog +1 The provider fallback spans parsing, snapshot conversion, and menu presentation, so the rebase must keep those layers and their coverage aligned.

Root-cause cluster

Relationship: canonical
Canonical: #2504
Summary: This PR is the concrete candidate fix for the earlier OpenCode subscription-endpoint HTTP 500 reports.

Members:

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

Merge-risk options

Maintainer options:

  1. Rebase onto descriptor cost styles (recommended)
    Move the OpenCode no-limit rendering decision into the current descriptor-selected style boundary, then validate the rebased provider path before merge.
Copy recommended automerge instruction
@clawsweeper automerge

Special instructions:
Rebase the OpenCode no-limit cost rendering onto descriptor-selected cost styles, preserving the billing fallback and focused regression tests.

Technical review

Best possible solution:

Rebase the fallback onto current main, select the no-limit OpenCode presentation through the provider descriptor, and retain focused parsing, fetcher, and menu-model coverage for limited and no-limit accounts.

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

Yes—the PR supplies a redacted live before/after fetch trace, and current main still follows the subscription-only path shown in source. This review did not execute a live account request.

Is this the best way to solve the issue?

No—the billing fallback is narrow, but its menu-card presentation must move to main’s descriptor-selected cost-style boundary rather than retain provider-specific routing in the generic renderer.

Full review comments:

  • [P1] Move the OpenCode card rule to the descriptor — Sources/CodexBar/MenuCardView+Costs.swift:447-449
    This still branches on .opencode inside the old provider-argument renderer. Main now supplies a descriptor-selected cost style to this renderer, and GitHub marks the head dirty; rebase this no-limit presentation onto that boundary so the fallback can merge without restoring parallel routing.
    Confidence: 0.98

Overall correctness: patch is incorrect
Overall confidence: 0.98

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning high; reviewed against 22b24b885693.

Labels

Label justifications:

  • P2: This repairs a provider-specific usage failure for OpenCode pay-as-you-go accounts.
  • merge-risk: 🚨 compatibility: The branch is dirty against the shipped descriptor presentation refactor and cannot merge safely without adapting its card rendering.
  • rating: 🦐 gold shrimp: Overall readiness is 🦐 gold shrimp; proof is 🦞 diamond lobster and patch quality is 🦐 gold shrimp.
  • status: ⏳ waiting on author: ClawSweeper has contributor-facing work open and is waiting for author action. Sufficient (live_output): The PR body includes redacted live before/after output showing the prior HTTP 500 and a recovered pay-as-you-go usage snapshot through the full fetch path.
  • proof: sufficient: Contributor real behavior proof is sufficient. The PR body includes redacted live before/after output showing the prior HTTP 500 and a recovered pay-as-you-go usage snapshot through the full fetch path.

Evidence

Acceptance criteria:

  • [P1] swift test --filter OpenCode.
  • [P1] make check.
  • [P1] make test.

What I checked:

Likely related people:

  • steipete: Authored the shipped descriptor-based menu-card architecture and the recorded maintainer follow-up that added regression coverage for this PR. (role: current presentation architecture author and recent area contributor; confidence: high; commits: 5bd587850611, a33fdc7695b2; files: Sources/CodexBar/MenuCardView+Costs.swift, Sources/CodexBarCore/Providers/ProviderUsagePresentation.swift, Sources/CodexBarCore/Providers/OpenCode/OpenCodeProviderDescriptor.swift)

Rank-up moves

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

  • Rebase the no-limit presentation onto the descriptor-selected cost-style boundary.
  • Run focused OpenCode tests, make check, and make test on the rebased head.

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 (14 earlier review cycles; latest 8 shown)
  • reviewed 2026-08-03T15:54:54.555Z sha a33fdc7 :: needs maintainer review before merge. :: none
  • reviewed 2026-08-03T16:14:52.378Z sha a57ec42 :: needs maintainer review before merge. :: none
  • reviewed 2026-08-03T16:21:26.367Z sha 3497473 :: needs maintainer review before merge. :: none
  • reviewed 2026-08-03T19:00:02.014Z sha 3497473 :: needs maintainer review before merge. :: none
  • reviewed 2026-08-05T13:58:15.840Z sha 3497473 :: needs maintainer review before merge. :: none
  • reviewed 2026-08-06T01:57:14.709Z sha 3497473 :: needs maintainer review before merge. :: none
  • reviewed 2026-08-07T12:06:59.188Z sha 3497473 :: needs maintainer review before merge. :: none
  • reviewed 2026-08-07T13:53:50.157Z sha 3497473 :: needs changes before merge. :: [P1] Rebase the menu-card path onto descriptor cost styles

@epoch-chrono

Copy link
Copy Markdown
Author

Fair ask — the PR body claimed a live verification without showing anything inspectable. I have now added the artifacts under "Evidence from a real pay-as-you-go workspace", captured today against a live account with IDs redacted.

It covers three things rather than just the after state:

  • Before: the same account and cookie against main with this PR reverted, returning OpenCode API error: HTTP 500: HTTPError, plus the two log lines that precede it.
  • The raw HTTP: the three requests the provider makes, showing the workspace GET at 200, the subscription GET returning the =[],null) payload, and the POST retry returning 500.
  • After: the same account through the full fetch path on this branch, reporting monthly spend, limit and remaining balance.

On the fixed-point concern specifically: the evidence includes the raw billing fields, so the arithmetic is checkable rather than asserted. monthlyUsage 1556267684 / 1e8 = $15.56 against a monthlyLimit of 20 already in whole USD, and balance 1326177004 / 1e8 = $13.26, which sits above the reloadTrigger of 5 — consistent with auto-reload not having fired. The divisor itself is not something I chose: OpenCodeGoZenBalanceParser.billingScale already uses 1e8 for the Zen balance this app renders today.

Two limits on the proof, stated plainly: it exercises CodexBarCore directly rather than the packaged app, because this machine has Command Line Tools but no full Xcode, so the SwiftUI rendering is covered by OpenCodeMenuCardCostTests instead of a screenshot. And CI on this PR is still awaiting maintainer approval, so the suite has not run yet.

@clawsweeper clawsweeper Bot added 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. merge-risk: 🚨 auth-provider 🚨 Merging this PR could break OAuth, tokens, provider routing, model choice, or credentials. 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 29, 2026
@epoch-chrono

Copy link
Copy Markdown
Author

On the remaining schema/unit risk, it may help to know how this degrades in practice, since the failure modes are not symmetric.

If a field is renamed or dropped, nothing is displayed wrong. OpenCodeZenBillingParser.parse requires customerID and monthlyUsage before it trusts any number; without them it returns nil, the fetcher logs "billing payload did not contain monthly usage fields" and rethrows the original subscription error, so the provider goes back to showing an error rather than a plausible-looking wrong figure. A missing monthlyLimit or balance degrades to nil individually: spend still renders, just without the percentage or the balance line.

If the unit convention changes, the realistic direction under-reports rather than over-reports. Moving monthlyUsage/balance to whole USD, or to any smaller scale, makes the 1e8 divisor produce roughly $0.00 — wrong, but obviously wrong to whoever is looking at the card. The only way to silently inflate the number would be opencode.ai moving to a larger scale than 1e8, which would be an unusual direction for a currency field.

Worth being explicit about the limits: the fixture tests pin today's shape, so they will keep passing if opencode.ai changes the payload upstream — the graceful nil path above is the actual protection, not the tests. And the fallback only runs after the subscription path has already failed, so workspaces that still return a subscription never reach this code. If you would rather have a defensive sanity check on the parsed magnitude before merge, I am happy to add one.

Merge current main, preserve subscription-account classification on fallback, and add regression coverage.
@steipete

steipete commented Aug 2, 2026

Copy link
Copy Markdown
Owner

Completed the maintainer follow-up in a33fdc7695.

  • Merged current main (1a2aad7ee5) into the contributor branch without rewriting published commits.
  • Rejects the billing fallback when the billing payload still contains a subscription, preserving the original subscription API error instead of misclassifying the account as pay-as-you-go.
  • Adds the exact transient subscription-API failure regression.
  • Resolves the stale-base lint failures by separating the OpenCode fetcher's network and parsing extensions and extracting the pay-as-you-go cost helper.
  • Adds the 0.46.1 changelog entry with thanks to @epoch-chrono.
  • Preserves VISION.md exactly as it appears on current main.

The previous CI failures were stale-base issues: lint reported an 851-line OpenCodeUsageFetcher type body, while musl failed installing the Swift Static Linux SDK before either build step ran.

Proof on the pushed tree:

  • swift test --filter OpenCode — 130 tests passed.
  • make check — clean (SwiftFormat and SwiftLint: 0 violations).
  • make test — 779 selections across 65 groups; all 65 passed first attempt, with no retries or timeouts.
  • /Users/steipete/Projects/agent-skills/skills/autoreview/scripts/autoreview --mode commit --commit e7e5088417b08c12b0db3d374320d22a05dd805f — clean, no accepted/actionable findings. That review snapshot has the same PR tree as a33fdc7695 relative to current main.

No merge performed.

@clawsweeper clawsweeper Bot added the merge-risk: 🚨 compatibility 🚨 Merging this PR could break existing users, config, migrations, defaults, or upgrades. label Aug 3, 2026
@clawsweeper clawsweeper Bot added rating: 🦞 diamond lobster Very strong PR readiness with only minor maintainer review expected. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. 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: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. rating: 🦞 diamond lobster Very strong PR readiness with only minor maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. merge-risk: 🚨 auth-provider 🚨 Merging this PR could break OAuth, tokens, provider routing, model choice, or credentials. labels Aug 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

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. 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.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants