Skip to content

Fix menu bar layout editor drag-and-drop - #3121

Merged
steipete merged 13 commits into
steipete:mainfrom
J2TeamNNL:upstream-pr/layout-editor-drag
Aug 21, 2026
Merged

Fix menu bar layout editor drag-and-drop#3121
steipete merged 13 commits into
steipete:mainfrom
J2TeamNNL:upstream-pr/layout-editor-drag

Conversation

@J2TeamNNL

Copy link
Copy Markdown
Contributor

Summary

Drag-and-drop in the menu bar layout editor never starts a drag session, so the trash
drop zone ("Drag here to remove") and chip reordering are unreachable with the mouse —
the Delete key is the only way to remove a token.

The chips are Buttons with .draggable attached. On macOS the button's gesture
recognizer claims the mouse-down before the drag can begin. Attaching .draggable to the
button's label (as the placed chips currently do) does not help either, because the
button still owns the gesture.

Changes

  • New MenuBarLayoutEditorChip: a plain draggable view instead of a Button, keeping
    click selection, .focusable() + space/return activation, and the button accessibility
    trait plus the named "Remove" action.
  • Used for placed chips, palette tokens, the line-break chip, and conditional chips. The
    conditional context menus and the strip's drop destinations are unchanged.
  • The trash zone is now also a click target: with a token selected it reads "Remove
    selected" and removing works without dragging or the Delete key.
  • One new string, menu_bar_layout_remove_selected, translated in all 22 catalogs.

Commands run

  • swift build --target CodexBar — clean (typechecks the whole module)
  • node Scripts/check-app-locales.mjsApp locales OK: Checked 22 catalogs against 1480 English keys.

Verification caveat

This was developed on a machine with only CommandLineTools and no Xcode, so make test
and swiftlint could not run here (Testing module unavailable; swiftlint fails loading
sourcekitdInProc). No screenshots/GIF for the same reason. The change is behavioural
drag-and-drop in a settings pane, so it needs a click-through on a machine with Xcode —
happy to iterate if CI or review finds anything.

Layout editor chips were Buttons with .draggable attached. On macOS the
button's gesture recognizer claims the mouse-down, so no drag session ever
starts: reordering and the trash drop zone were unreachable by mouse and the
Delete key was the only way to remove a token. Moving .draggable onto the
button label does not help, because the button still owns the gesture.

Replace the chips with a plain draggable view that keeps click selection,
keyboard activation, and accessibility, and make the trash zone a click
target for the selected token as well.
@clawsweeper

clawsweeper Bot commented Aug 21, 2026

Copy link
Copy Markdown

🦞👀
ClawSweeper picked this up.

Pull request received. I will update this pull request when review starts.

@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: 1b67f6e355

ℹ️ About Codex in GitHub

Codex has been enabled to automatically 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 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

/// removed without dragging or reaching for the Delete key.
private var removeDropTarget: some View {
HStack(spacing: 6) {
let canRemoveSelection = self.selectedPosition != nil

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 Clear selection when merging layout lines

After selecting a token on the second line and clicking “Remove line break,” the merge action leaves selectedPosition pointing to the now-nonexistent line 1. This condition still presents the new trash target as active and labels it “Remove selected,” but clicking it silently does nothing because the stored position is invalid; clear the selection during the merge or validate that the selected position still exists before setting this state.

Useful? React with 👍 / 👎.

Comment on lines +62 to +64
.allowsHitTesting(!self.isDisabled)
.accessibilityElement()
.accessibilityAddTraits(.isButton)

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 Preserve disabled accessibility semantics on chips

When the layout already has two lines, the line-break chip sets isDisabled, but this only suppresses focus and mouse hit testing while the following modifiers still expose it as a button with a default accessibility action. Unlike the previous .disabled(...), VoiceOver can therefore encounter what appears to be an enabled control whose activation silently no-ops at handleActivate; apply disabled accessibility semantics as well as suppressing pointer interaction.

Useful? React with 👍 / 👎.

@clawsweeper clawsweeper Bot added P2 Normal priority bug or improvement with limited blast radius. 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 Aug 21, 2026
@clawsweeper

clawsweeper Bot commented Aug 21, 2026

Copy link
Copy Markdown

Codex review: needs real behavior proof before merge. Reviewed August 21, 2026, 6:52 PM ET / 22:52 UTC.

ClawSweeper review

What this changes

The PR replaces layout-editor token buttons with accessible draggable chips and adds selected-token removal through the trash target.

Merge readiness

Blocked until real behavior proof is added - 5 items remain

Keep open: current main still uses button-wrapped draggable layout tokens, but this patch has two P2 interaction/accessibility defects and lacks native after-fix proof.

Priority: P2
Reviewed head: 44b06a0c8951641e5b4eca30c3313d1c5622cc27

Review scores

Measure Result What it means
Overall readiness 🧂 unranked krab (1/6) The scoped approach is plausible, but two interaction defects and absent native proof leave the PR unready to merge.
Proof confidence 🧂 unranked krab (1/6) Needs real behavior proof before merge: The PR reports build and locale checks but provides no after-fix native interaction evidence; add redacted settings-pane media or live output, then update the PR body for re-review.
Patch quality 🦐 gold shrimp (3/6) 2 actionable review findings remain.

Verification

Check Result Evidence
Real behavior Needs proof Needs real behavior proof before merge: The PR reports build and locale checks but provides no after-fix native interaction evidence; add redacted settings-pane media or live output, then update the PR body for re-review.
Evidence reviewed 5 items Current main still has the reported drag structure: Current main wraps each placed token in a Button and attaches the draggable modifier to its label, so the PR’s central mouse-drag problem remains relevant.
Effective PR scope is focused: Against current main, the PR changes two SwiftUI files and 23 localization catalogs, with 198 additions and 104 deletions; the unrelated files shown against the older base are already on main.
New trash action can act on stale selection: The new trash target treats any non-nil selected position as removable, while the existing line-break merge leaves a second-line selection pointing at a removed line; removal then silently does nothing.
Findings 2 actionable findings [P2] Clear stale selection before enabling the trash target
[P2] Expose the disabled line-break chip as disabled
Security None None.

Live Verification

Command: swift build --target CodexBar

Result: FAIL (failed) — execution before step 1 run: sh -lc pnpm install --ignore-scripts --frozen-lockfile failed: ! Corepack is about to download https://registry.npmjs.org/pnpm/-/pnpm-11.22.0.tgz

sh -lc pnpm install --ignore-scripts --frozen-lockfile failed: ! Corepack is about to download https://registry.npmjs.org/pnpm/-/pnpm-11.22.0.tgz

Assertions:

  • FAIL expect_output: Build of target: 'CodexBar' complete!

How this fits together

CodexBar’s menu bar layout editor turns saved usage-token settings into editable chips. Selecting, dragging, dropping, and removing chips updates the persisted menu bar layout.

flowchart LR
A[Saved layout settings] --> B[Layout editor]
B --> C[Token chips]
C --> D[Selection and keyboard input]
C --> E[Drag and drop]
D --> F[Updated layout]
E --> F[Updated layout]
Loading

Before merge

  • Add real behavior proof - Needs real behavior proof before merge: The PR reports build and locale checks but provides no after-fix native interaction evidence; add redacted settings-pane media or live output, then update the PR body for re-review.
  • Clear stale selection before enabling the trash target (P2) - After a token on line two is selected, “Remove line break” merges that line but leaves the stored position invalid. The new trash target then says “Remove selected” while its action silently no-ops; clear or validate selection when the layout is merged.
  • Expose the disabled line-break chip as disabled (P2) - isDisabled only removes hit testing and focus. VoiceOver still receives a button with a default action that no-ops at the two-line limit; add disabled accessibility semantics or avoid exposing an actionable element.
  • Resolve merge risk (P1) - Merging now leaves an active-looking trash target after a line merge and exposes a disabled line-break chip as an enabled VoiceOver control.
  • Resolve merge risk (P1) - No after-fix native settings-pane proof demonstrates that mouse reordering and drag-to-remove now work on macOS.

Findings

  • [P2] Clear stale selection before enabling the trash target — Sources/CodexBar/MenuBarLayoutEditor.swift:492-508
  • [P2] Expose the disabled line-break chip as disabled — Sources/CodexBar/MenuBarLayoutEditorChip.swift:62-67
Agent review details

Security

None.

Review metrics

Metric Value Why it matters
Effective diff scope 25 files: 2 Swift files, 23 locale catalogs, 0 tests The implementation is focused, but the changed behavior has no new regression coverage and needs native proof.

Merge-risk options

Maintainer options:

  1. Repair interaction state and prove the native flow (recommended)
    Clear or validate selection after merging lines, add disabled accessibility semantics, then attach redacted macOS proof of reordering, drag-to-remove, selected removal, and the disabled line-break state.

Technical review

Best possible solution:

Keep the chip approach, clear or validate selection across layout changes, expose disabled accessibility state, and land only after a redacted native interaction recording proves reordering and removal.

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

No native macOS reproduction was supplied or run here; current main source clearly maps the reported drag path, but the required click-through remains unproven.

Is this the best way to solve the issue?

No. The plain-chip direction is narrowly targeted, but stale selection and disabled accessibility semantics must be repaired before it is a complete solution.

Full review comments:

  • [P2] Clear stale selection before enabling the trash target — Sources/CodexBar/MenuBarLayoutEditor.swift:492-508
    After a token on line two is selected, “Remove line break” merges that line but leaves the stored position invalid. The new trash target then says “Remove selected” while its action silently no-ops; clear or validate selection when the layout is merged.
    Confidence: 0.99
  • [P2] Expose the disabled line-break chip as disabled — Sources/CodexBar/MenuBarLayoutEditorChip.swift:62-67
    isDisabled only removes hit testing and focus. VoiceOver still receives a button with a default action that no-ops at the two-line limit; add disabled accessibility semantics or avoid exposing an actionable element.
    Confidence: 0.99

Overall correctness: patch is incorrect
Overall confidence: 0.99

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning high; reviewed against 00faa6ed477a.

Labels

Label changes:

  • add merge-risk: 🚨 compatibility: Replacing native buttons with custom gesture and accessibility behavior can regress existing keyboard, selection, and assistive-technology workflows.

Label justifications:

  • P2: The layout editor’s mouse removal and accessibility behavior are broken on a limited settings surface.
  • merge-risk: 🚨 compatibility: Replacing native buttons with custom gesture and accessibility behavior can regress existing keyboard, selection, and assistive-technology workflows.
  • rating: 🧂 unranked krab: Overall readiness is 🧂 unranked krab; proof is 🧂 unranked krab and patch quality is 🦐 gold shrimp.
  • status: 📣 needs proof: The PR needs real behavior proof before ClawSweeper can clear the contributor ask. Needs real behavior proof before merge: The PR reports build and locale checks but provides no after-fix native interaction evidence; add redacted settings-pane media or live output, then update the PR body for re-review.

Evidence

Acceptance criteria:

  • [P1] make check.
  • [P1] make test.
  • [P1] Fresh-bundle macOS recording or screenshots showing reorder, drag-to-remove, selected removal, and disabled line-break behavior.

What I checked:

  • Current main still has the reported drag structure: Current main wraps each placed token in a Button and attaches the draggable modifier to its label, so the PR’s central mouse-drag problem remains relevant. (Sources/CodexBar/MenuBarLayoutEditor.swift:433, 00faa6ed477a)
  • Effective PR scope is focused: Against current main, the PR changes two SwiftUI files and 23 localization catalogs, with 198 additions and 104 deletions; the unrelated files shown against the older base are already on main. (44b06a0c8951)
  • New trash action can act on stale selection: The new trash target treats any non-nil selected position as removable, while the existing line-break merge leaves a second-line selection pointing at a removed line; removal then silently does nothing. (Sources/CodexBar/MenuBarLayoutEditor.swift:492, 44b06a0c8951)
  • Disabled chip remains exposed as an enabled accessibility button: The replacement chip blocks hit testing and focus when disabled but still adds the button trait and default accessibility action without disabled semantics. (Sources/CodexBar/MenuBarLayoutEditorChip.swift:62, 44b06a0c8951)
  • Feature provenance and release check: Blame attributes the original line-break control to the v0.54.0 release commit; the current PR head was subsequently formatted by the same area contributor. (Sources/CodexBar/MenuBarLayoutEditor.swift:414, 22a2168842a9)

Likely related people:

  • steipete: The existing line-break editor behavior dates to the v0.54.0 release commit authored by Peter Steinberger, who also committed the current-head formatting pass. (role: layout-editor feature introducer and recent area contributor; confidence: high; commits: 22a2168842a9, 44b06a0c8951; files: Sources/CodexBar/MenuBarLayoutEditor.swift, Sources/CodexBar/MenuBarLayoutEditorChip.swift)

Rank-up moves

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

  • Clear or validate selection after removing the line break.
  • Mark disabled chips as disabled to assistive technologies.
  • Add redacted native proof of reorder, drag-to-remove, selected removal, and the two-line limit.

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 (1 earlier review cycle)
  • reviewed 2026-08-21T16:16:24.040Z sha 1b67f6e :: needs real behavior proof before merge. :: [P2] Clear selection when removing the line break | [P2] Expose disabled accessibility state for the line-break chip

kiranmagic7 and others added 12 commits August 21, 2026 13:11
…its) (steipete#3116)

* fix(commandcode): Add support for individual-pro-v1 plan ($80/mo credits)

Command Code's updated Pro tier ($20/mo → $80 credits) ships as
individual-pro-v1 (legacy individual-pro remains $30). The new planId
hit the hard unknownPlan throw in CommandCodeUsageFetcher, surfaced as
'Unknown Command Code plan: individual-pro-v1'.

Add the versioned plan to CommandCodePlanCatalog (verified against
live frontend bundle assets/constants-B6rERLKd.js and pricing docs).
Pro pricing now: $20 → $80 (docs/resources/pricing-limits), legacy
Pro kept for backwards compat.

* test(commandcode): Cover individual-pro-v1 plan resolution

Regression coverage for the $80 Pro v1 tier: an active subscription
with planId individual-pro-v1 must resolve through
CommandCodePlanCatalog instead of hitting the unknownPlan throw, and
the catalog check now pins pro-v1 at 80 credits.
…ponses (steipete#3128)

Mainland Personal/Solo Token Plan (cn-personal) intermittently shows "Could not
parse Alibaba Token Plan usage: Missing Personal usage windows" even though auth
succeeds. The `/tokenplan/personal/api/v2/usage` gateway sometimes answers with a
200 "Success" envelope (`code=SUCCESS`, `successResponse=true`, empty errorCode)
whose payload omits the `per5HourPercentage`/`per1WeekPercentage` windows. The
parser treated that absence as a hard parse failure.

- Throw a distinct `.usageWindowsUnavailable` for a Success-with-no-windows body
  instead of `parseFailed("Missing Personal usage windows")`.
- Retry the usage call a few times (the payload is usually populated on an
  immediate re-request) before surfacing it.
- When it stays empty, surface the softer "temporarily unavailable; it will
  refresh automatically" message. CodexBar keeps the last-good card either way
  (a returned empty snapshot would blank it, so this stays a thrown error).

Verified on a real cn-personal account: the fetch retries and, while the endpoint
was returning empty, surfaced the transient message with the last-good card
preserved. Adds AlibabaTokenPlanPersonalUsageRetryTests (recovers when a full
response follows an empty one; throws .usageWindowsUnavailable when every attempt
is empty).

Refs steipete#2500.

Co-authored-by: LeoLin <leolin990405@gmail.com>
…ete#3111)

* fix(claude): migrate email-keyed iCloud snapshots to slot keys

* fix(sync): confirm CloudKit snapshot saves before deleting predecessors

Terminal delete failures are reported once with delayed retries only for
recoverable errors, and email-keyed leftovers wait until the replacement
record is saved.

* fix(sync): persist leftover snapshot deletes across delayed retries

Keep pending predecessor deletes in the persistence envelope before sleeping so a relaunch can finish the CloudKit migration if the retry task never ran.

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(sync): stop retrying terminal CloudKit replacement saves

Mark slot-keyed migration snapshots complete after permission, auth, or invalid-argument save failures so the 120s snapshot push does not keep requeueing the same record.

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(sync): bind delayed CloudKit deletes to the originating engine

Skip leftover-record retries after an account switch so a sleeping task cannot delete a same-named snapshot in a newly signed-in iCloud account.

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(sync): drop stale CloudKit predecessors that are live again

A later live email-keyed snapshot must not stay queued for delete just because an earlier slot-keyed save still has a pending predecessor set.

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(sync): cancel leftover snapshot deletes when they become live

A delayed CloudKit retry must not delete an email-keyed snapshot that was published again after a transient predecessor delete. Drop that name from the persisted retry set and the engine queue.

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(sync): do not retry CloudKit deletes for live snapshots

A transient in-flight delete can land after the predecessor is live again. Skip persist-and-retry when the record is in the current live snapshot set so cancellation is not resurrected.

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(sync): isolate CloudKit migration state from the next iCloud account

Clear predecessor maps and snapshot hashes when persistence is wiped, and requeue leftover deletes only after the current live snapshot set has been reconciled.

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(sync): persist predecessor deletes and requeue empty publications

Keep the replacement-to-predecessor map in the persistence envelope across relaunch, and still requeue leftover snapshot deletes when the next publication is empty.

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(sync): wait for every shared-mailbox replacement before deleting

Two Claude Swap slots can share one email-keyed predecessor. Delete that leftover only after no unsaved replacement still points at it.

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(sync): retry lost CloudKit responses and keep shared leftovers

Treat serverResponseLost as a recoverable retry, and confirm saved replacements before abandoning failed siblings so a shared email-keyed record is not deleted early.

* fix(sync): queue predecessor deletes for unchanged slot payloads

When a slot snapshot is already published, newly obsolete email-keyed leftovers still need to be recorded and deleted instead of being skipped by the payload-hash shortcut.

* fix(sync): confirm slot saves and ignore remote cache as live

Predecessor deletes now wait for a confirmed replacement hash, and delete retries treat only local pending/confirmed snapshots as live so a fetched leftover cannot cancel its own removal.

* fix(sync): do not treat terminal save failures as confirmed

Skip retrying an unchanged terminal replacement without recording it in lastSnapshotHashes, so an unconfirmed slot cannot retire an email-keyed leftover.

* fix(sync): record confirmed save hashes and skip all terminal snapshot saves

Confirmed CloudKit saves now keep the in-flight payload hash, and terminal failures skip retrying that hash even when the snapshot has no predecessor.

* fix(sync): requeue in-flight snapshot updates and clear save markers on stop

A newer payload that arrives during an unconfirmed save stays pending and is flushed after that save completes, and toggling iCloud off no longer leaves in-flight hashes that skip every later publication.

* fix(sync): retry unavailable iCloud accounts and drop in-flight hashes on conflict

accountTemporarilyUnavailable is treated as a transient CloudKit error, and a server-winning conflict no longer leaves pendingSaveHashes blocking later snapshot publications.

* fix(sync): do not requeue fetched snapshots over in-flight local saves

Fetched CloudKit snapshots no longer overwrite an in-flight local payload, and pending local updates win when merging unpublished fleet cache entries.

* fix(sync): drop retained snapshots when iCloud sync stops

Pending snapshot payloads from before disable are discarded so re-enabling sync cannot upload or delete against a stale account set.

* fix(sync): limit email-keyed snapshot cleanup to Claude Swap

Predecessor deletes must not run for other providers that move from
email to a durable account ID. Drop the unreleased changelog line.

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(sync): defer restored predecessor deletes until live snapshots reconcile

CKSyncEngine can confirm an in-flight slot save on relaunch before local snapshots publish. Wait until that set is applied so a leftover email-keyed record that became live again is not deleted.

Co-authored-by: Cursor <cursoragent@cursor.com>

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
* perf(spend): parallelize loads and memoize model build

- Parallelize independent provider refreshes in makeRequest via
  TaskGroup (was sequential 400ms-6s additive).
- Parallelize Codex multi-account loads in SpendDashboardSource.load
  via ThrowingTaskGroup (was sequential 2s×N).
- Memoize SpendDashboardModel: cache CurrencyExchange conversion per
  currency pair, hoist bounds once per build, and reuse static
  utcCalendar for Mistral/OpenRouter bucket (was new calendar per
  entry, 2920× per build).

Evidence:
- SpendDashboardController.swift:237 parallel baselines
- SpendDashboardController.swift:433 parallel codex
- SpendDashboardModel.swift:300 conversionCache + bounds hoist
- SpendDashboardModel.swift:1069 utcCalendar reuse

Before: 全部 3-10s empty → 2-3s; build 40ms → 8ms.
After: TaskGroup wall-time = slowest provider, model build cached.

* fix(spend): restore Codex account order after parallel load

Task group completion order was appended directly to inputs, but providerRows uses input offset as tie-breaker for equal/unknown totals, so out-of-order completions reordered Codex · steipete#1/steipete#2 rows. Carry request index and sort results before appending, with compact formatting to keep file_length under warning.

Fixes ClawSweeper P2 for steipete#3105.

* test(spend): add out-of-order Codex concurrent order regression

Verifies that parallel Codex loads restore configured request order even when second account's snapshot completes first. Equal totals make completion order visible via providerRows tie-breaker, so without sorting the rows would reorder.

Covers ClawSweeper P2 for steipete#3105 and serves as needs-proof evidence.

* test: update gatekeeper anchors after rebase to 54.0

* fix(spend): repair parallel load CI - file_length and escaping captures

* fix(spend): debounce frequent refresh and throttle date window rebuilds

- 250ms debounce for withObservationTracking and token publication bursts
- 30s throttle for refreshDateWindow same-day revisits
- display-only fast path to avoid Codex scan for filter/currency changes
- update gatekeeper anchors for line shifts

* Improve Antigravity retrieval: retired Flash alias and offline fallback

- Map retired Flash wire ids (3.6/3.5/3-flash-agent) to 3.7-flash via canonicalModelID (opencodex RETIRED_FLASH_TIERS lesson), humanize via canonical, dedup collapsed windows by lowest remaining
- Add AntigravityOfflineStore counting ~/.gemini/antigravity-cli/conversations/*.db (GEMINI_CLI_HOME override) with tokscale cache fallback, and AntigravityOfflineFetchStrategy as terminal offline probe in auto/cli pipelines
- Cover with AntigravityModelLabelTests retired alias cases and AntigravityOfflineStoreTests (db/cache/count)

* fix(gate): add missing provider-specific markers and sync anchors

- add // Provider-specific by design for OpenCodex enrichment and token publication sync
- sync gate anchors after debounce/throttle line shifts

* fix(lint): wrap long provider-specific comment

* Fix provider architecture gatekeeper for Antigravity offline and retired alias

- Move CLI home marker to before gemini literal and update SpendDashboard marker to avoid flagging its own reason
- Add marker before family() and update suppressed anchors to 748/751/754/757
- Allowlist offline gemini, family cluster, and UsageStore codex constructs

* test: include offline strategy in antigravity pipeline expectations

* fix(gate): sync remaining anchors and add missing markers

* chore: trigger CI

* fix(spend): make debounce instant for testing

* fix(gate): update anchors after merge with main

* fix(lint): break long delay line

* fix(gate): drop stale codex anchor absorbed by sourceRevisions cluster
@clawsweeper clawsweeper Bot added the merge-risk: 🚨 compatibility 🚨 Merging this PR could break existing users, config, migrations, defaults, or upgrades. label Aug 21, 2026
@steipete
steipete merged commit 5c71095 into steipete:main Aug 21, 2026
1 check passed
steipete added a commit that referenced this pull request Aug 21, 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. 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.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants