Skip to content

Add completion spec: Vagrant (vagrant) - #306

Merged
acarl005 merged 5 commits into
mainfrom
app-3965/command-spec-vagrant
Aug 6, 2026
Merged

Add completion spec: Vagrant (vagrant)#306
acarl005 merged 5 commits into
mainfrom
app-3965/command-spec-vagrant

Conversation

@warp-agent-staging

@warp-agent-staging warp-agent-staging Bot commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds a hand-written completion spec for the vagrant CLI (HashiCorp Vagrant), closing the gap where signature_by_name("vagrant") returned None.

command-signatures/json/vagrant.json covers:

  • All 36 top-level subcommands reported by 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.
  • Nested command groups: box (add/list/outdated/prune/remove/repackage/update/help), cloud (auth/box/provider/publish/search/version, including the third-level auth, box, provider and version leaves), plugin (install/license/list/uninstall/update/repair/expunge), snapshot (delete/list/pop/push/restore/save).
  • Flags for every subcommand, with --foo / --no-foo pairs marked exclusiveOn each other, filepaths/folders templates on path arguments, and static value suggestions for providers, architectures, checksum types, shells, and sort/order enums.
  • Global flags (--color/--no-color, --machine-readable, --debug, --timestamp, --debug-timestamp, --no-tty, -h, -v) marked isPersistent, since Vagrant accepts them at every subcommand level.

command-signatures/src/generators/vagrant.rs adds the two generators fish backs with dynamic helpers, registered in generators/mod.rs via dynamic_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 the boxes directory under the Vagrant home (honoring $VAGRANT_HOME) and reverses Vagrant's -VAGRANTCOLON- / -VAGRANTSLASH- directory escaping, matching BoxCollection#undir_name. Referenced by init, box remove, box repackage, box update --box, and box 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 against Vagrant::Environment#active_machines and Vagrant::BoxCollection in 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 sh pipeline and produce no suggestions in a Windows shell. Windows support is deliberately out of scope here.

Deviations from the fish reference

  • connect and share are in the fish commands list but are omitted: they were provided by the vagrant-share plugin, which is no longer shipped and does not appear in vagrant list-commands or vagrant --help on 2.4.9.
  • cap appears in vagrant list-commands but is omitted as an internal capability-dispatch command, matching fish.
  • autocomplete, list-commands, provider, upload, validate, plugin repair, and plugin expunge are added beyond the fish surface — they exist on current Vagrant.

Verification

./script/presubmit passes: npm run format:check, cargo fmt --check, cargo clippy --all-targets --all-features -- -D warnings, and cargo test (129 tests). That includes this repo's spec invariants — every generatorName resolves in dynamic_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.9 binary rather than written from memory: vagrant list-commands and vagrant <subcommand> -h were 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 — asserts signature_by_name("vagrant") resolves and exposes all 36 top-level subcommands plus every nested box / cloud / plugin / snapshot subcommand.
  • parse_machines / parse_boxes unit 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 a VAGRANT_HOME and 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:

$ VAGRANT_HOME="/tmp/spacetest/my vagrant home" sh -c 'ls -1 ${VAGRANT_HOME:-$HOME/.vagrant.d}/boxes'      # unquoted
ls: cannot access '/tmp/spacetest/my': No such file or directory
ls: cannot access 'vagrant': No such file or directory
ls: cannot access 'home/boxes': No such file or directory

$ VAGRANT_HOME="/tmp/spacetest/my vagrant home" sh -c 'ls -1 "${VAGRANT_HOME:-$HOME/.vagrant.d}/boxes"'    # as shipped
hashicorp-VAGRANTSLASH-bionic64
mybox

Verified in a real Warp session

warp-oss was built from a local warpdotdev/warp checkout with warp-command-signatures pointed 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_machines produces the three machine names, each described by its provider:

db        docker
default   virtualbox
web       libvirt

vagrant box remove + Tab — vagrant_boxes produces the four installed boxes, with -VAGRANTSLASH- un-escaped back to /:

generic/ubuntu2204     Installed box
hashicorp/bionic64     Installed box
mybox                  Installed box
ubuntu/jammy64         Installed box

vagrant + Tab lists the static subcommands with their descriptions.

Follow-up (required, after this merges)

warpdotdev/warp pins warp-command-signatures to a git rev in Cargo.toml / Cargo.lock, so vagrant completions will not reach the client until that rev is bumped. That bump is a separate PR against warpdotdev/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 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 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.
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.

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>
@cla-bot cla-bot Bot added the cla-signed label Aug 6, 2026
@warp-agent-staging warp-agent-staging Bot added the warpy-factory Opened by the Warp factory agents label Aug 6, 2026
@warp-agent-staging
warp-agent-staging Bot marked this pull request as ready for review August 6, 2026 02:12
@warp-agent-staging
warp-agent-staging Bot requested a review from acarl005 August 6, 2026 02:12
@oz-for-oss

oz-for-oss Bot commented Aug 6, 2026

Copy link
Copy Markdown

@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 /oz-review on this pull request to retrigger a review (up to 3 times on the same pull request).

Powered by Oz

@oz-for-oss oz-for-oss 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.

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

Comment thread command-signatures/src/generators/vagrant.rs Outdated
- 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>
@acarl005
acarl005 merged commit fe35266 into main Aug 6, 2026
8 checks passed
@acarl005
acarl005 deleted the app-3965/command-spec-vagrant branch August 6, 2026 03:08
acarl005 pushed a commit to warpdotdev/warp that referenced this pull request Aug 6, 2026
## 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

[![Demonstrating Warp's completion dropdown for three command lines:
"vagrant ", "vagrant up ", and "vagrant box remove ", pausing on each
dropdown.](https://staging.warp.dev/api/v1/agent/artifacts/019fd53d-300d-7642-8f14-a96259b45a81/download)](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.](https://staging.warp.dev/api/v1/agent/artifacts/019fd539-0d09-71f2-905b-fef1925557c9/download)
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.](https://staging.warp.dev/api/v1/agent/artifacts/019fd53a-f633-71f2-8619-61973537adbc/download)
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.](https://staging.warp.dev/api/v1/agent/artifacts/019fd53c-5578-7808-8959-71d13b553c47/download)
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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cla-signed warpy-factory Opened by the Warp factory agents

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants