Skip to content

feat(core): local real-usage data layer — unified event engine + registerable scanners + pricing foundation - #2527

Closed
Yuxin-Qiao wants to merge 22 commits into
steipete:mainfrom
Yuxin-Qiao:feat/usage-spend-foundation
Closed

feat(core): local real-usage data layer — unified event engine + registerable scanners + pricing foundation#2527
Yuxin-Qiao wants to merge 22 commits into
steipete:mainfrom
Yuxin-Qiao:feat/usage-spend-foundation

Conversation

@Yuxin-Qiao

@Yuxin-Qiao Yuxin-Qiao commented Jul 31, 2026

Copy link
Copy Markdown
Contributor

No description provided.

Split out the data layer from the Usage & Spend work so UI modules can
land as small follow-up PRs on top of it. No UI / App-target changes.

- Per-tool local session scanners: Antigravity, Gemini CLI, Kimi Code,
  MiniMax, OpenCode, Qwen Code (WAL-aware SQLite, incremental source
  fingerprints, Gregorian-day bucketing).
- Pricing: models.dev catalog + Google/ThirdParty tiers, routing-prefix
  stripping, overflow-safe thresholds, provider-reported vs estimated cost.
- Core plumbing: cost-usage scanner/cache helpers, subagent rollout shape,
  parser hash, branding/descriptor updates.

Foundation for the dashboard UI; behavior additive and backward compatible.

Co-authored-by: Cursor <cursoragent@cursor.com>
@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. P2 Normal priority bug or improvement with limited blast radius. merge-risk: 🚨 compatibility 🚨 Merging this PR could break existing users, config, migrations, defaults, or upgrades. labels Jul 31, 2026
@clawsweeper

clawsweeper Bot commented Jul 31, 2026

Copy link
Copy Markdown

Codex review: needs changes before merge. Reviewed August 2, 2026, 12:22 PM ET / 16:22 UTC.

ClawSweeper review

What this changes

Adds a shared local usage-event aggregation and pricing layer, registerable scanners for several developer-tool histories, and visible progress during full Codex history refreshes.

Merge readiness

⚠️ Needs maintainer review before merge - 6 items remain

This PR is still necessary as the proposed local Usage & Spend data-layer split, but two previously identified current-head defects remain: ZCode is not declared through the provider capability path, and cache-creation tokens do not affect long-context rate selection. The supplied proof directly shows the manual scan-progress UI and a populated dashboard, while the checkout’s missing PR-head object prevents an independent line-by-line branch read.

Priority: P2
Reviewed head: 40949c04df6c1de286e7b695e731b919fdb5f50c
Owner decision: Required. See Decision needed.

Review scores

Measure Result What it means
Overall readiness 🦐 gold shrimp (3/6) The PR has meaningful real-machine evidence and a promising design, but two concrete correctness fixes are required before it is merge-ready.
Proof confidence 🐚 platinum hermit (4/6) ✨ media proof bonus Sufficient (screenshot): The prepared screenshots directly show after-fix scan progress and a reconciled Usage & Spend overview; the PR body also records real-machine scanner results. Any refreshed proof should redact local account details and private paths.
Patch quality 🦐 gold shrimp (3/6) 2 actionable review findings remain.

Verification

Check Result Evidence
Real behavior Verified Sufficient (screenshot): The prepared screenshots directly show after-fix scan progress and a reconciled Usage & Spend overview; the PR body also records real-machine scanner results. Any refreshed proof should redact local account details and private paths.
Evidence reviewed 5 items Current capability gate: Current main gates dashboard eligibility, settings enablement, and token refresh on supportsTokenCost. The PR’s proposed supportsDashboardHistory path is therefore required for its local scanner declarations to become user-visible.
Z.ai descriptor boundary: Current main’s Z.ai descriptor declares supportsTokenCost false and no local-history capability. The supplied current PR review context shows the new .zcode scanner is registered but still not declared by this provider, leaving it outside the new dashboard capability path.
Unresolved current-head review findings: The supplied review history records the ZCode declaration and cache-creation long-context defects against an earlier reviewed head; the final supplied PR-head commit only changes nested billing-route ownership and comparison-window cost withholding, not either affected path.
Findings 2 actionable findings [P1] Declare the ZCode source on the z.ai provider
[P2] Include cache creation in long-context rate selection
Security None None.

How this fits together

CodexBar’s Usage & Spend feature combines provider data and local tool histories into token/cost snapshots for the dashboard and refresh pipeline. Provider descriptors decide which sources are eligible; scanners parse local data, the shared engine aggregates it, and the dashboard presents the resulting history.

flowchart LR
  A[Local tool histories] --> B[Registered scanners]
  B --> C[Unified usage events]
  C --> D[Aggregation and pricing]
  D --> E[Provider snapshots]
  E --> F[Dashboard and token refresh]
  G[Manual refresh] --> B
Loading

Decision needed

Question Recommendation
Should CodexBar formally expose ZCode local history through the existing Z.ai provider, rather than keep that scanner registered but intentionally unavailable in the dashboard? Expose ZCode through Z.ai: Declare .zcode in the Z.ai provider configuration and retain focused capability-path coverage.

Why: The mechanical fix is small, but whether ZCode belongs under the Z.ai provider is a user-visible provider-product contract and should be confirmed by the owner of that descriptor.

Before merge

  • Declare the ZCode source on the z.ai provider (P1) - The new registry is reachable only through sources declared by a provider. This branch registers .zcode, but the supplied current-head review and the Z.ai descriptor contract show no Z.ai declaration, so capability gating filters it out and the scanner remains test-only. Add the intended .zcode declaration and cover the dashboard capability path.
  • Include cache creation in long-context rate selection (P2) - The shared models.dev pricing request prices cache-creation tokens but computes the long-context threshold from only input plus cache-read tokens. A request whose cache creation crosses the model threshold therefore receives short-context rates; include that bucket with overflow-safe arithmetic.
  • Resolve merge risk (P1) - Merging without a Z.ai .zcode declaration would ship a scanner that remains invisible to the provider/dashboard capability path.
  • Resolve merge risk (P1) - Long-context requests with substantial cache creation can use a lower pricing tier than their total context warrants, understating estimated cost.
  • Resolve merge risk (P1) - The current PR-head objects are unavailable in this checkout, so a maintainer should refresh the branch inspection before merging after any further updates.

Findings

  • [P1] Declare the ZCode source on the z.ai provider — Sources/CodexBarCore/Providers/Zai/ZaiProviderDescriptor.swift:35-36
  • [P2] Include cache creation in long-context rate selection — Sources/CodexBarCore/Vendored/CostUsage/CostUsagePricing+ThirdParty.swift:45-49
Agent review details

Security

None.

Review metrics

Metric Value Why it matters
Patch size 8,193 added, 168 removed The feature is a large data-layer change, making narrow regression coverage especially important before merge.
Files affected 94 files affected The patch crosses scanner parsing, pricing, provider descriptors, dashboard wiring, localization, and tests.
Commit history 22 commits The supplied history shows substantial iterative repair, so current-head review must confirm prior findings remain resolved.

Merge-risk options

Maintainer options:

  1. Repair and verify the data-layer contracts (recommended)
    Declare the ZCode source on its intended provider, correct long-context pricing selection, and add focused regression coverage before merge.
  2. Defer unsupported scanner placement
    If the Z.ai product placement is not approved, remove or defer the registered ZCode adapter rather than shipping an unreachable scanner.
Copy recommended automerge instruction
@clawsweeper automerge

Special instructions:
Implement the ZCode provider declaration and cache-creation threshold fixes with focused capability and pricing regressions; preserve existing provider ownership behavior.

Technical review

Best possible solution:

Declare ZCode on the intended Z.ai local-history capability, include cache-creation tokens in overflow-safe long-context threshold selection, and add focused regressions proving both dashboard eligibility and the pricing boundary before landing this data-layer split.

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

Yes for the two blockers from source and supplied current-head review evidence: the descriptor path excludes ZCode when undeclared, and the pricing threshold omits cache creation. A live branch run was not possible because the PR-head object is unavailable in this checkout.

Is this the best way to solve the issue?

No: the current branch needs the two narrow corrections before it is the best landing path. The shared scanner/aggregation design remains a plausible maintainable direction once the provider contract is explicitly approved and the pricing boundary is fixed.

Full review comments:

  • [P1] Declare the ZCode source on the z.ai provider — Sources/CodexBarCore/Providers/Zai/ZaiProviderDescriptor.swift:35-36
    The new registry is reachable only through sources declared by a provider. This branch registers .zcode, but the supplied current-head review and the Z.ai descriptor contract show no Z.ai declaration, so capability gating filters it out and the scanner remains test-only. Add the intended .zcode declaration and cover the dashboard capability path.
    Confidence: 0.92
  • [P2] Include cache creation in long-context rate selection — Sources/CodexBarCore/Vendored/CostUsage/CostUsagePricing+ThirdParty.swift:45-49
    The shared models.dev pricing request prices cache-creation tokens but computes the long-context threshold from only input plus cache-read tokens. A request whose cache creation crosses the model threshold therefore receives short-context rates; include that bucket with overflow-safe arithmetic.
    Confidence: 0.88

Overall correctness: patch is incorrect
Overall confidence: 0.86

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning high; reviewed against 1fd7ec83b5d9.

Labels

Label justifications:

  • P2: This is a broad but non-emergency Usage & Spend feature whose remaining defects have limited, provider-specific blast radius.
  • merge-risk: 🚨 compatibility: Provider capability declarations determine whether existing users see local history in dashboard and refresh flows.
  • merge-risk: 🚨 auth-provider: The patch changes billing-provider attribution and must keep tool subscriptions distinct from model vendors.
  • merge-risk: 🚨 availability: It adds local scans and full-rescan behavior that can affect refresh duration and cancellation.
  • rating: 🦐 gold shrimp: Overall readiness is 🦐 gold shrimp; proof is 🐚 platinum hermit and patch quality is 🦐 gold shrimp.
  • status: ⏳ waiting on author: ClawSweeper has contributor-facing work open and is waiting for author action. Sufficient (screenshot): The prepared screenshots directly show after-fix scan progress and a reconciled Usage & Spend overview; the PR body also records real-machine scanner results. Any refreshed proof should redact local account details and private paths.
  • proof: sufficient: Contributor real behavior proof is sufficient. The prepared screenshots directly show after-fix scan progress and a reconciled Usage & Spend overview; the PR body also records real-machine scanner results. Any refreshed proof should redact local account details and private paths.
  • proof: 📸 screenshot: Contributor real behavior proof includes screenshot evidence. The prepared screenshots directly show after-fix scan progress and a reconciled Usage & Spend overview; the PR body also records real-machine scanner results. Any refreshed proof should redact local account details and private paths.

Evidence

Acceptance criteria:

  • [P1] swift test --filter 'ZcodeSessionScannerTests|CostUsageFetcherTests|UsageEventAggregatorTests|CostUsagePricingTests|ModelsDevPricingTests'.
  • [P1] make check.

What I checked:

  • Current capability gate: Current main gates dashboard eligibility, settings enablement, and token refresh on supportsTokenCost. The PR’s proposed supportsDashboardHistory path is therefore required for its local scanner declarations to become user-visible. (Sources/CodexBar/SpendDashboardController.swift:335, 1fd7ec83b5d9)
  • Z.ai descriptor boundary: Current main’s Z.ai descriptor declares supportsTokenCost false and no local-history capability. The supplied current PR review context shows the new .zcode scanner is registered but still not declared by this provider, leaving it outside the new dashboard capability path. (Sources/CodexBarCore/Providers/Zai/ZaiProviderDescriptor.swift:35, b1170d83963d)
  • Unresolved current-head review findings: The supplied review history records the ZCode declaration and cache-creation long-context defects against an earlier reviewed head; the final supplied PR-head commit only changes nested billing-route ownership and comparison-window cost withholding, not either affected path. (Sources/CodexBarCore/Vendored/CostUsage/CostUsagePricing+ThirdParty.swift:45, 40949c04df6c)
  • Real behavior proof: Prepared local artifacts visibly show the new “Scanning history 9/393” refresh state and a populated Usage & Spend overview after reconciliation. (/home/runner/_work/clawsweeper/clawsweeper/artifacts/event/codex/proof-scratch/2527/media-proof-manifest.json:1)
  • Checkout limitation: The checked-out repository is clean at current main, but the supplied PR-head object is absent from this partial clone. Git’s read-only promisor fetch could not resolve the GitHub host, so direct inspection of the branch was unavailable.

Likely related people:

  • steipete: The current Z.ai provider descriptor and its capability boundary trace to this history, including the release-base commit that owns the relevant configuration. (role: provider descriptor owner; confidence: high; commits: b1170d83963d; files: Sources/CodexBarCore/Providers/Zai/ZaiProviderDescriptor.swift)
  • Yuxin-Qiao: Recent current-main work touched the Spend Dashboard controller, and the supplied PR history shows continued work on the local-history and pricing proposal. (role: recent dashboard contributor; confidence: medium; commits: e1e2cc20272a, 40949c04df6c; files: Sources/CodexBar/SpendDashboardController.swift, Sources/CodexBarCore/Vendored/CostUsage/CostUsagePricing+ThirdParty.swift)

Rank-up moves

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

  • Declare .zcode through the approved Z.ai capability path and add a dashboard-eligibility regression.
  • Include cache creation in long-context threshold selection and add a focused pricing regression.
  • Refresh the branch review after the fixes so the actual head can be source-checked.

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 (17 earlier review cycles; latest 8 shown)
  • reviewed 2026-08-02T03:07:48.641Z sha b366ef8 :: needs changes before merge. :: [P1] Declare ZCode history on the z.ai provider | [P2] Include cache creation in long-context rate selection
  • reviewed 2026-08-02T03:59:11.495Z sha b366ef8 :: needs changes before merge. :: [P1] Declare ZCode history on the z.ai provider | [P2] Include cache creation in long-context rate selection
  • reviewed 2026-08-02T10:06:20.454Z sha 20c8725 :: found issues before merge. :: [P1] Declare ZCode history on the z.ai provider | [P2] Include cache creation in long-context rate selection
  • reviewed 2026-08-02T10:18:13.127Z sha 20c8725 :: needs changes before merge. :: [P1] Preserve the outer billing provider for nested routes | [P2] Withhold incomplete cost from comparison windows
  • reviewed 2026-08-02T11:30:32.820Z sha 20c8725 :: needs changes before merge. :: [P1] Preserve the outer billing provider for nested routes | [P2] Withhold partial costs from comparison windows
  • reviewed 2026-08-02T15:07:17.543Z sha 40949c0 :: needs maintainer review before merge. :: none
  • reviewed 2026-08-02T15:16:38.848Z sha 40949c0 :: needs maintainer review before merge. :: none
  • reviewed 2026-08-02T15:52:15.439Z sha 40949c0 :: found issues before merge. :: [P1] Declare the ZCode source for its provider | [P2] Include cache creation in long-context rate selection

@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: 854090a0b0

ℹ️ 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".

Comment on lines 38 to +39
supportsTokenCost: false,
localHistorySources: [.geminiCLI],

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Wire local history sources into token-cost loading

For every newly opted-in provider, including Gemini, supportsTokenCost remains false and no production code consumes localHistorySources: SpendDashboardController.costCapableProviders filters these providers out, UsageStore.refreshTokenUsage resets their token state, and CostUsageFetcher.supportsTokenSnapshot rejects them if called directly. Consequently the six new scanners are reachable only from tests and users never see their local history; the dashboard and loading pipeline need to use supportsDashboardHistory and dispatch the declared adapters.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Fixed in 3a22838. The token refresh pipeline now uses supportsDashboardHistory: UsageStore.refreshTokenUsage no longer resets local-history providers, SettingsStore.isCostUsageEffectivelyEnabled admits them, and CostUsageFetcher.supportsTokenSnapshot plus SpendDashboardController.costCapableProviders already dispatch the registered local scanners. Covered by UsageStoreManualTokenRefreshTests.

Comment on lines +61 to +72
if let cost = Self.estimatedCost(
model: model,
usage: usage,
pricingDate: pricingDate,
modelsDevCatalog: modelsDevCatalog,
modelsDevCacheRoot: modelsDevCacheRoot),
cost.isFinite
{
let nextCost = self.cost + cost
if nextCost.isFinite {
self.cost = nextCost
self.sawCost = true

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 Withhold Kimi totals when any turn is unpriced

When a day contains both a priceable Kimi model and a model absent from the pricing catalog, the latter turn still contributes tokens but this branch only records successful prices and leaves sawCost true. The later day and 30-day aggregation therefore publishes the priced subtotal as if it covered all usage, understating spend without an incompleteness signal; track unpriced usage and emit nil for the affected aggregate, as the Qwen and OpenCode scanners do.

Useful? React with 👍 / 👎.

Enabling `supportsTokenCost` for Groq changes which providers surface in
the descriptor-driven generic Cost row — that is dashboard behavior whose
expectations live in the App-layer tests (SpendDashboardModelTests,
GroqMenuCardModelTests). Those App tests are not part of this data-layer
split, so flipping the flag here breaks CI. Defer the flag to the UI
follow-up that carries the matching test updates; the
`costSource: .providerReported` tagging stays.

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

Generalize the Usage & Spend data layer into a registerable scanner framework
modeled on tokscale's define_clients!, so adding support for a mainstream tool
means registering one adapter instead of editing central switches.

- LocalHistoryScanning: per-tool protocol (source id, display name, home
  resolution, scan) with a bundled LocalHistoryScanContext.
- LocalHistoryScannerRegistry: source-keyed, order-preserving registry with a
  process-wide `shared` instance pre-populated from LocalHistoryBuiltInScanners.
- Wrap the six existing scanners (Kimi/Gemini/OpenCode/MiniMax/Antigravity/
  Qwen) as built-in registrations; no App-layer behavior change.
- ZcodeSessionScanner: reads ~/.zcode/cli/rollout/model-io-sess_*.jsonl and
  normalizes ZCode's cache-inclusive input (cross-checked against totalTokens)
  so cached prefixes are never billed twice; priced at the official Z.ai rate.
- Cursor/Trae degraded scanners: read the local state DBs to surface real
  per-day model activity, with all token/cost fields left nil because neither
  tool mirrors token usage locally (billing is server-side).

Tests cover the registry, zcode cache normalization, and the degraded sources.

Co-authored-by: Cursor <cursoragent@cursor.com>
@Yuxin-Qiao Yuxin-Qiao changed the title feat(core): generalized usage & spend scanning + pricing foundation feat(core): local real-usage data layer — registerable scanners + pricing foundation Aug 1, 2026

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

ℹ️ 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".

Comment on lines 721 to +724
modelName: modelName,
costUSD: self.sawCost ? self.costUSD : nil,
totalTokens: self.sawTotalTokens ? self.totalTokens : nil,
inputTokens: self.sawInputTokens && !self.missingInputTokens ? self.inputTokens : 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 Preserve billing ownership while merging breakdowns

When any report containing an explicit billingProviderID passes through CostUsageDailyReport.merged, this accumulator rebuilds the breakdown without retaining that field, so even a single unambiguous provider becomes nil. This loses the structured ownership needed to attribute namespaced third-party usage correctly; accumulate the IDs and preserve the value when they agree.

AGENTS.md reference: AGENTS.md:L46-L46

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Fixed in 204f1eb. BreakdownAccumulator now retains billingProviderID and keeps it when merged sources agree, drops it when they conflict, and never lets a source without evidence erase another source's evidence. Covered by CostUsageDailyReportMergeTests.

Comment on lines +282 to +284
// Cost only exists for `opencode.db` rows (JSON files carry none). When nothing was priced,
// stay token-only ("XXX"/nil) so the dashboard does not show a phantom zero spend.
let totalCost = self.sum(daily.compactMap(\.costUSD))

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 Withhold OpenCode's total after any unpriced day

When the scan contains at least one provider-priced database day and another day containing legacy JSON or otherwise unpriced records, compactMap drops the nil day before summing. The snapshot therefore publishes a partial subtotal as the complete history cost even though the daily data marks coverage incomplete; return nil for the aggregate whenever any contributing day is unpriced.

Useful? React with 👍 / 👎.

Comment on lines +294 to +297
historyDays: days,
historyCoverageIsEstablished: true,
historyLabel: "OpenCode",
daily: daily,

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 Mark OpenCode database costs as provider-reported

When opencode.db supplies a nonnil cost, the scanner explicitly treats it as the provider-reported amount, but this initializer omits costSource and therefore defaults the snapshot to .estimated. Consumers that distinguish actual billed spend from rate-card estimates will mislabel every priced OpenCode snapshot; pass .providerReported when publishing these database-derived costs.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Fixed in 65af90d. The OpenCode snapshot now withholds the headline cost whenever any token-bearing day is unpriced, instead of compactMap-ing the nil day and publishing a priced subtotal as the complete total. Covered by OpenCodeSessionScannerTests.

Comment on lines +258 to +260
totalTokens: totalTokens,
requestCount: total.requests,
costUSD: daySawCost ? dayCost : 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 Withhold MiniMax cost when any turn is unpriced

When a MiniMax day mixes a priceable model with a turn whose model has no catalog rate and whose stored cost is nil or zero, daySawCost remains true from the priced turn and this publishes only that subtotal. The model/day and later history totals then understate spend without an incompleteness signal; track unpriced billable usage and emit nil for affected aggregates.

Useful? React with 👍 / 👎.

Comment on lines +222 to +224
totalTokens: totalTokens,
requestCount: total.requests,
costUSD: daySawCost ? dayCost : 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 Withhold Antigravity cost when any generation is unpriced

When an Antigravity day contains both a recognized priced model and an unknown or newly introduced model, the unknown generation contributes tokens while daySawCost remains true from the recognized model. This line consequently exposes the priced subtotal as a complete day cost, and the history total inherits the understatement; propagate an unpriced-usage flag and withhold affected totals.

Useful? React with 👍 / 👎.

Comment on lines +96 to +100
// Anchor the (single) record on the last active day when known, otherwise today. Trae
// exposes no per-day token history, so there is exactly one degraded entry.
let anchor = lastActive ?? now
let anchorDay = calendar.startOfDay(for: anchor)
let dayKey = CostUsageLocalDay.key(from: anchorDay, calendar: calendar)

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 Exclude Trae activity outside the requested history window

When telemetry.lastSessionDate is older than historyDays, the scanner still anchors and returns an entry on that stale date because no start/end range check is performed. A user who has not opened Trae for months therefore receives an out-of-window activity record in a snapshot claiming established recent-history coverage; return nil or omit the entry when the anchor lies outside the requested interval.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Fixed in 10fb613. TraeLocalActivityScanner now returns nil when the telemetry last-session date falls outside the requested history window, so a stale anchor no longer surfaces as recent activity. Covered by TraeLocalActivityScannerTests.

@clawsweeper clawsweeper Bot added proof: sufficient Contributor real behavior proof is sufficient. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. and removed status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. labels Aug 1, 2026
Refactor the local-history framework from "each scanner builds its own
snapshot" to a two-layer design modeled on tokscale's UnifiedMessage:

- UnifiedUsageEvent: a single normalized record (full token detail, or
  degraded model-only) that every thin tool parser emits. Per-event
  billingProviderID carries source evidence for harness tools.
- UsageEventAggregator: the one place that does day/model bucketing,
  cached-prefix normalization (total cross-check, fallback subtract),
  models.dev pricing, provider-reported-cost passthrough, partial-pricing
  nil handling, and snapshot construction. Previously this logic was
  re-implemented (and occasionally dropped) in every scanner.

Migrate Zcode, Qwen, Cursor, and Trae to thin parsers over the engine
(Zcode 381->200 lines; Qwen -237). Engine output is byte-identical to the
prior hand-rolled accumulators, verified by the existing suites.

Add CopilotSessionScanner: reads GitHub Copilot CLI's
session-state/*/events.jsonl session.shutdown modelMetrics rollup,
normalizes model ids to pricing keys, and traces each model to the real
billing vendor (claude-* -> anthropic, gpt-* -> openai, gemini-* -> google)
so a harness is priced at the model source, not the tool.

New mainstream tools now only need a thin parse->events adapter plus one
registration line; aggregation/normalization/pricing are reused and cannot
be forgotten. Engine covered by 7 focused tests; Copilot by 3.

Co-authored-by: Cursor <cursoragent@cursor.com>
@Yuxin-Qiao Yuxin-Qiao changed the title feat(core): local real-usage data layer — registerable scanners + pricing foundation feat(core): local real-usage data layer — unified event engine + registerable scanners + pricing foundation Aug 1, 2026

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

ℹ️ 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".

Comment on lines +107 to +108
let costs = daily.compactMap(\.costUSD)
let totalCost = costs.isEmpty ? nil : costs.reduce(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 Withhold aggregate cost after an unpriced day

When a Qwen, ZCode, or Copilot history contains at least one fully priced day and another day whose model is absent from the catalog, makeDaily correctly leaves the latter day's cost nil, but compactMap drops that incompleteness and publishes the priced subtotal as last30DaysCostUSD. Require every token-bearing day to have a cost before emitting the aggregate so the headline does not understate the history.

Useful? React with 👍 / 👎.

Comment on lines +7 to +9
let inputTokens: Int
let cacheReadInputTokens: Int
let outputTokens: Int

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 Apply cache-write rates in shared pricing

For Copilot and ZCode records with nonzero cacheWriteTokens, the aggregator retains cacheCreationTokens for display, but this request cannot pass that bucket to pricing, so cacheCreationInputCostPerToken is never applied. Depending on whether the source includes writes in its raw input, those tokens are either omitted from cost or charged at the ordinary input rate, producing an incorrect estimate whenever the catalog has a distinct cache-write rate.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Already addressed by 5c2ae86 at the current head: UsageEventAggregator passes cacheCreationInputTokens into ModelsDevCostRequest, so catalog cache-write rates are applied for Copilot/ZCode records. No further change needed.

Comment on lines +81 to +82
if let pricing = self.google[canonicalModel] {
return self.googleCostUSD(

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 Prefer refreshed Gemini rates over offline fallbacks

When the models.dev cache contains updated pricing for one of the four built-in Gemini models, this early return always chooses the embedded rate and never consults the refreshed catalog. The table is documented as an offline fallback for models that precede the catalog, so catalog corrections or later price changes remain ignored and Antigravity spend stays stale; consult the catalog first and use this table only when lookup fails.

Useful? React with 👍 / 👎.

Fixes CI swift-test-macos shard failures: blankLinesBetweenImports,
redundantSwiftTestingSuite, indent, redundantThrows. No logic change;
both suites still pass.

Co-authored-by: Cursor <cursoragent@cursor.com>
@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. merge-risk: 🚨 other 🚨 Merging this PR has meaningful risk outside the owned taxonomy. and removed proof: sufficient Contributor real behavior proof is sufficient. rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. labels Aug 1, 2026

@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: 3eb62c2605

ℹ️ 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".

Comment on lines +439 to +440
AND json_extract(data, '$.time.created') >= ?
AND json_extract(data, '$.time.created') < ?

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 Fall back to OpenCode's timestamp column

For OpenCode databases where the timestamp is stored only in the message.time_created column, these predicates evaluate against NULL and filter out every otherwise valid assistant row. The repository's existing OpenCodeGoLocalUsageReader.messageUsageSQL explicitly uses COALESCE(json_extract(data, '$.time.created'), time_created) for this schema, so apply the same fallback here or these databases silently produce no local history.

Useful? React with 👍 / 👎.

Comment on lines +254 to +256
modelBreakdowns.append(CostUsageDailyReport.ModelBreakdown(
modelName: key.model,
costUSD: modelCost,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Preserve OpenCode provider ownership

When OpenCode routes requests through the providerID retained in its JSON/DB records, this breakdown always omits billingProviderID because the wire model, SQL query, and UsageRecord discard that field. Consequently downstream rendering cannot attribute models to the configured billing provider and may mix provider-specific usage; carry the recorded provider ID through to this initializer.

AGENTS.md reference: AGENTS.md:L46-L46

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Fixed in 65af90d. The OpenCode snapshot now passes costSource: .providerReported whenever any database-derived cost is published, and .estimated when the total is withheld. Covered by OpenCodeSessionScannerTests.

events.append(UnifiedUsageEvent(
day: dayKey,
model: model,
billingProviderID: Self.billingProvider(for: model),

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Keep Copilot billing ownership with Copilot

For Copilot sessions using Claude, GPT, or Gemini models, this derives billingProviderID from the model family and labels GitHub-billed Copilot activity as another provider's usage. Keep the underlying vendor IDs only for rate-card lookup via pricingProviderIDs, but set breakdown ownership to Copilot unless the source supplies explicit routing evidence.

AGENTS.md reference: AGENTS.md:L46-L46

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Already addressed by 5c2ae86 at the current head: Copilot breakdowns always set billingProviderID to copilot and use the vendor (anthropic/openai/google) only in pricingProviderIDs for rate lookup. Covered by CopilotSessionScannerTests.

@clawsweeper clawsweeper Bot added the merge-risk: 🚨 auth-provider 🚨 Merging this PR could break OAuth, tokens, provider routing, model choice, or credentials. label Aug 1, 2026
Manual refresh reconciles the entire local history in one pass instead of
creeping across refreshes:

- CostUsageFetcher: forceRefresh forces a rescan and lifts the 512MB
  per-refresh byte budget (configureFullRescan), so users with gigabytes of
  session history see the true total on a single manual refresh rather than
  watching token counts climb over several clicks.
- CostUsageScanner: per-file progress callback (progressHandler) threaded
  through the scan loop.
- SpendDashboardController: CodexScanProgressStore bounces scan-queue progress
  onto the main actor for live UI updates.
- PreferencesSpendDashboardPane: show "Scanning history X/Y" beside the
  refresh spinner during a full rescan (21 locales).

Co-authored-by: Cursor <cursoragent@cursor.com>
@clawsweeper clawsweeper Bot added the status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. label Aug 2, 2026

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

ℹ️ 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".

MiniMaxLocalHistoryScanner(),
AntigravityLocalHistoryScanner(),
QwenCodeLocalHistoryScanner(),
ZcodeLocalHistoryScanner(),

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Declare ZCode history on the z.ai provider

Fresh evidence after the earlier pipeline issue is that declared local adapters are now dispatched, but the newly registered .zcode adapter is still not declared by any provider descriptor: a repo-wide search of localHistorySources finds no .zcode, and ZaiProviderDescriptor remains unsupported. Consequently z.ai is filtered out by supportsDashboardHistory, so this production scanner remains reachable only from tests; add .zcode to the appropriate provider's token-cost configuration.

Useful? React with 👍 / 👎.

Comment on lines +174 to +176
totalTokens: input + cacheRead + output,
cacheReadTokens: cacheRead,
cacheCreationTokens: cacheCreation,

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 Include Kimi cache-creation tokens in usage totals

When a Kimi turn has nonzero inputCacheCreation, these fields are disjoint from inputOther, but totalTokens excludes the cache-creation bucket. The shared aggregator likewise derives its daily and headline totals without that bucket, so last30DaysTokens is understated and no longer equals the displayed input/cache-read/cache-creation/output components; include cache creation in the accumulated consumption total while preserving the uncached-input normalization signal separately.

Useful? React with 👍 / 👎.

Comment on lines +39 to +42
let context = input.addingReportingOverflow(cacheRead)
let usesLongContextRates = pricing.thresholdTokens.map {
context.overflow || context.partialValue > $0
} ?? false

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 Count cache creation when selecting long-context rates

When cache-creation tokens push a request over a model's thresholdTokens while input + cacheRead remains below it, this context check selects the short-context rates even though cache creation is subsequently priced as a separate input bucket. This disagrees with the Claude pricing path, which includes cache creation in the threshold calculation, and underprices affected Copilot/ZCode requests; include cacheCreation using overflow-safe arithmetic.

Useful? React with 👍 / 👎.

continue
}
let size = max(0, resourceValues?.fileSize ?? 0)
guard size <= self.maximumBytes - visitedBytes else { break }

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 Mark byte-limited Kimi scans as incomplete

When eligible Kimi history exceeds the 512 MiB budget, this exits at the first file that does not fit and permanently omits that file plus every later enumerated file. The resulting snapshot nevertheless sets historyCoverageIsEstablished to true and has no truncation signal or incremental cache, so the dashboard presents an arbitrary partial subtotal as complete on every refresh; retain/report incomplete coverage or scan a deterministic complete window.

Useful? React with 👍 / 👎.

@clawsweeper clawsweeper Bot added status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. proof: 📸 screenshot Contributor real behavior proof includes screenshot evidence. and removed proof: 📸 screenshot Contributor real behavior proof includes screenshot evidence. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. labels Aug 2, 2026
Session directories enumerate in arbitrary order, so an unsorted first-N pass
can fill the 20000-file cap with old messages and omit recent usage. Sort
candidates by modification date before enforcing the cap; add a fileLimit
override for tests and a recency regression test.
@clawsweeper clawsweeper Bot added rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. and removed rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. labels Aug 2, 2026

@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: 20c872500f

ℹ️ 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".

"qwen": UsageProvider.qwencloud.rawValue,
"z.ai": UsageProvider.zai.rawValue,
]
for namespace in components.reversed() {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Preserve the outer billing provider for nested routes

When a model ID contains a routing provider plus a vendor namespace, such as openrouter/anthropic/claude-*, iterating the namespaces in reverse selects Anthropic and attributes the breakdown to Claude even though OpenRouter owns the billed request. Prefer the outer explicit route, or withhold ownership when the namespace chain is ambiguous, so routed usage is not displayed under a different provider.

AGENTS.md reference: AGENTS.md:L46-L46

Useful? React with 👍 / 👎.

Comment on lines +110 to +112
let hasUnpricedTokenDay = daily.contains { $0.totalTokens != nil && $0.costUSD == nil }
let costs = daily.compactMap(\.costUSD)
let totalCost = (costs.isEmpty || hasUnpricedTokenDay) ? nil : costs.reduce(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 Withhold partial costs from comparison windows

When a requested comparison period contains both a priced day and one of the unpriced token days detected here, the headline correctly becomes nil, but CostUsageTokenSnapshot.summary(forLastDays:) still compactMaps the same daily costs and exposes the priced subtotal in the 7/30/90-day UI. Propagate the incomplete-day check into window summaries so a narrower comparison does not present partial spend as complete.

Useful? React with 👍 / 👎.

Comment on lines +89 to +92
SELECT (timestamp / 1000) AS seconds, model
FROM ai_code_hashes
WHERE timestamp >= ? AND timestamp < ? AND model IS NOT NULL AND model != ''
LIMIT \(self.maximumRows);

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 Deduplicate Cursor rows before applying the cap

When the requested Cursor window contains more than 500,000 ai_code_hashes rows, this unordered limit is applied to raw activity rather than distinct (day, model) pairs. The selected rows can therefore be dominated by one busy day/model, and the later in-memory dedup cannot recover models or days beyond the limit even though the snapshot reports established coverage; select distinct buckets before limiting, or mark the result incomplete.

Useful? React with 👍 / 👎.

@clawsweeper clawsweeper Bot added rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. and removed rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. merge-risk: 🚨 availability 🚨 Merging this PR could cause crashes, hangs, restart loops, stalls, or process outages. labels Aug 2, 2026
- Walk model namespaces from the outside in so nested routes such as
  openrouter/anthropic/claude-* keep the routing provider as the billing
  owner instead of resolving to the inner vendor.
- summary(forLastDays:) now returns nil cost whenever any token-bearing
  entry in the window is unpriced, so 7/30/90-day comparisons never present
  a priced subtotal as complete.
@clawsweeper clawsweeper Bot added status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. merge-risk: 🚨 availability 🚨 Merging this PR could cause crashes, hangs, restart loops, stalls, or process outages. and removed status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. labels Aug 2, 2026

@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: 40949c04df

ℹ️ 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".

billingProviderID: UsageProvider.kimi.rawValue,
inputTokens: input,
outputTokens: output,
totalTokens: input + cacheRead + output,

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 Check Kimi token-total additions for overflow

When a malformed Kimi history record contains nonnegative token counts whose sum exceeds Int.max, validOrNil accepts each field but this expression traps before the shared aggregator's checked arithmetic can reject the record, crashing the usage refresh instead of skipping corrupt input. Build the reported total with overflow-reporting additions, or omit it when the sum is not representable.

Useful? React with 👍 / 👎.

@clawsweeper clawsweeper Bot added rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. feature: ✨ showcase ClawSweeper spotlight: unusually compelling feature idea for maintainer attention. 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: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. 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 Aug 2, 2026
@steipete

steipete commented Aug 3, 2026

Copy link
Copy Markdown
Owner

Maintainer decision on the Usage & Spend program (applies to #2322, #2527, #2548, #2569, #2575, #2577 — closing together):

We want the ideas — the token-activity view and the cross-provider cost overview in particular are genuinely good, and we're adopting them. What we can't absorb is the delivery shape: 8k–20k-line PRs bundling scanners, pricing, identity, and UI can't be reviewed honestly, and live testing of the current heads surfaced the kind of defects that big surfaces hide (duplicate token-activity cards in the Models view; the unified Overview rendering no chip for an enabled provider; the account-attribution issue flagged earlier).

So we're taking this work as a base in-house and rebuilding it in small, individually landable slices — first the token-activity view rebuilt on the shared scan cache (no separate annual scan), then the cost overview aligned with the #2578 design discussion. Your commits will be cherry-picked where they fit, and every slice that draws on this work will credit you in the changelog, as today's merges already do.

@Yuxin-Qiao — you're this repo's most prolific contributor and much of today's release is your work. Focused PRs the size of #2574 land same-day; that's the shape that serves both of us.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feature: ✨ showcase ClawSweeper spotlight: unusually compelling feature idea for maintainer attention. 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. 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: 📸 screenshot Contributor real behavior proof includes screenshot evidence. 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