From 9e7c204201fc72c0de7891b95145dbfefa86ffee Mon Sep 17 00:00:00 2001 From: kimi-reviewer-andresmgsl Date: Wed, 22 Jul 2026 15:16:42 +0000 Subject: [PATCH] chore: rename CLI and project to stoke --- README.md | 92 +++++++++++++++++++++++++++------------------------ package.json | 8 ++--- src/api.js | 6 ++++ src/cli.js | 34 +++++++++++++++---- src/config.js | 8 +++-- 5 files changed, 90 insertions(+), 58 deletions(-) diff --git a/README.md b/README.md index f17bd63..88d2871 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,6 @@ -# forgejo-cli +# stoke + +> CLI for the heavy-duty forge (Forgejo). Named after the act of feeding and tending a fire — the operator's hand on the forge. A command-line interface for [Forgejo](https://forgejo.org/), built with [Commander.js](https://github.com/tj/commander.js/). It targets the instance at `https://forgejo.heavyduty.builders` and is designed so that every real operation performed against Forgejo becomes a new CLI command. @@ -10,9 +12,9 @@ A command-line interface for [Forgejo](https://forgejo.org/), built with [Comman ## Installation ```bash -cd forgejo-cli +cd stoke npm install -npm link # makes the `forgejo` binary available globally +npm link # makes the `stoke` binary available globally ``` Or run it directly without linking: @@ -25,8 +27,8 @@ node src/cli.js Authentication state is stored in a JSON file: -- Default: `~/.config/forgejo-cli/config.json` -- Override with `--config ` or `FORGEJO_CONFIG_FILE` +- Default: `~/.config/stoke/config.json` +- Override with `--config ` or `STOKE_CONFIG_FILE` (or `FORGEJO_CONFIG_FILE` as a fallback) The configuration directory is created with permissions `0700` and the file with `0600` so only the owner can read the token. @@ -47,14 +49,16 @@ Example stored config: | Variable | Purpose | | --- | --- | -| `FORGEJO_URL` | Default Forgejo base URL | -| `FORGEJO_USERNAME` | Default username/email for `auth login` | -| `FORGEJO_PASSWORD` | Default password for `auth login` | -| `FORGEJO_CONFIG_FILE` | Path to the config file | -| `FORGEJO_CONFIG_DIR` | Directory for the config file | +| `STOKE_URL` | Default Forgejo base URL | +| `STOKE_USERNAME` | Default username/email for `auth login` | +| `STOKE_PASSWORD` | Default password for `auth login` | +| `STOKE_CONFIG_FILE` | Path to the config file | +| `STOKE_CONFIG_DIR` | Directory for the config file | | `XDG_CONFIG_HOME` | Followed when resolving the default config directory | | `GITHUB_TOKEN` | GitHub token used by `repo import` when `--github-token` is omitted | +`FORGEJO_*` variants are still accepted as fallbacks for backward compatibility. + ## Commands ### Global options @@ -65,7 +69,7 @@ Example stored config: -V, --version display version ``` -### `forgejo auth login` +### `stoke auth login` Authenticate and persist an access token. @@ -83,29 +87,29 @@ Options: Interactive example: ```bash -forgejo auth login +stoke auth login # prompts for username and password ``` Non-interactive example using environment variables: ```bash -export FORGEJO_USERNAME='kimi-reviewer-andresmgsl' -export FORGEJO_PASSWORD='...' -forgejo auth login +export STOKE_USERNAME='kimi-reviewer-andresmgsl' +export STOKE_PASSWORD='...' +stoke auth login ``` Password file example (avoids shell history and special-character issues): ```bash -chmod 600 /run/secrets/forgejo-password -forgejo auth login -n kimi-reviewer-andresmgsl --password-file /run/secrets/forgejo-password +chmod 600 /run/secrets/stoke-password +stoke auth login -n kimi-reviewer-andresmgsl --password-file /run/secrets/stoke-password ``` Existing token example: ```bash -forgejo auth login -t +stoke auth login -t ``` Flow: @@ -115,30 +119,30 @@ Flow: 3. Requests the standard non-admin scopes: `read/write` for `activitypub`, `issue`, `misc`, `organization`, `package`, `repository`, and `user`. 4. Writes the token, token id, user details and URL to the config file. -### `forgejo auth logout` +### `stoke auth logout` Revoke the stored token remotely and delete the local config. ```bash -forgejo auth logout +stoke auth logout ``` Flow: 1. Calls `DELETE /api/v1/users/{login}/tokens/{id}` using the stored token. -2. Removes `~/.config/forgejo-cli/config.json`. +2. Removes `~/.config/stoke/config.json`. -### `forgejo auth status` +### `stoke auth status` Display the currently authenticated user. ```bash -forgejo auth status +stoke auth status ``` Calls `GET /api/v1/user` with the stored token. -### `forgejo repo create` +### `stoke repo create` Create a new repository for the authenticated user. @@ -155,13 +159,13 @@ Options: Example: ```bash -forgejo repo create --name forgejo-cli-test --private \ - -d "Test repository created via forgejo-cli" +stoke repo create --name stoke-test --private \ + -d "Test repository created via stoke" ``` Calls `POST /api/v1/user/repos`. -### `forgejo repo list` +### `stoke repo list` List repositories for the authenticated user. @@ -171,12 +175,12 @@ Options: ``` ```bash -forgejo repo list +stoke repo list ``` Calls `GET /api/v1/user/repos` and auto-paginates. -### `forgejo repo import` +### `stoke repo import` Import a remote repository into Forgejo, including git history, issues, pull requests, labels, milestones, releases and wiki. @@ -207,7 +211,7 @@ Options: Example used to mirror `heavy-duty/box`: ```bash -forgejo repo import \ +stoke repo import \ --from https://github.com/heavy-duty/box.git \ --name box \ --service github \ @@ -217,7 +221,7 @@ forgejo repo import \ Calls `POST /api/v1/repos/migrate`. -### `forgejo repo import-batch` +### `stoke repo import-batch` Import multiple repositories from a JSON manifest. @@ -249,13 +253,13 @@ Manifest format: Example: ```bash -forgejo repo import-batch -f repos.json -forgejo repo import-batch -f repos.json --dry-run +stoke repo import-batch -f repos.json +stoke repo import-batch -f repos.json --dry-run ``` Calls `POST /api/v1/repos/migrate` once per entry. -### `forgejo issue list` +### `stoke issue list` List issues in a repository. @@ -269,12 +273,12 @@ Options: ``` ```bash -forgejo issue list -o kimi-reviewer-andresmgsl -r box -s all -l 0 +stoke issue list -o kimi-reviewer-andresmgsl -r box -s all -l 0 ``` Calls `GET /api/v1/repos/{owner}/{repo}/issues` and auto-paginates. -### `forgejo pr list` +### `stoke pr list` List pull requests in a repository. @@ -287,12 +291,12 @@ Options: ``` ```bash -forgejo pr list -o kimi-reviewer-andresmgsl -r box -s all -l 0 +stoke pr list -o kimi-reviewer-andresmgsl -r box -s all -l 0 ``` Calls `GET /api/v1/repos/{owner}/{repo}/pulls` and auto-paginates. -### `forgejo branch list` +### `stoke branch list` List branches in a repository. @@ -304,12 +308,12 @@ Options: ``` ```bash -forgejo branch list -o kimi-reviewer-andresmgsl -r box +stoke branch list -o kimi-reviewer-andresmgsl -r box ``` Calls `GET /api/v1/repos/{owner}/{repo}/branches` and auto-paginates. -### `forgejo collaborator add` +### `stoke collaborator add` Add a collaborator to a repository. @@ -324,8 +328,8 @@ Options: Example: ```bash -forgejo collaborator add -o kimi-reviewer-andresmgsl -r infra -u andres --permission admin -forgejo collaborator add -o kimi-reviewer-andresmgsl -r infra -u dan --permission admin +stoke collaborator add -o kimi-reviewer-andresmgsl -r infra -u andres --permission admin +stoke collaborator add -o kimi-reviewer-andresmgsl -r infra -u dan --permission admin ``` Calls `PUT /api/v1/repos/{owner}/{repo}/collaborators/{user}`. @@ -347,7 +351,7 @@ src/ - Tokens are stored on disk with `0600` permissions. - Passwords are never persisted; they are only used to generate a token. -- Prefer `--password-file` or `FORGEJO_PASSWORD` over `-p` to keep passwords out of shell history and avoid `!` history-expansion issues. +- Prefer `--password-file` or `STOKE_PASSWORD` over `-p` to keep passwords out of shell history and avoid `!` history-expansion issues. - The generated token name includes the hostname and a timestamp to avoid collisions. ## Verification: heavy-duty repository imports @@ -367,4 +371,4 @@ Counts match GitHub for all repositories. Git history, issues, pull requests, la ## Next steps -The CLI is authenticated and the first full repository import is complete. Every subsequent Forgejo task you need will be added as a new command under `forgejo`. +The CLI is authenticated and the first full repository import is complete. Every subsequent Forgejo task you need will be added as a new command under `stoke`. diff --git a/package.json b/package.json index ba3d1ba..2566d9d 100644 --- a/package.json +++ b/package.json @@ -1,8 +1,8 @@ { - "name": "forgejo-cli", + "name": "stoke", "version": "1.0.0", - "description": "", - "main": "index.js", + "description": "CLI for the heavy-duty forge (Forgejo)", + "main": "src/cli.js", "scripts": { "test": "node --test test/**/*.test.js", "start": "node src/cli.js" @@ -15,6 +15,6 @@ "commander": "^15.0.0" }, "bin": { - "forgejo": "src/cli.js" + "stoke": "src/cli.js" } } diff --git a/src/api.js b/src/api.js index bec8cab..d73ee5d 100644 --- a/src/api.js +++ b/src/api.js @@ -149,6 +149,12 @@ class ForgejoClient { permission, }); } + + async renameRepo(owner, repo, newName) { + return this.request('PATCH', `/repos/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}`, { + name: newName, + }); + } } module.exports = { ForgejoClient }; diff --git a/src/cli.js b/src/cli.js index 7d803c2..6de14ac 100755 --- a/src/cli.js +++ b/src/cli.js @@ -12,8 +12,8 @@ const pkg = require('../package.json'); const program = new Command(); program - .name('forgejo') - .description('CLI for Forgejo (https://forgejo.heavyduty.builders)') + .name('stoke') + .description('CLI for the heavy-duty forge (https://forgejo.heavyduty.builders)') .version(pkg.version) .configureOutput({ outputError: (str, write) => write(`Error: ${str}`) }); @@ -21,7 +21,7 @@ program .option('-c, --config ', 'path to configuration file') .hook('preAction', (thisCommand) => { if (thisCommand.opts().config) { - process.env.FORGEJO_CONFIG_FILE = thisCommand.opts().config; + process.env.STOKE_CONFIG_FILE = thisCommand.opts().config; } }); @@ -53,7 +53,7 @@ function readSecretFile(filePath, label) { function makeTokenName() { const host = require('node:os').hostname() || 'unknown'; - return `forgejo-cli-${host}-${Date.now()}`; + return `stoke-${host}-${Date.now()}`; } const DEFAULT_TOKEN_SCOPES = [ @@ -84,9 +84,9 @@ const auth = program auth .command('login') .description('Authenticate against a Forgejo instance and store an access token') - .option('-u, --url ', 'Forgejo base URL', process.env.FORGEJO_URL || 'https://forgejo.heavyduty.builders') - .option('-n, --username ', 'account username or email', process.env.FORGEJO_USERNAME) - .option('-p, --password ', 'account password', process.env.FORGEJO_PASSWORD) + .option('-u, --url ', 'Forgejo base URL', process.env.STOKE_URL || process.env.FORGEJO_URL || 'https://forgejo.heavyduty.builders') + .option('-n, --username ', 'account username or email', process.env.STOKE_USERNAME || process.env.FORGEJO_USERNAME) + .option('-p, --password ', 'account password', process.env.STOKE_PASSWORD || process.env.FORGEJO_PASSWORD) .option('--password-file ', 'read account password from a file') .option('-t, --token ', 'use an existing personal access token instead of generating one') .option('--token-file ', 'read an existing personal access token from a file') @@ -350,6 +350,26 @@ repo } }); +repo + .command('rename') + .description('Rename a repository') + .requiredOption('-o, --owner ', 'repository owner') + .requiredOption('-r, --repo ', 'current repository name') + .requiredOption('--name ', 'new repository name') + .action(async (options) => { + try { + const config = loadConfig(); + const client = ForgejoClient.fromConfig(config); + const result = await client.renameRepo(options.owner, options.repo, options.name); + console.log(`Repository renamed to ${result.full_name}`); + console.log(`URL: ${result.html_url}`); + } catch (err) { + console.error(`Repository rename failed: ${err.message}`); + if (err.status) console.error(`HTTP status: ${err.status}`); + process.exit(1); + } + }); + repo .command('import-batch') .description('Import multiple repositories from a JSON manifest') diff --git a/src/config.js b/src/config.js index 2852a8b..93d5af1 100644 --- a/src/config.js +++ b/src/config.js @@ -2,9 +2,11 @@ const path = require('node:path'); const os = require('node:os'); const fs = require('node:fs'); -const CONFIG_DIR = process.env.FORGEJO_CONFIG_DIR - || path.join(process.env.XDG_CONFIG_HOME || os.homedir(), '.config', 'forgejo-cli'); -const CONFIG_PATH = process.env.FORGEJO_CONFIG_FILE +const CONFIG_DIR = process.env.STOKE_CONFIG_DIR + || process.env.FORGEJO_CONFIG_DIR + || path.join(process.env.XDG_CONFIG_HOME || os.homedir(), '.config', 'stoke'); +const CONFIG_PATH = process.env.STOKE_CONFIG_FILE + || process.env.FORGEJO_CONFIG_FILE || path.join(CONFIG_DIR, 'config.json'); const CONFIG_MODE = 0o600; const DIR_MODE = 0o700;