Skip to content

chore: sync fork with upstream (12 commits) - #57

Merged
cte13 merged 13 commits into
mainfrom
chore/upstream-sync
Sep 18, 2026
Merged

cte13 merged 13 commits into
mainfrom
chore/upstream-sync

Conversation

@cte13

@cte13 cte13 commented Sep 18, 2026

Copy link
Copy Markdown
Owner

Summary

Merges chattymin/PokeTokenBar main (12 commits) into the fork.
After this merge, the fork is 0 commits behind upstream.

Important

Merge with "Create a merge commit" — do not squash, or the upstream ancestry is lost and GitHub shows phantom "commits behind" counts.

Upstream highlights:

Conflict resolutions and adaptations

  • UsageStore: Combined upstream's zero-token synthetic activity check (> 0) with the fork's activeProviders visibility filtering. Preserved the fork's Antigravity credential revocation / summary methods alongside upstream's antigravityHasTokenFile property.
  • PopoverView: Preserved the fork's OpenCode Go limit rows (with updated span: parameter for pacing), and adopted upstream's antigravityHasTokenFile check and quota pacing markers.
  • AntigravityRateLimitsProvider: Unified token-file reading method naming (readTokenFile), kept both upstream CLI/IDE path discovery tests and the fork's credential persistence and auto-renewal tests.
  • PerformanceTests: Included both OpenCode Go limit strings and localized Antigravity group window labels in speech bubble tests.
  • Test infrastructure: Added AppEnv.allowLiveFetchForTesting so CredentialSwitchCacheTests can safely exercise mocked URLProtocol refreshes without tripping live network guards, and hardened SessionKeySettingsRenderingTests against CPU load spikes during full suite runs.

Type of change

  • Bug fix
  • New feature
  • Refactor / cleanup
  • Documentation
  • Other: upstream sync (merge commit)

UI changes

Upstream UI additions merged:

  • Pace marker lines on quota bars.
  • Bulk Rare Candy slider and growth previews in Bag.
  • Floating pet toggle in footer.
  • Skipped release notices in Settings.
  • Unown letter forms collection in Pokédex.
Before After
Quota bars displayed usage percentage without pace indicator Quota bars include a pace marker showing target linear burn rate
Rare Candy used one at a time Bulk Rare Candy use slider with preview
Settings showed "up to date" even if a release was skipped Shows notice and button to un-skip release

Checklist

  • swift build and swift test pass locally (1331 tests, 0 failures, 16 skipped); ./scripts/test-gate.sh passes (93.18% coverage >= 75%); iOS target also builds (PokeTokenBariOS simulator build succeeded)
  • PR title and description are written in English
  • UI changes are described above (before/after — images optional)
  • No copyrighted assets, secrets, or private tooling references are committed (see CONTRIBUTING)
  • Tests were added or updated for this change

florianbehrend and others added 13 commits September 19, 2026 00:51
…navailable" (chattymin#304)

* fix(pricing): add exact rows for the Claude 5 family

`claude-opus-5` and `claude-sonnet-5` were absent from `ModelPricing.table`,
so `estimatedCost` returned nil, `LocalUsageReader.Bucket.add` merged
`.unavailable`, and `UsageCost.text` rendered "unavailable" instead of an
amount. Since the Claude 5 family is the current generation, that blanked the
cost for effectively all Claude usage.

These models were priced only through the `contains("opus")` model-family
fallback, which chattymin#289 removed without adding replacement rows.

Rates from https://platform.claude.com/docs/en/about-claude/pricing:
Opus 5 $5/$25 with $6.25 5m cache write and $0.50 cache read; Sonnet 5
$2/$10 with $2.50 and $0.20.

`testPricingExactAndFallbackAndZero` asserted `rate(for: "claude-opus-5") ==
.zero`, pinning the defect as intended behaviour; it now asserts the real
rates and uses an unreleased identity for the unpriced case.

Adds `testModelsReadFromProviderLogsAreAllPriced` as the inverse guard to
`testUnknownNamesNeverBorrowFamilyPrices`: the existing test only proves an
unknown name borrows no price, and could never report a current model going
unpriced. Verified to fail against the pre-fix table.

Fixes chattymin#303

* docs(pricing): cite the Anthropic source and check date for the Claude rows

The table header only carries a `checked` date and URL for the OpenAI
pricing page, so the Claude rows had no source citation at all. Records
where the Claude 5 rates came from and when they were verified, in the
same style as the existing header comment.
…tymin#309)

The model id is a separate SKU from Flash, and an unknown name returns no estimate.
…hattymin#307)

A value that saturates Int.max makes the following add SIGTRAP, and the same file kills every refresh until it is removed.
…tymin#311)

The banner button was labeled Later but permanently skipped that version, so Check now claimed the installed build was latest.
…ymin#323)

Share one L.antigravityGroupTitle helper across popover, limit alerts,
and rare-candy windows so non-English UI no longer mixes in API English.
…om the footer (chattymin#302)

A still-valid cached Claude token hid an in-place account switch from the
Refresh button, because only a 401 cleared the cache. User refresh now skips
that cache. The popover footer can show the pet again after Hide, using the
same floatingPetEnabled flag as Settings.
* feat: show a pace marker on quota bars

Quota bars only warned once a window was nearly exhausted. They said how
much was spent, never whether the spending was fast for how far into the
window it was — the difference between "62% with four hours left" and
"62% with twenty minutes left".

Draw a 1px tick at the point an even burn would have reached by now. Fill
past the tick means the window will run out before it resets.

The marker needs the window length, which each provider reports its own
way, so LimitWindowSpan collects those mappings (Codex: explicit minutes,
Antigravity: window name, Claude: entry kind or legacy field name) and
every row passes a plain TimeInterval down. Rows whose length is unknown
(Codex personal spend limit) simply get no marker.

Two deliberate restraints:

- No timer. A 5-hour window moves 0.33%p per minute, so the existing
  refresh interval and reopening the popover already carry the tick
  along, and the always-on animation cost stays untouched.
- Out-of-range elapsed fractions hide the marker instead of clamping. A
  5-hour window starts at the first request, so an idle window can carry
  a stale resets_at; pinning that to either end would claim the window
  just started or just ended.

Marker position runs through the same displayPercent conversion as the
fill, so remaining mode cannot flip one without the other. The rendering
test reads painted pixels rather than the view tree, because a SwiftUI
shape never becomes an NSView and a pure-function test alone would not
notice the view passing a hardcoded mode.

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

* fix: size the pace marker to the painted track, not the layout box

The tick was framed against the overlay's geometry — 12pt, the ProgressView's
layout box — while the track it marks is only 6pt of that box. A 16pt tick on a
6pt bar read as a staple laid over the bar rather than a mark on it.

Anchor the tick to the track instead: 6pt plus 2pt of overhang per side, with
rounded ends at 2.5pt wide. 2.5pt lands on exactly 5px at 2x, so the tick stays
crisp instead of smearing across a half pixel the way a 1pt hairline can.

The existing rendering test only looks for the darkest *column*, so it passes
whichever box the height came from. testPaceMarkerStaysCloseToPaintedTrackHeight
measures the painted height against the painted track; putting the old frame
back makes it fail (15pt against 10pt), which is how it was checked.

Also teach the screenshot generator to render the pace marker, so the release
asset pass covers it. Bars wrap AppKit controls, which ImageRenderer draws as an
unsupported placeholder, so that helper captures through an NSWindow.

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

* docs: record that generated screenshots lose the control tint

The screenshot helper captures through an NSWindow, which gets the bars drawn at
all, but not in colour: a test process never becomes active, so AppKit draws the
progress indicator unemphasized and the fill lands grey instead of tinted.
Activation policy, NSApp.activate, key/main overrides and a compositor capture of
the on-screen window were all tried and all stayed grey.

Say so where the helper is defined, so its output is read as a layout check and
promotional images keep coming from captures of the running app.

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

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
* feat: display offline waiting hint when egg hatch is delayed by network

* fix: prevent transient online flicker by scoping offline hint strictly to isHatchWaitingForNetwork

* fix: reset isHatchWaitingForNetwork on save import and successful network fetch

* fix: harden delayed egg hatch retries

* test: return suspended provider results
Co-authored-by: Patrick.Park <pdm001125@naver.com>
Conflict resolutions and adaptations:
- UsageStore: combined upstream's zero-token synthetic activity check (> 0) with the fork's activeProviders visibility filtering, and preserved the fork's Antigravity credential revocation / summary methods alongside upstream's antigravityHasTokenFile property.
- PopoverView: preserved fork's OpenCode Go limit rows (with updated span parameters for pacing), and adopted upstream's antigravityHasTokenFile check and pace markers.
- AntigravityRateLimitsProvider & tests: resolved token file helper naming (readTokenFile), included upstream's CLI/IDE path discovery tests alongside fork's credential persistence and auto-renewal tests.
- PerformanceTests: included both OpenCode Go limit strings and localized Antigravity group window labels in the speech bubble performance tests.
- Test safety: allowed testing bypass (AppEnv.allowLiveFetchForTesting) for CredentialSwitchCacheTests to safely exercise mocked URLProtocol refreshes without tripping live network guards, and hardened SessionKeySettingsRenderingTests scrolling wait against CPU load spikes.
@cte13
cte13 merged commit 37a574b into main Sep 18, 2026
@cte13
cte13 deleted the chore/upstream-sync branch September 22, 2026 01:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

9 participants