Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,10 @@ public struct CustomSidebarTemplateCatalog: Sendable {
}
let installedSource = source
.split(separator: "\n", omittingEmptySubsequences: false)
.filter { !$0.trimmingCharacters(in: .whitespaces).hasPrefix("// cp Examples/CustomSidebars/") }
.filter { line in
let trimmed = line.trimmingCharacters(in: .whitespaces)
return !(trimmed.hasPrefix("//") && trimmed.contains("cp Examples/CustomSidebars/"))
}
.joined(separator: "\n")
return CustomSidebarTemplate(descriptor: descriptor, source: installedSource)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,14 @@ public extension Notification.Name {

/// Holds a gallery request until the progressively mounted Custom Sidebars
/// section is ready to present it.
// lint:allow namespace-type — one-shot, main-actor handoff from a host menu to the lazily mounted Custom Sidebars section (#15931); candidate to become an injected SettingsRuntime value.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P3: This plain // comment between the enum's /// doc block and the declaration detaches the doc comment: Swift associates a doc comment only with the declaration it immediately precedes, so CustomSidebarTemplateGalleryRequest loses "Holds a gallery request until the progressively mounted Custom Sidebars section…" in Xcode quick help / DocC. Convert the line to a /// doc line so it stays part of the doc block; the namespace scanner matches the marker against raw text regardless, so the suppression still works (verified: the rule fires without the marker and is silenced with it).

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. At Packages/macOS/CmuxSettingsUI/Sources/CmuxSettingsUI/Environment/SettingsHostActions.swift, line 13:

<comment>This plain `//` comment between the enum's `///` doc block and the declaration detaches the doc comment: Swift associates a doc comment only with the declaration it immediately precedes, so `CustomSidebarTemplateGalleryRequest` loses "Holds a gallery request until the progressively mounted Custom Sidebars section…" in Xcode quick help / DocC. Convert the line to a `///` doc line so it stays part of the doc block; the namespace scanner matches the marker against raw text regardless, so the suppression still works (verified: the rule fires without the marker and is silenced with it).</comment>

<file context>
@@ -10,6 +10,7 @@ public extension Notification.Name {
 
 /// Holds a gallery request until the progressively mounted Custom Sidebars
 /// section is ready to present it.
+// lint:allow namespace-type — one-shot, main-actor handoff from a host menu to the lazily mounted Custom Sidebars section (#15931); candidate to become an injected SettingsRuntime value.
 @MainActor
 public enum CustomSidebarTemplateGalleryRequest {
</file context>
Suggested change
// lint:allow namespace-type — one-shot, main-actor handoff from a host menu to the lazily mounted Custom Sidebars section (#15931); candidate to become an injected SettingsRuntime value.
/// lint:allow namespace-type — one-shot, main-actor handoff from a host menu to the lazily mounted Custom Sidebars section (#15931); candidate to become an injected SettingsRuntime value.

@MainActor
public enum CustomSidebarTemplateGalleryRequest {
private static var pending = false

public static func request() {
pending = true
NotificationCenter.default.post(name: .customSidebarTemplateGalleryRequested)
NotificationCenter.default.post(name: .customSidebarTemplateGalleryRequested, object: nil)
}

public static func consume() -> Bool {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,10 +98,12 @@ struct CustomSidebarValidationTests {
func downloadableCustomSidebarExamplesValidate() throws {
let directory = examplesDirectory()
let report = validator.validate(directory: directory, dataContext: Self.richSidebarContext)
// manifest.json is the built-in template catalog's index, not a sidebar.
let sidebars = report.entries.filter { $0.name != "manifest" }

#expect(report.names.sorted() == ["activity", "agents-board", "agents-cards", "agents-dense", "agents-focus", "agents-timeline", "btop-agents", "clock", "compact", "finder", "focus", "kitchen-sink", "panel-info", "panel-sessions", "panel-subagents", "panel-todo", "ports", "status-board", "workspaces"])
#expect(report.validCount == 19)
#expect(report.errorCount == 0)
#expect(sidebars.map(\.name).sorted() == ["activity", "agents-board", "agents-cards", "agents-dense", "agents-focus", "agents-timeline", "btop-agents", "clock", "compact", "finder", "focus", "kitchen-sink", "panel-info", "panel-sessions", "panel-subagents", "panel-todo", "ports", "status-board", "workspaces"])
#expect(sidebars.filter(\.isValid).count == 19)
#expect(sidebars.allSatisfy(\.isValid))
Comment on lines +105 to +106

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P3: sidebars.filter(\.isValid).count == 19 and sidebars.allSatisfy(\.isValid) assert the same property: the name comparison above pins sidebars to exactly these 19 names, so "19 of them valid" is the same statement as "all valid". Keep only one — allSatisfy gives better failure diagnostics.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. At Packages/macOS/CmuxSwiftRenderUI/Tests/CmuxSwiftRenderUITests/CustomSidebarValidationTests.swift, line 105:

<comment>`sidebars.filter(\.isValid).count == 19` and `sidebars.allSatisfy(\.isValid)` assert the same property: the name comparison above pins `sidebars` to exactly these 19 names, so "19 of them valid" is the same statement as "all valid". Keep only one — `allSatisfy` gives better failure diagnostics.</comment>

<file context>
@@ -98,10 +98,12 @@ struct CustomSidebarValidationTests {
-        #expect(report.validCount == 19)
-        #expect(report.errorCount == 0)
+        #expect(sidebars.map(\.name).sorted() == ["activity", "agents-board", "agents-cards", "agents-dense", "agents-focus", "agents-timeline", "btop-agents", "clock", "compact", "finder", "focus", "kitchen-sink", "panel-info", "panel-sessions", "panel-subagents", "panel-todo", "ports", "status-board", "workspaces"])
+        #expect(sidebars.filter(\.isValid).count == 19)
+        #expect(sidebars.allSatisfy(\.isValid))
     }
</file context>
Suggested change
#expect(sidebars.filter(\.isValid).count == 19)
#expect(sidebars.allSatisfy(\.isValid))
#expect(sidebars.allSatisfy(\.isValid))

}

@MainActor
Expand Down
1 change: 1 addition & 0 deletions Sources/CmuxExtensionSidebarSelection.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import AppKit
import CmuxExtensionSidebarExamples
import CmuxFoundation
import CmuxSettings
import CmuxSettingsUI
import CmuxSidebarProviderKit
import Foundation

Expand Down
8 changes: 4 additions & 4 deletions cmuxTests/SidebarProviderMenuRegressionTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -446,7 +446,7 @@ struct SidebarProviderMenuRegressionTests {
let directory = root.appendingPathComponent("sidebars", isDirectory: true)
defer { try? FileManager.default.removeItem(at: root) }

let template = try #require(CustomSidebarOnboardingAssets().exampleTemplate(id: "focus"))
let template = try #require(CustomSidebarOnboardingAssets().exampleTemplate(id: "agents-board"))
let first = CmuxExtensionSidebarSelection.writeCustomSidebar(
named: template.suggestedName,
fileExtension: template.fileExtension,
Expand All @@ -468,14 +468,14 @@ struct SidebarProviderMenuRegressionTests {
return
}

#expect(firstName == "focus")
#expect(secondName == "focus-2")
#expect(firstName == "agents-board")
#expect(secondName == "agents-board-2")
#expect(firstURL != secondURL)
#expect(CustomSidebarValidator().validate(fileURL: firstURL).errorMessage == nil)
#expect(CustomSidebarValidator().validate(fileURL: secondURL).errorMessage == nil)
#expect(
CmuxExtensionSidebarSelection.discoveredCustomSidebarNames(sidebarsDirectory: directory)
== ["focus", "focus-2"]
== ["agents-board", "agents-board-2"]
)
}

Expand Down
7 changes: 7 additions & 0 deletions tests/test_ci_change_areas.py
Original file line number Diff line number Diff line change
Expand Up @@ -5767,6 +5767,13 @@ def test_static_preflight_rejects_stale_embedded_schema_before_native_work() ->
else 'print("Ran 1 test in 0.001s\\nOK")\n' if category == "tests"
else "pass\n")
target.chmod(0o755)
# Other static-preflight steps run their own validators; stub them too.
for path in sorted(set(re.findall(r"scripts/[\w./-]+\.(?:py|sh)", "\n".join(scripts)))):
target = repo / path
if not target.exists():
target.parent.mkdir(parents=True, exist_ok=True)
target.write_text("#!/usr/bin/env bash\nexit 0\n" if target.suffix == ".sh" else "pass\n")
target.chmod(0o755)
for name in ("verify-local.py", "verification_receipt.py"):
shutil.copy2(ROOT / "scripts" / name, repo / "scripts" / name)
generator = repo / "scripts/generate-cmux-config-schema.py"
Expand Down
2 changes: 1 addition & 1 deletion vendor/bonsplit
Loading