Commands
hoplocate, open, and operate on repos from hop.yaml.
hop — locate, open, and operate on repos from hop.yaml. Grammar: hop <selection> [action] <selection> a repo name (substring; fzf on ambiguity), a <name>/<wt> worktree, a group name, or --all (every cloned repo) [action] builtin verb (cd, where, open), batch verb (pull, push, sync), or any PATH tool / shell alias (git pull, code ., p). Omitted: cd into the selection. Getting started: 1. Wire the shell shim: shll shell-setup 2. Build the config: hop add -r ~/code Examples: hop fzf picker, print the selection hop <name> cd into the repo (needs the shell shim) hop <name>/<wt> same, rooted at worktree <wt> hop <name> where print the repo's absolute path hop <name> open open the repo in an app (wt's menu) hop <name> code . run any PATH tool in the repo dir hop <name> sync auto-commit, git pull --rebase, git push hop <group> pull batch verb across a group's cloned repos hop --all sync batch verb across every cloned repo Management subcommands (clone, ls, add, rm, config, ...) are listed below — see `hop <command> -h` for each. Notes: - cd and tool-form run in your parent shell via the shim (shll shell-setup, or eval "$(hop shell-init zsh)"). Without it, use cd "$(hop <name> where)". - A group or --all accepts only pull/push/sync; cd, open, where, and arbitrary tools are single-repo. - Ambiguous or no-match queries open fzf prefilled with your query. - Config lives at ~/.config/hop/hop.yaml.
hop [flags]hop [command]
| flag | type | description | copy |
|---|---|---|---|
--all | select every cloned repo from hop.yaml (plural selection — use with pull/push/sync) |
No flags match that filter.
show raw -h output
hop — locate, open, and operate on repos from hop.yaml.
Grammar: hop <selection> [action]
<selection> a repo name (substring; fzf on ambiguity), a <name>/<wt>
worktree, a group name, or --all (every cloned repo)
[action] builtin verb (cd, where, open), batch verb (pull, push,
sync), or any PATH tool / shell alias (git pull, code ., p).
Omitted: cd into the selection.
Getting started:
1. Wire the shell shim: shll shell-setup
2. Build the config: hop add -r ~/code
Examples:
hop fzf picker, print the selection
hop <name> cd into the repo (needs the shell shim)
hop <name>/<wt> same, rooted at worktree <wt>
hop <name> where print the repo's absolute path
hop <name> open open the repo in an app (wt's menu)
hop <name> code . run any PATH tool in the repo dir
hop <name> sync auto-commit, git pull --rebase, git push
hop <group> pull batch verb across a group's cloned repos
hop --all sync batch verb across every cloned repo
Management subcommands (clone, ls, add, rm, config, ...) are listed
below — see `hop <command> -h` for each.
Notes:
- cd and tool-form run in your parent shell via the shim (shll shell-setup,
or eval "$(hop shell-init zsh)"). Without it, use cd "$(hop <name> where)".
- A group or --all accepts only pull/push/sync; cd, open, where, and
arbitrary tools are single-repo.
- Ambiguous or no-match queries open fzf prefilled with your query.
- Config lives at ~/.config/hop/hop.yaml.
Usage:
hop [flags]
hop [command]
Available Commands:
add register on-disk repos into hop.yaml (single dir, or -r to walk a tree)
clone git clone the resolved repo, an ad-hoc URL, or all missing repos with --all
completion Generate the autocompletion script for the specified shell
config config helpers (init, where, print)
help Help about any command
ls list all repos as aligned name/path columns
rm remove a registered repo from hop.yaml
shell-init emit shell integration (zsh or bash)
skill print hop's agent skill bundle (usage briefing) to stdout
update self-update the hop binary via Homebrew
Flags:
--all select every cloned repo from hop.yaml (plural selection — use with pull/push/sync)
Use "hop [command] --help" for more information about a command.
hop addregister on-disk repos into hop.yaml (single dir, or -r to walk a tree)
Register on-disk repos into hop.yaml. By default, classifies just <dir> and — when it is a normal git repo with a remote — merges its URL into hop.yaml using the group convention (convention layout → the 'default' group; otherwise an invented group keyed off the parent dir basename). add writes by default. With -r/--recursive, walks <dir> for git repos (DFS, depth-bounded via --depth, symlink-following) and registers every one it finds. With -p/--print, renders the merge plan to stdout instead of writing (a dry-run, valid at both breadths). With -g/--group <name>, forces all discovered repos into the named group, auto-creating it if absent. A non-git directory is a no-op (a clear message, exit 0), not an error.
hop add <dir> [flags]
| flag | type | description | copy |
|---|---|---|---|
--depth | int | maximum DFS depth (only meaningful with -r; root counts as depth 0; must be >= 1) (default 3) | |
-g, --group | string | force all discovered repos into the named group, auto-creating it if absent | |
-p, --print | render the merge plan to stdout instead of writing to hop.yaml (a dry-run) | ||
-r, --recursive | walk <dir> for git repos (DFS) instead of classifying just <dir> |
No flags match that filter.
hop add ~/code/acme/widget register one existing repo into hop.yaml hop add -r ~/code walk ~/code and register every repo found hop add -r -p ~/code preview the recursive plan without writing hop add -g vendor ~/forks/x register into a forced (auto-created) group
show raw -h output
Register on-disk repos into hop.yaml.
By default, classifies just <dir> and — when it is a normal git repo with a
remote — merges its URL into hop.yaml using the group convention (convention
layout → the 'default' group; otherwise an invented group keyed off the parent
dir basename). add writes by default.
With -r/--recursive, walks <dir> for git repos (DFS, depth-bounded via --depth,
symlink-following) and registers every one it finds. With -p/--print, renders
the merge plan to stdout instead of writing (a dry-run, valid at both breadths).
With -g/--group <name>, forces all discovered repos into the named group,
auto-creating it if absent.
A non-git directory is a no-op (a clear message, exit 0), not an error.
Examples:
hop add ~/code/acme/widget register one existing repo into hop.yaml
hop add -r ~/code walk ~/code and register every repo found
hop add -r -p ~/code preview the recursive plan without writing
hop add -g vendor ~/forks/x register into a forced (auto-created) group
Usage:
hop add <dir> [flags]
Flags:
--depth int maximum DFS depth (only meaningful with -r; root counts as depth 0; must be >= 1) (default 3)
-g, --group string force all discovered repos into the named group, auto-creating it if absent
-p, --print render the merge plan to stdout instead of writing to hop.yaml (a dry-run)
-r, --recursive walk <dir> for git repos (DFS) instead of classifying just <dir>
hop clonegit clone the resolved repo, an ad-hoc URL, or all missing repos with --all
hop clone [<name> | <url> | --all] [flags]
| flag | type | description | copy |
|---|---|---|---|
--all | clone every repo from hop.yaml that isn't already on disk | ||
--group | string | target group for ad-hoc URL clone (only used with <url>) (default "default") | |
--name | string | override the URL-derived name for the on-disk path (only used with <url>) | |
--no-add | skip the hop.yaml write-back (only used with <url>) | ||
--no-cd | suppress the printed path so the shell shim does not cd (only used with <url>) |
No flags match that filter.
show raw -h output
Usage:
hop clone [<name> | <url> | --all] [flags]
Flags:
--all clone every repo from hop.yaml that isn't already on disk
--group string target group for ad-hoc URL clone (only used with <url>) (default "default")
--name string override the URL-derived name for the on-disk path (only used with <url>)
--no-add skip the hop.yaml write-back (only used with <url>)
--no-cd suppress the printed path so the shell shim does not cd (only used with <url>)
hop configconfig helpers (init, where, print)
hop confighop config [command]
show raw -h output
Usage: hop config hop config [command] Available Commands: init bootstrap a starter hop.yaml at the resolved write target print print the resolved hop.yaml contents to stdout where print the resolved hop.yaml path (regardless of file existence) Use "hop config [command] --help" for more information about a command.
hop config initbootstrap a starter hop.yaml at the resolved write target
hop config init
show raw -h output
Usage: hop config init
hop config printprint the resolved hop.yaml contents to stdout
hop config print
show raw -h output
Usage: hop config print
hop config whereprint the resolved hop.yaml path (regardless of file existence)
hop config where
show raw -h output
Usage: hop config where
hop lslist all repos as aligned name/path columns
hop ls [flags]
| flag | type | description | copy |
|---|---|---|---|
--json | emit machine-readable JSON (composes with --trees) | ||
--treeswt list --json | list worktrees per repo via wt list --json |
No flags match that filter.
show raw -h output
Usage:
hop ls [flags]
Flags:
--json emit machine-readable JSON (composes with --trees)
--trees wt list --json list worktrees per repo via wt list --json
hop rmremove a registered repo from hop.yaml
Remove a registered repo from hop.yaml. With no argument, pipes the registered repos through fzf and removes the selected entry's URL from its group. With a <name>, resolves it via the same match-or-fzf algorithm used by 'hop <name> where' and removes that entry directly — naming a repo prunes it even if its folder is already gone. Removal always targets a whole repo entry; any '/<worktree>' suffix on <name> is ignored (worktrees are not registry entries). Because 'hop rm <name>' writes the registry, it asks for consent first. On a terminal it shows the resolved match and prompts 'Proceed? [y/N]' (default No); answer y/yes to remove, anything else aborts with no change. Pass --yes/-y to skip the prompt (for scripts and agents). With no terminal and no --yes, the removal is refused (exit 3) rather than run unattended — re-run with --yes, or preview with --dry-run. The interactive picker (no <name>) needs no prompt: the pick itself is the consent. Removing a group's last URL leaves the (now-empty) group as a placeholder, so it stays a valid 'hop clone --group' target. With --stale, the picker is pre-filtered to repos whose resolved path no longer exists on disk — the quick way to prune entries for repos you have deleted. --stale is a picker-scoping flag and cannot be combined with a <name>. With --dry-run, the target is resolved through the same path as a live removal but nothing is written — hop reports which entry it would remove and exits 0, leaving hop.yaml untouched. --dry-run needs no consent (it writes nothing), so it is never prompted or refused.
hop rm [<name>] [flags]
| flag | type | description | copy |
|---|---|---|---|
--dry-run | preview the removal without writing hop.yaml | ||
--stale | limit the picker to repos whose resolved path no longer exists on disk | ||
-y, --yes | skip the confirmation prompt on 'hop rm <name>' (consent for automation) |
No flags match that filter.
hop rm pick any registered repo to remove hop rm widget remove the repo matching 'widget' (prompts on a terminal) hop rm widget --yes remove without the confirmation prompt hop rm --stale pick among only the repos missing from disk hop rm widget --dry-run preview the removal without writing hop.yaml
show raw -h output
Remove a registered repo from hop.yaml.
With no argument, pipes the registered repos through fzf and removes the
selected entry's URL from its group. With a <name>, resolves it via the same
match-or-fzf algorithm used by 'hop <name> where' and removes that entry
directly — naming a repo prunes it even if its folder is already gone. Removal
always targets a whole repo entry; any '/<worktree>' suffix on <name> is
ignored (worktrees are not registry entries).
Because 'hop rm <name>' writes the registry, it asks for consent first. On a
terminal it shows the resolved match and prompts 'Proceed? [y/N]' (default No);
answer y/yes to remove, anything else aborts with no change. Pass --yes/-y to
skip the prompt (for scripts and agents). With no terminal and no --yes, the
removal is refused (exit 3) rather than run unattended — re-run with --yes, or
preview with --dry-run. The interactive picker (no <name>) needs no prompt: the
pick itself is the consent.
Removing a group's last URL leaves the (now-empty) group as a placeholder, so
it stays a valid 'hop clone --group' target.
With --stale, the picker is pre-filtered to repos whose resolved path no longer
exists on disk — the quick way to prune entries for repos you have deleted.
--stale is a picker-scoping flag and cannot be combined with a <name>.
With --dry-run, the target is resolved through the same path as a live removal
but nothing is written — hop reports which entry it would remove and exits 0,
leaving hop.yaml untouched. --dry-run needs no consent (it writes nothing), so
it is never prompted or refused.
Examples:
hop rm pick any registered repo to remove
hop rm widget remove the repo matching 'widget' (prompts on a terminal)
hop rm widget --yes remove without the confirmation prompt
hop rm --stale pick among only the repos missing from disk
hop rm widget --dry-run preview the removal without writing hop.yaml
Usage:
hop rm [<name>] [flags]
Flags:
--dry-run preview the removal without writing hop.yaml
--stale limit the picker to repos whose resolved path no longer exists on disk
-y, --yes skip the confirmation prompt on 'hop rm <name>' (consent for automation)
hop shell-initemit shell integration (zsh or bash)
hop shell-init <shell>
show raw -h output
Usage: hop shell-init <shell>
hop skillprint hop's agent skill bundle (usage briefing) to stdout
Print hop's agent skill bundle — a stable, one-page usage briefing for an agent driving an installed hop, byte-identical to the repo's canonical docs/site/skill.md (also rendered at https://shll.ai/hop/skill). The bundle is raw markdown written verbatim to stdout: no rendering, no pager, no added framing (stdout is data). It is embedded in the binary at build time, so it is offline and version-locked to this release.
hop skill
show raw -h output
Print hop's agent skill bundle — a stable, one-page usage briefing for an agent driving an installed hop, byte-identical to the repo's canonical docs/site/skill.md (also rendered at https://shll.ai/hop/skill). The bundle is raw markdown written verbatim to stdout: no rendering, no pager, no added framing (stdout is data). It is embedded in the binary at build time, so it is offline and version-locked to this release. Usage: hop skill
hop updateself-update the hop binary via Homebrew
hop update [flags]
| flag | type | description | copy |
|---|---|---|---|
--skip-brew-updatebrew update | skip the internal brew update tap-metadata refresh (the version check and upgrade still run) |
No flags match that filter.
show raw -h output
Usage:
hop update [flags]
Flags:
--skip-brew-update brew update skip the internal brew update tap-metadata refresh (the version check and upgrade still run)