Add macOS usage and cost center - #430
Conversation
SergeSerb2
left a comment
There was a problem hiding this comment.
PR adds macOS usage and cost tracking. Architecture is sound (protocol + impl + mocks aligned), but the diff of ServerMetaRpc.swift is truncated mid-function, blocking verification of RPC types. Critical: verify the server-side AppSettings schema includes tokenEfficiency as non-optional before merge — if missing, settings loads will crash.
Could not anchor
- important
apps/mac/Sources/T3Kit/ServerMetaRpc.swift— ServerMetaRpc.swift diff ends mid-function at theencode()method. Cannot verify complete RPC type definitions forproviderUsageSummary()call or wire schema. Confirm the full file changes includeProviderUsageSummaryInputandProviderUsageSummarytypes with server API alignment.
SurgeCode auto-review · model=codex/gpt-5.6-luna · head=e6155d760f6c
| projectOverrides: overrides), | ||
| tokenEfficiency: AppTokenEfficiencySettings( | ||
| showComposerHints: settings.tokenEfficiency.showComposerHints, | ||
| showCostWarnings: settings.tokenEfficiency.showCostWarnings, |
There was a problem hiding this comment.
blocking: Settings decoding will crash if server response omits tokenEfficiency field. Verify server-side AppSettings schema includes this field (non-optional or with default). This is a breaking change if server support is incomplete.
| .number.precision(.fractionLength(0...2))) | ||
| }, | ||
| set: { text in | ||
| let normalized = text.replacingOccurrences(of: ",", with: ".") |
There was a problem hiding this comment.
nit: Invalid USD threshold input (e.g. "abc") silently converts to nil via Double() with no user feedback. TextField clears silently. Consider validating on blur or showing an error hint so users know input was rejected.
SergeSerb2
left a comment
There was a problem hiding this comment.
Adds usage tracking and cost center configuration to macOS app. Implementation includes new entity types for usage queries/summaries, settings for token efficiency (profile, cost warnings, composer hints), and a comprehensive usage reporting UI with filtering by date, project, provider, and thread.
Review blocker: ServerMetaRpc.swift diff is truncated mid-method (line ~3600), preventing review of the TokenEfficiencySettingsPatch.encode() wire protocol implementation. Cannot verify complete serialization correctness. Clarify: verify textFieldStyle(.settings) is defined in the project (not a standard SwiftUI style; if missing, compilation fails).
Could not anchor
- blocking
apps/mac/Sources/T3Kit/ServerMetaRpc.swift— Diff is truncated mid-implementation ofTokenEfficiencySettingsPatch.encode(to:)method. Cannot review wire protocol serialization logic or verify field mappings to server contract. Provide complete file or confirm the truncation is not due to incomplete implementation. - important
apps/mac/Sources/SurgeCodeMac/UI/Settings/UsageSettingsTab.swift— New usage querying, cost calculations, and date-window logic added with no unit tests. Recommend tests for:AppUsageSummaryfiltering (by provider/thread/date),AppUsageTokens.cacheEfficiencyedge cases (zero values),UsageDateWindow.bounds()calculations, andUsageFormatnumber/currency formatting with edge cases (zero, partial costs, nil values).
SurgeCode auto-review · model=codex/gpt-5.6-luna · head=46ea9c615bd8
| normalized.isEmpty ? nil : Double(normalized) | ||
| })) | ||
| .textFieldStyle(.settings) | ||
| .multilineTextAlignment(.trailing) |
There was a problem hiding this comment.
important: textFieldStyle(.settings) is not a standard SwiftUI style. Verify this is defined as a custom TextFieldStyle extension in the project; if missing, will cause compilation failure.
| @@ -1836,6 +1929,7 @@ public struct AppSettings: Hashable, Sendable { | |||
| self.addProjectBaseDirectory = addProjectBaseDirectory | |||
| self.workflowModelRouting = workflowModelRouting | |||
There was a problem hiding this comment.
important: AppSettings adds new field tokenEfficiency with non-optional default. Verify JSON decoding/encoding round-trips correctly when the field is missing from persisted settings (e.g., old app versions). The default initializer provides AppTokenEfficiencySettings(), which should work if Codable is synthesized, but confirm integration tests cover settings load/save cycle.
| showCostWarnings: settings.tokenEfficiency.showCostWarnings, | ||
| efficiencyProfile: settings.tokenEfficiency.profile.rawValue, | ||
| perTurnEstimatedCostWarningUsd: settings.tokenEfficiency.perTurnWarningUsd, | ||
| dailyEstimatedCostWarningUsd: settings.tokenEfficiency.dailyWarningUsd, |
There was a problem hiding this comment.
info: Date formatting uses ISO8601DateFormatter with .withFractionalSeconds. Confirm the server's ProviderUsageSummaryInput accepts this format; if server uses a different ISO8601 variant, the query may fail silently with mismatched timestamps.
…nter Add worktree control center
SergeSerb2
left a comment
There was a problem hiding this comment.
PR adds usage tracking, cost reporting, and worktree lifecycle management to the macOS app. Core model, protocol, and backend implementations look sound. No blocking issues found.
Notable points:
- Worktree operations (create/repair/remove) properly check thread status and have rollback on error.
- Usage query filtering by project/provider/thread follows expected patterns.
- New
ChatThreadfields (branch,worktreePath) correctly added to equality check. - Task group concurrency in
worktreeSnapshots()is idiomatic.
Minor concerns: refreshVcsStatus() errors silently fall back; directoryAllocatedSize() could be slow on large repos; verify UsageDateWindow.bounds() handles date math correctly.
SurgeCode auto-review · model=codex/gpt-5.6-luna · head=cf2c79be03c8
| let page = try? await client.getArchivedShellSnapshot( | ||
| cursor: archivedCursor, limit: 100) | ||
| else { break } | ||
| ownedThreads.append(contentsOf: page.threads.map(mapThread)) |
There was a problem hiding this comment.
nit: refreshVcsStatus() error is silently ignored, leaving isDirty and refName at fallback values. For status-critical operations, consider logging the failure or exposing a degraded-status flag so callers know the result may be stale.
| guard let values = try? url.resourceValues(forKeys: keys), | ||
| values.isSymbolicLink != true, values.isRegularFile == true | ||
| else { continue } | ||
| total += Int64(values.totalFileAllocatedSize ?? values.fileAllocatedSize ?? 0) |
There was a problem hiding this comment.
info: directoryAllocatedSize() enumerates every file under the worktree. On large repos (multi-GB), this can block. If performance becomes an issue, consider depth limits or sampling. For now this is fine, but worth documenting if the snapshot call ever feels slow.
| let providers = all.byProvider.filter { $0.id == providerID } | ||
| guard let bucket = providers.first else { | ||
| return AppUsageSummary( | ||
| turns: 0, |
There was a problem hiding this comment.
nit: When providerInstanceID is not found in byProvider, the mock returns an empty byProvider array but still filters byModel by that provider prefix. This can result in byModel buckets with no matching provider entry. Either filter both or filter neither to keep the structure consistent.
Summary
Area
apps/mac— native macOS appapps/windows— Windows desktop appapps/mobile— iPhone companion appapps/server— backend serverpackages/contracts,packages/shared,packages/client-runtime, …) or relay (infra/relay)Release size
size:XS— tiny internal, documentation, or narrowly scoped fixsize:S— small user-visible fix or contained improvementsize:M— normal feature or meaningful behavior changesize:L— broad feature or substantial cross-package changesize:XL— release-system, architecture, or ecosystem-scale changeVerification
pnpm run verify --allpasses (check + typecheck + tests; addslint:mobileand the Swift suite)pnpm run test:macpasses (required forapps/macchanges)Screenshots / Recordings
The Usage-center screen was captured and inspected during the macOS UI probe. The local capture is available at
/tmp/surgecode-usage-probe.m7s8fr/13b-settings-usage.png.Release notes
Adds a Usage center for inspecting token consumption, cache efficiency, estimated cost, and provider/model breakdowns across configurable date windows and filters.