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

688 lines
17 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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> 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 <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
```
```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 <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.
```text
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
```
```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 <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)
```
```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 clones `.git/config`. Git stdout/stderr and exit status are forwarded.
### `stoke repo create`
```text
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)
```
```bash
stoke repo create --name stoke-test --private -d "Test repository"
```
Calls `POST /api/v1/user/repos`.
### `stoke repo list`
```text
Options:
-l, --limit <number> 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 <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.
```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> 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 <owner> repository owner (required)
-r, --repo <repo> current name (required)
--name <new-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 <owner> current owner (required)
-r, --repo <repo> repository name (required)
--to <new-owner> 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 <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)
```
```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 <owner> (required)
-r, --repo <repo> (required)
-t, --title <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`.