From 25670253eab715508522e32a914e15f82be1c096 Mon Sep 17 00:00:00 2001 From: kimi-reviewer-andresmgsl Date: Wed, 22 Jul 2026 15:06:35 +0000 Subject: [PATCH] feat: add repo collaborator command --- README.md | 21 +++++++++++++++++++++ src/api.js | 6 ++++++ src/cli.js | 24 ++++++++++++++++++++++++ 3 files changed, 51 insertions(+) diff --git a/README.md b/README.md index bb61197..f17bd63 100644 --- a/README.md +++ b/README.md @@ -309,6 +309,27 @@ forgejo branch list -o kimi-reviewer-andresmgsl -r box Calls `GET /api/v1/repos/{owner}/{repo}/branches` and auto-paginates. +### `forgejo collaborator add` + +Add a collaborator to a repository. + +```text +Options: + -o, --owner repository owner (required) + -r, --repo repository name (required) + -u, --user username of the collaborator (required) + --permission read, write, or admin (default: write) +``` + +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 +``` + +Calls `PUT /api/v1/repos/{owner}/{repo}/collaborators/{user}`. + ## Architecture ```text diff --git a/src/api.js b/src/api.js index 9a3f66d..bec8cab 100644 --- a/src/api.js +++ b/src/api.js @@ -143,6 +143,12 @@ class ForgejoClient { async listBranches(owner, repo, opts = {}) { return this.getAll(`/repos/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}/branches`, opts); } + + async addCollaborator(owner, repo, username, permission) { + return this.request('PUT', `/repos/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}/collaborators/${encodeURIComponent(username)}`, { + permission, + }); + } } module.exports = { ForgejoClient }; diff --git a/src/cli.js b/src/cli.js index f4b096b..7d803c2 100755 --- a/src/cli.js +++ b/src/cli.js @@ -529,6 +529,30 @@ branchCmd } }); +const collaborator = program + .command('collaborator') + .description('Manage repository collaborators'); + +collaborator + .command('add') + .description('Add a collaborator to a repository') + .requiredOption('-o, --owner ', 'repository owner') + .requiredOption('-r, --repo ', 'repository name') + .requiredOption('-u, --user ', 'username of the collaborator') + .option('--permission ', 'permission level: read, write, admin', 'write') + .action(async (options) => { + try { + const config = loadConfig(); + const client = ForgejoClient.fromConfig(config); + await client.addCollaborator(options.owner, options.repo, options.user, options.permission); + console.log(`Added ${options.user} as ${options.permission} collaborator to ${options.owner}/${options.repo}.`); + } catch (err) { + console.error(`Failed to add collaborator: ${err.message}`); + if (err.status) console.error(`HTTP status: ${err.status}`); + process.exit(1); + } + }); + program.parseAsync(process.argv).catch((err) => { console.error(err); process.exit(1);