Skip to content

Feature: Improve run command (Ctrl+Shift+P) - #3644

Merged
mergify[bot] merged 16 commits into
mainfrom
feature/run-command
Oct 21, 2026
Merged

mergify[bot] merged 16 commits into
mainfrom
feature/run-command

Conversation

@BornToBeRoot

Copy link
Copy Markdown
Owner

Changes proposed in this pull request

Run command (Ctrl+Shift+P)

  • Dialog instead of flyout: a dialog at the top of the window with an input field, syntax hint, error line and suggestion list; title bar with a close button, and Esc closes it.
  • Runs tools directly: e.g. ping 10.0.0.1, dns borntoberoot.net 1.1.1.1 aaaa, rdap 1.10 asn, scan 10.0.0.0/24, rdp server01.
  • Aliases: scan, portscan, ping, trace/tracert, dns/nslookup, rdp/mstsc, ps/pwsh, ssh, vnc, web, geo, wol.
  • Syntax: command target [argument] [type]. Type and argument can come in any order, lists are separated with ; (spaces allowed), and values with spaces go in quotes ("Google Public DNS").
  • Profiles with @: rdp @server01 runs the tool's profile action with the profile's settings; names can contain spaces. Duplicate names show an error, and you pick the profile from the list.
  • Suggestions: recent commands, tools, profiles of the tool (with group and the tool's own host), type values, and configured DNS servers.
    • The best match comes first.
    • Up/Down select, Tab completes (keeping the arguments, e.g. pin 10.0.0.1 → ping 10.0.0.1), Enter runs.
    • Enter runs what was typed. With an empty input or an unknown command, it shows an error instead of guessing.
  • Validation before running: uses the same validators as each tool's input field, plus DNS server and broadcast checks. Errors are shown in the dialog.
  • Remote tools (Remote Desktop, PowerShell, PuTTY, TigerVNC, Web Console) open their Connect dialog pre-filled; a profile connects directly.
  • New tool support: IP Geolocation (geo), Wake on LAN (wol [broadcast]), and Web Console now accepts a URL.
  • History: run commands are saved (the number of entries comes from the general history setting), case-insensitive. Entries of hidden tools are not shown.
  • Hidden tools: only tools that are visible in the tool list are offered.
  • settings opens the settings; if they're already open, nothing changes.

DNS Lookup

  • PTR for IP addresses: IP addresses from the run command, IP Scanner/Traceroute ("DNS Lookup > IP address") and profiles are looked up with PTR. Short forms like 10 count as host names.
  • Settings stay as they are: DNS server and type can be passed to a new tab without changing the tool's saved settings.

Navigation (refactoring)

  • NavigationManager replaces the old EventSystem:
    • Typed requests (ApplicationRequest, plus DNSLookupRequest, PortScannerRequest, RDAPRequest and WakeOnLANRequest) carry the target, a profile and options.
    • Tools implement IApplicationRequestHandler instead of a big switch in the main window.
  • All callers migrated: IP Scanner, Traceroute, Network Interface, RDAP → Whois, and "open settings". Traceroute's "RDAP > AS number" sends the type ASN.
  • Profile actions are public methods (e.g. ConnectProfile(profile)), so requests can run profiles.

Bug fixes in existing code

  • Tool list doesn't scroll: it now scrolls to a tool that is opened from somewhere else (dashboard, another tool, run command).
  • Tool search blocks redirects: "Open in…" and the run command no longer fail while the tool search on the left is filtering.
  • Input fields lose their text: input histories are updated in place instead of cleared and refilled, so fields keep their text (the old workaround is gone).

Refactorings

  • Histories: ListHelper.Modify works on the collection directly, ignores empty values, and takes an optional comparer. The 34 AddXToHistory methods are removed and inlined.
  • Profiles: ProfileInfo.IsEnabled(app) and ProfileInfo.GetTarget(app) replace the 16 override pairs in the tools' view models.
  • Waiting for a view: WaitForLoadedAsync() (event-based, with a 5 s timeout) replaces the while (!_loaded) polling loops in the five remote tools.
  • Removed: the old flyout, RunCommandInfo/RunCommandType, and the unused RunCommandComboBox.

Tests

  • First test project in the solution: NETworkManager.Tests with xUnit v3 (dotnet test via Microsoft.Testing.Platform in global.json).
  • 56 tests for the run command parser and the history helper.

Docs

  • New page run-command.md: syntax, command table with aliases and examples, profiles, suggestions, keys.
  • Changelog: the run command, DNS Lookup PTR, the scroll fix, the refactorings and the test project. The PR link is still missing.
  • Sidebar: the following doc pages each moved down one position.

Related issue(s)

To-Do

Contributing

By submitting this pull request, I confirm the following:

BornToBeRoot and others added 13 commits October 21, 2026 17:36
Replaces the EventSystem (Models), which passed a single string, with
NavigationManager in the main project:

- ApplicationRequest (target or profile) with derived requests for
  options: DNSLookupRequest (DNS server, query type), PortScannerRequest
  (ports), RDAPRequest (query type).
- Host views implement IApplicationRequestHandler; MainWindow passes the
  request to the shown view instead of a switch per application.
- Profile actions of the tools are public (e.g. ConnectProfile(profile))
  so a request can run a profile.
- Web Console accepts a URL (connect dialog), like the other remote tools.
- All callers migrated (IP Scanner, Traceroute, Network Interface, RDAP,
  open settings). Traceroute > RDAP > AS number queries with type ASN.
- The application search is cleared before a request, so a filtered
  application list doesn't make the request fail.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- RunCommandParser (Models): "command target [argument] [type]" or
  "command @Profile". Whitespace around ";" is removed, so lists can be
  typed with spaces; a type keyword and the second argument (e.g. ports,
  DNS server) can be in any order; the rest after "@" is the profile
  name (names can contain spaces).
- First test project of the solution (NETworkManager.Tests, xUnit v3)
  with tests for the parser. dotnet test uses Microsoft.Testing.Platform
  (global.json).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- The run command (Ctrl+Shift+P) opens a dialog instead of the flyout:
  type e.g. "ping 10.0.0.1", "dns borntoberoot.net 1.1.1.1 aaaa" or
  "rdp @server01" and press Enter. Esc closes the dialog.
- Suggestions: recent commands, applications (with aliases like ping,
  dns, rdp, ssh), profiles of the application (@name) and type values.
  Up/Down select, Tab completes, Enter runs the selection (the input as
  typed is preselected).
- The target is validated with the validators of the application's
  input fields before the application is opened.
- Only visible applications are offered.
- Run command history (setting RunCommand_History).
- Removed the flyout and the unused RunCommandComboBox.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The application list only scrolled to the selected application on
startup and after clearing the search. An application opened from
somewhere else (dashboard, another application, run command) could stay
out of view.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ListHelper.Modify works on the ObservableCollection itself: an existing
entry is moved to the top, a new one inserted, and the oldest ones are
removed. Replaces the pattern copy/clear/refill (with a workaround to
restore the input text after the clear) and replacing the collection
in 34 places in 22 view models. Unit tests for the helper.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The 34 AddXToHistory methods only called ListHelper.Modify and were each
called once. ListHelper.Modify now ignores default values (null, 0) and
empty strings, which the remote tools checked in their methods, so the
call sites call it directly. PuTTY keeps its check for port and baud,
which are converted to strings.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ProfileInfo.IsEnabled(application) and GetTarget(application) (the
tool's host, IP range, domain, URL, ...) replace the IsProfileEnabled
and GetSearchableField overrides of 16 view models. The profile panel
and the run command use the same mappings.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
WaitForLoadedAsync (Utilities.WPF) completes on the Loaded event (or
immediately if the view is already loaded) and replaces the
"while (!_loaded) await Task.Delay(250)" loops of the remote tools.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Suggestions: exact command/alias first (e.g. "lookup" no longer opens
  DNS Lookup), exact profile name first in "@" mode, recent commands of a
  command before its profiles, the tool's target of a profile (e.g. RDP
  host) instead of the general host.
- DNS servers: configured servers as suggestions, matched by name
  case-insensitively; values with spaces can be quoted ("Google Public
  DNS").
- DNS Lookup uses PTR for IP addresses from any request (run command,
  IP Scanner, Traceroute, profiles); shortened IPv4 forms like "10" are
  host names.
- A failed suggestion (e.g. a recent command with an ambiguous profile
  name) is put into the input to correct it.
- Syntax hints use resource strings; history entries are parsed once.
- Docs: quotes, DNS servers, duplicate profile names, "@" only at the
  start of the target.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Enter runs what was typed: no preselected suggestion for an empty
  input or an unknown command with arguments (e.g. "pin 10.0.0.1");
  completing a command keeps the arguments.
- "@": a profile is only preselected if exactly one matches, so
  duplicate names show the error and the profiles to select.
- Parser: a list that is being typed ("10.0.0.1; ") stays the target,
  ";" in quotes is kept, quotes around "@name" are removed.
- Web Console requests require the WebView2 runtime.
- The run command "settings" keeps the open settings page.
- History and profiles are loaded once per dialog.
- New commands: ipgeolocation (geo) and wakeonlan (wol <MAC>
  [broadcast]).
- Application list: removed a redundant scroll on startup.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Run command "settings" with a filtered application list no longer
  crashes (the search is cleared first).
- The dialog has a title bar with a close button.
- The DNS server argument is validated (configured name or IP address /
  host with a domain); a mistyped type like "aaa" is reported.
- A request is only passed to the application if it is shown.
- After running a suggestion with the mouse, the focus isn't taken back
  by the closing dialog.
- History: entries of hidden applications are not shown; commands are
  stored case-insensitively (ListHelper.Modify with a comparer).
- Text after a quoted profile name is an unknown argument.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- The suggestion list is limited to 340 px, so it fits into the dialog
  (max. 500 px) and the selected entry is always visible.
- WaitForLoadedAsync stops waiting after 5 seconds, so a request to a
  view that wasn't shown doesn't run later when the view is opened.
- Completing a command uses the shortest matching name ("pin" → "ping").
- Profile names are compared like they are parsed (trimmed, without
  quotes), so recent commands with such names work.
- Empty DNS server list entries ("1.1.1.1; ") are ignored.
- Commands without arguments use the last word for the suggestions.
- Command names are computed once per dialog; one close function for
  the run command dialog.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Copilot AI balanced review requested due to automatic review settings October 21, 2026 20:32
@github-actions github-actions Bot added this to the next-release milestone Oct 21, 2026

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.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@mergify

mergify Bot commented Oct 21, 2026 •

Copy link
Copy Markdown
Contributor

This pull request does not currently match the merge queue conditions, so it cannot be queued from here. The box comes back if it matches again.

@BornToBeRoot BornToBeRoot changed the title Feature/run command Feature: Improve run command (Ctrl+Shift+P) Oct 21, 2026
@mergify
mergify Bot merged commit efdf21b into main Oct 21, 2026
5 checks passed
@mergify
mergify Bot deleted the feature/run-command branch October 21, 2026 20:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants