Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 33 additions & 7 deletions Sources/CodeCaps/GlanceViews.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ struct GlancePopover: View {
/// and `⌘,` land in the same place: the Settings page last used.
var openSettings: () -> Void

@Environment(\.colorScheme) private var colorScheme

/// Rows the owner has expanded inline. Lives in the popover so it survives
/// re-renders while the popover is open, and is cleared when the popover
/// dismisses — persisting across launches would imply the popover remembers
Expand Down Expand Up @@ -298,14 +300,14 @@ struct GlancePopover: View {
.accessibilityElement(children: .ignore)
.accessibilityLabel(runawayFooterAccessibilityLabel)
.help("Runaway Usage Notice: click to inspect")
.padding(.trailing, 4)
} else {
Spacer()
}

openCodeCapsButton
}
.padding(.horizontal, Metrics.glanceGutter)
.padding(.leading, Metrics.glanceGutter)
.padding(.trailing, 6)
.frame(height: Metrics.glanceFooterHeight)
}

Expand All @@ -315,13 +317,12 @@ struct GlancePopover: View {
} label: {
HStack(spacing: 5) {
Text("Open CodeCaps")
Text("⌘1").font(.system(size: 10)).foregroundStyle(.tertiary)
Text("⌘1")
.font(.system(size: 10, weight: .medium))
.foregroundStyle(colorScheme == .dark ? Color.black.opacity(0.55) : Color.white.opacity(0.75))
}
.font(.system(size: 12, weight: .medium))
.padding(.horizontal, 10)
.frame(height: 28)
}
.buttonStyle(.borderedProminent)
.buttonStyle(GlanceFooterProminentButtonStyle())
.help("Open CodeCaps")
.accessibilityLabel("Open CodeCaps")
}
Expand Down Expand Up @@ -1964,3 +1965,28 @@ func glanceResetHelp(_ reset: Date?, now: Date) -> String? {
guard reset > now else { return "Reset was due \(when)" }
return "Resets in \(glanceResetFullCountdown(reset, now: now)), on \(when)"
}

/// Dedicated prominent button style matching the runaway notice banner in height (28pt)
/// and corner radius (6pt), while maintaining high contrast in both dark and light modes.
struct GlanceFooterProminentButtonStyle: ButtonStyle {
@Environment(\.isEnabled) private var isEnabled
@Environment(\.colorScheme) private var colorScheme

func makeBody(configuration: Configuration) -> some View {
configuration.label
.font(.system(size: 12, weight: .medium))
.foregroundStyle(colorScheme == .dark ? Color.black.opacity(0.92) : Color.white)
.padding(.horizontal, 10)
.frame(height: 28)
.background(
RoundedRectangle(cornerRadius: 6)
.fill(Theme.accent.opacity(configuration.isPressed ? 0.82 : 1.0))
)
.overlay(
RoundedRectangle(cornerRadius: 6)
.strokeBorder(Color.white.opacity(colorScheme == .dark ? 0.25 : 0.15), lineWidth: 0.5)
)
.contentShape(RoundedRectangle(cornerRadius: 6))
.shadow(color: Color.black.opacity(configuration.isPressed ? 0.02 : 0.12), radius: 1, y: 1)
}
}
2 changes: 2 additions & 0 deletions Sources/CodeCaps/PlatformLogo.swift
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,8 @@ public enum PlatformLogoImage {
"grok-bot": ("grok-bot", "svg"),
"minimax": ("minimax", "png"),
"muse": ("muse", "png"),
"muse-assist": ("muse-assist", "png"),
"muse-code": ("muse-code", "png"),
"cursor": ("cursor", "svg"),
]

Expand Down
2 changes: 1 addition & 1 deletion Sources/CodeCaps/QuotaComponents.swift
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@ enum Metrics {
static let glanceHeaderSegmentPadding: CGFloat = 11
/// The dots between the cluster's phrases.
static let glanceHeaderDotSize: CGFloat = 3
static let glanceFooterHeight: CGFloat = 38
static let glanceFooterHeight: CGFloat = 40
/// A source's heading band in From Fleet.
static let glanceGroupHeaderHeight: CGFloat = 22
/// The list's own padding above the first row and below the last.
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
19 changes: 15 additions & 4 deletions Sources/QuotaCore/QuotaModels.swift
Original file line number Diff line number Diff line change
Expand Up @@ -644,12 +644,21 @@ private enum QuotaProviders {
Expected(key: "xai", label: "Grok", via: nil),
Expected(key: "grok-bot", label: "Grok Bot", via: "cursor"),
Expected(key: "minimax", label: "MiniMax", via: nil),
Expected(key: "muse", label: "Muse", via: nil),
Expected(key: "muse-assist", label: "Muse Assist", via: nil),
Expected(key: "muse-code", label: "Muse Code", via: nil),
]

static func canonicalKey(provider: String, providerKey: String?, via: String?) -> String {
if via?.trimmingCharacters(in: .whitespacesAndNewlines).lowercased() == "antigravity" {
return "google-antigravity"
if let viaLower = via?.trimmingCharacters(in: .whitespacesAndNewlines).lowercased() {
if viaLower == "antigravity" {
return "google-antigravity"
}
if viaLower == "assist" || viaLower == "assistant" {
return "muse-assist"
}
if viaLower == "code" {
return "muse-code"
}
Comment on lines +656 to +661

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

kody code-review Bug high

Provider misclassification in canonicalKey applies the via branch for assist/assistant/code without confirming Muse, so manifest groups keyed solely by canonicalKey(provider:providerKey:nil, via:group.via) (QuotaModels.swift:494) and deduped through manifestIndex silently merge a non-Muse group advertised with via: "code" into Muse Code and regroup its windows. Gate the muse-assist/muse-code returns on a trimmed, lowercased providerKey or fallback provider containing muse.

let rawProvider = (providerKey?.isEmpty == false ? providerKey! : provider)
                .trimmingCharacters(in: .whitespacesAndNewlines).lowercased()
            if rawProvider.contains("muse") {
                if viaLower == "assist" || viaLower == "assistant" { return "muse-assist" }
                if viaLower == "code" { return "muse-code" }
            }
Prompt for LLM

File Sources/QuotaCore/QuotaModels.swift:

Line 656 to 661:

Provider misclassification in `canonicalKey` applies the `via` branch for `assist`/`assistant`/`code` without confirming Muse, so manifest groups keyed solely by `canonicalKey(provider:providerKey:nil, via:group.via)` (`QuotaModels.swift:494`) and deduped through `manifestIndex` silently merge a non-Muse group advertised with `via: "code"` into Muse Code and regroup its windows. Gate the `muse-assist`/`muse-code` returns on a trimmed, lowercased `providerKey` or fallback `provider` containing `muse`.

Suggested Code:

let rawProvider = (providerKey?.isEmpty == false ? providerKey! : provider)
                .trimmingCharacters(in: .whitespacesAndNewlines).lowercased()
            if rawProvider.contains("muse") {
                if viaLower == "assist" || viaLower == "assistant" { return "muse-assist" }
                if viaLower == "code" { return "muse-code" }
            }

Talk to Kody by mentioning @kody

Was this suggestion helpful? React with 👍 or 👎 to help Kody learn from this interaction.

​

​

}
let raw = (providerKey?.isEmpty == false ? providerKey! : provider)
.trimmingCharacters(in: .whitespacesAndNewlines).lowercased()
Expand All @@ -661,7 +670,9 @@ private enum QuotaProviders {
"xai": "xai", "grok": "xai", "grok-build": "xai",
"grok-bot": "grok-bot", "grok bot": "grok-bot", "grokbot": "grok-bot",
"minimax": "minimax", "minimax-code": "minimax",
"muse": "muse", "muse-cli": "muse", "muse-sdk": "muse",
"muse-assist": "muse-assist", "muse assist": "muse-assist", "muse_assist": "muse-assist", "muse-assistant": "muse-assist", "muse assistant": "muse-assist",
"muse-code": "muse-code", "muse code": "muse-code", "muse_code": "muse-code",
"muse": "muse-code", "muse-cli": "muse-code", "muse-sdk": "muse-code",
"kimi": "kimi", "moonshot": "kimi", "moonshot-ai": "kimi",
"gemini-cli": "gemini-cli",
"copilot": "github-copilot", "github-copilot": "github-copilot", "github_copilot": "github-copilot",
Expand Down
4 changes: 2 additions & 2 deletions Tests/CodeCapsTests/GlanceHeightTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -105,9 +105,9 @@ final class GlanceHeightTests: XCTestCase {
}

func testThePopoverAddsItsChromeAroundTheList() {
// Header 40 + footer 38 + two 1pt dividers + 8pt above and below the list.
// Header 40 + footer 40 + two 1pt dividers + 8pt above and below the list.
let total = QuotaGlanceMetrics.popoverHeight(forListHeight: 100)
let expected: CGFloat = 40 + 38 + 2 + 16 + 100
let expected: CGFloat = 40 + 40 + 2 + 16 + 100
XCTAssertEqual(total, expected)
}

Expand Down
7 changes: 4 additions & 3 deletions Tests/CodeCapsTests/PlatformLogoResourceTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ final class PlatformLogoResourceTests: XCTestCase {
"anthropic", "claude", "openai", "codex",
"google-antigravity", "antigravity",
"google-antigravity:gemini", "google-antigravity:third-party",
"gemini", "xai", "grok", "grok-cli", "grok-bot", "minimax", "muse", "cursor",
"gemini", "xai", "grok", "grok-cli", "grok-bot", "minimax",
"muse", "muse-assist", "muse-code", "cursor",
]

func testEveryProviderKeyResolvesABundledMark() {
Expand All @@ -50,7 +51,7 @@ final class PlatformLogoResourceTests: XCTestCase {
let bundle = try XCTUnwrap(ResourceBundle.resolved,
"the SwiftPM resource bundle could not be resolved at all")
let marks = ["claude", "openai", "gemini", "gemini-color", "gemini-mono",
"cursor", "grok", "grok-bot", "minimax", "muse"]
"cursor", "grok", "grok-bot", "minimax", "muse", "muse-assist", "muse-code"]
// Every named mark must be present in some form. Deliberately not an
// exact count: the owner replacing the fabricated MiniMax `{M}` with
// the real PNG mark added a file, and an equality assertion is a test
Expand All @@ -67,7 +68,7 @@ final class PlatformLogoResourceTests: XCTestCase {
/// a different hat: `NSImage` returns an object, and the row draws nothing.
func testEveryBundledMarkRasterises() throws {
let bundle = try XCTUnwrap(ResourceBundle.resolved)
for name in ["claude", "openai", "gemini", "gemini-mono", "cursor", "grok", "grok-bot", "minimax", "muse"] {
for name in ["claude", "openai", "gemini", "gemini-mono", "cursor", "grok", "grok-bot", "minimax", "muse", "muse-assist", "muse-code"] {
for ext in ["svg", "png"] {
guard let url = bundle.url(forResource: name, withExtension: ext) else { continue }
let image = try XCTUnwrap(NSImage(contentsOf: url), "\(name).\(ext) did not load")
Expand Down
6 changes: 3 additions & 3 deletions Tests/QuotaCoreTests/QuotaCoreTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -202,10 +202,10 @@ final class QuotaCoreTests: XCTestCase {
let future = window(provider: "new-provider", occurred: "2023-11-14T22:05:00Z")
let response = QuotaResponse(generatedAt: "2023-11-14T22:10:00Z", windows: [future])
let sections = response.platformSections(now: now)
XCTAssertEqual(Array(sections.prefix(8)).map(\.providerKey), [
"anthropic", "openai", "google-antigravity", "cursor", "xai", "grok-bot", "minimax", "muse",
XCTAssertEqual(Array(sections.prefix(9)).map(\.providerKey), [
"anthropic", "openai", "google-antigravity", "cursor", "xai", "grok-bot", "minimax", "muse-assist", "muse-code",
])
XCTAssertTrue(sections.prefix(8).allSatisfy(\.isMissing))
XCTAssertTrue(sections.prefix(9).allSatisfy(\.isMissing))
XCTAssertEqual(sections.last?.providerKey, "new-provider")
}

Expand Down
11 changes: 11 additions & 0 deletions docs/EFFORT-LOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,16 @@
# CodeCaps — Effort Log

## 2026-10-05 — Glance footer equidistant polish, Muse Assist & Muse Code quota split [AG, in progress]

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

kody code-review Kody Rules critical

Required pre-work coordination is missing from the docs/EFFORT-LOG.md entry, which marks this substantial change in progress without a repo-first #agent-sync claim or a reference to AGENT-SYNC.md. Read /Users/jay/apps/AGENT-SYNC.md, post a claim in #agent-sync with repo: CodeCaps as the first field, and add the claim reference to the entry.

Also found in:

  • docs/EFFORT-LOG.md:5-5
  • ios/CodeCapsCompanion/Widgets/WidgetViews.swift:144-144
  • ios/CodeCapsCompanion/Widgets/WidgetViews.swift:142-142
  • ios/CodeCapsCompanion/Widgets/WidgetViews.swift:143-143

Kody rule violation: Keep credentials out of public source and verify UI changes with automated screenshots

Prompt for LLM

File docs/EFFORT-LOG.md:

Line 3:

Required pre-work coordination is missing from the `docs/EFFORT-LOG.md` entry, which marks this substantial change in progress without a repo-first `#agent-sync` claim or a reference to `AGENT-SYNC.md`. Read `/Users/jay/apps/AGENT-SYNC.md`, post a claim in `#agent-sync` with `repo: CodeCaps` as the first field, and add the claim reference to the entry.

**Also found in:**
- `docs/EFFORT-LOG.md:5-5`
- `ios/CodeCapsCompanion/Widgets/WidgetViews.swift:144-144`
- `ios/CodeCapsCompanion/Widgets/WidgetViews.swift:142-142`
- `ios/CodeCapsCompanion/Widgets/WidgetViews.swift:143-143`

Talk to Kody by mentioning @kody

Was this suggestion helpful? React with 👍 or 👎 to help Kody learn from this interaction.

​

​


Lane: `ag/glance-footer-equidistant-muse-split`.

- Glance footer geometry & styling polish: updated footer height to 40pt with 28pt custom prominent button style (`GlanceFooterProminentButtonStyle`), exactly matching the runaway marquee notice banner's 28pt height and `RoundedRectangle(cornerRadius: 6)`. Configured button padding so top (6pt), bottom (6pt), and trailing (6pt) margins to the window and divider edges are mathematically equidistant. Ensured high-contrast rendering across dark mode (pastel accent with dark ink) and light mode (deep accent with crisp white text).
- Split Muse into two separate providers: replaced generic `muse` with dedicated `muse-assist` ("Muse Assist") and `muse-code` ("Muse Code") in `QuotaProviders.expected` (total 9 expected providers). Preserved backward compatibility with aliases for `muse-assist`, `muse-assistant`, `muse-code`, `muse`, `muse-cli`, and `muse-sdk`.
- Asset bundling & cross-platform mappings: bundled high-resolution `muse-assist.png` (transparent background blue script "m") and `muse-code.png` (Meta infinity loop artwork from `MuseCode - Dark Mode.png`). Generated 1x/2x/3x asset catalogs (`provider-muse-assist.imageset`, `provider-muse-code.imageset`) for iOS companion and widgets. Updated `PlatformLogo`, `CompanionQuotaModel`, `WidgetPresentation`, and `WidgetViews`.
- Verification: all 721 unit tests passing across `QuotaCoreTests` (390 tests) and `CodeCapsTests` (331 tests); clean build of `CodeCapsCompanion` iOS simulator target via `xcodebuild`.

---

## 2026-10-04 — Glance title breathing room, dynamic pacing highlights, PiP widget, and iOS companion polish [AG, in progress]

Lane: `ag/ui-glance-pacing-pip-ios-polish`. Board `bb2a8b26`, `7175aba0`, `1ac04ba9`, `4be8a67a`, `4bcf84f1`.
Expand Down
12 changes: 10 additions & 2 deletions ios/CodeCapsCompanion/App/Models/CompanionQuotaModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -293,7 +293,9 @@ public struct CompanionQuotaItem: Identifiable, Codable, Equatable {
if key.contains("grok-bot") { return "provider-grok-bot" }
if key.contains("grok") || key.contains("xai") { return "provider-grok" }
if key.contains("minimax") { return "provider-minimax" }
if key.contains("muse") { return "provider-muse" }
if key.contains("muse-assist") || key.contains("muse_assist") { return "provider-muse-assist" }
if key.contains("muse-code") || key.contains("muse_code") { return "provider-muse-code" }
if key.contains("muse") { return "provider-muse-code" }
if key.contains("antigravity") || key.contains("gemini") { return "provider-gemini" }
return nil
}
Expand Down Expand Up @@ -1269,8 +1271,14 @@ public final class CompanionQuotaModel: ObservableObject {
if pKey.contains("minimax") || prov.contains("minimax") {
return ("minimax", "MiniMax", "minimax")
}
if pKey.contains("muse-assist") || prov.contains("muse-assist") || prov.contains("muse assist") || id.contains("assist") {
return ("muse-assist", "Muse Assist", "muse-assist")
}
if pKey.contains("muse-code") || prov.contains("muse-code") || prov.contains("muse code") || id.contains("code") {
return ("muse-code", "Muse Code", "muse-code")
}
if pKey.contains("muse") || prov.contains("muse") {
return ("muse", "Muse", "muse")
return ("muse-code", "Muse Code", "muse-code")
}
Comment on lines 1280 to 1282

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

kody code-review Bug high

Canonicalization drift affects canonicalManifestKey (lines 1299-1317): the legacy mapping returns muse-code, but the mirror lacks the muse/muse-cli/muse-sdk → muse-code aliases and the new via assist/code handling this PR added to QuotaProviders.canonicalKey, despite its doc comment claiming “the aliases match.” The manifest label lookup (lines 1248-1254), iconHint(for:) lookup (lines 1320-1323), and server ordering key (lines 879-884) compare canonicalManifestKey(...) against muse-code, causing legacy Muse manifest groups to canonicalize to muse on iOS/widget, lose their server labels and icon hints, and fall into the “future keys” bucket (line 898), while Mac (QuotaModels.swift:494) honors the manifest and renders the same provider differently; port the alias rows and via branches into both mirrors.

Prompt for LLM

File ios/CodeCapsCompanion/App/Models/CompanionQuotaModel.swift:

Line 1280 to 1282:

Canonicalization drift affects `canonicalManifestKey` (lines 1299-1317): the legacy mapping returns `muse-code`, but the mirror lacks the `muse`/`muse-cli`/`muse-sdk` → `muse-code` aliases and the new `via` assist/code handling this PR added to `QuotaProviders.canonicalKey`, despite its doc comment claiming “the aliases match.” The manifest label lookup (lines 1248-1254), `iconHint(for:)` lookup (lines 1320-1323), and server ordering key (lines 879-884) compare `canonicalManifestKey(...)` against `muse-code`, causing legacy Muse manifest groups to canonicalize to `muse` on iOS/widget, lose their server labels and icon hints, and fall into the “future keys” bucket (line 898), while Mac (`QuotaModels.swift:494`) honors the manifest and renders the same provider differently; port the alias rows and `via` branches into both mirrors.

Talk to Kody by mentioning @kody

Was this suggestion helpful? React with 👍 or 👎 to help Kody learn from this interaction.

​

​

Comment on lines +1274 to 1282

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

kody code-review Bug high

Provider misclassification in the new Muse branches places the unscoped id.contains("assist") and id.contains("code") disjuncts before the grok-bot, cursor, and grok/xai checks, relabeling any non-Muse window whose WireRawWindow.id merely contains "code" or "assist" as Muse Code or Muse Assist and collapsing it into platformGroups[platKey] (lines 862-868); for example, local-mac:cursor:code-review renders as Muse Code with the Muse mark. Only evaluate the id assist/code test when pKey or prov already identifies Muse, matching the pre-existing id.contains("grok-bot") pattern.

if pKey.contains("muse") || prov.contains("muse") {
            let wantsAssist = pKey.contains("assist") || prov.contains("assist") || id.contains("assist")
            return wantsAssist
                ? ("muse-assist", "Muse Assist", "muse-assist")
                : ("muse-code", "Muse Code", "muse-code")
        }
Prompt for LLM

File ios/CodeCapsCompanion/App/Models/CompanionQuotaModel.swift:

Line 1274 to 1282:

Provider misclassification in the new Muse branches places the unscoped `id.contains("assist")` and `id.contains("code")` disjuncts before the grok-bot, cursor, and grok/xai checks, relabeling any non-Muse window whose `WireRawWindow.id` merely contains "code" or "assist" as Muse Code or Muse Assist and collapsing it into `platformGroups[platKey]` (lines 862-868); for example, `local-mac:cursor:code-review` renders as Muse Code with the Muse mark. Only evaluate the `id` assist/code test when `pKey` or `prov` already identifies Muse, matching the pre-existing `id.contains("grok-bot")` pattern.

Suggested Code:

if pKey.contains("muse") || prov.contains("muse") {
            let wantsAssist = pKey.contains("assist") || prov.contains("assist") || id.contains("assist")
            return wantsAssist
                ? ("muse-assist", "Muse Assist", "muse-assist")
                : ("muse-code", "Muse Code", "muse-code")
        }

Talk to Kody by mentioning @kody

Was this suggestion helpful? React with 👍 or 👎 to help Kody learn from this interaction.

​

​

if pKey.contains("grok-bot") || prov.contains("grok-bot") || prov.contains("grok bot") || id.contains("grok-bot") {
return ("grok-bot", "Grok Bot", "grok-bot")
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"images": [
{
"idiom": "universal",
"scale": "1x",
"filename": "provider-muse-assist.png"
},
{
"idiom": "universal",
"scale": "2x",
"filename": "provider-muse-assist@2x.png"
},
{
"idiom": "universal",
"scale": "3x",
"filename": "provider-muse-assist@3x.png"
}
],
"info": {
"author": "xcode",
"version": 1
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"images": [
{
"idiom": "universal",
"scale": "1x",
"filename": "provider-muse-code.png"
},
{
"idiom": "universal",
"scale": "2x",
"filename": "provider-muse-code@2x.png"
},
{
"idiom": "universal",
"scale": "3x",
"filename": "provider-muse-code@3x.png"
}
],
"info": {
"author": "xcode",
"version": 1
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
8 changes: 7 additions & 1 deletion ios/CodeCapsCompanion/Widgets/WidgetPresentation.swift
Original file line number Diff line number Diff line change
Expand Up @@ -678,8 +678,14 @@ public enum WidgetPresentation {
if pKey.contains("minimax") || prov.contains("minimax") {
return ("minimax", "MiniMax", "minimax")
}
if pKey.contains("muse-assist") || prov.contains("muse-assist") || prov.contains("muse assist") || id.contains("assist") {
return ("muse-assist", "Muse Assist", "muse-assist")
}
if pKey.contains("muse-code") || prov.contains("muse-code") || prov.contains("muse code") || id.contains("code") {
return ("muse-code", "Muse Code", "muse-code")
}
if pKey.contains("muse") || prov.contains("muse") {
return ("muse", "Muse", "muse")
return ("muse-code", "Muse Code", "muse-code")
}
if pKey.contains("grok-bot") || prov.contains("grok-bot") || prov.contains("grok bot") || id.contains("grok-bot") {
return ("grok-bot", "Grok Bot", "grok-bot")
Expand Down
4 changes: 3 additions & 1 deletion ios/CodeCapsCompanion/Widgets/WidgetViews.swift
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,9 @@ struct ProviderMarkView: View {
if low.contains("openai") || low.contains("codex") { return "provider-openai" }
if low.contains("cursor") { return "provider-cursor" }
if low.contains("minimax") { return "provider-minimax" }
if low.contains("muse") { return "provider-muse" }
if low.contains("muse-assist") || low.contains("muse_assist") { return "provider-muse-assist" }
if low.contains("muse-code") || low.contains("muse_code") { return "provider-muse-code" }
if low.contains("muse") { return "provider-muse-code" }

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

kody code-review Kody Rules high

Verification gap in the HogHunterIOS simulator verification leaves the added low.contains("muse") fallback to provider-muse-code unverified for generic Muse identifiers because the diff contains no simulator screenshot capture. Add an automated xcrun simctl io booted screenshot <artifact> step to the simulator verification.

Also found in:

  • ios/CodeCapsCompanion/Widgets/WidgetViews.swift:142-142
  • ios/CodeCapsCompanion/Widgets/WidgetViews.swift:143-143

Kody rule violation: Gate iOS/TestFlight releases on a signing-safe workflow and verify UI changes with automated screenshots

Prompt for LLM

File ios/CodeCapsCompanion/Widgets/WidgetViews.swift:

Line 144:

Verification gap in the `HogHunterIOS` simulator verification leaves the added `low.contains("muse")` fallback to `provider-muse-code` unverified for generic Muse identifiers because the diff contains no simulator screenshot capture. Add an automated `xcrun simctl io booted screenshot <artifact>` step to the simulator verification.

**Also found in:**
- `ios/CodeCapsCompanion/Widgets/WidgetViews.swift:142-142`
- `ios/CodeCapsCompanion/Widgets/WidgetViews.swift:143-143`

Talk to Kody by mentioning @kody

Was this suggestion helpful? React with 👍 or 👎 to help Kody learn from this interaction.

​

​

if low.contains("antigravity") { return "provider-antigravity" }
if low.contains("gemini") { return "provider-gemini" }
if low.contains("grok-bot") { return "provider-grok-bot" }
Expand Down
Loading