stoke/docs/COMMANDS.md
grok-reviewer-andresmgsl 2dcd8e6f1b docs: shorten README and move command reference to docs/COMMANDS.md
Keep the README scannable (install, quick start, capability map, config,
security, develop) and put full options/examples/API mapping in
docs/COMMANDS.md without dropping detail. Ship COMMANDS.md in the npm
package files list.
2026-07-26 23:11:30 +00:00

17 KiB
Raw Blame History

stoke command reference

Full options, examples, and API mapping for every command. For install and overview, see the README.

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

-c, --config <path>   path to configuration file
-h, --help            display help
-V, --version         display version

The global --config flag must come before the subcommand:

stoke --config /path/to/config.json auth status

Auth

stoke auth login

Authenticate and persist an access token.

Options:
  -u, --url <url>            Forgejo base URL (default: https://forgejo.heavyduty.builders)
  -n, --username <username>  account username or email
  -p, --password <password>  account password
  --password-file <path>     read account password from a file
  -t, --token <token>        use an existing personal access token instead of generating one
  --token-file <path>        read an existing personal access token from a file
  --token-name <name>        name for the generated token
  --full-scopes              grant full read/write access on all non-admin scopes
  --scopes <csv>             comma-separated list of scopes for the generated token
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 <personal-access-token>
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 <csv>. Granted scopes are printed after a successful login.

stoke auth logout

Revoke the stored token remotely and delete local config.

Options:
  -p, --password <password>  account password (needed for remote revocation)
  --password-file <path>     read account password from a file
  --local-only               skip remote revocation; only delete local config
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

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.

Arguments:
  [directory]          destination directory (default: repository name)

Options:
  -o, --owner <owner>  repository owner (required)
  -r, --repo <repo>    repository name (required)
  --branch <branch>    checkout this branch instead of the default
  --depth <depth>      shallow clone depth
  --origin <name>      remote name (default: origin)
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 clones .git/config. Git stdout/stderr and exit status are forwarded.

stoke repo create

Options:
  --name <name>                    repository name (required)
  -d, --description <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 <branch>        default branch (default: main)
stoke repo create --name stoke-test --private -d "Test repository"

Calls POST /api/v1/user/repos.

stoke repo list

Options:
  -l, --limit <number>   max repos to display (default: 50; 0 = all)
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).

Options:
  --from <clone-addr>      source clone URL (required)
  --name <name>            repository name in Forgejo (required)
  --service <service>      git, github, gitea, gitlab, ... (default: github)
  --owner <owner>          Forgejo owner (default: current user)
  -d, --description <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 <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.

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.

Options:
  -f, --file <path>   path to JSON manifest (required)
  --dry-run           print the manifest without importing

Manifest entry shape:

[
  {
    "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
  }
]
stoke repo import-batch -f repos.json
stoke repo import-batch -f repos.json --dry-run

stoke repo rename

Options:
  -o, --owner <owner>    repository owner (required)
  -r, --repo <repo>      current name (required)
  --name <new-name>      new name (required)
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.

Options:
  -o, --owner <owner>    current owner (required)
  -r, --repo <repo>      repository name (required)
  --to <new-owner>       username or org (required)
stoke repo transfer -o kimi-reviewer-andresmgsl -r box --to heavy-duty

Calls POST /api/v1/repos/{owner}/{repo}/transfer.


Issues

stoke issue list

Options:
  -o, --owner <owner>    (required)
  -r, --repo <repo>      (required)
  -s, --state <state>    open, closed, all (default: open)
  -t, --type <type>      issues or pulls (default: issues)
  -l, --limit <number>   (default: 50; 0 = all)
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

Options:
  -o, --owner <owner>       (required)
  -r, --repo <repo>         (required)
  -t, --title <title>       (required)
  -b, --body <body>
  --body-file <path>
  --assignee <username...>
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

Options:
  -o, --owner <owner>    (required)
  -r, --repo <repo>      (required)
  -n, --number <number>  (required)
  --json
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.

Options:
  -o, --owner <owner>    (required)
  -r, --repo <repo>      (required)
  -n, --number <number>  (required)
  -b, --body <body>
  --body-file <path>
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

Options:
  -o, --owner <owner>    (required)
  -r, --repo <repo>      (required)
  -s, --state <state>    open, closed, all (default: open)
  -l, --limit <number>   (default: 50; 0 = all)
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

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>
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

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
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

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.

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.

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
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

stoke release list -o heavy-duty -r stoke

Calls GET /api/v1/repos/{owner}/{repo}/releases (auto-paginated).

stoke release view

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.

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
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

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.

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.

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.

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

stoke branch list -o heavy-duty -r stoke

Calls GET /api/v1/repos/{owner}/{repo}/branches (auto-paginated).


Collaborators

stoke collaborator add

Options:
  -o, --owner <owner>            (required)
  -r, --repo <repo>              (required)
  -u, --user <username>          (required)
  --permission <permission>      read, write, or admin (default: write)
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.

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)
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

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).

stoke org avatar -o heavy-duty -f heavy-duty-logo.png

Calls POST /api/v1/orgs/{org}/avatar.

stoke org team list

stoke org team list -o heavy-duty

Calls GET /api/v1/orgs/{org}/teams (auto-paginated).

stoke org team create

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)
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.

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.

stoke user list -q andres

Calls GET /api/v1/users/search (auto-paginated).

stoke user show

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.

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
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.