Compare commits

...

1 commit

Author SHA1 Message Date
2dcd8e6f1b docs: shorten README and move command reference to docs/COMMANDS.md
Some checks failed
ci / test (pull_request) Has been cancelled
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
3 changed files with 771 additions and 1007 deletions

1089
README.md

File diff suppressed because it is too large Load diff

688
docs/COMMANDS.md Normal file
View file

@ -0,0 +1,688 @@
# 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`.

View file

@ -34,6 +34,7 @@
"README.md",
"LICENSE",
"docs/DESIGN.md",
"docs/COMMANDS.md",
"assets/logo-mark.svg"
]
}