CLI command coverage index
The per-package guides (architecture.md, examples.md)
document the typed surface from the method outward — "here's PrMerge, here's what it
runs." This page inverts that: from the CLI command inward — "I know git rebase --onto
/ jj parallelize / gh api; is it covered by a typed method, or do I need the escape
hatch?" Each table row is one typed method and the exact subcommand/flags it runs, sourced
directly from the wrapper's client type (Git/Jj/GitHub/GitLab/Gitea in
src/VcsToolkit.*/*.fs) — the same source architecture.md and
examples.md document, cross-checked directly against the implementation so a
method those guides haven't caught up to yet still shows up here.
This index doubles as a map of the untyped surface: everything a wrapper's Run/RunRaw
escape hatch reaches but no typed method models yet is a candidate for a future typed method.
How to read this
-
Runs — the argv the method builds, elided to the load-bearing flags (see the linked
source file for the full contract: option types, error classification, argv-injection
guards — every method placing a caller-supplied value in a bare positional slot rejects an
empty or
--leading value before spawning; see each wrapper's own doc comment for the exact guard). -
Every client (
Git,Jj,GitHub,GitLab,Gitea) also exposes a.At(dir)cwd-bound view (GitAt,JjAt,GitHubAt,GitLabAt,GiteaAt): its methods mirror the client 1:1, only dropping the leadingdirparameter (git.At(dir).Status()isgit.Status(dir)). The tables below list each method once, on the unbound client — the bound view is not a separate row. -
Not modeled sections per wrapper list commands consciously left untyped — reachable
only through that wrapper's
Run/RunRawescape hatch. Each wrapper's CLI has far more surface than any table below or its "not modeled" list enumerates in full (git alone ships well over a hundred subcommands); the lists name the ones a consumer is most likely to look for. Anything not in a table above it is, by definition, unmodeled — go to the escape hatch. -
A method already reachable through a facade (
VcsToolkit.Core'sRepo,VcsToolkit.Forge'sForge) is not repeated here — this index is the wrapper-level wiring the facades dispatch to; see Facade escape-hatch routers for how a facade caller drops back to the wrapper level.
git (VcsToolkit.Git — the git binary)
Client: Git / GitAt (src/VcsToolkit.Git/Git.fs). See
architecture.md (the "VcsToolkit.Git / VcsToolkit.Jj" section)
for this client's place in the layering.
Status, log, branches, revisions
Method |
Runs |
Notes |
|---|---|---|
|
|
parsed |
|
|
raw text |
|
|
tracked-only dirtiness |
|
|
combined branch + WT snapshot; |
|
|
repo-relative, NUL-safe paths |
|
|
|
|
|
current one flagged |
|
|
|
|
|
scoped to paths; non-empty required; chunks across several within-budget calls above |
|
|
full hash |
|
|
abbreviated hash |
|
|
peels annotated tags |
|
|
fresh repo, no commits |
|
|
stable across worktrees |
|
|
this worktree's git dir |
|
|
|
|
|
|
|
|
|
|
|
fully-qualified ref |
|
|
|
|
|
parsed |
|
|
|
|
|
no fetch |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
C-locale so the English-keyed parser survives a non-English git |
|
|
|
|
|
this repo's actual empty-tree id (SHA-1 or SHA-256) |
|
|
tracked files only |
|
probes |
no subcommand |
|
probes the |
no subcommand |
|
probes the |
no subcommand |
|
probes the |
fresh cancellation budget for cleanup paths |
|
probes the |
no subcommand |
|
probes the |
no subcommand |
|
probes the |
no subcommand |
Staging & committing
Method |
Runs |
Notes |
|---|---|---|
|
|
large sets go via |
|
|
staged index |
|
|
via |
|
|
full message |
|
|
Checkout, worktrees, tags, clone, config, show
Method |
Runs |
Notes |
|---|---|---|
|
|
trailing |
|
|
|
|
|
no switch |
|
|
|
|
|
via |
|
|
|
|
|
|
|
|
|
|
|
via |
|
|
lightweight |
|
|
via |
|
|
|
|
|
|
|
|
UTF-8-decoded, lossy on non-UTF-8 content |
|
|
verbatim bytes — byte-exact for non-UTF-8 content |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Diff
Method |
Runs |
Notes |
|---|---|---|
|
layered on |
parsed |
|
|
untrimmed; |
Fetch, push, merge, rebase, sequencer, stash
Method |
Runs |
Notes |
|---|---|---|
|
|
prompt-off, retried 3× on transient failure |
|
|
same retry |
|
|
same retry |
|
|
via |
|
|
|
|
|
via |
|
|
via |
|
|
|
|
|
fresh cancellation budget, for cleanup paths |
|
|
editor suppressed |
|
|
squash-safe undo |
|
|
destructive |
|
|
editor suppressed; not |
|
|
|
|
|
editor suppressed |
|
|
mainly the apply-backend's "nothing to commit" stop |
|
|
restores the pre- |
|
|
conflict detected via |
|
|
|
|
|
editor suppressed; can stop again on the next commit's conflict |
|
|
|
|
|
|
|
|
editor suppressed |
|
|
ends a bisect session; no |
|
|
|
|
|
|
|
|
parsed |
|
|
applies without dropping; index resolved at operation time |
|
|
drops without applying; index resolved at operation time |
|
composed: |
data-loss-safe: brackets the push with a stash-depth check so a bare pop never grabs an unrelated entry |
|
|
via |
Submodules
Method |
Runs |
Notes |
|---|---|---|
|
|
parsed |
|
|
parsed |
|
|
via |
Discovery & raw escape hatches
Method |
Runs |
Notes |
|---|---|---|
|
|
|
|
|
|
|
|
|
|
like |
git — not modeled (examples) → escape hatch
add -p/interactive staging, am/apply (patch application other than the in-progress-am
probes above), archive, bundle, describe, difftool/mergetool, fsck, gc, grep,
ls-files/ls-tree, merge-base, mv/rm (path staging goes through Add), notes,
rebase --onto (a three-way rebase onto an explicit upstream — only the plain rebase <onto>
form is typed), reflog, replace, reset (soft/mixed — only --hard/--merge are typed),
send-email, shortlog, sparse-checkout, submodule (only list/status/update are
typed, as SubmoduleList/SubmoduleStatus/SubmoduleUpdate above — add/deinit/foreach/
sync/set-branch/set-url/absorbgitdirs go through the escape hatch), subtree,
verify-commit/verify-tag. Reach any of these through Run/RunRaw.
jj (VcsToolkit.Jj — the jj binary)
Client: Jj / JjAt (src/VcsToolkit.Jj/Jj.fs). See
architecture.md (the "VcsToolkit.Git / VcsToolkit.Jj" section)
for this client's place in the layering. Every bookmark/remote name a caller supplies is
matched with jj's exact: string-pattern prefix (never a bare name), so a */?/[] in a
caller-supplied name can't fan a mutation out across every matching ref.
Configuration, status, log, describe, bookmarks
Method |
Runs |
Notes |
|---|---|---|
|
|
|
|
|
key guarded; flag-like values are accepted |
|
|
resolves the workspace root first; snapshots the WC |
|
|
|
|
|
up to |
|
|
non-empty filesets required |
|
|
|
|
|
local bookmark on |
|
|
|
|
|
on |
|
|
arbitrary revision |
|
|
on top of the WC |
|
|
undescribed child; unlike |
|
|
snapshots the WC first |
|
|
local + remote-tracking |
|
|
local bookmarks nearest to |
|
|
remote also rejected if it contains a glob metacharacter |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
does not mark the bookmark for remote deletion |
|
|
remote glob-like, empty, and |
|
|
Diff, query, conflicts, files
Method |
Runs |
Notes |
|---|---|---|
|
layered on |
parsed |
|
|
verbatim; working-copy form is reachable as |
|
|
per-file, resolves the workspace root first |
|
|
|
|
|
one id per line |
|
|
|
|
|
|
|
|
lossless paths; empty output on no conflicts (never errors) |
|
|
untrimmed raw stdout |
|
|
newest commit of a multi-commit revset |
|
|
newest predecessor first |
|
|
plain path, not a fileset |
|
|
UTF-8-decoded, lossy on non-UTF-8 content |
|
|
verbatim bytes |
Rebase, squash/split, merging, sparse
Method |
Runs |
Notes |
|---|---|---|
|
|
whole descendant closure — not git's |
|
|
explicit branch |
|
|
moves the WC |
|
|
|
|
|
non-empty filesets required |
|
|
via |
|
|
non-empty filesets required (else opens jj's interactive editor) |
|
|
empty filesets absorbs everything |
|
|
empty list clears the WC |
|
|
multiple parents |
|
|
|
|
|
|
|
|
new reversing commit on |
Git integration, workspaces, operation log
Method |
Runs |
Notes |
|---|---|---|
|
|
retried 3× |
|
|
same retry |
|
|
same retry |
|
|
|
|
|
colocated-repo sync |
|
|
dirless, absolute |
|
|
parsed |
|
|
mutates jj's remote configuration |
|
|
mutates jj's remote configuration |
|
|
mutates jj's remote configuration |
|
|
mutates jj's remote configuration |
|
|
capture before a risky sequence |
|
|
newest first |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
via |
|
|
|
|
fan-out of |
bounded to 8 concurrent calls |
|
|
shared rollback protocol behind |
|
|
op-log-rollback scope around a mutation sequence |
Discovery & raw escape hatches
Method |
Runs |
Notes |
|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
like |
jj — not modeled (examples) → escape hatch
config list/config edit, debug, file chmod/file track/file untrack, fix,
git init, interdiff, next/prev, parallelize, resolve (interactive; only the
non-interactive listing is typed, as ResolveList), simplify-parents, util. Reach any of
these through Run/RunRaw — note the doc comment's warning that Run/RunRaw are
unguarded: jj's --config/--config-toml and user-defined aliases can reach code
execution, so never forward untrusted argv there.
gh (VcsToolkit.GitHub — the GitHub CLI)
Client: GitHub / GitHubAt (src/VcsToolkit.GitHub/GitHub.fs). See
architecture.md (the "VcsToolkit.GitHub / VcsToolkit.GitLab / VcsToolkit.Gitea" section).
Method |
Runs |
Notes |
|---|---|---|
|
|
exit code only; unscoped across hosts |
|
|
scoped to a |
|
|
|
|
|
raw REST/GraphQL body; flag-guarded endpoint |
|
|
via |
|
|
any state; the 2-arg overload omits |
|
|
|
|
|
via |
|
|
via |
|
|
|
|
|
|
|
|
mutates the working copy |
|
|
branches on |
|
|
via |
|
|
returns the comment URL |
|
|
via |
|
|
|
|
|
parsed |
|
|
via |
|
|
|
|
|
returns the issue URL |
|
|
|
|
|
|
|
|
returns the comment URL |
|
|
Actions runs, newest first |
|
|
id is |
|
|
blocks until the run finishes; stdout capture bounded to the last 256 lines/256 KiB |
|
|
via |
|
|
via |
|
|
|
|
|
|
|
|
|
|
|
via |
|
|
confirmation is always supplied |
|
|
|
|
|
|
|
|
|
|
like |
gh — not modeled (examples) → escape hatch
browse, cache, codespace, extension, gist, label, org, project, pr lock/
reopen/status, repo clone/create/fork/edit/sync/list, ruleset, search,
secret, ssh-key, variable, workflow (list/view/enable/disable — workflow run
is modeled as WorkflowDispatch). Reach any of these through Run/RunRaw, or Api for a
raw REST/GraphQL call.
glab (VcsToolkit.GitLab — the GitLab CLI)
Client: GitLab / GitLabAt (src/VcsToolkit.GitLab/GitLab.fs). The surface is
deliberately lean — auth, project view, and the MR lifecycle — mirroring GitHub's shape,
not its breadth. See
architecture.md (the "VcsToolkit.GitHub / VcsToolkit.GitLab / VcsToolkit.Gitea" section).
Method |
Runs |
Notes |
|---|---|---|
|
|
exit code only; glab#911 can make this a false positive — see the source doc comment |
|
|
|
|
|
raw REST/GraphQL body; flag-guarded endpoint |
|
|
via |
|
|
any state |
|
|
|
|
|
via |
|
|
via |
|
|
|
|
|
|
|
|
mutates the working copy |
|
|
body rejected if exactly |
|
|
via |
|
|
records the current user's approval |
|
|
withdraws an approval |
|
|
bucketed |
|
|
parsed |
|
|
via |
|
|
|
|
|
body rejected if exactly |
|
|
|
|
|
|
|
|
body rejected if exactly |
|
|
≤100 |
|
|
|
|
|
via |
|
|
confirmation is always supplied |
|
|
|
|
|
|
|
|
|
|
like |
glab — not modeled (examples) → escape hatch
alias, ci (status/view/trace/run/lint), incident, label, mr rebase/
subscribe/todo, release upload, repo archive/clone/create/fork/mirror/
transfer, schedule, snippet, ssh-key, token, user, variable, webhook. Reach any
of these through Run/RunRaw, or Api for a raw REST/GraphQL call.
tea (VcsToolkit.Gitea — the Gitea/Forgejo CLI)
Client: Gitea / GiteaAt (src/VcsToolkit.Gitea/Gitea.fs). The narrowest of the three
forge wrappers — tea itself has no single-PR view, no current-repo view, no draft toggle
(so no PrMarkReady), no PR-checks command, no single-release view, and no api escape
hatch; authentication is ambient only (tea login add, out of band — there is no
WithToken/WithEnvToken on this client). See
architecture.md (the "VcsToolkit.GitHub / VcsToolkit.GitLab / VcsToolkit.Gitea" section).
Method |
Runs |
Notes |
|---|---|---|
|
|
|
|
|
via |
|
|
synthesized — |
|
|
via |
|
|
via |
|
|
|
|
|
mutates the working copy |
|
|
comment is a bare positional when present |
|
|
Gitea's request-changes review; reason required |
|
|
shared with issues |
|
(none — refused before spawning) |
|
|
|
via |
|
|
synthesized — |
|
|
returns tea's text output (URL on the final line) |
|
|
|
|
(none — refused before spawning) |
|
|
|
shared with PRs |
|
|
≤~50 (Gitea server page cap); same |
|
|
via |
|
(none — refused before spawning) |
|
|
|
|
|
|
|
|
|
|
|
like |
There is intentionally no RepoView, PrMarkReady, PrChecks, ReleaseView, IssueReopen, or
ReleaseDelete command implementation on Gitea — tea has no equivalent command; the VcsToolkit.Forge
facade reports these Unsupported for the Gitea backend.
tea — not modeled (examples) → escape hatch
admin, issues labels, label, login add/edit/delete (only login list, internally,
via AuthStatus), milestone, notification, organization, releases assets, repos
create/list/delete, times, whoami. Reach any of these through Run/RunRaw — e.g.
flipping a Gitea draft (a WIP: title prefix) via pr edit at the REST-API level, since tea
has no pr edit at all.
Facade escape-hatch routers
VcsToolkit.Core's Repo and VcsToolkit.Forge's Forge cover only the portable
intersection across backends/forges; both expose an escape hatch back to the wrapper level
so dropping to a wrapper-level method (any row above) never needs an extra dependency:
-
*
VcsToolkit.Core* (src/VcsToolkit.Core/Repo.fs) —Repo.Git/Repo.Jj(Someonly for the handle's own backend; the raw client, stilldir-taking) andRepo.GitAt/Repo.JjAt(the view bound to this handle'sCwd— re-anchor withrepo.At(path)first to reach another directory). Its portableRepo.Diff()/Repo.DiffText()wrap the typed working-copy form ofGit.Diff/Git.DiffTextorJj.Diff/Jj.DiffText, andRepo.Remotes()wraps eitherGit.RemotesorJj.GitRemoteListinto a facade-owned name/URL DTO. Its portableRepo.Clone/CloneWith(the one associated constructor, since there is no handle yet) wrap eitherGit.CloneRepoorJj.GitCloneunder a unifiedCloneOptions(CloneKind.Git/JjColocated/JjNonColocated). -
*
VcsToolkit.Forge* (src/VcsToolkit.Forge/Forge.fs) —Forge.GitHubClient/Forge.GitLabClient/Forge.GiteaClient(Someonly for the handle's own backend), or the wrapper client's ownApi/Runfor anything beyond that.
A facade operation marked Unsupported on a given backend (e.g. a Gitea release-by-tag view)
has no wrapper method to drop to either — the CLI itself can't do it; go through the
forge's REST API (Api) or your own HTTP client, as the forge table above notes.
Keeping this index current
A new typed method changes what a row in this index should say. When adding one to a
wrapper's client type, add or update the row in the matching table above — and drop it from
that wrapper's "not modeled" list if it was mentioned there. scripts/check-command-index.ps1
(wired into CI, see .github/workflows/ci.yml) compares each wrapper's approved public API
surface (tests/VcsToolkit.PublicApi.Tests/ApprovedApi/*.approved.txt) against this file's
wrapper-specific method rows in both directions, so it fails the build if a public method is
missing a row or if a row names a method absent from that wrapper's approved API surface.
See also
- Architecture — the package layering, cross-cutting design principles, and the escape hatches this index cross-references.
- Examples cookbook — worked usage of the typed methods this index indexes.
- MCP server guide — the agent-facing tool surface built on
Repo/Forge.
VcsToolkit