Repository navigation
feat(cli): shell completion for zsh, bash, and fish #10568
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
teamleaderleo
merged 151 commits into
manaflow-ai:main
from
ammachado:feature/cmux-shell-autocomplete
Oct 19, 2026
+11,470
−277
Merged
Changes from all commits
Commits
Show all changes
151 commits
Select commit
Hold shift + click to select a range
12cf54a
docs: add shell completion design spec
ammachado 5d0713a
docs: add shell completion implementation plan
ammachado 0c9c95a
feat(cli): add ArgumentParser facade routing bridge
ammachado cfbcff6
fix(cli): localize facade help abstract
ammachado 3f093f9
feat(cli): add command tree snapshot check
ammachado 860b12a
fix(cli): repair command tree project wiring
ammachado 2566811
feat(cli): add cmux completion command
ammachado d575b37
fix(cli): wrap completion argument help
ammachado 6ecc900
test(cli): refresh completion command tree snapshot
ammachado 0ee0b30
fix(cli): render positional command tree names
ammachado abb9dd1
feat(cli): add completion candidate safety contract
ammachado 9cfcca4
feat(cli): complete live cmux refs, themes, and VM ids
ammachado a50d959
feat(cli): declare meta command family
ammachado 4beaa35
test(cli): refresh meta command tree snapshot
ammachado 3694966
feat(cli): declare auth command family
ammachado 8ec74ec
fix(cli): order auth command aliases
ammachado 3a89edb
fix(cli): retain auth aliases in legacy router
ammachado 03e183e
test(cli): refresh auth command tree snapshot
ammachado 6c7c398
fix(cli): declare top-level auth aliases
ammachado 665ad12
test(cli): refresh top-level auth aliases snapshot
ammachado d1ed33b
feat(cli): declare VM and remote commands
ammachado a32f30a
fix(cli): order VM command configuration arguments
ammachado a7ca23e
test(cli): refresh VM command tree snapshot
ammachado 7e60576
feat(cli): declare window command family
ammachado 85c40b2
test(cli): refresh window command tree snapshot
ammachado 63f4060
feat(cli): add workspace command facade
ammachado 8d0ba8c
fix(cli): disambiguate workspace completions
ammachado 149e3f4
fix(cli): use directory completion property
ammachado fadce0e
test(cli): refresh workspace command tree snapshot
ammachado b6c2d73
fix(cli): preserve delegated command help
ammachado a652d23
fix(cli): preserve workspace argument passthrough
ammachado d074b68
feat(cli): declare pane and surface command family
ammachado d75fe78
test(cli): refresh pane and surface command tree snapshot
ammachado cb8a643
feat(cli): declare browser command family
ammachado f1e57aa
fix(cli): expose browser legacy alias declarations
ammachado c3aa848
test(cli): refresh browser command tree snapshot
ammachado 1c58680
fix(cli): expose browser completion arguments
ammachado 7e83af0
fix(cli): restore browser double-click declaration
ammachado 2ac0115
test(cli): refresh browser completion tree snapshot
ammachado d7d0249
fix(cli): scope browser completion options
ammachado 08d952e
test(cli): narrow browser completion tree snapshot
ammachado 68f823d
fix(cli): restrict browser option groups
ammachado c3f78b8
feat(cli): declare browser automation arguments
ammachado e1a2eb1
feat(cli): declare browser select and scroll arguments
ammachado 49c9741
feat(cli): declare browser automation syntax
ammachado dab9d48
feat(cli): complete browser command metadata
ammachado e07230f
feat(cli): declare browser navigation completion
ammachado 3b12e1e
test(cli): finalize browser completion tree snapshot
ammachado 897ce7a
fix(cli): align browser wait completion options
ammachado e812341
test(cli): refresh final browser command tree snapshot
ammachado bae006d
feat(cli): declare tmux compatibility commands
ammachado 8553bc0
test(cli): refresh tmux compatibility tree snapshot
ammachado 26330bb
fix(cli): complete panel target candidates
ammachado 1dec02b
feat(cli): declare hooks and agent launchers
ammachado 29cc338
fix(cli): make agent launcher declarations explicit
ammachado de94c8c
test(cli): refresh hooks command tree snapshot
ammachado 3e3d060
feat(cli): declare notification command family
ammachado 0fe72d5
fix(cli): preserve facade validation exit codes
ammachado c74ca1c
fix(cli): expose facade validation output
ammachado 698505a
fix(cli): preserve notification selector diagnostics
ammachado 515c765
test(cli): refresh notification command tree snapshot
ammachado c5c4afe
feat(cli): declare remaining system command family
ammachado 08d7187
refactor(cli): derive command name list from declared tree
ammachado 092a7a6
test(cli): gate dispatch and alias parity
ammachado e467446
fix(cli): handle global options on both sides of the command
ammachado 96ea371
i18n(cli): localize command abstracts and option help
ammachado 4b63c4a
fix(cli): route ArgumentParser completion requests to the facade
ammachado d1f104f
docs(cli): document shell completion install
ammachado 5e6421d
fix: handle AgentHookFailureStage.journalAppend in failure reporting
ammachado 1e565d5
fix(cli): preserve exit codes and argument handling in the ArgumentPa…
ammachado bece065
fix(cli): localize new completion docs topic strings
ammachado f1854f6
fix(cli): address CodeRabbit review findings on the ArgumentParser fa…
ammachado 70eb8fe
fix(cli): localize completion docs label and add real translations
ammachado e0ea3fb
docs: drop shell-completion planning docs from the PR
ammachado 9ec2303
fix(cli): close wait-for lock TOCTOU race, tighten completion check, …
ammachado cb44e0b
refactor(cli): finish collapsing legacy routing protocols onto Shared…
ammachado 174a487
refactor(cli): extract shared filesystem-wait helper
ammachado 6907a6d
feat(brew): install shell completions from the cask
ammachado 10e9ea4
docs(i18n): sync translated READMEs with SSH --command and shell comp…
ammachado 79833a1
fix(cli): keep legacy parsing authoritative behind the facade
ammachado 0adaf7a
fix(cli): adopt async CMUXCLI.run() and declare commands added on main
ammachado ce92b8f
test(cli): gate cr as a passthrough alias, not a help alias
ammachado ea8c2c5
fix(cli): declare local-tmux and its tmux alias in the facade tree
ammachado 148d3e7
fix(cli): restrict the tmux alias to attach and restore local-tmux pa…
ammachado e85ff10
fix(cli): correct restore --surface, wait-for locks, and the tmux alias
ammachado a949672
feat(cli): declare the command surface completion was missing
ammachado 78f1910
fix(cli): bound and sanitize dynamic completion candidates
ammachado e0470e6
test(cli): make CLI subprocess tests hermetic and unstallable
ammachado 9dcc8c1
test(cli): pin the tmux alias and attach-retry noise regressions
ammachado b41fd7b
fix(cli): restore the tmux alias diagnostic and facade retry silence
ammachado 4a79ea9
i18n(cli): drop duplicate dismiss-notification selector locales
ammachado 1592996
fix(cli): declare the agent and sudo commands main added
ammachado 84c82f2
test(cli): gate every command `cmux help` lists on a facade declaration
ammachado 298d242
fix(cli): declare the guide and sessions commands
ammachado 43bbc4a
test(cli): gate vm verbs and documented flag spellings on the facade …
ammachado cd689a1
fix(cli): declare every vm verb and the --skill spellings
ammachado 088a47e
test(cli): pin facade rejections of shapes the legacy runner accepts
ammachado 808e7c7
fix(cli): route only facade-native commands through ArgumentParser
ammachado c255c46
fix(cli): declare current, glaeda, and socket-status commands main added
ammachado 968ac0b
fix(cli): declare paste and resize-window commands main added
ammachado d362645
Merge commit '90e1689ffc9d118dd70ae27f38a80ca636a9783f' into feature/…
ammachado 9579d72
test(cli): parse grouped `cmux help` in the dispatch parity gate
ammachado 1d4b359
fix(cli): declare commands main added since the last catch-up
ammachado fc8683b
test(cli): wait-for locks must live in the private signal directory
ammachado def113c
fix(cli): keep wait-for locks in the private signal directory
ammachado 1c19511
test(cli): register completion gates in CI and bound their subprocesses
ammachado 9a14564
docs: split shell completion snippets and require compinit for zsh
ammachado 98ba9ff
fix(cli): declare missing flags and subcommands in completion facades
ammachado daa4da0
test(cli): share the process-group-killing runner and fix test messages
ammachado 3138dd6
fix(cli): complete workspace status and loading arguments
ammachado 34f8851
Merge main (51b60f3b30) into feature/cmux-shell-autocomplete
ammachado 96a253b
fix(cli): scope completion candidates to explicit workspace and windo…
ammachado 33041d6
Merge main (70e997fb47b0) into feature/cmux-shell-autocomplete
ammachado 1a052f0
Merge main (541c7351fa65) into feature/cmux-shell-autocomplete
ammachado 2a8303e
fix(cli): complete and localize wait-for lock help
teamleaderleo c80261b
Merge current main for CLI completion review
teamleaderleo ffdf8b6
Merge origin/main (1a7d5cd08ad) into feature/cmux-shell-autocomplete
ammachado f625b18
Merge main (fcaefa330ba1) into feature/cmux-shell-autocomplete
ammachado 381a6b2
test(cli): completion must use the --socket and --password typed on t…
ammachado eade79b
fix(cli): complete against the --socket and --password typed on the line
ammachado ee75927
fix(cli): declare vm network/agent-updates and refresh the command tree
ammachado 0ddcd6b
Merge main
teamleaderleo 58f1290
i18n(cli): keep Localizable.xcstrings in main's order
ammachado 2893f10
fix(cli): adopt the three-parameter custom completion form
ammachado eed5abc
fix(cli): declare browser repl and refresh the command tree
ammachado 3492a4e
docs(cli): sync wait-for usage in CLI contract with -L/-U flags
ammachado eb43ec2
Merge main (f60146706458) into feature/cmux-shell-autocomplete
ammachado bafefab
Merge main (c72d139fb06b) into feature/cmux-shell-autocomplete
ammachado 4c21e70
test(cli): completion must skip bash's lone = and offer every setting…
ammachado d89c6b1
fix(cli): skip bash's lone = in completion selectors; offer themes an…
ammachado 84f17f8
Merge commit 'b98fdc2fef8bf385a1211613916885a367e977ba' into feature/…
ammachado 555139b
test(cli): cmux config completion must offer every documented verb
ammachado 5024644
fix(cli): offer unset, toggle, cycle and preset in cmux config comple…
ammachado 08750ef
test(ci): register the config completion verbs check
ammachado e17d2bf
Merge main (ce6be93cf232) into feature/cmux-shell-autocomplete
ammachado e54e492
Merge main (033c9be367ee) into feature/cmux-shell-autocomplete
ammachado a8d1478
test(cli): cmux hooks completion must offer every documented verb
ammachado bcc435a
fix(cli): offer feed in cmux hooks completion
ammachado d3f5ee6
Merge commit '785c43710ab6960ad3f2aa2776c2206666e00364' into feature/…
ammachado 402e575
docs(cli): add jump-to-last-prompt to the command tree snapshot
ammachado c9c9cad
Merge main (67431d2c1cec) into feature/cmux-shell-autocomplete
ammachado 8eb6102
Merge main (5ded302c84aa) into feature/cmux-shell-autocomplete
ammachado d3a565e
docs(cli): regenerate command tree for the muse hook agent
ammachado c9bb915
Merge commit '2eafd0dfac2a37f4f7717ca78bda3ac68d4733ca' into feature/…
ammachado 24a815a
Merge main (0f1a17598367) into feature/cmux-shell-autocomplete
ammachado 6be072c
fix(cli): declare vm restart in the completion tree
ammachado 4eb2bf5
Merge main (6249b33cdfda) into feature/cmux-shell-autocomplete
ammachado 59d9477
Merge main (56ca4b90d803) into feature/cmux-shell-autocomplete
ammachado 961a8c3
Merge origin/main into feature/cmux-shell-autocomplete
teamleaderleo 7b12ff7
Merge remote-tracking branch 'origin/main' into pr-10568-b
teamleaderleo 8d25f8d
Merge remote-tracking branch 'origin/main' into pr-10568-c
teamleaderleo File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,128 @@ | ||
| import Foundation | ||
|
|
||
| extension CMUXCLI { | ||
| func runDumpCommandTree() throws { | ||
| let data = Data(CmuxCommand._dumpHelp().utf8) | ||
| let toolInfo = try JSONDecoder().decode(CommandTreeToolInfo.self, from: data) | ||
| // ArgumentParser synthesizes its own "help" subcommand alongside any | ||
| // explicitly declared one with the same name, so the same path can | ||
| // appear twice; keep one entry per path. | ||
| var seenPaths: Set<String> = [] | ||
| let entries = commandTreeEntries(from: toolInfo.command) | ||
| .sorted { $0.path < $1.path } | ||
| .filter { seenPaths.insert($0.path).inserted } | ||
|
|
||
| for entry in entries { | ||
| print("command \(entry.path) aliases=\(entry.aliases)") | ||
| for argument in entry.arguments.sorted(by: { $0.name < $1.name }) { | ||
| print(" arg \(argument.name) kind=\(argument.kind) completion=\(argument.completion)") | ||
| } | ||
| } | ||
| } | ||
|
|
||
| private func commandTreeEntries(from root: CommandTreeCommandInfo) -> [CommandTreeEntry] { | ||
| root.subcommands | ||
| .flatMap { commandTreeEntries(from: $0, path: []) } | ||
| } | ||
|
|
||
| private func commandTreeEntries( | ||
| from command: CommandTreeCommandInfo, | ||
| path: [String] | ||
| ) -> [CommandTreeEntry] { | ||
| let path = path + [command.commandName] | ||
| let entry = CommandTreeEntry( | ||
| path: path.joined(separator: " "), | ||
| aliases: command.aliases?.sorted().joined(separator: ",") ?? "-", | ||
| arguments: command.arguments | ||
| .filter { $0.preferredName?.rendered != "--help" } | ||
| .map(CommandTreeArgumentEntry.init) | ||
| ) | ||
| return [entry] + command.subcommands.flatMap { commandTreeEntries(from: $0, path: path) } | ||
| } | ||
| } | ||
|
|
||
| private struct CommandTreeToolInfo: Decodable { | ||
| let command: CommandTreeCommandInfo | ||
| } | ||
|
|
||
| private struct CommandTreeCommandInfo: Decodable { | ||
| let commandName: String | ||
| let aliases: [String]? | ||
| let subcommands: [CommandTreeCommandInfo] | ||
| let arguments: [CommandTreeArgumentInfo] | ||
|
|
||
| private enum CodingKeys: String, CodingKey { | ||
| case commandName | ||
| case aliases | ||
| case subcommands | ||
| case arguments | ||
| } | ||
|
|
||
| init(from decoder: Decoder) throws { | ||
| let container = try decoder.container(keyedBy: CodingKeys.self) | ||
| commandName = try container.decode(String.self, forKey: .commandName) | ||
| aliases = try container.decodeIfPresent([String].self, forKey: .aliases) | ||
| subcommands = try container.decodeIfPresent([CommandTreeCommandInfo].self, forKey: .subcommands) ?? [] | ||
| arguments = try container.decodeIfPresent([CommandTreeArgumentInfo].self, forKey: .arguments) ?? [] | ||
| } | ||
| } | ||
|
|
||
| private struct CommandTreeArgumentInfo: Decodable { | ||
| let kind: String | ||
| let preferredName: CommandTreeArgumentName? | ||
| let valueName: String? | ||
| let completionKind: CommandTreeCompletionKind? | ||
| } | ||
|
|
||
| private struct CommandTreeArgumentName: Decodable { | ||
| let kind: String | ||
| let name: String | ||
|
|
||
| var rendered: String { | ||
| switch kind { | ||
| case "long": "--\(name)" | ||
| case "short", "longWithSingleDash": "-\(name)" | ||
| default: name | ||
| } | ||
| } | ||
| } | ||
|
|
||
| private enum CommandTreeCompletionKind: Decodable { | ||
| case list(values: [String]) | ||
| case file(extensions: [String]) | ||
| case directory | ||
| case shellCommand(command: String) | ||
| case custom | ||
| case customAsync | ||
| case customDeprecated | ||
|
|
||
| var rendered: String { | ||
| switch self { | ||
| case .list(let values): "list(\(values.sorted().joined(separator: ",")))" | ||
| case .file(let extensions): "file(\(extensions.sorted().joined(separator: ",")))" | ||
| case .directory: "directory" | ||
| case .shellCommand(let command): "shell-command(\(command))" | ||
| case .custom: "custom" | ||
| case .customAsync: "custom-async" | ||
| case .customDeprecated: "custom-deprecated" | ||
| } | ||
| } | ||
| } | ||
|
|
||
| private struct CommandTreeEntry { | ||
| let path: String | ||
| let aliases: String | ||
| let arguments: [CommandTreeArgumentEntry] | ||
| } | ||
|
|
||
| private struct CommandTreeArgumentEntry { | ||
| let name: String | ||
| let kind: String | ||
| let completion: String | ||
|
|
||
| init(_ argument: CommandTreeArgumentInfo) { | ||
| name = argument.preferredName?.rendered ?? argument.valueName ?? "-" | ||
| kind = argument.kind == "positional" ? "argument" : argument.kind | ||
| completion = argument.completionKind?.rendered ?? "-" | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.