Skip to content

Cache menu card heights and skip closed merged-menu rebuild#1314

Merged
steipete merged 6 commits into
steipete:mainfrom
hhh2210:codex/menu-card-height-fingerprint
Jun 5, 2026
Merged

Cache menu card heights and skip closed merged-menu rebuild#1314
steipete merged 6 commits into
steipete:mainfrom
hhh2210:codex/menu-card-height-fingerprint

Conversation

@hhh2210
Copy link
Copy Markdown
Contributor

@hhh2210 hhh2210 commented Jun 5, 2026

Refs #1274.

Summary

  • keep menu-card height cache entries reusable across menu-content version invalidations when callers provide a width + content fingerprint
  • add a UsageMenuCardView.Model height fingerprint and pass it through the merged, stacked, history, and chart menu-card call sites
  • keep no-fingerprint callers version-scoped, with focused tests for stable content, changed content, legacy fallback, eviction, and provider scoping
  • after the latest Serious lag for the latest release #1274 retest, trim the fingerprint/account-info hot paths so the cache key no longer gives back most of the saved measurement work

Why

The latest #1274 samples after #1297 and #1314 split the remaining Merge Icons lag into two pieces:

  1. populateMenu -> addMenuCardSections -> MenuCardItemHostingView.measuredHeight, where each cache miss allocates a fresh NSHostingView just to measure card height.
  2. The follow-up cost introduced by this PR's first pass: heightFingerprint string formatting/hash work plus menuCardModel -> accountInfo -> loadAuthBackedCodexAccount -> CodexOAuthCredentialsStore.parse on repeated rebuilds.

#1286 moved close rebuild work off the synchronous dismiss path, and #1297 targets icon-observation churn. This PR remains the next separate measured-height slice, but now also addresses the obvious cost regressions called out in the #1314 retest. It still does not claim to close #1274; affected macOS 26.x / Merge Icons machines should retest the packaged build.

Claw/Copilot Follow-up

  • replaced raw text cache-key fields, including account email, with per-process salted text shapes (chars, utf8, lines, hash), so cache keys no longer retain raw PII or user-visible strings
  • encoded optional string presence explicitly, including storageText, so nil and "" no longer collapse into the same height identity
  • pruned stale version: fallback keys on invalidateMenus() while retaining content-fingerprinted keys, avoiding old version-scoped entries accumulating until the global 256-entry flush
  • made the height-cache tests use deterministic AccountInfo(email: nil, plan: nil) fixtures instead of UsageFetcher().loadAccountInfo()

Latest #1274 Retest Follow-up

@giuseppebisemi's #1314 retest showed the measured-height leaf dropped, but part of the work moved into the new fingerprint and the broader model construction still reparsed Codex OAuth credentials. Current head 254412f0 responds to that specific critique:

  • MenuCardHeightFingerprint.stringShape no longer uses CryptoKit digest formatting, String(format:), or withVaList; it uses a per-process salted Hasher value plus cheap UTF-8 newline counting.
  • Metric.heightFingerprint no longer calls percentLabel, so the fingerprint path no longer reaches PercentStyle.labelSuffix -> L(...) -> ProcessInfo.environment per metric.
  • Localization.isRunningTestsProcess() now caches the startup result instead of reading ProcessInfo.processInfo.environment on repeated localization calls.
  • UsageStore.accountInfo(for:) now has a short configRevision-scoped cache, so close/open rebuild bursts do not re-read and re-parse auth.json / JWT payloads each time.
  • menuCardModel now requests fallback account info only for providers whose metadata uses account fallback; non-Codex provider cards no longer pay for Codex auth parsing they will not display.

This is intentionally not full menu-model memoization. The first populateMenu, SwiftUI hosting/view construction, and actual model reuse remain separate future work for #1274.

Packaged macOS 26.5 Proof From The Measured-Height Slice

Local packaged-app run at earlier PR head 74528926, redacted for account/path data:

ProductVersion: 26.5
BuildVersion:   25F71
Bundle:         CodexBar.app packaged from PR head 74528926
Signing:        CODEXBAR_SIGNING=adhoc
Status item:    codexbar-merged (Merge Icons path)
Command:        CODEXBAR_SIGNING=adhoc Scripts/package_app.sh release
Launch proof:   Info.plist CodexGitCommit=74528926; codesign --verify --deep --strict passed

Repeated menu-open proof:

peekaboo menubar click --index 1 --verify --json
=> verified=true, executionTime=0.172299s

sample <CodexBar pid> 12 1 -mayDie -file /tmp/codexbar-pr1314-after-repeat-open.sample.txt
for 12 rounds:
  peekaboo menubar click --index 1 --json
  peekaboo press escape --foreground --json

Observed result across the 12 repeated open/close rounds:

open clicks: 12/12 success
open click execution time: min 0.039995s, avg 0.045455s, max 0.056921s
sample header: 10,363 main-thread samples, /usr/bin/sample, macOS 26.5 (25F71)

Stack occurrence counts in the sample:
MenuCardItemHostingView    0
measuredHeight             0
menuCardHeight             0
cachedMenuCardHeight       0
addMenuCardSections        0
populateMenu               1
NSHostingView              19
GraphHost                  3

Interpretation: on this macOS 26.5 packaged Merge Icons run, repeated unchanged merged-menu opens did not show the old MenuCardItemHostingView.measuredHeight / addMenuCardSections hot path in the sampled main thread. There are still ordinary SwiftUI NSHostingView attach/layout frames, so this proof supports the targeted measured-height cache slice rather than claiming all menu work is gone.

Current Head Validation

Current head: 254412f0.

  • swift test --filter UsageStoreCoverageTests (21 tests)
  • swift test --filter MenuCardHeightFingerprintTests (3 tests)
  • swift test --filter StatusMenuHeightCacheTests (6 tests)
  • make check (SwiftFormat lint + SwiftLint: 0 violations)
  • swift test (3246 tests / 385 suites)

Earlier CI had passed for PR head 74528926 (GitGuardian, build-linux-cli arm64/x64, and lint-build-test). Current head CI is expected to rerun, but I am not treating slow CI or Claw re-review as part of this local proof.

Remaining Scope

I would still keep #1274 open after this PR. #1314 now proves the repeated unchanged measured-height cache path on one local macOS 26.5 Merge Icons packaged run, and current head removes the most obvious fingerprint/account parse regressions from that slice. It does not remove the first populateMenu, does not reuse actual menu item hosting views, and does not fully memoize UsageMenuCardView.Model construction.

Skip closed merged-menu rebuild (folded in, head b6d1129e, #1274)

@giuseppebisemi's post-254412f0 retest confirmed this slice's targeted costs collapsed (heightFingerprint 76→3, CodexOAuthCredentialsStore.parse ~50→5, menuCardModel 105→33, addMenuCardSections 83→6, and the ProcessInfo.environment/percentLabel reads gone) and isolated the remaining freeze to a single structural path:

388  rebuildClosedMenuIfNeeded   (deferred close task)
126    populateMenu
 56    NSHostingView.layout()

Root cause: menuDidClose only defers the merged menu when it is already stale at close time, but observeStoreChanges invalidates with allowStaleContentDuringDataRefresh: true and still falls through to prepareAttachedClosedMenusIfNeeded() — so a merged menu that closed fresh is rebuilt while closed on the next background tick.

Rather than ship this as a third open PR, it is folded in here (same Merge Icons menu-rebuild domain). The fix: in prepareAttachedClosedMenusIfNeeded, when the menu being prepared is the merged menu, defer it unconditionally (insert into closedMenusDeferredUntilNextOpen and skip rebuildClosedMenuIfNeeded). Guarding inside prepareAttachedClosedMenusIfNeeded itself — rather than only the stale-refresh path — also covers allowStale=false invalidations (config / provider-order / manual), so the eager closed rebuild is gone on every path. That takes the 388-sample subtree to 0.

Correctness: menuWillOpen runs refreshMenuForOpenIfNeeded synchronously before the menu is registered open and before AppKit displays it, so the deferred merged menu is fully repopulated before it is shown — no stale flash or width jump — and the deferred-set entry is cleared on open, so it does not leak. The only remaining merged-menu populate is the one on open, the boundary @giuseppebisemi and I drew.

Validation at head b6d1129e:

  • swift test --filter StatusMenuOpenRefreshTests (29 tests) — includes the rewritten "closed merged menu defers rebuild until next open instead of pre-warming" assertion and the two pre-warm-deferral tests re-pointed to the non-merged fallback menu
  • make check (SwiftFormat lint + SwiftLint: 0 violations)
  • swift test (3246 tests / 385 suites)

This still does not remove the first populateMenu or reuse hosting views; it eliminates the redundant closed rebuild only.

Copilot AI review requested due to automatic review settings June 5, 2026 04:22
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

This PR updates menu-card height caching to support a “fingerprinted” cache key so stable card content can reuse measured heights even across invalidateMenus() calls, reducing unnecessary re-measurement.

Changes:

  • Replace content-version-based cache invalidation with a fingerprint-driven cache key strategy.
  • Add new tests covering fingerprinted vs unfingerprinted cache behavior across menu invalidation.
  • Thread heightCacheFingerprint through menu-card item creation and apply fingerprints to several menu sections.

Reviewed changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
Tests/CodexBarTests/StatusMenuHeightCacheTests.swift Updates existing cache test expectation and adds new fingerprinted/unfingerprinted cache tests plus a helper controller factory.
Sources/CodexBar/StatusItemController+ZaiHourlyChartMenu.swift Adds a stable fingerprint for the hourly-usage submenu height caching.
Sources/CodexBar/StatusItemController+UsageHistoryMenu.swift Adds a stable fingerprint for the usage-history submenu height caching.
Sources/CodexBar/StatusItemController+MenuTracking.swift Stops clearing the height cache on invalidateMenus(), relying on versioned/fingerprinted keys instead.
Sources/CodexBar/StatusItemController+MenuCardItems.swift Adds heightCacheFingerprint plumbing into makeMenuCardItem and the cache lookup.
Sources/CodexBar/StatusItemController+MenuCardHeightCache.swift Changes cache key from version to fingerprint and adds an optional fingerprint parameter.
Sources/CodexBar/StatusItemController+Menu.swift Uses model-derived fingerprints for multiple menu-card sections to stabilize caching across invalidations.
Sources/CodexBar/StatusItemController+CodexStackedMenu.swift Adds model-derived fingerprints for stacked cards.
Sources/CodexBar/MenuCardHeightFingerprint.swift Introduces a fingerprint generator based on UsageMenuCardView.Model content.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +6 to +8
"name=\(self.providerName)",
"email=\(self.email)",
"subtitle=\(self.subtitleText)",
Comment on lines +2 to +22
func heightFingerprint(section: String, additional: [String] = []) -> String {
MenuCardHeightFingerprint.join([
"section=\(section)",
"provider=\(self.provider.rawValue)",
"name=\(self.providerName)",
"email=\(self.email)",
"subtitle=\(self.subtitleText)",
"subtitleStyle=\(self.subtitleStyle.heightFingerprint)",
"plan=\(self.planText ?? "")",
"placeholder=\(self.placeholder ?? "")",
"credits=\(self.creditsText ?? "")",
"creditsHint=\(self.creditsHintText ?? "")",
"creditsCopy=\(self.creditsHintCopyText ?? "")",
"metrics=\(MenuCardHeightFingerprint.join(self.metrics.map(\.heightFingerprint)))",
"notes=\(MenuCardHeightFingerprint.join(self.usageNotes))",
"dashboard=\(self.inlineUsageDashboard?.heightFingerprint ?? "")",
"providerCost=\(self.providerCost?.heightFingerprint ?? "")",
"tokenUsage=\(self.tokenUsage?.heightFingerprint ?? "")",
"openaiAPI=\(self.openAIAPIUsage == nil ? "0" : "1")",
] + additional)
}
Comment on lines +553 to +555
heightCacheFingerprint: row.model.heightFingerprint(
section: "overview",
additional: ["storage=\(storageText ?? "")"]),
Comment on lines +199 to +212
private func makeHeightCacheController() -> StatusItemController {
let settings = self.makeSettings()
settings.statusChecksEnabled = false
settings.refreshFrequency = .manual
settings.mergeIcons = false
let store = self.makeCodexStore(settings: settings, dashboardAuthorized: false)
return StatusItemController(
store: store,
settings: settings,
account: UsageFetcher().loadAccountInfo(),
updater: DisabledUpdaterController(),
preferencesSelection: PreferencesSelection(),
statusBar: self.makeStatusBarForTesting())
}
Comment on lines 34 to 37
self.menuContentVersion &+= 1
self.menuCardHeightCache.removeAll(keepingCapacity: true)
if !allowStaleContentDuringDataRefresh {
self.latestRequiredMenuRebuildVersion = self.menuContentVersion
}
@clawsweeper
Copy link
Copy Markdown

clawsweeper Bot commented Jun 5, 2026

Codex review: needs real behavior proof before merge. Reviewed June 5, 2026, 3:33 PM ET / 19:33 UTC.

Summary
The branch adds content-fingerprinted menu-card height caching, a short configRevision-scoped account-info cache, closed merged-menu rebuild deferral, focused menu/cache tests, and a changelog wording update.

Reproducibility: yes. for the targeted redundant rebuild path from source: current main invalidates closed menus and prewarms attached menus, while the PR defers the merged menu until the next open. I did not reproduce the macOS 26.x lag live in this read-only review.

Review metrics: 2 noteworthy metrics.

  • Diff surface: 17 files; +570/-33. The PR touches menu rendering, menu tracking, account accessors, tests, and changelog text, so the risk is broader than a single cache helper.
  • Account cache TTL: 30 seconds. This new TTL defines how long displayed Codex account data may remain stale after auth data changes without a config revision bump.

Merge readiness
Overall: 🦐 gold shrimp
Proof: 🦐 gold shrimp
Patch quality: 🐚 platinum hermit
Result: blocked until stronger real behavior proof is added.

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

Rank-up moves:

  • [P1] Add redacted current-head macOS 26.x packaged Merge Icons proof covering repeated open/close and absence of measuredHeight plus closed merged-menu rebuild samples.
  • Have a maintainer explicitly accept or adjust the 30-second account-info cache freshness behavior.

Proof guidance:

  • [P1] Needs stronger real behavior proof before merge: The PR has useful terminal/sample proof for an earlier measured-height head, but needs redacted current-head packaged proof for the folded closed merged-menu deferral; updating the PR body should trigger a fresh ClawSweeper review, or a maintainer can comment @clawsweeper re-review. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.

Mantis proof suggestion
A real packaged macOS menu proof would materially reduce the remaining review uncertainty for the folded closed-rebuild deferral. A maintainer can ask Mantis to capture proof by posting a new PR comment that starts with the OpenClaw Mantis account mention, followed by:

visual task: verify current PR head in packaged CodexBar on macOS 26.x Merge Icons with repeated open/close sampling showing no measuredHeight or closed merged-menu rebuild hot path.

Risk before merge

  • [P1] Final-head runtime proof is still weaker than the code/tests: the packaged macOS 26.5 sample covers an earlier measured-height head, while the folded closed merged-menu deferral is supported by source, tests, and described retest context rather than current-head packaged output.
  • [P1] The new account-info cache can display stale Codex identity or plan text for up to 30 seconds after auth data changes when settings.configRevision is not bumped.
  • [P1] Height reuse now depends on every fingerprinted call site including all layout-affecting inputs; a missed field could reuse a stale menu-card height until eviction, a text-scale change, or app restart.

Maintainer options:

  1. Add final-head packaged proof (recommended)
    Ask for redacted terminal/sample output or a recording from the exact current head showing repeated Merge Icons open/close with no measuredHeight or closed merged-menu rebuild hot path.
  2. Accept the 30-second account cache
    Maintainers can intentionally accept transient stale account identity/plan text as the price of avoiding repeated auth.json/JWT parsing during menu rebuild bursts.
  3. Tighten auth freshness before merge
    If stale identity text is not acceptable, require a narrower invalidation path or shorter cache lifetime before landing the performance cache.

Next step before merge

  • [P1] Human review should decide whether the current-head proof gap and auth/cache freshness risks are acceptable; automation cannot supply the contributor’s packaged macOS runtime proof.

Security
Cleared: No concrete security or supply-chain issue was found; the sensitive area is an in-memory account-info cache and salted text-shape fingerprinting rather than new dependency, secret, or execution surface.

Review details

Best possible solution:

Land this after redacted current-head packaged macOS 26.x Merge Icons proof covers both repeated measured-height cache hits and skipped closed merged-menu rebuilds, with maintainer acceptance or adjustment of the account-cache freshness window.

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

Yes for the targeted redundant rebuild path from source: current main invalidates closed menus and prewarms attached menus, while the PR defers the merged menu until the next open. I did not reproduce the macOS 26.x lag live in this read-only review.

Is this the best way to solve the issue?

Unclear until final runtime proof is added. The implementation is a plausible narrow performance slice with focused tests, but the auth-cache freshness tradeoff and current-head packaged behavior need maintainer review before merge.

AGENTS.md: found and applied where relevant.

Codex review notes: model gpt-5.5, reasoning high; reviewed against de55f4850b8d.

Label changes

Label justifications:

  • P1: The PR targets a user-visible Merge Icons lag regression affecting menu responsiveness on macOS 26.x systems.
  • merge-risk: 🚨 auth-provider: The diff changes Codex account-info parsing and caching, which can affect displayed account identity and plan freshness.
  • merge-risk: 🚨 availability: The diff changes main-thread menu rebuild and height-measurement behavior; an unsafe cache or deferral path could leave menus clipped, stale, or laggy.
  • rating: 🦐 gold shrimp: Overall readiness is 🦐 gold shrimp; proof is 🦐 gold shrimp and patch quality is 🐚 platinum hermit.
  • status: 📣 needs proof: The PR needs real behavior proof before ClawSweeper can clear the contributor ask. Needs stronger real behavior proof before merge: The PR has useful terminal/sample proof for an earlier measured-height head, but needs redacted current-head packaged proof for the folded closed merged-menu deferral; updating the PR body should trigger a fresh ClawSweeper review, or a maintainer can comment @clawsweeper re-review. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.
Evidence reviewed

What I checked:

Likely related people:

  • hhh2210: Related merged menu performance work in Reduce merged menu rebuild latency #1286 introduced the current menu-card height cache/tracking files, and the same contributor authored the active performance slice. (role: recent feature owner; confidence: high; commits: 65e39f4dcb3a, de55f4850b8d; files: Sources/CodexBar/StatusItemController+MenuTracking.swift, Sources/CodexBar/StatusItemController+MenuCardHeightCache.swift, Tests/CodexBarTests/StatusMenuOpenRefreshTests.swift)
  • steipete: The repository owner imported the current baseline history and force-pushed the latest changelog-only commit on this PR, so release-note and final-merge routing likely goes through them. (role: repository owner and recent adjacent editor; confidence: medium; commits: 723734ef3422, 400f98aa0e9b; files: CHANGELOG.md, Sources/CodexBar/UsageStore+Accessors.swift)
  • giuseppebisemi: The PR body cites their macOS 26.5 retests and samples as the user-behavior signal driving the measured-height and closed-rebuild slices. (role: field profiler and retester; confidence: medium)
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.

@clawsweeper clawsweeper Bot added rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. labels Jun 5, 2026
@hhh2210
Copy link
Copy Markdown
Contributor Author

hhh2210 commented Jun 5, 2026

@clawsweeper re-review

Updated the PR body with packaged macOS 26.5 / Merge Icons proof from the local PR-head bundle.

Patch-quality blockers already addressed in 74528926:

  • raw email/raw text fields are no longer retained in height-cache keys; layout text now uses per-process salted SHA-256 text shapes with length/line metadata
  • optional fields now preserve presence, including storageText, so nil and "" do not share a height identity
  • invalidateMenus() now prunes stale version: fallback keys while retaining content-fingerprinted keys, avoiding old version-scoped entries accumulating until the global 256-entry flush
  • height-cache tests now use deterministic AccountInfo(email: nil, plan: nil) fixtures
  • added MenuCardHeightFingerprintTests for raw text non-retention and nil/empty field identity

Packaged runtime proof now added to the PR body:

  • macOS 26.5 (25F71), arm64
  • CODEXBAR_SIGNING=adhoc Scripts/package_app.sh release
  • launched CodexBar.app with CodexGitCommit=74528926; codesign --verify --deep --strict CodexBar.app passed
  • Peekaboo verified the codexbar-merged status item path
  • 12 repeated menu open/escape rounds succeeded; open click time min/avg/max was 0.039995s / 0.045455s / 0.056921s
  • /usr/bin/sample captured 10,363 main-thread samples during those rounds
  • sample occurrence counts: MenuCardItemHostingView=0, measuredHeight=0, menuCardHeight=0, cachedMenuCardHeight=0, addMenuCardSections=0, populateMenu=1, NSHostingView=19, GraphHost=3

Local validation after the update:

  • swift build
  • swift test --filter MenuCardHeightFingerprintTests (2 tests)
  • swift test --filter StatusMenuHeightCacheTests (6 tests)
  • make check (SwiftFormat lint + SwiftLint: 0 violations)
  • swift test (3244 tests / 385 suites)
  • CI for PR head 74528926 is green: GitGuardian, build-linux-cli arm64/x64, and lint-build-test

Remaining scope: this is still a targeted cache-policy slice. It reduces the repeated unchanged measured-height path on one macOS 26.5 packaged Merge Icons run, but does not remove the first populateMenu, does not reuse actual menu item hosting views, and should not close #1274 without broader affected-user retesting.

@clawsweeper
Copy link
Copy Markdown

clawsweeper Bot commented Jun 5, 2026

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

Re-review progress:

@clawsweeper clawsweeper Bot added P1 Urgent regression or broken agent/channel workflow affecting real users now. merge-risk: 🚨 availability 🚨 Merging this PR could cause crashes, hangs, restart loops, stalls, or process outages. 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. and removed rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. labels Jun 5, 2026
@hhh2210 hhh2210 changed the title Cache menu card heights by content Cache menu card heights and skip closed merged-menu rebuild Jun 5, 2026
@clawsweeper clawsweeper Bot added rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. merge-risk: 🚨 auth-provider 🚨 Merging this PR could break OAuth, tokens, provider routing, model choice, or credentials. and removed 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. labels Jun 5, 2026
hhh2210 and others added 6 commits June 5, 2026 12:26
Menu cards size from semantic text styles (.body/.footnote/.headline/…)
that scale with the macOS system text-size / Dynamic Type setting. That
scale was in neither the content fingerprint nor the cache key, and no
observer clears the cache when it changes, so a runtime text-size change
could return a height measured at the old scale (clipped or over-tall
cards) until the next data refresh or the 256-entry flush.

Add the resolved .body point size to MenuCardHeightCacheKey. Widening the
key is the safe direction: identical scale keeps hitting as before, a
changed scale forces a fresh measurement. It can never return a stale
height, only (at worst) re-measure once after a scale change.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
In Merge Icons mode prepareAttachedClosedMenusIfNeeded eagerly rebuilt the closed merged menu on every store tick, running a full main-thread populateMenu (incl. SwiftUI hosting-view layout) that menuWillOpen redoes on display anyway. Defer the merged menu until next open instead, taking the residual close-path freeze to zero. Refs steipete#1274.
@steipete steipete force-pushed the codex/menu-card-height-fingerprint branch from ef527e8 to 400f98a Compare June 5, 2026 19:27
@steipete steipete merged commit 88eb603 into steipete:main Jun 5, 2026
4 checks passed
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. merge-risk: 🚨 availability 🚨 Merging this PR could cause crashes, hangs, restart loops, stalls, or process outages. P1 Urgent regression or broken agent/channel workflow affecting real users now. rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Serious lag for the latest release

3 participants