Skip to content

Commands

hop v0.2.6 · captured 2026-08-31

-h/--help work on every command; -v/--version at the tool root.

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.

usage
  • hop [flags]
  • hop [command]
flags
flagtypedescriptioncopy
--allselect every cloned repo from hop.yaml (plural selection — use with pull/push/sync)
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.

usage
  • hop add <dir> [flags]
flags
flagtypedescriptioncopy
--depthintmaximum DFS depth (only meaningful with -r; root counts as depth 0; must be >= 1) (default 3)
-g, --groupstringforce all discovered repos into the named group, auto-creating it if absent
-p, --printrender the merge plan to stdout instead of writing to hop.yaml (a dry-run)
-r, --recursivewalk <dir> for git repos (DFS) instead of classifying just <dir>
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
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
usage
  • hop clone [<name> | <url> | --all] [flags]
flags
flagtypedescriptioncopy
--allclone every repo from hop.yaml that isn't already on disk
--groupstringtarget group for ad-hoc URL clone (only used with <url>) (default "default")
--namestringoverride the URL-derived name for the on-disk path (only used with <url>)
--no-addskip the hop.yaml write-back (only used with <url>)
--no-cdsuppress the printed path so the shell shim does not cd (only used with <url>)
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)
usage
  • hop config
  • hop 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
usage
  • hop config init
show raw -h output
Usage:
  hop config init
hop config printprint the resolved hop.yaml contents to stdout
usage
  • hop config print
show raw -h output
Usage:
  hop config print
hop config whereprint the resolved hop.yaml path (regardless of file existence)
usage
  • hop config where
show raw -h output
Usage:
  hop config where
hop lslist all repos as aligned name/path columns
usage
  • hop ls [flags]
flags
flagtypedescriptioncopy
--jsonemit machine-readable JSON (composes with --trees)
--treeswt list --jsonlist worktrees per repo via wt list --json
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.

usage
  • hop rm [<name>] [flags]
flags
flagtypedescriptioncopy
--dry-runpreview the removal without writing hop.yaml
--stalelimit the picker to repos whose resolved path no longer exists on disk
-y, --yesskip the confirmation prompt on 'hop rm <name>' (consent for automation)
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
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)
usage
  • 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.

usage
  • 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
usage
  • hop update [flags]
flags
flagtypedescriptioncopy
--skip-brew-updatebrew updateskip the internal brew update tap-metadata refresh (the version check and upgrade still run)
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)