中文 | English
leo-cli builds a leo binary for personal command-line workflows. It currently covers five practical jobs:
- Index local Git repositories and pick one from an interactive terminal list.
- Generate a shell helper so
repocan jump into the selected repository. - Build SQL
INvalues from clipboard, txt, or csv input and copy the result. - Copy container images with registry aliases through
skopeo copy. - Search and follow configured project logs in a temporary browser workspace.
Download a binary from GitHub Releases. Asset names look like:
leo-v0.0.9-darwin-arm64
leo-v0.0.9-linux-amd64
leo-v0.0.9-windows-amd64.exe
macOS / Linux:
chmod +x leo-v0.0.9-darwin-arm64
mv leo-v0.0.9-darwin-arm64 ~/bin/leoWindows:
ren leo-v0.0.9-windows-amd64.exe leo.exePut the directory containing leo or leo.exe on your PATH.
Or build locally:
make buildThe binary is written to:
bin/leo
Create the repository index:
leo repo reindexOpen the repository picker:
leo repoType to filter. Press Enter to print the selected repository path. Press Esc or Ctrl-C to cancel.
Enable the shell jump helper:
eval "$(leo shell init zsh)"bash:
eval "$(leo shell init bash)"Add the matching eval line to ~/.zshrc or ~/.bashrc, then run:
reporepo opens the picker and runs cd after a repository is selected.
Read from clipboard:
leo joinRead from stdin:
seq 1 10 | leo joinRead from file:
leo join ids.txt
leo join ids.csvIn the interactive picker:
- Left/Right: switch csv columns.
- Up/Down: switch output formats.
- u: toggle unique/original values.
- Enter: copy the current result.
- Esc: cancel.
When no file is provided, piped stdin is used before clipboard. Values are unique by default, preserving first-seen order. Output formats include comma lists, parenthesized lists, field in (...), and quoted lists.
Convert Unix seconds, Unix milliseconds, and common date-time strings:
leo time
leo time 1783512043
leo time 1783512043000
leo time "(2026-07-08 20:00:43)"Without a value, leo time uses the current time.
Date-time strings without an explicit timezone are treated as UTC+8. Use --to to choose the output timezone:
leo time 1783512043 --to +9
leo time "2026-07-08 20:00:43" --to +9
leo time 1783512043 --to Asia/TokyoConfigured time.zones are printed as extra common timezone rows. Values can be UTC offsets or IANA timezone names.
First configure registry aliases:
docker:
registries:
it: source-registry.example.com
t: mirror-registry.example.comList aliases:
leo docker listCopy images:
leo docker copy it/apps/example-service:v1.2.4 t
leo docker copy it/apps/example-service:v1.2.4 t/library/example-service:latest
leo docker copy registry.example.com/app:v1 mirror.example.com/app:v1Print the command without running it:
leo docker copy python:3.12 t --drySelect a platform:
leo docker copy python:3.12-slim t --platform linux/arm64
leo docker copy python:3.12-slim t --platform linux/arm64/v8docker copy calls skopeo. It does not use the local Docker daemon or docker context. The default platform is linux/amd64.
From a project root or any child directory, run:
leo logNo project configuration is required. leo uses the nearest Git root (or the
current directory outside Git), checks common paths such as runtime/logs,
logs, log, var/log, and storage/logs, then performs a bounded search for
directories named log or logs when those paths are absent.
Use one or more explicit directories when logs live elsewhere:
leo log --logs ./custom/logs
leo log --logs ./api/logs --logs ./worker/logsRelative --logs paths are resolved from the directory where the command is
run. For persistent project aliases or custom roots, add configuration:
proj:
demo_01:
logs:
- runtime/logs
- /docker-runtimeConfigured projects take priority when the current directory matches. leo
walks upward, finds the nearest ancestor whose name contains the project key,
and resolves relative log directories from that root. An alias can use a
different match string:
proj:
mc:
match: demo_01
logs:
- runtime/logsUseful overrides:
leo log --project mc
leo log --host 0.0.0.0 --port 9031An explicit --project is strict and cannot be combined with --logs.
The default listener is 127.0.0.1 on an automatically selected port. On a remote server, open the printed URL manually through SSH port forwarding, or explicitly bind to an internal-network address. Plain HTTP on a non-loopback address is only appropriate on a trusted development network.
The workspace discovers supported text logs recursively, streams bounded on-demand searches, and follows active files with rotation/truncation notices. Time presets include the last 1, 5, and 10 minutes as well as longer ranges. Selecting a preset or clicking the current range button searches immediately. Clear keeps all filters, empties the table, and uses the click time as the next search start until a preset is reapplied. New records appear at the top; scrolling down preserves the older records being read while new-record counts accumulate.
Logs are read in place: the viewer does not copy log contents, build a persistent index, or store queries, tokens, sessions, or UI state. Stop the server with Ctrl-C.
Default config path:
~/.config/leo-cli/config.yaml
If the file does not exist, leo creates:
repo:
roots:
- ~/work
time:
zones:
- +9
- +0
- America/Los_AngelesExample:
repo:
roots:
- ~/work
- ~/repo
- $HOME/src
docker:
registries:
it: source-registry.example.com
t: mirror-registry.example.com
time:
zones:
- +9
- +0
- America/Los_Angeles
proj:
demo_01:
logs:
- runtime/logstime.zones controls the extra common timezone rows printed by leo time. It accepts UTC offsets like +9 and IANA names like America/Los_Angeles.
Paths support:
~for the current user's home directory.- Environment variables such as
$HOME. - Relative paths, which are resolved to absolute paths.
Missing or unreadable repository roots are printed as warnings. repo reindex only fails when all configured roots are unusable.
Default data path:
~/.local/share/leo-cli/leo-cli.sqlite3
XDG_CONFIG_HOME and XDG_DATA_HOME override the default config and data locations when set.
The repository index uses SQLite with WAL. Rows are upserted by absolute repository path. Stale repositories that no longer exist on disk are not removed automatically yet.
| Command | Description |
|---|---|
leo --version / leo version |
Print version and commit metadata |
leo repo reindex |
Scan configured repository roots and update the index |
leo repo |
Open the interactive repository picker and print the selected path |
leo shell init zsh |
Print zsh integration |
leo shell init bash |
Print bash integration |
leo join [FILE] |
Build SQL IN values from clipboard, txt, or csv |
leo time [VALUE] |
Convert current time, timestamps, and common time strings |
leo docker list |
Print Docker registry aliases |
leo docker copy SOURCE DESTINATION |
Copy an image with skopeo copy |
leo log |
Open the current project's temporary log workspace |
Run from source:
make devRun tests:
make testBuild:
make buildVersion metadata comes from .env:
version=v0.0.9
Create a tag and bump the patch version:
make releaseUse an explicit version:
make release V=v0.1.0Build cross-platform binaries, push the tag, and publish a GitHub release with GitHub CLI:
make release-github
make release-github V=v0.1.0This requires an installed and authenticated GitHub CLI.
cmd/ Cobra command wiring
internal/config/ YAML config, default paths, path expansion
internal/dockercopy/ Docker image reference and registry alias resolution
internal/logview/ Safe log discovery, parsing, search, and follow
internal/logweb/ Authenticated HTTP APIs and embedded browser workspace
internal/project/ Current-project matching and root resolution
internal/refresh/ Initial index and background metadata refresh
internal/repoindex/ Git repository scanning and metadata extraction
internal/repoui/ Bubble Tea repository picker
internal/shellinit/ Shell integration script generation
internal/store/ SQLite storage and migrations
internal/termio/ Terminal input/output compatibility layer
internal/version/ Build-time version metadata
scripts/ Release helper scripts