smith, a CLI client for Forgejo
... akin to gh, glab, or tea!
smith is a fork of forgejo-cli
(fj) — see NOTICE for upstream attribution. It carries the FDR-0016
vanity-remote discovery patches, a serve-cutting_garden subcommand exposing
cutting-garden node RPC over Forgejo, and the eng repository conventions.
You can...
- Open, edit, comment on, close issues
- Create and merge pull requests
- Easily create AGit pull requests, no need to fork!
- Create, star, watch, and edit repositories
- Manage organizations and teams
- Publish new releases
- Serve a cutting-garden RFC 0013 traversal plugin (
smith serve-cutting_garden)
all from the command line! Upstream's wiki
documents the common commands, which smith keeps compatible.
Issues as a cutting-garden organize document
smith serve-cutting_garden exposes a Forgejo repository's issues as a
cutting-garden tree, and declares them WRITABLE — so cg organize can edit a
repo's issues as a text document and apply the result. An issue renders as
- [140 area-organize bug milestone=v0.3] Fix the parser
where the tag atoms are its labels, milestone= is an inline field, and the
trailer is its title. Editing any of them writes back: moving a line between
## =v0.4 headings reassigns the milestone, adding or removing a tag atom
replaces the label set, retitling renames the issue, and the open/closed state
is a bucket like any other.
A label or milestone you name that the repo does not have yet is created
rather than refused — the label with a color derived from its hyphen namespace
(so area-* share a hue), the milestone open with no due date. Deleting the
last atom of a milestone= clears it; nothing here ever closes or renames a
milestone, and assignees and Forgejo's scoped/exclusive labels are not modeled.
New issues can be written straight into the document. A box whose id starts
with + is created on apply:
- [+wrap-bug bug milestone=v0.3] Wrapped boxes lose their description
The title is the only thing it needs; the tags, milestone and heading it sits under become the new issue's labels, milestone and state.
See man smith-cutting_garden for the full reference.
Manual pages
smith ships man pages alongside the binary:
smith(1)— what this fork adds: the global flags,serve-cutting_garden,api, vanity remote discovery, and build identitysmith-cutting_garden(7)— the cutting-garden traversal plugin: the tree it serves, the organize surface, and what it deliberately declinessmith-keystore(5)—keys.json: where it lives and what goes in itsmith-multi-forge(7)— how a host picks a backend, and what works on GitHub
smith(1) deliberately covers only the fork's own surface; for the commands
inherited from upstream fj, use smith <command> --help and upstream's
wiki.
smith doesn't try to replace your usage of git, it's meant to work alongside it.
It handles all the Forgejo-specific things that git doesn't.
GitHub support (v1)
smith also speaks GitHub for a slice of commands. This is a vertical slice,
not full parity — see the limitations below so nothing surprises you.
What works against GitHub:
smith issue search— labels, state,--creator,--assignee, and a free-text query (served by GitHub's search API)smith issue view— body,comments, andcomment <idx>smith issue createsmith issue commentsmith issue closesmith pr search— same filters asissue search; defaults to open PRssmith pr view— body,comments,comment <idx>, andlabelssmith pr status— mergeability plus every check on the head commit (commit statuses and GitHub Actions check runs), with--waitsmith pr commentsmith repo viewsmith api— raw REST passthrough, now targetingapi.github.comforgithub.com(Bearer auth + GitHub headers). Forgejo behavior is unchanged.
Everything else (the other PR subcommands such as create/merge/checkout/diff, wiki, actions, releases, tags, user, org, and the other issue/repo subcommands) is still Forgejo-only. Against github.com those commands stop with a "not yet supported on GitHub" error that lists what does work.
Routing. The backend is chosen from the resolved host: github.com /
api.github.com go to the GitHub backend; everything else goes to Forgejo (the
default). Override with the global --backend forgejo|github flag. GitHub
Enterprise / self-hosted hosts are not auto-detected in v1 — use --backend github for them; per-host config is future work.
Auth. Store a GitHub personal access token like any other host credential:
cd /tmp && smith --host github.com auth add-key <github-login> # reads the token on stdin
The token needs the repo scope (classic PAT), or Issues + Pull requests
read/write for a fine-grained PAT. Run it from outside a git repo: auth commands
still resolve the current directory's remote first (#32).
With no token, GitHub access is anonymous — public repos only, heavily
rate-limited, and smith prints a one-line stderr warning when it goes to
GitHub unauthenticated.
v1 limitations (user-facing):
smith issue create --label Xapplies label names against GitHub (GitHub accepts names), but does nothing against a Forgejo repo in v1 — Forgejo's create API takes label IDs and name→ID resolution isn't wired yet, so label-on-create is GitHub-only for now.smith repo viewon the GitHub path shows less than the old Forgejo view: it keeps owner/name, description, archived/private markers, primary language, topics, and the URL, but drops the fork-parent name, star/watch/fork counts, the "(approx.)" open-issue/PR/release counts line, the external issue-tracker URL, and the archived-since date. Richer fields return in v2.smith issue view <N>on a GitHub pull request declines to show it rather than redirecting — usesmith pr view <N>instead.- GitHub PR commands need an explicit number (
owner/repo#N); guessing the PR from the current branch is Forgejo-only. smith apiaccepts a query string right in the endpoint, e.g.smith api "repos/OWNER/REPO/issues?state=open".
Installation
Build from source with just build, or cargo build --release for the smith
binary. Releases are published on the fork's forge at
code.linenisgreat.com/smith.
Licensing
This project is licensed under either Apache License Version 2.0 or MIT License at your option.
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.