Skip to content

feat: multi-metric tracking — v2 schema, editor, auto-discovery, and 1:N refresh - #2

Merged
linletian merged 13 commits into
mainfrom
feat/multi-metric-tracking
Jun 17, 2026
Merged

feat: multi-metric tracking — v2 schema, editor, auto-discovery, and 1:N refresh#2
linletian merged 13 commits into
mainfrom
feat/multi-metric-tracking

Conversation

@linletian

Copy link
Copy Markdown
Owner

Summary

Introduces multi-metric tracking architecture to replace the previous single-metric-per-instance model.

Changes

  • New data models: MetricConfig and MetricSnapshot to support multiple metrics per instance
  • v2 schema migration: Updated Instance, GlobalSettings, SlotViewData for the new metrics array structure
  • Auto-discovery & 1:N refresh: Instances are auto-discovered, each mapped to N metric suppliers for independent refresh
  • Multi-metric editor: Expandable settings panel with per-metric configuration UI and usage display
  • Parser-compatible keys: Fixed config key format for OpenCode Go and GitHub Copilot metric parsers
  • Balance preservation: Ensures InstanceType propagates correctly through SlotViewData and menu bar expansion
  • Docs & tests: Updated architecture docs, PRD, MiniMax API docs; added snapshot reference tests for animations

linletian and others added 13 commits June 16, 2026 23:11
…cking

Introduce MetricConfig (persisted, Codable) and MetricSnapshot (runtime, transient) as the v2 foundation for 1:N metric tracking. MetricConfig carries key/group/window/displayInMenuBar/shortName; MetricSnapshot carries runtime percent/display/color/isUnlimited. Includes Codable round-trip tests.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
…h metrics array

Instance: dimension→computed from metrics[0].key, enabled→trackingEnabled computed bridge. GlobalSettings: InstancesContainer with schema_version=2 and needsMigration detection. SlotViewData: metricSnapshots drives instanceType/colorState/dimension/weekly as computed properties, weekly.isUnlimited now from MetricSnapshot. Includes schema version, persistence round-trip, and old/new format decoding tests.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
PersistenceService: decodeAndMigrateV1 reads legacy dimension/enabled JSON, migrates to metrics/trackingEnabled v2 format with .backup safety. RefreshService: mapInstanceToSlotData iterates instance.metrics for 1:N MetricSnapshot mapping, auto-discovers new MiniMax model names on refresh, re-maps slot data after discovery. AppStateProxy: adapted loadInstances return signature. Includes RefreshServiceMappingTests for 1:N mapping across MiniMax, OpenCode, DeepSeek, and edge cases.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
InstanceEditorView: MiniMax capability-bucket checkboxes with per-window toggles and shortName fields, OpenCode window toggles. SettingsView: expandable instance rows with per-metric displayInMenuBar switches. UsageCardView: multi-metric grouped/flat content with isUnlimited→FlowingGlowBar path, displayInMenuBar filter. MenuBarIconRenderer: expandToMetricSlots with per-metric shortName fallback. MenuBarController: trackingEnabled count and extra metric height.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Add MetricConfig.swift, MetricSnapshot.swift to APIUsageStatus target; add MetricConfigCodableTests, InstanceDecodingTests, PersistenceServiceTests, RefreshServiceMappingTests, SchemaVersionTests to test target.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
…animation

Golden images for FlowingGlowBar glow strip rendering and breathing animation shadow states (critical/normal/warning).

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
…cking

ARCHITECTURE: update §4.1 data models (Instance/SlotViewData/MetricConfig/MetricSnapshot), §3.2 data flow (1:N mapping), §7.1 slot layout (expandToMetricSlots), §12 file structure. PRD: update §3.1 menu bar (multi-metric expansion), §3.2 usage panel (grouped cards), §3.3 provider table (capability buckets, OpenCode Go), §3.5 service management. minimax.md: model_name→capability bucket, updated rawData keys. README: update MiniMax description.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
…expansion

SlotViewData: add balanceInstanceType stored property so the computed instanceType returns .balance(...) instead of deriving a fake .quota from the synthetic MetricSnapshot. MenuBarIconRenderer.expandToMetricSlots: forward instanceType and colorState when creating per-metric render slots so balance instances show amount/currency in the menu bar icon instead of 0%.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Editor was generating MetricConfig.key "githubCopilot.premium_interactions" but CopilotResponseParser outputs rawData key "premium_interactions", causing value lookup to return "0" and display 0/0.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Editor was generating MetricConfig.key "opencode.5h"/"opencode.weekly"/"opencode.monthly" but OpenCodeSupplier.makeResponse outputs rawData keys "5h"/"weekly"/"monthly", causing all three windows to show 0%.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
…ations

Iterate slot.metricSnapshots for quota-type instances so a critical weekly window triggers a notification even when the 5h window is below threshold. Previously only slot.instanceType (first snapshot) was evaluated.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Thresholds JSON uses flat keys (usage_warning_percent, balance_warning) not nested objects. Instance's dimension and enabled are computed properties not in CodingKeys — tests now assert encoded['tracking_enabled'] and XCTAssertNil on dimension. DeepSeek balance test asserts .balance not .quota (balanceInstanceType is preserved). Removed testMissingSchemaVersionField (no migration scenario). Added ENABLE_HARDENED_RUNTIME=NO to Debug config for test bundle loading.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Replace hardcoded timestamp that misidentifies the date (1_783_432_800 is July 6 not June 17) with Calendar.nextDate(after:matching:) which computes the correct next Monday 00:00 UTC regardless of the input date.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant