# stoke command reference Full options, examples, and API mapping for every command. For install and overview, see the [README](../README.md). Read commands accept **`--json`** to print the raw Forgejo API response (pretty-printed) instead of the human format: `auth status`, `repo list`, `issue list`, `issue show`, `pr list`, `pr show`, `release list`, `release view`, `label list`, `branch list`, `org repos`, `org team list`, `org team member-list`, `user list`, `user show` --- ## Global options ```text -c, --config path to configuration file -h, --help display help -V, --version display version ``` The global `--config` flag must come **before** the subcommand: ```bash stoke --config /path/to/config.json auth status ``` --- ## Auth ### `stoke auth login` Authenticate and persist an access token. ```text Options: -u, --url Forgejo base URL (default: https://forgejo.heavyduty.builders) -n, --username account username or email -p, --password account password --password-file read account password from a file -t, --token use an existing personal access token instead of generating one --token-file read an existing personal access token from a file --token-name name for the generated token --full-scopes grant full read/write access on all non-admin scopes --scopes comma-separated list of scopes for the generated token ``` ```bash stoke auth login # prompts for username and password export STOKE_USERNAME='you' export STOKE_PASSWORD='...' stoke auth login stoke auth login -n you --password-file /run/secrets/stoke-password stoke auth login -t stoke auth login --scopes read:issue,write:issue,read:repository ``` **Flow** 1. `GET /api/v1/user` — verify credentials, resolve canonical `login` 2. `POST /api/v1/users/{login}/tokens` — mint a token (unless `-t` / `--token-file`) 3. Write token, token id, user details, and URL to the config file **Default token scopes** (least privilege for daily issue/PR/repo work): | Scope | Covers | | --- | --- | | `read:issue`, `write:issue` | issues, PR comments/reviews, labels | | `read:repository`, `write:repository` | repos, branches, releases, collaborators, pull requests | | `read:user` | `auth status`, `user list`, `user show` | | `read:organization` | `org repos`, `org team list`, `org team member-list` | Org administration (`org create`, `org avatar`, team create/member mutations) and package publishing need broader access — use `--full-scopes` or `--scopes `. Granted scopes are printed after a successful login. ### `stoke auth logout` Revoke the stored token remotely and delete local config. ```text Options: -p, --password account password (needed for remote revocation) --password-file read account password from a file --local-only skip remote revocation; only delete local config ``` ```bash stoke auth logout stoke auth logout --password-file /run/secrets/pw stoke auth logout --local-only ``` Forgejo only accepts Basic auth on token endpoints — a token cannot revoke itself. Without a password (or with `--local-only`), the token stays active server-side; revoke it in the web UI under Settings → Applications. **Flow:** `DELETE /api/v1/users/{login}/tokens/{id}` (Basic auth), then remove the config file. ### `stoke auth status` ```bash stoke auth status ``` Calls `GET /api/v1/user` with the stored token. --- ## Repos ### `stoke repo clone` Clone from the configured Forgejo instance using stored credentials. ```text Arguments: [directory] destination directory (default: repository name) Options: -o, --owner repository owner (required) -r, --repo repository name (required) --branch checkout this branch instead of the default --depth shallow clone depth --origin remote name (default: origin) ``` ```bash stoke repo clone -o heavy-duty -r stoke stoke repo clone -o heavy-duty -r stoke ~/src/stoke --depth 1 ``` The token is passed to git ephemerally via `GIT_CONFIG_*` — never in the remote URL, argv, or the clone’s `.git/config`. Git stdout/stderr and exit status are forwarded. ### `stoke repo create` ```text Options: --name repository name (required) -d, --description repository description --private make the repository private --public make the repository public --auto-init initialize with a README (default) --no-auto-init empty repository, no README --default-branch default branch (default: main) ``` ```bash stoke repo create --name stoke-test --private -d "Test repository" ``` Calls `POST /api/v1/user/repos`. ### `stoke repo list` ```text Options: -l, --limit max repos to display (default: 50; 0 = all) ``` ```bash stoke repo list ``` Calls `GET /api/v1/user/repos` (auto-paginated). ### `stoke repo import` Import a remote repository (git history, issues, PRs, labels, milestones, releases, wiki). ```text Options: --from source clone URL (required) --name repository name in Forgejo (required) --service git, github, gitea, gitlab, ... (default: github) --owner Forgejo owner (default: current user) -d, --description --private / --public --issues / --no-issues --labels / --no-labels --milestones / --no-milestones --pull-requests / --no-pull-requests --releases / --no-releases --wiki / --no-wiki --lfs --github-token source token (GitHub defaults to GITHUB_TOKEN or `gh auth token`) ``` A source token is only required for `--service github` (rate limits + private repos). Other services send no token unless one is passed explicitly. ```bash stoke repo import \ --from https://github.com/heavy-duty/box.git \ --name box \ --service github \ --public \ --issues --labels --milestones --pull-requests --releases --wiki ``` Calls `POST /api/v1/repos/migrate`. ### `stoke repo import-batch` Import many repos from a JSON manifest. ```text Options: -f, --file path to JSON manifest (required) --dry-run print the manifest without importing ``` Manifest entry shape: ```json [ { "name": "rig", "from": "https://github.com/heavy-duty/rig.git", "service": "github", "private": false, "issues": true, "labels": true, "milestones": true, "pull_requests": true, "releases": true, "wiki": true } ] ``` ```bash stoke repo import-batch -f repos.json stoke repo import-batch -f repos.json --dry-run ``` ### `stoke repo rename` ```text Options: -o, --owner repository owner (required) -r, --repo current name (required) --name new name (required) ``` ```bash stoke repo rename -o heavy-duty -r old-name --name new-name ``` Calls `PATCH /api/v1/repos/{owner}/{repo}`. ### `stoke repo transfer` Transfer to a user or organization. Caller needs admin on the repo and create rights under the new owner (e.g. org owner) for an immediate transfer. ```text Options: -o, --owner current owner (required) -r, --repo repository name (required) --to username or org (required) ``` ```bash stoke repo transfer -o kimi-reviewer-andresmgsl -r box --to heavy-duty ``` Calls `POST /api/v1/repos/{owner}/{repo}/transfer`. --- ## Issues ### `stoke issue list` ```text Options: -o, --owner (required) -r, --repo (required) -s, --state open, closed, all (default: open) -t, --type issues or pulls (default: issues) -l, --limit (default: 50; 0 = all) ``` ```bash stoke issue list -o heavy-duty -r stoke -s all -l 0 ``` Calls `GET /api/v1/repos/{owner}/{repo}/issues` (auto-paginated). ### `stoke issue create` ```text Options: -o, --owner (required) -r, --repo (required) -t, --title (required) -b, --body <body> --body-file <path> --assignee <username...> ``` ```bash stoke issue create -o heavy-duty -r stoke -t "Ship v2" --body-file body.md ``` Calls `POST /api/v1/repos/{owner}/{repo}/issues`. ### `stoke issue show` ```text Options: -o, --owner <owner> (required) -r, --repo <repo> (required) -n, --number <number> (required) --json ``` ```bash stoke issue show -o heavy-duty -r stoke -n 10 ``` Calls `GET /api/v1/repos/{owner}/{repo}/issues/{number}`. ### `stoke issue comment` Body required (whitespace-only rejected). If both `-b` and `--body-file` are set, **`--body-file` wins**. ```text Options: -o, --owner <owner> (required) -r, --repo <repo> (required) -n, --number <number> (required) -b, --body <body> --body-file <path> ``` ```bash stoke issue comment -o heavy-duty -r stoke -n 10 -b "Confirmed." ``` Calls `POST /api/v1/repos/{owner}/{repo}/issues/{number}/comments`. --- ## Pull requests ### `stoke pr list` ```text Options: -o, --owner <owner> (required) -r, --repo <repo> (required) -s, --state <state> open, closed, all (default: open) -l, --limit <number> (default: 50; 0 = all) ``` ```bash stoke pr list -o heavy-duty -r stoke -s all -l 0 ``` Calls `GET /api/v1/repos/{owner}/{repo}/pulls` (auto-paginated). ### `stoke pr create` ```text Options: -o, --owner <owner> (required) -r, --repo <repo> (required) -t, --title <title> (required) --head <branch> source branch (required; cross-repo: user:branch) --base <branch> target branch (default: main) -b, --body <body> --body-file <path> ``` ```bash stoke pr create -o heavy-duty -r stoke -t "Fix config handling" \ --head fix/config --base main --body-file pr-body.md ``` Calls `POST /api/v1/repos/{owner}/{repo}/pulls`. ### `stoke pr merge` ```text Options: -o, --owner <owner> (required) -r, --repo <repo> (required) -n, --number <number> (required) --method <method> merge, rebase, rebase-merge, squash (default: merge) --title <title> --message <message> --delete-branch ``` ```bash stoke pr merge -o heavy-duty -r stoke -n 2 --delete-branch ``` Calls `POST /api/v1/repos/{owner}/{repo}/pulls/{number}/merge`. ### `stoke pr show` ```bash stoke pr show -o heavy-duty -r stoke -n 3 ``` Calls `GET /api/v1/repos/{owner}/{repo}/pulls/{number}`. ### `stoke pr comment` Body required. If both `-b` and `--body-file` are set, **`--body-file` wins**. ```bash stoke pr comment -o heavy-duty -r stoke -n 3 -b "Looks good." ``` Calls `POST /api/v1/repos/{owner}/{repo}/issues/{number}/comments`. ### `stoke pr review` `approve` / `approved` may omit a body; `request-changes` and `comment` require a non-empty body. Raw body is preserved — only emptiness is checked with `trim()`. **`--body-file` wins** over `-b`. ```text Options: -o, --owner <owner> (required) -r, --repo <repo> (required) -n, --number <number> (required) --event <event> approve|approved, request-changes|request_changes, comment (required) -b, --body <body> --body-file <path> --commit <sha> sent as commit_id when set ``` ```bash stoke pr review -o heavy-duty -r stoke -n 3 --event approve -b "Ship it." stoke pr review -o heavy-duty -r stoke -n 3 --event request-changes --body-file notes.md stoke pr review -o heavy-duty -r stoke -n 3 --event approve --commit 9fceb02 ``` Calls `POST /api/v1/repos/{owner}/{repo}/pulls/{number}/reviews`. --- ## Releases ### `stoke release list` ```bash stoke release list -o heavy-duty -r stoke ``` Calls `GET /api/v1/repos/{owner}/{repo}/releases` (auto-paginated). ### `stoke release view` ```bash stoke release view -o heavy-duty -r stoke --tag v1.2.1 ``` Calls `GET /api/v1/repos/{owner}/{repo}/releases/tags/{tag}`. ### `stoke release create` If the tag does not exist, Forgejo creates it from `--target` (or the default branch). **`--body-file` wins** over `-b`. ```text Options: -o, --owner <owner> (required) -r, --repo <repo> (required) --tag <tag> (required) --target <ref> -t, --title <title> -b, --body <body> --body-file <path> --draft --prerelease ``` ```bash stoke release create -o heavy-duty -r stoke --tag v1.3.0 --body-file release-notes.md ``` Calls `POST /api/v1/repos/{owner}/{repo}/releases`. --- ## Labels ### `stoke label list` ```bash stoke label list -o heavy-duty -r stoke ``` Calls `GET /api/v1/repos/{owner}/{repo}/labels` (auto-paginated). ### `stoke label create` Color: 6 hex digits, optional leading `#`. Validated before any network call. ```bash stoke label create -o heavy-duty -r stoke --name release --color 0E8A16 \ -d "Release flow and version/packaging work" ``` Calls `POST /api/v1/repos/{owner}/{repo}/labels`. ### `stoke label delete` Exactly one of `--id` or `--name` (both rejected). A name is resolved via the label list first. ```bash stoke label delete -o heavy-duty -r stoke --name needs-triage ``` Calls `DELETE /api/v1/repos/{owner}/{repo}/labels/{id}`. ### `stoke label add` / `stoke label remove` PRs are issues for labeling. Unknown names fail with `Label not found`. ```bash stoke label add -o heavy-duty -r stoke -n 12 --name release scope:cli stoke label remove -o heavy-duty -r stoke -n 12 --name needs-triage ``` --- ## Branches ### `stoke branch list` ```bash stoke branch list -o heavy-duty -r stoke ``` Calls `GET /api/v1/repos/{owner}/{repo}/branches` (auto-paginated). --- ## Collaborators ### `stoke collaborator add` ```text Options: -o, --owner <owner> (required) -r, --repo <repo> (required) -u, --user <username> (required) --permission <permission> read, write, or admin (default: write) ``` ```bash stoke collaborator add -o heavy-duty -r infra -u andres --permission admin ``` Calls `PUT /api/v1/repos/{owner}/{repo}/collaborators/{user}`. --- ## Organizations ### `stoke org create` Authenticated user becomes the first owner. ```text Options: --name <name> org username / URL slug (required) --full-name <full-name> -d, --description <description> --website <website> --location <location> --visibility <visibility> public, limited, private (default: public) ``` ```bash stoke org create --name heavy-duty --full-name "Heavy Duty Builders" \ --website https://heavyduty.builders --visibility public ``` Calls `POST /api/v1/orgs`. ### `stoke org repos` ```bash stoke org repos -o heavy-duty -l 0 ``` Calls `GET /api/v1/orgs/{org}/repos` (auto-paginated). ### `stoke org avatar` Upload a local image as the org logo (caller must be an owner). ```bash stoke org avatar -o heavy-duty -f heavy-duty-logo.png ``` Calls `POST /api/v1/orgs/{org}/avatar`. ### `stoke org team list` ```bash stoke org team list -o heavy-duty ``` Calls `GET /api/v1/orgs/{org}/teams` (auto-paginated). ### `stoke org team create` ```text Options: -o, --org <org> (required) --name <name> (required) -d, --description <description> --permission <permission> read, write, admin (default: read) --all-repos --can-create-repo --units <units> comma-separated team units (default: repo.code,repo.issues,repo.pulls,repo.releases,repo.wiki,repo.projects) ``` ```bash stoke org team create -o heavy-duty --name members --permission write --all-repos ``` Calls `POST /api/v1/orgs/{org}/teams`. ### `stoke org team member-list` / `member-add` / `member-remove` Requires team membership (or instance admin). Adding a user to any team also makes them an org member; the **Owners** team is what grants org admin. ```bash stoke org team member-list --team-id 2 stoke org team member-add --team-id 1 -u andres stoke org team member-remove --team-id 1 -u kimi-reviewer-andresmgsl ``` --- ## Users ### `stoke user list` Non-admin searches are visibility-limited; an empty query often returns only the authenticated user. ```bash stoke user list -q andres ``` Calls `GET /api/v1/users/search` (auto-paginated). ### `stoke user show` ```bash stoke user show -u andres ``` Calls `GET /api/v1/users/{username}`. --- ## Raw API ### `stoke api` Authenticated passthrough for anything not wrapped yet. Pass the path **without** the `/api/v1` prefix. ```text Arguments: <endpoint> path starting with / (required) Options: -X, --method <method> GET, POST, PUT, PATCH, DELETE (default: GET, or POST when --input is given) --input <json> JSON body, inline or @path --paginate all pages (GET endpoints that return a JSON array); overrides limit/page in the endpoint ``` ```bash stoke api /user stoke api "/repos/heavy-duty/stoke/pulls?state=closed" --paginate stoke api /repos/heavy-duty/stoke/issues/12/comments --input '{"body":"hi"}' stoke api /repos/heavy-duty/stoke/contents/CHANGELOG.md --input @payload.json ``` Rejected before network: bad method, `--paginate` on non-GET, `GET` + `--input`, malformed `--input` JSON, endpoint not starting with `/`. **Security:** this is a full authenticated passthrough. Never interpolate untrusted strings (issue titles, PR bodies, user input) into the endpoint or `--input`.