Skip to content

Sync upstream v0.49.2 and prepare iOS 1.21.0 - #89

Merged
o1xhack merged 195 commits into
mobile-devfrom
upstream-sync/v0.49.2-mobile.1.21.0
Aug 17, 2026
Merged

o1xhack merged 195 commits into
mobile-devfrom
upstream-sync/v0.49.2-mobile.1.21.0

Conversation

@o1xhack

@o1xhack o1xhack commented Aug 17, 2026

Copy link
Copy Markdown
Owner

Summary

  • merge upstream releases v0.48.0 through v0.49.2 as one release train
  • preserve fork Mobile sync, Production CloudKit, CI and release invariants
  • add generic provider details, Fireworks, IBM Bob and custom plugin presentation on iOS
  • bump Mac to 0.49.2.1 / 116.1 and iOS to 1.21.0 (193)
  • add four-language release notes and compatibility evidence

Verification

  • Mac: 8796 tests across 851 suites, 0 failures
  • iOS: 632 tests in authoritative xcresult, 0 failures or skips
  • 16/16 substituted old/new sync compatibility combinations pass
  • CloudKit Production schema audit: NO_DEPLOY
  • signed, notarized and stapled Mac draft candidate verified
  • final independent review: P0/P1/P2/blocker = 0

Release closeout

Closes #77
Closes #78
Closes #79
Closes #80
Closes #81

Peter Steinberger and others added 30 commits August 3, 2026 09:57
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* Add scoped-weekly (Fable) percentage as a menu-bar layout token

Claude's model-scoped weekly carve-outs (the "Fable only" window from #1851)
already show in the dropdown and in quota notifications, but the always-visible
menu bar could only show session, weekly, or automatic. This adds a scoped-weekly
token so the promo-window limit can sit in the bar.

- New PercentWindow.scopedWeekly, shown with an "F" prefix, selectable in the
  layout editor (palette, label, live and representative previews).
- scopedWeeklyWindow resolver matches the claude-weekly-scoped-* id prefix rather
  than a model name; when several are active it shows the most constrained one.
- The scoped-weekly percent is added to the icon-observation signature so a
  scoped-only change refreshes the title, mirroring weekly= and avoiding the
  stale-title problem from #2300 and #2299.
- Absent window renders the standard "–" placeholder; editor label localized.

Addresses #2360.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* Address review: label scoped-weekly token by active model

Codex flagged that the token hard-coded "F" / "Fable only" while the resolver
accepts any claude-weekly-scoped-* window and picks the most constrained, so a
non-Fable window could be shown under the wrong model label.

- scopedWeeklyNamedWindow now returns the NamedRateWindow.
- The .scopedWeekly token derives its prefix from the active window's title
  (first letter) and its accessibility text from the full title, instead of a
  fixed "F" / "Fable only".
- Carry the title through MenuBarLayoutRenderData and include it in the
  icon-observation signature, so a model change refreshes the title.
- Resolver test now asserts a non-Fable most-constrained window carries its title.

The editor palette label stays "Fable %" (a proper noun that reads the same across
locales); a generic name is left as a naming choice.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* Add menu bar pace layout tokens

The 0.45 layout editor replaced the old Percent/Pace/Both display modes,
but no token exposes the signed pace delta the Both mode used to render.
`Runs out` is not a substitute: it answers when a window ends, always
estimating from the weekly (or automatic) lane, while pace answers how far
off the sustainable rate usage currently runs.

Add Session/Weekly/Auto pace tokens that mirror the percent tokens' window
selection and reuse the existing `MenuBarDisplayText.paceText` formatting
(`+11%` ahead of the rate, `-8%` behind, `0%` on pace). Each token resolves
pace for its own window, so Weekly pace never borrows the session delta.

Pace needs the store's historical dataset and work-day setting, so it is
resolved upstream like `runsOut` through a shared `menuBarLayoutPaceText`
helper that both the status item and the editor preview call. The existing
3% expected-usage floor in `weeklyPace` still applies, so a token renders
the en-dash placeholder early in a window while its siblings stay visible.

Refs #2534

* Include layout pace tokens in the icon observation signature

Pace values change with the historical dataset, the work-day setting,
and the clock, none of which move the percent fields already hashed by
providerStoreIconObservationSignature. A historicalPaceRevision bump
therefore woke the icon observer but produced an unchanged signature,
so updateIcons() was skipped and a custom pace token kept its stale
value until an unrelated icon change forced a redraw.

Contribute the active layout's pace values to the signature the same
way cost and account tokens already do, gated on the layout actually
containing a pace token. The regression test renders two snapshots with
identical used percents but different resets: without this fix both
signatures were identical.

Refs #2534

* docs: credit menu bar pace contributor

* fix: localize scoped weekly label

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Co-authored-by: Petr Kratochvíl <krato@krato.cz>
Co-authored-by: Peter Steinberger <steipete@mac-studio-sf2.local>
* Add one-shot dashboard snapshot command

* Fix dashboard pricing refresh policy

* Honor Cursor source policy in dashboard

* test: dedupe cliExecutableURL helper after branch update

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
Co-authored-by: Peter Steinberger <steipete@mac-studio-sf2.local>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
* feat: add provider plugin runtime

* feat: convert synthetic venice and crof to JS plugins

* test: prove JS provider parity

* docs: document provider plugin prototype

* fix: satisfy plugin runtime lint checks

---------

Co-authored-by: Peter Steinberger <steipete@mac-studio-sf2.local>
Co-authored-by: Peter Steinberger <steipete@mac-studio-sf2.local>
Co-authored-by: Peter Steinberger <steipete@mac-studio-sf2.local>
Co-authored-by: Peter Steinberger <steipete@mac-studio-sf2.local>
Co-authored-by: Shun Min Chang <ji394m6y7@gmail.com>
Co-authored-by: Peter Steinberger <steipete@mac-studio-sf2.local>
Co-authored-by: haoli <haoli@local.dev>
Co-authored-by: Peter Steinberger <steipete@mac-studio-sf2.local>
Co-authored-by: haoli <haoli@local.dev>
* feat: add declarative provider detail model

* feat: render declarative provider details

* feat: bridge provider details from JavaScript

* feat: convert detail providers to JavaScript

* style: satisfy provider detail test lint

* fix: align z.ai plugin quota lanes

---------

Co-authored-by: Peter Steinberger <steipete@mac-studio-sf2.local>
* Add live OhMyPi agent session discovery

Detect running OhMyPi harness processes, correlate them with bounded session metadata, and expose normalized sessions through the existing CLI and menu paths.

* Address OhMyPi review correlation gaps

Resolve OhMyPi metadata per live process environment, reject stale records, and isolate directory scan budget so existing provider discovery remains intact. Add focused regression coverage and document the fail-closed behavior.

* Preserve existing session metadata during OhMyPi scans

Give OhMyPi its own bounded directory budget so Codex and Claude correlation remain available, with regression coverage for the shared-provider behavior.

* Preserve legacy session JSON compatibility

Add an explicit v2 session payload for OhMyPi while keeping legacy remote clients decodable, and document and test the negotiated fallback.

* Expose OhMyPi in local session JSON

Keep the documented local --json output complete while preserving the remote v2-first compatibility fallback for older installations. Update CLI help, focused protocol coverage, and session documentation to distinguish current local output from legacy remote responses.

* fix(sessions): preserve legacy JSON compatibility

* Correct session JSON protocol overview

* feat(sessions): unify Pi-family discovery

Co-authored-by: William Mitchell <wdmitchell.uk@gmail.com>

---------

Co-authored-by: William Mitchell <wdmitchell.uk@gmail.com>
Co-authored-by: Peter Steinberger <steipete@mac-studio-sf2.local>
Co-authored-by: Peter Steinberger <steipete@mac-studio-sf2.local>
* fix: show cached spend while refreshing

Co-authored-by: hhh2210 <hzy2210@gmail.com>

* test: add cached spend refresh proof

---------

Co-authored-by: Peter Steinberger <steipete@mac-studio-sf2.local>
Co-authored-by: hhh2210 <hzy2210@gmail.com>
Co-authored-by: Peter Steinberger <steipete@mac-studio-sf2.local>
Co-authored-by: haoli <haoli@local.dev>
* Centralize Codex priority pricing

* fix: define Codex Fast USD pricing

* test: split pricing expectation math for CI type-checker

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Co-authored-by: Bryan Font <bfont@me.com>
Co-authored-by: Peter Steinberger <steipete@mac-studio-sf2.local>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: Peter Steinberger <steipete@mac-studio-sf2.local>
Co-authored-by: Derek Zeng <zengzhuoxi@gmail.com>
* feat: extend plugin host and convert providers

* fix: align z.ai plugin credential routing

---------

Co-authored-by: Peter Steinberger <steipete@mac-studio-sf2.local>
* test: characterize provider instance identity

* feat: add provider instance identity seam

---------

Co-authored-by: Peter Steinberger <steipete@mac-studio-sf2.local>
* feat: add user-installed provider plugins

* fix: broker owns plugin HTTP representation headers

Apply broker-owned Accept, Accept-Encoding, and Content-Type after
plugin-supplied headers so a plugin cannot relax the user-plugin
response boundary. Test transport gains configurable response headers.

* build: add reproducible sucrase bundle verification script

Regenerates and verifies Sources/CodexBarCore/Resources/Plugins/
sucrase-3.35.1.min.js from the official npm artifact (sucrase@3.35.1,
esbuild@0.25.8 pinned, IIFE browser bundle). Expected SHA-256
4d997e15b72cbc9ccf6e743c30c6eb48bf4533f6709852367b40766be5eba70b was
independently reproduced by the coordinator from the npm registry;
'check' mode fails closed on any mismatch.

* fix: gate user-plugin registry lookup for non-JavaScriptCore platforms

Linux CLI builds compile CodexBarConfig without the plugin runtime;
unknown plugin config entries are dropped with the existing warning,
matching the documented macOS-only plugin boundary.

---------

Co-authored-by: Peter Steinberger <steipete@mac-studio-sf2.local>
Co-authored-by: Peter Steinberger <steipete@mac-studio-sf2.local>
* test: keep widget-snapshot container I/O out of test runs

AdaptiveRefreshHeuristicsTests (and any suite reaching persistWidgetSnapshot without a save override) could hang forever on macOS 26 hosts: WidgetSnapshotStore.load() opens the real app-group container file and the open() can block indefinitely behind app-data (TCC) gating. Gate persistWidgetSnapshot so test runs only persist when a test explicitly installs _test_widgetSnapshotSaveOverride, and pin the behavior with regression tests.

* test: open widget-snapshot gate for injected snapshot URLs

Main's plugin series added a widgetSnapshotURL injection seam that promotion tests rely on; the gate now admits it alongside the save override and replaces the duplicate inline DEBUG guard.

---------

Co-authored-by: Peter Steinberger <steipete@mac-studio-sf2.local>
* feat: add standalone token activity heatmap

* fix: preserve token activity coverage

* fix: complete activity heatmap navigation

* fix: expose daily activity accessibility

* fix: publish daily accessibility semantics

* fix: expose dates in activity accessibility

* fix: expose weekly activity accessibility

* feat: derive token activity from shared cache

---------

Co-authored-by: Yuxin Qiao <104957188+Yuxin-Qiao@users.noreply.github.com>
Co-authored-by: Peter Steinberger <steipete@mac-studio-sf2.local>
* Expose provider-native cost scans

* feat(cli): expose Codex cost scan completeness

Co-authored-by: NickGuAI <yu.gu.columbia@gmail.com>

---------

Co-authored-by: Peter Steinberger <steipete@mac-studio-sf2.local>
* feat: resizable settings sidebar with persisted width

Replace the fixed 260pt settings sidebar with a drag-resizable one
(200-380pt, persisted via AppStorage). The divider stays the original
SwiftUI hairline; an input-only AppKit strip overlaid on the detail
pane's leading edge handles dragging, so the HStack layout is untouched.
Hover cursor via .pointerStyle(.columnResize) on macOS 15+ plus an
explicit-rect tracking area (visibleRect spans the whole window under
NSHostingView, so .inVisibleRect never fired).

* fix: hold the sidebar resize cursor with a cursor rect

The hover cursor was set imperatively on mouse enter/move, which SwiftUI
undid on its next render — the settings panes re-render continuously, so
the resize cursor only flashed. Cursor rects are declarative: AppKit
re-asks the view on every invalidation, so the cursor holds.

Measured on a probe harness hosting this view under a 20Hz re-render
loop, sampling NSCursor.currentSystem at 25Hz while an external driver
moved the pointer: imperative-only gave 0% resize on hover and 40%
during drag; with cursor rects, two clean transitions (arrow -> resize
on entry, back on exit) and 100% held across hover and drag.
Mechanical ./Scripts/lint.sh format output; #2660 landed with docComments
and wrap-body violations that broke CI on main.
* Wait for OpenCode Go Zen balance in CLI usage reads

* fix: bound OpenCode Go CLI balance lookup

* Keep OpenCode Go Zen wait scoped to usage reads

* Measure OpenCode Go Zen wait from task start

---------

Co-authored-by: Peter Steinberger <steipete@mac-studio-sf2.local>
* feat: per-model cost breakdown for OpenCode Go's daily cost history

Extract each local assistant message's modelID from opencode.db (the
real model behind the constant opencode-go Zen-proxy providerID) and
group cost/request counts by (day, model) instead of just by day, so
the shared Cost history chart shows a per-model breakdown for
OpenCode Go the same way it already does for Claude/Codex. Rows with
no modelID fall back to an "unknown" bucket instead of being dropped.

* fix: use lowercase docs/claude.md link to pass case-sensitive CI lint

macOS resolves docs/CLAUDE.md to the same file as docs/claude.md, but
the Linux lint runner's case-sensitive filesystem doesn't, failing the
documentation-link check.

* fix: normalize the trimmed model id when grouping OpenCode Go costs

The grouping key used the untrimmed modelID even though emptiness was
checked against the trimmed value, so a model id with incidental
leading/trailing whitespace would form its own bucket instead of
merging with the clean value for the same model. Group by the trimmed
value consistently, and add regression tests for whitespace-only and
whitespace-padded model ids.
* Fix ETXTBSY race in claude-swap CLI card test

The test wrote a shell script, set mode 0755, and executed it immediately.
Under swift test --parallel a concurrent fork inherits the still-open write
descriptor, so execve fails with ETXTBSY and the launch reports Cocoa 256.

Write the script body as data and execute a checked-in trampoline that reads
it, so execve only ever touches a file no test process has written.

Measured in swift:6.3.3-noble on arm64: 112 failures in 600 attempts with the
old shape, 0 in 600 with the trampoline.

* Apply ETXTBSY fix to the Linux test target

The first commit only touched Tests/CodexBarTests, which Package.swift builds
on macOS alone. The Linux job compiles CodexBarLinuxTests from TestsLinux, so
the race remained in the target that actually flaked.

Convert all three TestsLinux sites through a shared FakeExecutable helper, and
keep the macOS mirror in step.

Verified on Linux arm64 in swift:6.3.3-noble: 355 tests in 53 suites pass.
* Pin Perplexity promo expiry formatter to en_US_POSIX

The formatter set dateFormat but not locale, so MMM rendered in the user's
language inside an otherwise English string and diverged from the JS plugin
projection. Matches the en_US_POSIX pinning already used by every other
provider formatter.

Refs #868

* Assert the Perplexity promo expiry locale pin in tests

Parity coverage only trips on a non-English host, so an English runner
passes both before and after the regression. Add assertions that hold on
every host: the formatter keeps its en_US_POSIX locale, and the rendered
month stays ASCII English.

* Move the promo expiry fixture off the UTC month boundary

The formatter keeps the host time zone, so a midnight-UTC January instant
renders as Dec 31 west of UTC and failed the month assertion there even
with the locale pin correct.
steipete and others added 23 commits August 9, 2026 23:35
Co-authored-by: weirdo-adam <adam.ngc2237@gmail.com>
Co-authored-by: Yuxin Qiao <104957188+Yuxin-Qiao@users.noreply.github.com>
Co-authored-by: Yuxin Qiao <104957188+Yuxin-Qiao@users.noreply.github.com>
Co-authored-by: Yuxin Qiao <104957188+Yuxin-Qiao@users.noreply.github.com>
Co-authored-by: Jae Hyun <betive37@gmail.com>
* fix: deduplicate synced account usage

* fix: preserve synced account email aliases

* refactor: clarify synced alias ownership

* test: prove local snapshot ownership boundary
Co-authored-by: Yuxin Qiao <104957188+Yuxin-Qiao@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment