Skip to content

Closes #3602: Suppress ignored Claude notifications - #3959

Closed
austinywang wants to merge 21 commits into
mainfrom
issue-3602-suppress-idle-prompt-notifs
Closed

austinywang wants to merge 21 commits into
mainfrom
issue-3602-suppress-idle-prompt-notifs

Conversation

@austinywang

@austinywang austinywang commented May 12, 2026 •

Copy link
Copy Markdown
Contributor

Closes #3602

Summary

  • Add notifications.ignoredClaudeNotificationTypes support for Claude Code notification suppression, with idle_prompt documented as the recurring idle-prompt use case.
  • Move Claude notification normalization, extraction, suppression, and settings-file precedence into CMUXClaudeNotifications so the app and CLI share one domain boundary.
  • Treat an existing current settings file with missing or invalid ignoredClaudeNotificationTypes as an empty suppression set, so stale launch-time hook env cannot keep hiding notifications.
  • Wire the setting through config parsing, terminal env export, schema/docs, and runtime regression coverage.

Testing

  • Not run locally per repo policy; CI is the verification path for this branch.

@coderabbitai

coderabbitai Bot commented May 12, 2026 •

Copy link
Copy Markdown
📝 Walkthrough

Walkthrough

Adds ignored-CLAUDE-notification-type support: normalization utilities, settings/UserDefaults and file/template parsing, CLI parsing/fallback extraction, suppression decision that short-circuits hook rendering, environment/build wiring, unit/integration tests, docs, and CI test additions.

Changes

Notification Suppression Feature

Layer / File(s) Summary
Notification type normalization utility
Sources/ClaudeNotificationTypeNormalization.swift
ClaudeNotificationTypeNormalization defines normalization rules, config keys, and helpers to build normalized sets and stable unique lists.
Settings keys, defaults, and retrieval
Sources/cmuxApp.swift
Adds ClaudeCodeIntegrationSettings UserDefaults key, default list, and helpers to read and normalize stored ignored notification types.
Settings file parser and template wiring
Sources/CmuxSettingsJSONPathSupport.swift, Sources/KeyboardShortcutSettingsFileStore.swift, Sources/KeyboardShortcutSettingsFileStore+Template.swift
Whitelists notifications.ignoredClaudeNotificationTypes, parses an array value into normalized stored defaults, and includes the key in generated JSONC templates.
CLI parsed input extensions and helpers
CLI/cmux.swift
Adds rawFallbackNotificationTypeValues, claudeHookObject(fromJSONValue:), and logic to extract fallback-derived notification-type candidates during parsing.
CLI notification suppression logic
CLI/cmux.swift
Extracts notification-type candidates from parsed input (root and nested keys and fallback strings), normalizes them, loads ignored set from settings/env/UserDefaults, computes intersection, emits breadcrumb for suppressed types, prints OK, and returns early to skip rendering.
Environment injection and build wiring
Sources/GhosttyTerminalView.swift, cmux.xcodeproj/project.pbxproj
Injects CMUX_CLAUDE_IGNORED_NOTIFICATION_TYPES in terminal surface environment and adds new normalization source file to both cmux and cmux-cli targets.
Test coverage for suppression behavior
cmuxTests/KeyboardShortcutSettingsFileStoreStartupTests.swift, tests/test_claude_hook_ignored_notification_types.py
Swift unit test validates settings-file parsing and normalization; Python integration test runs a capturing socket server and verifies suppression, non-suppression, payload-shape handling, and cmux.json precedence.
User documentation & CI
docs/notifications.md, .circleci/config.yml, .github/workflows/ci.yml
Documents notifications.ignoredClaudeNotificationTypes example and adds the new Python regression test to CI workflows.

Sequence Diagram(s)

sequenceDiagram
  participant User as User/Config
  participant Settings as Settings System
  participant CLI as cmux CLI
  participant Parser as ClaudeHook Parser
  participant Suppressor as Suppression Logic
  participant Output as stdout / hook commands

  User->>Settings: Configure ignoredClaudeNotificationTypes (file / env / UserDefaults)
  Settings->>Settings: Normalize & store values
  Settings->>CLI: Inject via CMUX_CLAUDE_IGNORED_NOTIFICATION_TYPES env
  User->>CLI: Send claude-hook notification payload
  CLI->>Parser: Parse input, extract notification type candidates (including fallback)
  Parser->>Suppressor: Provide normalized candidate set
  Suppressor->>Settings: Load normalized ignored set
  Suppressor->>Suppressor: Compute intersection
  alt Intersection non-empty
    Suppressor->>Output: Emit breadcrumb, print "OK"
    Suppressor->>CLI: Return early (skip rendering)
  else Intersection empty
    Parser->>Output: Continue summary/mapping and emit notification commands
  end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Poem

🐰 A rabbit nibbles through the noise,
Hops past echoes of idle ploys—
Normalize names, check the list,
Whisper "OK" and gently desist.


Caution

Pre-merge checks failed

Please resolve all errors before merging. Addressing warnings is optional.

  • Ignore

❌ Failed checks (2 errors, 2 warnings)

Check name Status Explanation Resolution
Cmux Swift File And Package Boundaries ❌ Error PR violates boundary rule by adding 251 lines to oversized file CLI/cmux.swift (24.6K total, 20.5K budget). Implements feature, not bug fix. No extraction occurred. Extract notification suppression logic to SwiftPM package; retain only hook dispatch in CLI/cmux.swift.
Cmux Architecture Rethink ❌ Error Invalid settings files continue instead of blocking fallback to environment, allowing stale env state to persist when settings are corrupted, defeating precedence invariant. Change case .invalid: continue to return [] to prevent env fallback when cmux.json is malformed, ensuring removed settings unblock notifications.
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Description check ⚠️ Warning PR description covers summary and testing but is incomplete; missing demo video, review trigger block, and checklist items required by template. Add demo video section (N/A if no UI changes), include the Review Trigger copy/paste block, and complete the Checklist with checked boxes for completed items.
✅ Passed checks (12 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: adding Claude notification suppression functionality aligned with issue #3602.
Linked Issues check ✅ Passed The code changes fully implement issue #3602 objectives: array-based notification suppression via notifications.ignoredClaudeNotificationTypes, correct notification type extraction, preserved Running/Stopped status, configurable per-workspace via settings files, and proper field matching without false positives.
Out of Scope Changes check ✅ Passed All changes are directly aligned with #3602 objectives: notification suppression infrastructure, settings parsing, environment export, normalization helpers, documentation, and comprehensive test coverage. No out-of-scope changes detected.
Cmux Swift Actor Isolation ✅ Passed No actor isolation issues. ClaudeNotificationTypeNormalization is a pure utility enum. New settings methods follow existing patterns, called from @MainActor contexts only.
Cmux Swift Blocking Runtime ✅ Passed No blocking primitives added. Only synchronous operations: file reads, JSON parsing, string operations, Set.intersection(), UserDefaults reads. No semaphores, locks, sleeps, asyncAfter, or polling.
Cmux No Hacky Sleeps ✅ Passed No production Python/JS/TS/shell changes. New Python test uses event-based timeouts (threading.Event, socket I/O, deadline-driven loops), not hacky sleeps. Swift changes are covered by separate rule.
Cmux Swift Concurrency ✅ Passed All notification suppression code is synchronous. No DispatchQueue background work, fire-and-forget Tasks, or Combine patterns introduced. Uses only string/collection operations.
Cmux Swift @Concurrent ✅ Passed No @concurrent annotation violations found. All new code is synchronous. Calls to synchronous helpers from @MainActor are appropriate. No async functions or @concurrent misuse detected.
Cmux Swift Logging ✅ Passed No Swift logging violations. Uses telemetry.breadcrumb() infrastructure and existing logInvalid() function. No print/NSLog/debugPrint/dump added. No secrets logged.
Cmux User-Facing Error Privacy ✅ Passed No violations. User-facing content is limited to safe documentation, standard CLI output, internal diagnostic logs, and internal telemetry. No credentials, vendor names, or sensitive data exposed.
Cmux Swiftui State Layout ✅ Passed PR adds only utility enum and static functions, no @Published/@Observable/@State. GhosttyTerminalView change is environment variable configuration. No SwiftUI state violations detected.
Cmux Swift Auxiliary Window Close Shortcuts ✅ Passed PR does not add/modify NSWindow, NSPanel, NSWindowController, Window, or WindowGroup code. Changes are notification suppression logic, settings configuration, and environment variables only.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch issue-3602-suppress-idle-prompt-notifs

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@vercel

vercel Bot commented May 12, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
cmux Ready Ready Preview, Comment May 19, 2026 8:36am
cmux-staging Building Building Preview, Comment May 19, 2026 8:36am

@greptile-apps

greptile-apps Bot commented May 12, 2026 •

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR closes #3602 by adding notifications.ignoredClaudeNotificationTypes support to cmux settings, enabling users to suppress specific Claude Code Notification hook events (e.g. idle_prompt) without disabling the integration entirely.

  • New CMUXClaudeNotifications SwiftPM package centralizes normalization, extraction, suppression, and settings-file loading logic, shared by both the app target and CLI to eliminate the duplication flagged in a prior review.
  • CLI claude-hook notification path now reads current settings files first (before the launch-time env var), extracts notification subtypes from multiple payload shapes, and early-returns with a telemetry breadcrumb when all extracted types are in the ignored set; hook_event_name and root-level generic type fields are correctly excluded.
  • App target writes the ignored list to UserDefaults and exports it unconditionally via CMUX_CLAUDE_IGNORED_NOTIFICATION_TYPES, making an empty list explicitly authoritative so stale UserDefaults cannot resurrect a removed setting.

Confidence Score: 5/5

Safe to merge. All four issues flagged in previous review rounds are verifiably addressed, the new package boundary is correctly scoped, and both unit and integration tests cover the key edge cases.

The notification suppression path is narrow and well-isolated: it only fires in the CLI claude-hook notification subcommand, reads settings files synchronously before falling back to env or UserDefaults, and returns early without touching any shared mutable state. The shared normalization logic is now in a single place. The wrong-type and missing-key precedence cases are explicitly tested, and the hook_event_name exclusion regression prevents the accidental wildcard suppression footgun. No actor isolation regressions, no sensitive data in telemetry, and the 78-line addition to the CLI file is well within the growth budget.

No files require special attention.

Important Files Changed

Filename Overview
Packages/CMUXClaudeNotifications/Sources/CMUXClaudeNotifications/ClaudeNotifications.swift New 221-line package with well-scoped enums for normalization, extraction, settings-file loading, and suppression. All four concerns relate to a single domain; well within line-count and responsibility budgets.
CLI/cmux.swift Adds ~78 lines of CLI-specific wiring to the already 24k-line file. Well below the 250-line growth threshold; shared logic correctly lives in the new package rather than inline.
Sources/GhosttyTerminalView.swift Sets CMUX_CLAUDE_IGNORED_NOTIFICATION_TYPES unconditionally (including empty string) so an empty ignored list is explicitly authoritative, preventing stale UserDefaults from reactivating suppression in existing terminals.
Sources/KeyboardShortcutSettingsFileStore.swift Parses and normalizes ignoredClaudeNotificationTypes from the notifications section; correctly logs and skips invalid values without writing to UserDefaults, leaving the previous value intact for the env export.
tests/test_claude_hook_ignored_notification_types.py Comprehensive regression test covering flat, nested, JSON-string, array-fallback, and raw-fallback payload shapes; settings-file vs env-var precedence; invalid/malformed/wrong-type configs; and the hook_event_name exclusion fix.

Reviews (17): Last reviewed commit: "refactor: isolate Claude notification do..." | Re-trigger Greptile

Comment thread Sources/GhosttyTerminalView.swift
Comment thread Sources/KeyboardShortcutSettingsFileStore.swift Outdated
Comment thread CLI/cmux.swift Outdated
Comment thread CLI/cmux.swift Outdated
Comment thread CLI/cmux.swift Outdated
coderabbitai[bot]
coderabbitai Bot previously requested changes May 17, 2026

@coderabbitai coderabbitai 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.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@CLI/cmux.swift`:
- Around line 16879-16882: The breadcrumb currently logs the full
notificationTypes set which may contain freeform user content; change the code
before calling telemetry.breadcrumb so you compute a safe matched set (e.g., let
matchedTypes = notificationTypes.intersection(ignoredNotificationTypes) or
filter notificationTypes against a whitelist of known ignored types), and then
pass only matchedTypes.sorted().joined(separator: ",") (or omit the "types" key
entirely when matchedTypes.isEmpty) into telemetry.breadcrumb; update the
telemetry.breadcrumb call that uses notificationTypes to use matchedTypes (or
skip the field) to avoid logging unsanitized/high-cardinality values.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: e6255e3d-939b-4c7a-a859-87260bca2dc0

📥 Commits

Reviewing files that changed from the base of the PR and between 50b985b and 48ea5c2.

📒 Files selected for processing (11)
  • CLI/cmux.swift
  • Sources/ClaudeNotificationTypeNormalization.swift
  • Sources/CmuxSettingsJSONPathSupport.swift
  • Sources/GhosttyTerminalView.swift
  • Sources/KeyboardShortcutSettingsFileStore+Template.swift
  • Sources/KeyboardShortcutSettingsFileStore.swift
  • Sources/cmuxApp.swift
  • cmux.xcodeproj/project.pbxproj
  • cmuxTests/KeyboardShortcutSettingsFileStoreStartupTests.swift
  • docs/notifications.md
  • tests/test_claude_hook_ignored_notification_types.py

Comment thread CLI/cmux.swift

@cubic-dev-ai cubic-dev-ai 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.

1 issue found across 11 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="CLI/cmux.swift">

<violation number="1" location="CLI/cmux.swift:18955">
P2: Raw fallback payloads are matched as a single string, so ignored notification types embedded in fallback JSON (e.g. `notification_type`) may not be suppressed.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.
Re-trigger cubic

Comment thread CLI/cmux.swift Outdated
@lawrencecchen
lawrencecchen dismissed coderabbitai[bot]’s stale review May 18, 2026 07:04

Dismissed as stale. The requested telemetry privacy fix was applied in a22d3b6 and CodeRabbit acknowledged the inline thread as addressed; current head also resolves the remaining Cubic fallback parsing feedback.

Comment thread CLI/cmux.swift
Comment thread CLI/cmux.swift Outdated
coderabbitai[bot]
coderabbitai Bot previously requested changes May 19, 2026

@coderabbitai coderabbitai 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.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@CLI/cmux.swift`:
- Around line 16702-16708: The branch that currently returns a bare "OK"
(print("OK")) when suppressedNotificationTypes is non-empty should be replaced
with a product-facing message: keep the machine-readable breadcrumb via
telemetry.breadcrumb("claude-hook.notification.suppressed", ...) but replace
print("OK") with a sanitized human message that explains notifications were
suppressed, lists the suppressed types in user-friendly form, and provides 1–2
next actions (e.g., "See cmux.json to modify notification settings" and "Run
cmux --show-notifications to view current rules"). Update the output path so the
machine token remains unchanged for automated consumers while the human message
is written to stdout/stderr (sanitized) or a log, referencing
suppressedNotificationTypes and cmux.json in the text.
- Around line 18804-18818: The loop over paths currently continues scanning
lower-precedence files when loadIgnoredClaudeNotificationTypes returns
.parsed(nil), which resurrects legacy values; update the switch in the for-loop
(the call sites: loadIgnoredClaudeNotificationTypes,
normalizedClaudeNotificationTypes, and the foundSettingsFile flag) so that when
you get .parsed(let values) and values is nil you treat it as an explicit
removal and immediately return an empty array ([]); keep the existing behavior
of returning normalizedClaudeNotificationTypes(values) when values is non-nil,
and preserve the final return of nil only when no settings file was found.

In `@tests/test_claude_hook_ignored_notification_types.py`:
- Around line 25-37: The test currently falls back to any system "cmux"
(shutil.which) which can pick up stale/installed binaries; change the resolution
so the test requires CMUX_CLI_BIN or CMUX_CLI to point to the just-built
artifact or else fail: read CMUX_CLI_BIN/CMUX_CLI first and validate it exists
and is executable, accept candidates found in the build-only locations (the
existing candidates list populated from
"~/Library/Developer/Xcode/DerivedData/*/Build/Products/Debug/cmux" and
"/tmp/cmux-*/Build/Products/Debug/cmux") but remove the global PATH fallback
(the shutil.which branch) and instead raise a RuntimeError if no env var or
build-directory candidate is available; refer to the existing symbols
candidates, CMUX_CLI_BIN/CMUX_CLI, shutil.which, and os.path.getmtime when
implementing the checks.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 31c6ba89-463d-44df-b3ba-7b653b9d3601

📥 Commits

Reviewing files that changed from the base of the PR and between 48ea5c2 and 23613f8.

📒 Files selected for processing (8)
  • CLI/cmux.swift
  • Sources/CmuxSettingsJSONPathSupport.swift
  • Sources/GhosttyTerminalView.swift
  • Sources/KeyboardShortcutSettingsFileStore+Template.swift
  • Sources/KeyboardShortcutSettingsFileStore.swift
  • Sources/cmuxApp.swift
  • cmux.xcodeproj/project.pbxproj
  • tests/test_claude_hook_ignored_notification_types.py

Comment thread CLI/cmux.swift
Comment thread CLI/cmux.swift Outdated
Comment thread tests/test_claude_hook_ignored_notification_types.py Outdated
@lawrencecchen
lawrencecchen dismissed coderabbitai[bot]’s stale review May 19, 2026 02:50

All three CodeRabbit comments from this review have been addressed: two were fixed in 0d442bc and the hook stdout item was confirmed as an intentional Claude hook protocol requirement in-thread. Dismissing the stale changes-requested review after resolving its threads.

Comment thread CLI/cmux.swift Outdated
Comment on lines +18898 to +18901
guard let values = rawValues as? [String] else {
return .parsed(nil)
}
return .parsed(values)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P1 When notifications.ignoredClaudeNotificationTypes is present in the settings file but its value is not a [String] (e.g., the user wrote "idle_prompt" instead of ["idle_prompt"]), .parsed(nil) is returned. In ignoredClaudeNotificationTypesFromSettingsFiles, .parsed(nil) resolves to return [], which makes the settings file "win" with an empty ignore list — silently bypassing the env var the app already set from the still-valid UserDefaults value. The app correctly leaves UserDefaults untouched (logInvalid is called, nothing is written) and sets CMUX_CLAUDE_IGNORED_NOTIFICATION_TYPES from the preserved UserDefaults value, but the CLI never sees it because the settings-file lookup short-circuits. Returning .invalid here instead lets the loop fall through to the env var (and UserDefaults), which matches the app's intent for an invalid-type value.

Suggested change
guard let values = rawValues as? [String] else {
return .parsed(nil)
}
return .parsed(values)
guard let values = rawValues as? [String] else {
return .invalid
}
return .parsed(values)

Copy link
Copy Markdown
Contributor

Addressed Greptile's latest settings-file loader finding in 270a7c7: ignoredClaudeNotificationTypes with the wrong value type is now treated as an invalid settings file so lookup can fall back to the next source instead of acting like an explicit removal. Added the matching Python regression case.

Comment thread CLI/cmux.swift Outdated
coderabbitai[bot]
coderabbitai Bot previously requested changes May 19, 2026

@coderabbitai coderabbitai 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.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@CLI/cmux.swift`:
- Around line 18803-18808: The loop over paths currently ignores `.invalid`
results from loadIgnoredClaudeNotificationTypes(at:fileManager:) and continues
scanning, allowing ignoredClaudeNotificationTypes() to fall back to stale
env/UserDefaults; change the `.invalid` branch to treat the presence of a
malformed settings file as authoritative by returning an empty set immediately
(i.e., when loadIgnoredClaudeNotificationTypes(...) yields `.invalid` return an
empty Set from ignoredClaudeNotificationTypes()), so malformed files unblock
notifications instead of letting the loop continue.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 7d6c8c91-f727-4a1f-a51c-7c5b8b19ac21

📥 Commits

Reviewing files that changed from the base of the PR and between 23613f8 and 270a7c7.

📒 Files selected for processing (4)
  • .circleci/config.yml
  • .github/workflows/ci.yml
  • CLI/cmux.swift
  • tests/test_claude_hook_ignored_notification_types.py

Comment thread CLI/cmux.swift Outdated
@lawrencecchen
lawrencecchen dismissed coderabbitai[bot]’s stale review May 19, 2026 03:09

The single CodeRabbit request from this review has been addressed in-thread and intentionally declined: malformed settings files must fall back to the app-preserved env/default path, matching the Cursor and Greptile findings fixed in 270a7c7 and 76ee9f0. The review is also for a previous head commit.

@cursor cursor 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.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 4c7ba93. Configure here.

)
} else if section.keys.contains("ignoredClaudeNotificationTypes") {
logInvalid("notifications.ignoredClaudeNotificationTypes", sourcePath: sourcePath)
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

App merge ignores hook precedence

Medium Severity

When a valid primary cmux.json exists but omits notifications.ignoredClaudeNotificationTypes, the Claude hook treats the ignore list as empty and still renders matching notifications. The settings file store can still merge ignored types from legacy or App Support configs into UserDefaults and terminal env, so suppression looks enabled while hooks do not suppress.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 4c7ba93. Configure here.

@cubic-dev-ai cubic-dev-ai 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.

1 issue found across 11 files (changes from recent commits).

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="Packages/CMUXClaudeNotifications/Sources/CMUXClaudeNotifications/ClaudeNotifications.swift">

<violation number="1" location="Packages/CMUXClaudeNotifications/Sources/CMUXClaudeNotifications/ClaudeNotifications.swift:75">
P2: Plain string notification types are discarded because string extraction only attempts JSON parsing, so ignored-type suppression can fail for raw-string payload shapes.</violation>
</file>

Tip: Review your code locally with the cubic CLI to iterate faster.

Re-trigger cubic

return values.flatMap { self.values(inJSONValue: $0, scope: scope) }
}
if let string = value as? String {
return values(inRawFallback: string, scope: scope)

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: Plain string notification types are discarded because string extraction only attempts JSON parsing, so ignored-type suppression can fail for raw-string payload shapes.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At Packages/CMUXClaudeNotifications/Sources/CMUXClaudeNotifications/ClaudeNotifications.swift, line 75:

<comment>Plain string notification types are discarded because string extraction only attempts JSON parsing, so ignored-type suppression can fail for raw-string payload shapes.</comment>

<file context>
@@ -0,0 +1,221 @@
+            return values.flatMap { self.values(inJSONValue: $0, scope: scope) }
+        }
+        if let string = value as? String {
+            return values(inRawFallback: string, scope: scope)
+        }
+        return []
</file context>

@lawrencecchen lawrencecchen added the stale-revisit Closed after 30+ days without activity; preserved for possible revisit or reopening. label Sep 23, 2026
@github-project-automation github-project-automation Bot moved this from Todo to Done in cmux backlog Sep 23, 2026

This branch was successfully deployed

1 active deployment
Preview – cmux — 4c7ba93b Deployed May 19, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

stale-revisit Closed after 30+ days without activity; preserved for possible revisit or reopening.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add option to suppress idle_prompt notifications from Claude Code integration

3 participants