Skip to content

feat(tui): prioritize the Fleet menu surface (#5888) - #5905

Merged
Hmbown merged 1 commit into
mainfrom
fix/fleet-menu-simplify-5888
Sep 6, 2026
Merged

feat(tui): prioritize the Fleet menu surface (#5888)#5905
Hmbown merged 1 commit into
mainfrom
fix/fleet-menu-simplify-5888

Conversation

@Hmbown

@Hmbown Hmbown commented Sep 6, 2026

Copy link
Copy Markdown
Owner

Closes #5888.

Before → after

  • /fleet usage line: 14 verbs → 5 (members|setup|teams|workers|help). The other nine stay fully dispatchable, documented one level deeper in /fleet help under explicit groups (team model routes models|add|remove, saved routes save|save-as, durable run control via operations_for_domain). No match arm was removed — nothing becomes undispatchable.
  • Roster default surface: 12 rows → 11 — the untouched built-in general alias (same posture as worker) folds out of presentation; a user-authored general (any non-built-in origin, incl. saved-team members) stays visible; FleetRoster::get("general") and the identity-selector alias keep engine dispatch compat.
  • Footer unchanged (5 actions); narrow-terminal coverage retained via the existing (80,24)-blocker roster tests.

Tests: updated built_in_party_lists_all_members_in_canonical_order, fleet_aliases_are_registered_on_command_info, slash_command_and_cli_agree_on_fleet_verb_ids; added fleet_usage_presents_a_prioritized_core_and_help_keeps_the_rest_reachable, default_roster_folds_the_legacy_general_alias_out_of_presentation, user_defined_general_member_stays_visible.

Gate honesty: cargo check -p codewhale-tui clean; the three directly modified command tests pass locally. Several pre-existing fleet tests that build the live config/catalog abort with stack overflow on the preparing machine (8MB hard stack limit) — two were proven byte-identical at baseline via stash; hosted CI runs this exact suite green on ubuntu/macos/windows, so the matrix here is the authoritative gate. Design grounded in the #5888 source-audit comment; prepared by an implement agent whose execution was blocked by a stale parked-agent write claim (see #5575 family), applied and gated by the operator.


Note

Low Risk
Presentation and help copy only; no dispatch paths or roster engine semantics were removed.

Overview
/fleet surface (#5888) — The command palette usage string shrinks from fourteen verbs to five: members, setup, teams, workers, and help. Model routes (models, add, remove), saved routes (save, save-as), and durable ledger verbs remain typed as before; they are grouped in /fleet help instead of the usage line. Unknown-verb errors now cite the primary set and point to help.

Fleet roster — The default list hides only the built-in general alias (same posture as worker), so the UI shows eleven rows (operator plus ten members). Engine lookup and identity-selector alias behavior for general are unchanged; a user-defined general (non-built-in origin) still appears.

Tests — Assertions lock the shortened usage, help coverage for advanced and control verbs, roster canonical order without built-in general, and visibility rules for user-defined general.

Reviewed by Cursor Bugbot for commit 89b005b. Bugbot is set up for automated code reviews on this repo. Configure here.

Copilot AI lite review requested due to automatic review settings September 6, 2026 00:47
@cursor

cursor Bot commented Sep 6, 2026

Copy link
Copy Markdown

Bugbot couldn't run - usage limit reached

Bugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit.

A user or team admin can review and increase usage limits in the Cursor dashboard.

(requestId: serverGenReqId_6adc6744-d02f-4477-8511-78940eadd6d4)

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 6, 2026

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review Completed 2026-09-06T00:53:09.936779Z b141b4c PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@claude

claude Bot commented Sep 6, 2026

Copy link
Copy Markdown
Contributor

Claude finished @Hmbown's task in 2m 35s —— View job


Review: PR #5905 — prioritize the Fleet menu surface

  • Gather context (diff, changed files, CLAUDE.md/AGENTS.md)
  • Understand request (code review of PR)
  • Review crates/tui/src/commands/groups/core/fleet.rs
  • Review crates/tui/src/tui/views/fleet_roster.rs
  • Review crates/tui/src/tui/views/fleet_roster/tests.rs
  • Check for provider/model safety issues (N/A — no provider/model routing touched)
  • Post final review

Summary

This is a clean, minimal, presentation-only change. I traced every claim in the PR description against the code and found it accurate:

  • PRIMARY_VERBS/PRIMARY_USAGE (fleet.rs:38-40) drives both COMMAND_INFO.usage and help_text(), so the two can't drift — good reuse instead of duplicating the string.
  • No match arm was removed from FleetCmd::execute (fleet.rs:265-311): models, add, remove, save/save-as, and ControlOperation::parse_verb (list/status/interrupt/resume/restart) are all still reachable exactly as before. Only the advertised usage string and the unknown-verb error text changed.
  • fleet_roster.rs:196-216: the added filter only drops a member when both id == "general" and origin == ProfileOrigin::BuiltIn. I checked ProfileOrigin (roster.rs:47-55) — overrides always carry Config/Personal/Workspace/Plugin origin, never BuiltIn, so a user-authored general (e.g. a saved-team member) can never be incorrectly hidden by this check. FleetRoster::get/the identity-selector alias (identity.rs:360) are untouched, so dispatch compat holds.
  • Row-count math checks out: built-in members go from 11→10 (manager, scout, builder, reviewer, verifier, consultant, synthesizer, worker, planner, custom), so default surface is 11 rows (operator + 10) as claimed; FleetRosterMembersCount recomputes from the filtered members.len(), so the header count stays correct automatically.
  • requires_required_argument()/requires_argument() (traits.rs:100-103) still behave correctly since PRIMARY_USAGE still contains [/] and no <...>, matching the slash_command_and_cli_agree_on_fleet_verb_ids assertion that /fleet stays directly runnable.
  • The new fleet_unknown_arg_reports_error behavior: the error list intentionally excludes "help" from the joined verbs (PRIMARY_VERBS[..len-1]) and appends "— or /fleet help for the full verb list" separately — the existing test's contains("Use members, setup, teams") substring check still passes.
  • Confirmed no other view/module hardcodes the old "12 rows"/14-verb assumptions (grepped for stale counts) and no dispatch is index-based (activation is by member.id, not position), so the filtered presentation list can't desync from engine dispatch.
  • Out of scope for this PR, and not touched: provider/model routing, EPIC v0.8.65 EPIC: Separate provider facts, model facts, offerings, and route resolution #2608 provider-prefix invariants.

No correctness bugs, no dead code, no missing test coverage — the three new/updated tests (fleet_usage_presents_a_prioritized_core_and_help_keeps_the_rest_reachable, default_roster_folds_the_legacy_general_alias_out_of_presentation, user_defined_general_member_stays_visible) directly exercise the exact behaviors claimed in the PR body, including the user-authored-general-stays-visible edge case.

Note: I wasn't able to run cargo check/cargo test in this sandbox (bash tool calls beyond trivial commands required approval that wasn't available), so this review is based on careful static/manual tracing of the diff and its call sites rather than a fresh compile. The PR body's own gate-honesty note (clean cargo check -p codewhale-tui, three modified command tests passing locally, hosted CI as the authoritative gate for the stack-overflow-prone tests) is consistent with what I'd expect given the change's scope.

Nice work — this is exactly the kind of "fold advanced verbs one level deeper, dispatch untouched" change the ponytail method calls for.

Copilot AI left a comment

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.

🟢 Approval recommended

The changes appear confined to presentation/help-text and are covered by updated/new tests, with only a minor help-text capitalization typo to address.

Pull request overview

This PR implements issue #5888 by reducing the amount of Fleet UI/command surface presented at once in the TUI, while keeping all existing Fleet dispatch behavior reachable via /fleet help and preserving roster/alias compatibility.

Changes:

  • Shortens /fleet’s advertised usage to a prioritized core verb set and moves advanced verbs into grouped /fleet help text.
  • Updates the Fleet roster view to hide the built-in legacy general alias (while keeping it dispatchable) so the default presentation is one row per posture.
  • Adds/updates tests to lock the new usage/help behavior and the roster presentation rules around general.
File summaries
File Description
crates/tui/src/tui/views/fleet_roster/tests.rs Updates canonical built-in roster expectations and adds tests for folding the built-in general alias while preserving dispatch compatibility.
crates/tui/src/tui/views/fleet_roster.rs Filters the built-in general alias out of roster presentation while keeping engine roster semantics unchanged.
crates/tui/src/commands/groups/core/fleet.rs Introduces primary verb/usage constants, revises help text to document advanced verbs, and updates tests to enforce the new surface.
Review details
  • Files reviewed: 3/3 changed files
  • Comments generated: 1
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +66 to +68
Durable runs — these act on the durable .codewhale/fleet.jsonl ledger for this \
workspace, the same records `codewhale fleet` reads and writes. the ledger file, \
saved rosters, and config tables keep the Fleet name:\n",

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: b141b4c275

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +54 to +56
The fleet is who is working right now. The primary verbs cover the daily loop:\n\
/fleet (or /fleet members) opens the roster — each member's role, model, and access; \
Enter on a member row opens that member's editor. /fleet setup opens the authoring \

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Localize the expanded Fleet help prose

When the UI locale is non-English, /fleet help still emits these newly added English paragraphs—including the literal Enter hint—because help_text() constructs them directly instead of using tr(locale, MessageId::...). Move the new prose into localized message IDs and compose command/key tokens in code so the prioritized Fleet surface follows the TUI localization contract.

AGENTS.md reference: crates/tui/AGENTS.md:L25-L26

Useful? React with 👍 / 👎.

Comment on lines +66 to +68
Durable runs — these act on the durable .codewhale/fleet.jsonl ledger for this \
workspace, the same records `codewhale fleet` reads and writes. the ledger file, \
saved rosters, and config tables keep the Fleet name:\n",

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 Badge Do not advertise CLI-only restart as a slash action

When a user opens /fleet help, this heading says all following durable-run entries act on the ledger, but operations_for_domain(ControlDomain::Fleet) also includes FleetRestart, whose descriptor is limited to CLI_ONLY; the generated list therefore presents /fleet restart <worker-id> like a usable slash verb even though it always returns an unavailable receipt. Filter operations not offered on the Slash surface or explicitly label restart as CLI-only.

Useful? React with 👍 / 👎.

@codewhale-agent codewhale-agent 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.

Codewhale review

PR simplifies the /fleet usage line to five primary verbs and hides the built-in general alias from the default roster presentation while preserving dispatch and help coverage. Tests were updated and added appropriately.

Findings

  • [INFO] Built-in general filter does not trim id unlike operator filter (crates/tui/src/tui/views/fleet_roster.rs:212)
    The new presentation filter uses m.id.eq_ignore_ascii_case("general") without .trim(), while the operator row filter uses m.id.trim().eq_ignore_ascii_case("operator"). If a built-in member id ever contained surrounding whitespace, the alias would not be folded. Trimming keeps the alias handling consistent.

Suggestions

  • crates/tui/src/tui/views/fleet_roster.rs:212 — Use the same trimmed id comparison as the operator filter so the built-in general alias is consistently folded out of presentation even if ids contain surrounding whitespace.

                            && !(m.id.trim().eq_ignore_ascii_case("general")
    

Assessment

Changes align with the PR intent and are well-covered by unit tests. Dispatch compatibility is preserved and help text keeps advanced verbs reachable. Only a minor consistency nit was found.


Advisory review by Codewhale (codewhale review --pr 5905 --post, head b141b4c2753a7cff13bcc966cd10626d82818d36). Line-specific findings are also posted as inline review comments; mechanical fixes arrive as committable suggestions you can apply from the Files tab. CODEOWNERS approval still governs merge.

// origin, including saved-team members, which carry
// Personal/Workspace origin by construction) is the
// user's own member and stays visible.
&& !(m.id.eq_ignore_ascii_case("general")

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

[INFO] Built-in general filter does not trim id unlike operator filter

The new presentation filter uses m.id.eq_ignore_ascii_case("general") without .trim(), while the operator row filter uses m.id.trim().eq_ignore_ascii_case("operator"). If a built-in member id ever contained surrounding whitespace, the alias would not be folded. Trimming keeps the alias handling consistent.

// origin, including saved-team members, which carry
// Personal/Workspace origin by construction) is the
// user's own member and stays visible.
&& !(m.id.eq_ignore_ascii_case("general")

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Use the same trimmed id comparison as the operator filter so the built-in general alias is consistently folded out of presentation even if ids contain surrounding whitespace.

Suggested change
&& !(m.id.eq_ignore_ascii_case("general")
&& !(m.id.trim().eq_ignore_ascii_case("general")

The /fleet usage line advertised 14 verbs at once, mixing member/model
setup, saved teams, session workers, and durable run control. It now
presents the prioritized core only — /fleet [members|setup|teams|
workers|help] — and every other verb stays dispatchable, documented one
level deeper in /fleet help under explicit groups: team model routes
(models/add/remove), saved routes (save/save-as), and the durable run
control plane (data-driven via operations_for_domain). The unknown-target
error now points at the core set.

The roster's default surface showed the legacy built-in general alias
next to worker — the same posture twice. from_parts now folds only the
untouched built-in alias out of presentation (12 -> 11 rows); a
user-authored general (config/personal/project origin, incl. saved-team
members) stays visible, and dispatch keeps resolving general through
FleetRoster::get and the identity selector alias.

Local gates, honestly: cargo check -p codewhale-tui CLEAN. The three
directly modified command tests pass (fleet_aliases_are_registered_on_
command_info, fleet_usage_presents_a_prioritized_core_and_help_keeps_
the_rest_reachable, slash_command_and_cli_agree_on_fleet_verb_ids).
This machine's 8MB hard stack limit aborts several pre-existing fleet
tests that construct the live config/catalog (two proven byte-identical
at baseline via stash; CI runs the same suite green on all three OSes),
so hosted CI is the authoritative gate for this PR.

Signed-off-by: CodeWhale Bot <bot@codewhale.net>
@Hmbown
Hmbown force-pushed the fix/fleet-menu-simplify-5888 branch from b141b4c to 89b005b Compare September 6, 2026 03:25
@cursor

cursor Bot commented Sep 6, 2026

Copy link
Copy Markdown

Bugbot couldn't run - usage limit reached

Bugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit.

A user or team admin can review and increase usage limits in the Cursor dashboard.

(requestId: serverGenReqId_542d39aa-2e1f-4561-be4c-ea40f643a8f6)

@claude

claude Bot commented Sep 6, 2026

Copy link
Copy Markdown
Contributor

Claude finished @Hmbown's task in 2m 15s —— View job


Review: PR #5905 — prioritize the Fleet menu surface

  • Gather context (diff, changed files, CLAUDE.md/AGENTS.md)
  • Review crates/tui/src/commands/groups/core/fleet.rs diff
  • Review crates/tui/src/tui/views/fleet_roster.rs diff
  • Review crates/tui/src/tui/views/fleet_roster/tests.rs diff
  • Check provider/model/route safety implications
  • Post final review

Summary

This is a scoped presentation/help-text change; dispatch and roster-resolution semantics are preserved as claimed. No provider/model routing is touched (not applicable to §2 of the review criteria).

Findings

1. Correctness — none found.

  • PRIMARY_VERBS/PRIMARY_USAGE (fleet.rs:38-40) back both COMMAND_INFO.usage and help_text(), so they can't drift.
  • No FleetCmd::execute match arm was removed (fleet.rs:265-); models, add, remove, save/save-as, and every ControlOperation::parse_verb route are still reachable — only the advertised usage string and unknown-verb error text changed.
  • PRIMARY_VERBS[..PRIMARY_VERBS.len() - 1] (fleet.rs:307) can't underflow/panic — PRIMARY_VERBS is a 5-element compile-time constant.
  • fleet_roster.rs:196-216: the new filter only folds a member when id == "general" and origin == ProfileOrigin::BuiltIn; overrides never carry BuiltIn origin (roster.rs:47-55), so a user-authored general can't be incorrectly hidden. FleetRoster::get/the identity-selector alias are untouched.
  • Verified FleetRoster::from_members/built_ins_only/row_count referenced in the new tests all exist with matching signatures — the test file compiles against current APIs.

2. Pre-existing (not introduced by this diff), worth a follow-up:

  • Codex's CLI-only-restart point is valid but pre-existing. The for descriptor in operations_for_domain(...) loop in help_text() (fleet.rs:96-104, unchanged by this PR) has always unconditionally rendered every Fleet descriptor's slash_invocation(), including FleetRestart, which is available_on: CLI_ONLY (crates/lane/src/control.rs:760). Typing /fleet restart <id> still correctly returns an "unavailable/surface not offered" receipt at runtime (run_controlexecute_fleet_control(ControlSurface::Slash, ...)), so nothing is broken — but the newly-expanded "Durable runs" section makes this listing more prominent, so it's a reasonable follow-up to filter by descriptor.offers(ControlSurface::Slash) or annotate CLI-only rows.
  • Codex's localization point is also pre-existing. help_text() was already a raw, non-tr() English string before this PR (confirmed against origin/main); this PR adds more English prose to the same already-unlocalized function rather than newly violating crates/tui/AGENTS.md's "user-visible prose uses tr(locale, MessageId::...)" contract. Same carve-out as fleet_roster.rs's existing #3167 note. Not a new regression, but the surface area of unlocalized text did grow.
  • Copilot's lowercase "the" after "reads and writes." — this exact typo exists verbatim in the pre-PR text on origin/main; carried over, not introduced here.

3. Reuse/simplification — good: consolidating usage/help into PRIMARY_USAGE/PRIMARY_VERBS constants removes the prior duplicated literal. No dead code or needless allocation introduced.

4. Tests — solid coverage of the new behavior, including the important negative case (user_defined_general_member_stays_visible) confirming the alias-fold doesn't over-match by origin.

  • Minor [low], from codewhale-agent's inline finding: fleet_roster.rs:212 uses m.id.eq_ignore_ascii_case("general") without .trim(), while the operator filter on the line above uses m.id.trim().eq_ignore_ascii_case("operator"). Built-in ids are hardcoded without whitespace today so this can't currently misfire, but matching the existing trimmed comparison is a one-line consistency fix: Fix this →

5. Security — no secret handling, shell/exec, or input-validation surface touched.

Assessment

Low risk, matches the PR description's claims. No blocking issues. The one actionable item is the .trim() consistency nit; the CLI-only-restart and localization points are legitimate but pre-existing and out of scope for this diff.

@codewhale-agent codewhale-agent 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.

Codewhale review

PR simplifies the Fleet command surface by reducing the usage string to five primary verbs and moving advanced verbs into /fleet help. It also hides the built-in 'general' alias from the default roster while preserving user-defined 'general' members. Tests were updated and added. The change is mostly presentational with low risk, but there is a potential shadowed-member gap and a minor trimming inconsistency.

Findings

  • [WARNING] Built-in general alias may still be shown via shadowed list (crates/tui/src/tui/views/fleet_roster.rs:217)
    The filter only removes built-in general from roster.members(), not from roster.shadowed(). If a user-defined general shadows the built-in alias, the built-in entry could appear in the shadowed section, contradicting the goal of folding it out of presentation. Either filter shadowed members as well or verify that built-in aliases never appear in shadowed.
  • [INFO] Inconsistent trimming for id matching (crates/tui/src/tui/views/fleet_roster.rs:212)
    Operator id is checked with trim(), but the general alias check does not trim. If a built-in general id contains surrounding whitespace, it will not be hidden. Recommend using trim() for consistency.
  • [INFO] Missing test for unknown target error message (crates/tui/src/commands/groups/core/fleet.rs:305)
    The unknown target error message changed to use PRIMARY_VERBS and points to /fleet help, but no test covers this new string. Add a test that asserts the error message for an unknown verb includes the primary verbs and the help pointer.

Suggestions

  • crates/tui/src/tui/views/fleet_roster.rs:212 — Align the id check with the operator check by trimming whitespace before comparing, so built-in general is hidden even if ids carry stray whitespace.

                            && !(m.id.trim().eq_ignore_ascii_case("general")
                                && m.origin == ProfileOrigin::BuiltIn)
    

Assessment

Low risk overall. The change is well-tested for the main paths, but the shadowed-member gap should be investigated and possibly addressed to fully meet the fold-out-of-presentation goal. The trimming inconsistency is minor and safe to fix. Consider adding a test for the new error message.


Advisory review by Codewhale (codewhale review --pr 5905 --post, head 89b005b4b33bcc0fc8fccaebfeed3be746a5071b). Line-specific findings are also posted as inline review comments; mechanical fixes arrive as committable suggestions you can apply from the Files tab. CODEOWNERS approval still governs merge.

})
.cloned()
.collect(),
shadowed: roster.shadowed().to_vec(),

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

[WARNING] Built-in general alias may still be shown via shadowed list

The filter only removes built-in general from roster.members(), not from roster.shadowed(). If a user-defined general shadows the built-in alias, the built-in entry could appear in the shadowed section, contradicting the goal of folding it out of presentation. Either filter shadowed members as well or verify that built-in aliases never appear in shadowed.

// origin, including saved-team members, which carry
// Personal/Workspace origin by construction) is the
// user's own member and stays visible.
&& !(m.id.eq_ignore_ascii_case("general")

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

[INFO] Inconsistent trimming for id matching

Operator id is checked with trim(), but the general alias check does not trim. If a built-in general id contains surrounding whitespace, it will not be hidden. Recommend using trim() for consistency.

None => CommandResult::error(format!(
"Unknown /fleet target '{other}'. Use members, setup, teams, list, status, \
workers, interrupt <worker-id>, or resume <run-id>.."
"Unknown /fleet target '{other}'. Use {} — or /fleet help for the full \

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

[INFO] Missing test for unknown target error message

The unknown target error message changed to use PRIMARY_VERBS and points to /fleet help, but no test covers this new string. Add a test that asserts the error message for an unknown verb includes the primary verbs and the help pointer.

Comment on lines +212 to +213
&& !(m.id.eq_ignore_ascii_case("general")
&& m.origin == ProfileOrigin::BuiltIn)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Align the id check with the operator check by trimming whitespace before comparing, so built-in general is hidden even if ids carry stray whitespace.

Suggested change
&& !(m.id.eq_ignore_ascii_case("general")
&& m.origin == ProfileOrigin::BuiltIn)
&& !(m.id.trim().eq_ignore_ascii_case("general")
&& m.origin == ProfileOrigin::BuiltIn)

@Hmbown
Hmbown merged commit 31e2fdf into main Sep 6, 2026
46 of 47 checks passed
@Hmbown
Hmbown deleted the fix/fleet-menu-simplify-5888 branch September 6, 2026 05:05
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.

Simplify the Fleet menu: too many options at once

2 participants