Add completion spec: Vagrant (vagrant) - #306
Conversation
Adds a hand-written Fig-style spec for the vagrant CLI covering every subcommand reported by `vagrant list-commands` (Vagrant 2.4.9), the nested box/cloud/plugin/snapshot groups, and each subcommand's flags. Two generators back the dynamic values fish completes: `vagrant_machines` reads the project's .vagrant/machines directory (described by provider) and `vagrant_boxes` reads the Vagrant home box directory, un-escaping the -VAGRANTSLASH-/-VAGRANTCOLON- placeholders Vagrant stores names with. Co-Authored-By: Warp <agent@warp.dev>
|
@warp-agent-staging[bot] I'm starting a first review of this pull request. You can view the conversation on Warp. I completed the review and no human review was requested for this pull request. Comment Powered by Oz |
There was a problem hiding this comment.
Overview
Adds Vagrant completion support through a new JSON spec plus Rust dynamic generators for local machines and installed boxes. The attached diff only includes the Rust generator/test changes; GitHub did not provide a patch for command-signatures/json/vagrant.json, so review of the spec content itself is limited to the PR description.
Concerns
- No blocking correctness, security, or spec-drift concerns found in the annotated diff.
- One non-blocking robustness suggestion is inline.
Verdict
Found: 0 critical, 0 important, 1 suggestions
Approve with nits
Comment /oz-review on this pull request to retrigger a review (up to 3 times on the same pull request).
Powered by Oz
- Quote the resolved boxes path so a VAGRANT_HOME or HOME containing spaces is no longer split into separate `ls` arguments. - Select the generator command from the session shell: POSIX shells get the `sh`/`find` pipeline, PowerShell gets a native script, and cmd.exe runs that script via `powershell -NoProfile -Command`. This adds `CommandBuilder::per_shell_and_ignore_stderr`, and the newline invariant test now covers every shell rather than only POSIX. - Fold vagrant_tests.rs into vagrant.rs as an inline `mod tests`, matching git.rs and yc.rs, and add execution-path tests that run the real listings against fixtures whose paths contain spaces. Co-Authored-By: Warp <agent@warp.dev>
The requester scoped Windows out. Both generators go back to the plain POSIX command, so `completion-metadata` is untouched again: the `per_shell_and_ignore_stderr` constructor and its `CommandBuilder` variant are gone, along with the tests that only covered them. `all_command_specs_have_no_newlines` returns to checking POSIX alone, since with one command string per generator the only per-shell difference left is the constant stderr redirect. The quoting fix and its three execution-path tests stay - that defect was unrelated to Windows. Also restores the spec-surface regression test, which was dropped when the tests moved inline. Co-Authored-By: Warp <agent@warp.dev>
## Description Updates `warp-command-signatures` from `5e08807c` to `fe352669` so the client picks up the new `vagrant` completion spec. This is the client-side half of APP-3965; the spec itself merged in warpdotdev/command-signatures#306. Closes #9781 ### Merged PRs picked up by this bump - Add completion spec: Vagrant (vagrant) (warpdotdev/command-signatures#306) — the reason for this bump - Complete just completions: Justfile recipe generator (warpdotdev/command-signatures#307) - Add completion spec: tcpdump (warpdotdev/command-signatures#305) `fe352669` is the current `main` head of `warpdotdev/command-signatures` and is #306's merge commit. The diff is 3 lines — the `rev` in `Cargo.toml` and the two matching `source` lines in `Cargo.lock`. The two revs have **identical dependency manifests** (verified with `git diff 5e08807c fe352669 -- Cargo.toml '*/Cargo.toml'`, empty), so no other lockfile entry legitimately changes and no unrelated dependency churn rides along. `cargo metadata --locked` passes, confirming the lockfile is consistent. ## Verification **Testing-exempt category: dependency/version bump.** No regression test is added — the change is a git rev plus its lockfile consequence, so a unit test here could only assert the new rev string rather than detect a logic defect. The completion data itself is tested in `command-signatures`. The client-side resolution and UI checks below are the meaningful proof, and they are the whole point of this PR. ### Visual proof: `vagrant` completions in the running client Captured against a `warp-oss` build of **this PR's branch** (so the completions come from the pinned rev `fe352669`, not a local path override), running on an Xvfb display. The Vagrant CLI is not installed on the capture machine and is not needed — both generators are filesystem reads, so a fixture project (`.vagrant/machines/{web/virtualbox,db/libvirt,worker/docker}`) and a fixture box store were seeded. - **`vagrant <TAB>`** — the full static subcommand list with descriptions, in spec order (`autocomplete`, `box`, `cloud`, `destroy`, `docker-exec`, `docker-logs`, `docker-run`, `global-status`, `halt`, `help`, `init`, `list-commands`, `login`, `package`, `plugin`, `port`, `powershell`, `provider`, `provision`, `push`, `rdp`, `reload`, `resume`, `rsync`, `rsync-auto`, `snapshot`, `ssh`, `ssh-config`, `status`, `suspend`, `up`, `upload`, `validate`, `version`, `winrm`, `winrm-config`), followed by the global flags. - **`vagrant up <TAB>`** — the `vagrant_machines` generator resolving live against the fixture project: `db` described as `libvirt`, `web` as `virtualbox`, `worker` as `docker`, followed by `up`'s own flags (`--provision`/`--no-provision`, `--provider`, `--destroy-on-error`, …). - **`vagrant box remove <TAB>`** — the `vagrant_boxes` generator, **with the `-VAGRANTSLASH-` / `-VAGRANTCOLON-` un-escaping applied**: the on-disk directories `hashicorp-VAGRANTSLASH-bionic64`, `ubuntu-VAGRANTSLASH-focal64`, `generic-VAGRANTSLASH-alpine318`, and `registry.example.com-VAGRANTCOLON-8080-VAGRANTSLASH-internal-base` render as `hashicorp/bionic64`, `ubuntu/focal64`, `generic/alpine318`, and `registry.example.com:8080/internal-base`. No literal `VAGRANTSLASH`/`VAGRANTCOLON` text appears anywhere in the menu. One cosmetic note from the capture, not caused by this PR: the longest fixture entry (`registry.example.com:8080/internal-base`, an artificially long name invented for the un-escaping test) renders with its `Installed box` description column squeezed to empty, while the shorter names show it. The generator attaches that description unconditionally, so this is dropdown column truncation on an unusually long name rather than missing data. ### Deterministic checks - **`vagrant` resolves through warp's own completer registry.** Ran an ad-hoc (uncommitted) test against `CommandRegistry::global_instance()` — the same registry `crates/warp_completer/src/signatures/legacy/mod.rs` builds from the embedded signatures. Result: `registry.signature("vagrant")` returns `Some`, description `"Build and manage reproducible virtual machine environments"`, **36 subcommands**, and the nested `box` group resolves to `add, list, outdated, prune, remove, repackage, update, help`. - **Crate-level check against the exact feature set `warp_completer` enables.** Exercised `warp_command_signatures::signature_by_name("vagrant")` and `dynamic_command_signature_data()` with `default-features = false, features = ["embed-signatures"]`, matching what `warp_completer` enables on non-wasm. Result: signature resolves with all 36 subcommands, nested groups populated (`cloud`: auth/box/provider/publish/search/version; `plugin`: install/license/list/uninstall/update/repair/expunge; `snapshot`: delete/list/pop/push/restore/save), 19 options on `vagrant up`, and both `vagrant_machines` and `vagrant_boxes` generators registered in `dynamic_command_signature_data()`. An unknown command still resolves to `None`, confirming embedded data is genuinely being read. - **Before/after.** The same check against the *old* pin `5e08807c` returns `NOT FOUND` for `vagrant` with no generators registered, so this bump is what delivers the signature. - **`./script/format --check`** — clean. - **`cargo clippy -p warp_completer --all-targets --locked -- -D warnings`** — clean. - **`cargo check -p warp_completer --locked`** — clean. - **`cargo metadata --locked`** — passes. - **`cargo test -p warp_completer --locked`** — 138 passed, 25 failed. Those 25 failures are **pre-existing and unrelated**: the identical command on a clean `origin/master` checkout without this change produces the byte-identical `138 passed; 25 failed`. They all panic in `warp_features` with "Tried to check FeatureFlag::CloudEnvironments before feature flags were initialized", which happens because a single-crate test run does not pull in `warp_features/test-util` the way a workspace run does. Not introduced here. - The workspace-wide `./script/presubmit` was not run — disproportionate to a manifest-only pin, and CI covers it. Worth flagging for reviewers: the spec-surface regression tests in `command-signatures` cover the JSON there, but **nothing in this repo will fail if the `vagrant` signature is later dropped or renamed upstream** — the checks above are one-time confirmations, not standing guards. CHANGELOG-IMPROVEMENT: Added completions for `vagrant`, including its nested `box`, `cloud`, `plugin`, and `snapshot` command groups plus dynamic machine and box names. Originating thread: https://warpdev.slack.com/archives/C0BDQDW8V5E/p1785980828616589 <!-- oz:computer-use-videos start --> ### Computer-use video recordings [](https://oz.staging.warp.dev/artifacts/019fd53d-2cda-72e8-b3b4-75eb7b11a7c9) **Warp vagrant command-completion dropdowns**: Demonstrating Warp's completion dropdown for three command lines: "vagrant ", "vagrant up ", and "vagrant box remove ", pausing on each dropdown. <!-- oz:computer-use-videos end --> <!-- oz:computer-use-screenshots start --> <details> <summary>Computer-use screenshots (3)</summary>  Warp completion dropdown after typing "vagrant " showing autocomplete, box, cloud, destroy, docker-exec, docker-logs.  Warp completion dropdown after typing "vagrant up " showing db (libvirt), web (virtualbox), worker (docker), then flags --color, --debug, --debug-timestamp.  Warp completion dropdown after typing "vagrant box remove " showing box names with literal slashes/colon: generic/alpine318, hashicorp/bionic64, registry.example.com:8080/internal-base, ubuntu/focal64, then flags --all, --all-architectures. </details> <!-- oz:computer-use-screenshots end --> ### Rework changes - **[IMPORTANT] `Cargo.toml` — visual proof of `vagrant <TAB>` required.** Addressed. Built `warp-oss` from this PR's branch (not a local signatures path override, so the capture exercises the pinned rev) and captured a video plus three screenshots of `vagrant <TAB>`, `vagrant up <TAB>` (the `vagrant_machines` generator), and `vagrant box remove <TAB>` (the `vagrant_boxes` generator including `-VAGRANTSLASH-`/`-VAGRANTCOLON-` un-escaping). Embedded above and posted to the Linear ticket. The previous "no GUI/computer-use proof" caveat has been removed rather than left beside the new evidence. - No code changes in this cycle — the diff is unchanged at 3 lines across `Cargo.toml` and `Cargo.lock`. <!-- factory-agent: {"source":"factory-agent","task_id":"APP-3965","task_source":"linear","task_url":"https://linear.app/warpdotdev/issue/APP-3965/add-vagrant-completions","oz_run_id":"019fd50c-bdf9-71f9-98f4-305716f44f2f","repo":"warpdotdev/warp","review_rework_attempts":1} --> _This PR was generated with [Oz](https://warp.dev/oz)._ Co-authored-by: Warp Agent <agent@warp.dev>
Summary
Adds a hand-written completion spec for the
vagrantCLI (HashiCorp Vagrant), closing the gap wheresignature_by_name("vagrant")returnedNone.command-signatures/json/vagrant.jsoncovers:vagrant list-commands:autocomplete,box,cloud,destroy,docker-exec,docker-logs,docker-run,global-status,halt,help,init,list-commands,login,package,plugin,port,powershell,provider,provision,push,rdp,reload,resume,rsync,rsync-auto,snapshot,ssh,ssh-config,status,suspend,up,upload,validate,version,winrm,winrm-config.box(add/list/outdated/prune/remove/repackage/update/help),cloud(auth/box/provider/publish/search/version, including the third-levelauth,box,providerandversionleaves),plugin(install/license/list/uninstall/update/repair/expunge),snapshot(delete/list/pop/push/restore/save).--foo/--no-foopairs markedexclusiveOneach other,filepaths/folderstemplates on path arguments, and static value suggestions for providers, architectures, checksum types, shells, and sort/order enums.--color/--no-color,--machine-readable,--debug,--timestamp,--debug-timestamp,--no-tty,-h,-v) markedisPersistent, since Vagrant accepts them at every subcommand level.command-signatures/src/generators/vagrant.rsadds the two generators fish backs with dynamic helpers, registered ingenerators/mod.rsviadynamic_command_signature_data():vagrant_machines(fish's__fish_vagrant_machines) — walks up from the working directory for.vagrant/machines, then lists<machine>/<provider>two levels deep so each suggestion is described by the provider it was brought up with. Referenced by every subcommand that takes a[name|id]/[vm-name].vagrant_boxes(fish's__fish_vagrant_boxes) — lists theboxesdirectory under the Vagrant home (honoring$VAGRANT_HOME) and reverses Vagrant's-VAGRANTCOLON-/-VAGRANTSLASH-directory escaping, matchingBoxCollection#undir_name. Referenced byinit,box remove,box repackage,box update --box, andbox prune --name.Both generators read the filesystem rather than shelling out to
vagrant status/vagrant box list: Vagrant is a Ruby program with a multi-second start-up, which is too slow to run on a completion keystroke. The layout they read is the one Vagrant itself writes — confirmed againstVagrant::Environment#active_machinesandVagrant::BoxCollectionin 2.4.9 — and both degrade silently to no suggestions outside a Vagrant project / with no boxes installed.Both are POSIX-only, like the other generators in this repo: they run a
shpipeline and produce no suggestions in a Windows shell. Windows support is deliberately out of scope here.Deviations from the fish reference
connectandshareare in the fishcommandslist but are omitted: they were provided by thevagrant-shareplugin, which is no longer shipped and does not appear invagrant list-commandsorvagrant --helpon 2.4.9.capappears invagrant list-commandsbut is omitted as an internal capability-dispatch command, matching fish.autocomplete,list-commands,provider,upload,validate,plugin repair, andplugin expungeare added beyond the fish surface — they exist on current Vagrant.Verification
./script/presubmitpasses:npm run format:check,cargo fmt --check,cargo clippy --all-targets --all-features -- -D warnings, andcargo test(129 tests). That includes this repo's spec invariants — everygeneratorNameresolves indynamic_command_signature_data(), every JSON spec deserializes, and no generator command has an unquoted newline.The spec content was verified against a real
Vagrant 2.4.9binary rather than written from memory:vagrant list-commandsandvagrant <subcommand> -hwere run for every subcommand and nested subcommand, and each flag, argument name, and description in the spec comes from that output.14 tests live in
vagrant.rs:test_vagrant_spec_covers_every_subcommand_and_nested_group— assertssignature_by_name("vagrant")resolves and exposes all 36 top-level subcommands plus every nestedbox/cloud/plugin/snapshotsubcommand.parse_machines/parse_boxesunit coverage — provider descriptions, machines with no provider directory yet, multi-provider machines, non-listing lines,-VAGRANTSLASH-/-VAGRANTCOLON-un-escaping, blank lines, empty output.test_boxes_command_quotes_the_resolved_path— guards the quoting fix below.posix_execution::*— three tests that actually spawn the listings against on-disk fixtures, including aVAGRANT_HOMEand a project path that contain spaces, plus a no-Vagrant-project case that must stay silent.The quoted box path matters, and is reproducible directly:
Verified in a real Warp session
warp-osswas built from a localwarpdotdev/warpcheckout withwarp-command-signaturespointed at this branch, launched on a Linux desktop, and driven with the Tab key in/home/agent/vagrant-demo(a Vagrant project seeded with three machines and four installed boxes in the on-disk layout Vagrant writes). The screenshots below were re-captured from a rebuild of the final state of this branch.vagrant up+ Tab —vagrant_machinesproduces the three machine names, each described by its provider:vagrant box remove+ Tab —vagrant_boxesproduces the four installed boxes, with-VAGRANTSLASH-un-escaped back to/:vagrant+ Tab lists the static subcommands with their descriptions.Follow-up (required, after this merges)
warpdotdev/warppinswarp-command-signaturesto a git rev inCargo.toml/Cargo.lock, sovagrantcompletions will not reach the client until that rev is bumped. That bump is a separate PR againstwarpdotdev/warp(same pattern as warp#14742 for journalctl) and is deliberately not part of this change — it cannot be made until this PR merges.Originating thread: https://warpdev.slack.com/archives/C0BDQDW8V5E/p1785980828616589
Linear issue: https://linear.app/warpdotdev/issue/APP-3965/add-vagrant-completions
Source GitHub issue: warpdotdev/warp#9781
Computer-use screenshots (3)
Warp completions dropdown after typing 'vagrant up ' and pressing Tab, showing machine names db/default/web and flags.
Warp completions dropdown after typing 'vagrant box remove ' and pressing Tab, showing installed box names and --all flags.
Warp completions dropdown after typing 'vagrant ' and pressing Tab, showing subcommands autocomplete, box, cloud, destroy, docker-exec, docker-logs.
Conversation: https://staging.warp.dev/conversation/973d9e8f-7676-499c-a57b-933173040c1a
Run: https://oz.staging.warp.dev/runs/019fd4c8-89bf-7dfd-858c-3f34cb8c08e8
This PR was generated with Oz.