forgejo-cli
Use when managing a Forgejo or Gitea server from the terminal: issues, pull requests, repositories, file contents, labels, milestones, releases, webhooks, user settings, or any /api/v1 endpoint through a safe generic API command. Do not use this skill for unrelated requests; rout
#code-review #git
Install
npx skills add https://github.com/magnus919/agent-skills/tree/main/forgejo-cli
claude plugin marketplace add https://llmmart.ai/marketplace.json && claude plugin install magnus919-agent-skills@llmmart
git clone https://github.com/magnus919/agent-skills.git
The skills CLI installs just this skill, for any of its supported agents. Claude Code installs the whole magnus919/agent-skills collection as a plugin from our marketplace. Git is the plain clone.
README
Forgejo CLI v2 — safe repository automation
Manage a Forgejo server from the terminal without hand-written curl or accidental mutations. It covers daily repository work—issues, pull requests, repositories, contents, metadata, webhooks, and settings—and has a guarded API escape hatch for the rest.
Why Install This Skill
The CLI gives agents one predictable safety contract: JSON is machine-readable, diagnostics stay off stdout, mutations require confirmation, and dry runs never need a token or network access. For version-specific features such as Actions runners and variables, packages, organizations, teams, admin APIs, notifications, and permissions, use the generic API command with your server's Swagger schema.
It deliberately does not try to duplicate every API endpoint. Instead, it offers guarded first-class commands for common repository work and a generic client for the rest. The references explain when to use each, how to select a compatible schema, and how to handle pagination and token scopes.
What You Get
| Contents | Purpose |
|---|---|
scripts/forgejo-cli |
Argparse Forgejo API v1 client |
references/command-reference.md |
Endpoint and payload guide |
references/api-usage.md |
Authentication, pagination, versioning, and schema-discovery procedure |
references/endpoint-routing.md |
Decision guide for first-class commands versus generic API calls |
references/troubleshooting.md |
Safe diagnosis of API and transport failures |
V2-SPEC.md |
v2 acceptance criteria |
tests/ |
Offline stdlib contract tests |
Quick Start
Set FORGEJO_AGENT_TOKEN (default) or FORGEJO_USER_TOKEN, then run:
python3 scripts/forgejo-cli --dry-run --json repo create --name demo --private
python3 scripts/forgejo-cli --server https://forge.example api --method GET --path /api/v1/user --json
python3 scripts/forgejo-cli --server https://forge.example --page 1 --limit 50 --include-response issue list --owner acme --repo app --json
Triggers
- Managing Forgejo/Gitea issues, PRs, repos, file contents, releases, or hooks.
- Calling a version-specific
/api/v1/endpoint safely. - Previewing a Forgejo mutation.
Requirements
Python 3.8+ and requests for live API calls. --help and --dry-run need no token or dependency. Set FORGEJO_AGENT_TOKEN or FORGEJO_USER_TOKEN for token authentication. A deliberate Authorization header supports other documented schemes, but avoid putting secrets directly in shell history. Consult your Forgejo server's /api/swagger or /swagger.v1.json for exact schemas.
Skill manifest
Forgejo CLI v2
Run python3 scripts/forgejo-cli. --agent (default) uses FORGEJO_AGENT_TOKEN; --user uses FORGEJO_USER_TOKEN; --server URL selects an installation. Set FORGEJO_SERVER in your shell if your wrapper supplies it, otherwise pass --server explicitly.
Safety
- Mutations require
--force/--yes/-y, or--dry-run. --dry-run --jsonemits one plan withmethod,path,query, andbody; it makes no network request.--jsonwrites exactly one JSON value to stdout; diagnostics go to stderr.--pageand--limitwork for any list/search request. Add--include-responseto receive the HTTP status pluslinkandx-total-countpagination headers.--helpdoes not read credentials or contact a server. Path segments are encoded.
Common workflows
python3 scripts/forgejo-cli issue list --owner acme --repo app --json
python3 scripts/forgejo-cli --dry-run --json repo create --name demo --private
python3 scripts/forgejo-cli --dry-run --json api --method POST \
--path /api/v1/repos/acme/app/actions/variables --data '{"name":"KEY","value":"value"}'
First-class groups: issue, pr, repo, content, label, milestone, release, hook, and user. content expects base64 and update/delete require the current SHA. Use api for any other /api/v1/ endpoint; it supports JSON, raw files, multipart uploads/forms, and custom headers. Consult /api/swagger or /swagger.v1.json on the selected server. See command reference.
Choosing a command
Use a first-class command for its covered daily workflow. Use api when the operation is absent, requires version-specific fields, or needs a schema not represented by a simple flag. Before using api, read endpoint routing; read API usage for authentication, pagination, compatibility, and safe schema discovery. Read troubleshooting for 401/403/422 responses and transport failures.
Files (agent-skills)
-
evals
-
evals.json 2.8 KB
{ "schema_version": 1, "skill_name": "forgejo-cli", "evals": [ { "id": "forgejo-cli-core-workflow", "prompt": "Use forgejo cli to handle a realistic primary task. Explain the inputs, ordered workflow, and concrete output.", "expected_output": "A forgejo cli response defines the task boundary, identifies required inputs, applies the documented workflow, and produces a concrete output with verification.", "assertions": [ "Names the forgejo cli task and required inputs", "Applies an ordered workflow rather than generic advice", "Produces a concrete output and verification step" ] }, { "id": "forgejo-cli-failure-diagnosis", "prompt": "A forgejo cli task is failing with an ambiguous symptom. Diagnose it and give a bounded recovery path.", "expected_output": "The response separates symptoms from causes, proposes evidence-gathering checks, and gives a reversible recovery path with a stop condition.", "assertions": [ "Separates symptom, hypothesis, and evidence", "Uses targeted diagnostic checks", "Includes a reversible recovery and stop condition" ] }, { "id": "forgejo-cli-safety-boundary", "prompt": "Plan a forgejo cli change that could affect user data or external state. Show the safety gate before acting.", "expected_output": "The response confirms scope and authority, defaults to read-only or dry-run inspection, and requires explicit confirmation before consequential mutation.", "assertions": [ "Confirms target, scope, and authority before mutation", "Uses read-only or dry-run inspection first", "Requires explicit confirmation for consequential changes" ] }, { "id": "forgejo-cli-edge-case", "prompt": "Apply forgejo cli when requirements conflict or an important input is missing. Decide what to do next.", "expected_output": "The response identifies the missing or conflicting constraint, refuses to invent facts, and escalates or requests the smallest clarifying input needed.", "assertions": [ "Identifies the missing or conflicting constraint", "Does not invent unavailable facts", "Requests clarification or escalates with a bounded next step" ] }, { "id": "forgejo-cli-evidence-handoff", "prompt": "Create a review-ready forgejo cli handoff for another practitioner.", "expected_output": "The handoff records assumptions, decisions, artifacts, validation evidence, and unresolved risks so another practitioner can reproduce the result.", "assertions": [ "Records assumptions and decisions", "Links concrete artifacts to validation evidence", "States unresolved risks and reproducible next steps" ] } ] }
-
-
references
-
api-usage.md 2 KB
# API usage, compatibility, and pagination ## Establish the server contract 1. Pass the target with `--server https://forge.example`; do not treat the placeholder default as a usable service. 2. Request `GET /api/v1/version` with the generic command and record the Forgejo major version. 3. Open `https://forge.example/swagger.v1.json` (or `/api/swagger`) and use that server's schema for request fields. Forgejo guarantees API compatibility within a major version; do not assume a current server has the same endpoints or fields as an older Gitea-compatible installation. The upstream usage guide is https://forgejo.org/docs/latest/user/api-usage/. ## Authenticate safely Use `FORGEJO_AGENT_TOKEN` for automation and `FORGEJO_USER_TOKEN` for user-authorized work. Give tokens the narrowest Forgejo scope that can complete the request. The client sends these as `Authorization: token …`. The generic `--header Authorization=…` path supports Basic or Bearer authentication when an endpoint requires it. Prefer an environment-backed wrapper or a token for routine use: command-line credentials may be recorded in shell history and process listings. Never put tokens in `--data`, dry-run output, issue text, or logs. ## Paginate intentionally All list/search commands accept `--page N --limit N`, including generic API calls. Use `--include-response --json` on a live request to retain Forgejo's `link` and `x-total-count` headers: ```bash python3 scripts/forgejo-cli --server https://forge.example --page 1 --limit 50 \ --include-response --json issue list --owner acme --repo app ``` Follow the `rel="next"` URL until absent. Do not assume a fixed page size: server administrators configure defaults and maximum response items. ## Scope boundaries The generic `api` command intentionally accepts only `/api/v1/` paths. Package registries and other non-v1 endpoints require their native client or a separately reviewed HTTP workflow. First-class commands provide guardrails; the generic command provides coverage, not schema validation. -
command-reference.md 3.8 KB
# Command reference Global flags: `--agent`, `--user`, `--server URL`, `--json`, `--quiet/-q`, `--verbose/-v`, `--dry-run/-n`, `--force/--yes/-y`, `--page`, `--limit`, and `--include-response`. POST, PUT, PATCH, and DELETE require `--force` unless dry-running. `--page` and `--limit` are appended as query parameters; `--include-response` wraps live output as `{data, status, headers}` and preserves `link` and `x-total-count`. | Group | Commands | API route | | --- | --- | --- | | `issue` | list, show, create, edit, close, reopen, assign, labels, set-labels, add-labels, clear-labels, comments, comment, delete-comment | `/repos/{owner}/{repo}/issues` | | `pr` | list, show, create, edit, diff, comment, reviews, review, merge | `/repos/{owner}/{repo}/pulls` | | `repo` | list, show, search, create, edit, delete, branches | `/user/repos`, `/repos`, `/repos/search` | | `content` | get, create, update, delete | `/repos/{owner}/{repo}/contents/{path}` | | `label`, `milestone` | list, show, create, edit, delete | matching repository metadata collection | | `release` | list, show, create, edit, delete, assets, upload | `/repos/{owner}/{repo}/releases` | | `hook` | list, show, create, edit, delete | `/user/hooks` or `/repos/{owner}/{repo}/hooks` | | `user` | show, settings, update-settings | `/user`, `/user/settings` | Comma-separated `--labels`, `--assignees`, and `--events` become JSON arrays. PR merge maps `--style` to Forgejo's `Do` field. Hook create accepts `--url`, `--secret`, `--events`, and `--type`; it builds Forgejo's required nested `config` payload. Release create requires `--tag-name`; its display name is `--name`. Content is base64 in `--content`; update and delete require `--sha`. ## First-class command details - `issue list` and `pr list` default to `--state open`; override it when reviewing closed or all work. `issue close` and `issue reopen` use the same edit endpoint with an explicit state. - `content --path` preserves directory separators and encodes unsafe characters. Supply base64 data to `--content`, not plain text. Fetch the current file SHA before an update or delete to avoid overwriting a newer version. - `repo list --owner OWNER` lists that owner's public/visible repositories; without `--owner`, it lists the authenticated user's repositories. `repo create` intentionally requires no owner because it creates under the authenticated user. - `release upload --file PATH` sends a multipart attachment. `release upload --external-url URL` sends the equivalent form field. They are mutually exclusive. - `hook` operates on repository hooks when both `--owner` and `--repo` are present, otherwise on the authenticated user's hooks. Hook creation requires `--url`. ## Safe examples ```bash # See the exact update request before changing a file. python3 scripts/forgejo-cli --dry-run --json content update \ --owner acme --repo app --path docs/guide.md --content BASE64 --sha CURRENT_SHA # Obtain pagination links and a total count from a live list request. python3 scripts/forgejo-cli --server https://forge.example --page 1 --limit 50 \ --include-response --json pr list --owner acme --repo app ``` ## Generic API `forgejo-cli api --method GET|POST|PUT|PATCH|DELETE --path /api/v1/... [--query KEY=VALUE] [--data JSON | --data-file FILE] [--raw-file FILE] [--upload-file FILE --form KEY=VALUE] [--header KEY=VALUE] [--content-type TYPE]` Only `/api/v1/` paths are accepted. JSON, raw binary, multipart file/form payloads, and custom headers are supported. A supplied `Authorization` header is accepted when no token environment variable is set, enabling documented Basic or Bearer authentication; avoid putting credentials in shell history. Use it for Actions, packages, organizations, teams, admin APIs, notifications, repository permissions, and new endpoints; consult the target server's Swagger document for schemas. -
endpoint-routing.md 1.3 KB
# Endpoint routing guide Use the first-class command when it exposes every field needed by the task. It gives semantic flags, safe path encoding, mutation confirmation, and predictable JSON output. | Task | Default command | Use `api` instead when | | --- | --- | --- | | Issues and comments | `issue` | attachments, reactions, dependencies, time tracking, or a schema field not exposed by flags | | Pull requests | `pr` | commits/files/statuses, reviewers beyond the basic review call, or version-specific merge fields | | Repository and files | `repo`, `content` | collaborators, branch/tag protection, keys, mirrors, transfer, archive, or advanced settings | | Metadata and delivery | `label`, `milestone`, `release`, `hook` | a payload needs fields not represented by the first-class command | | Account settings | `user` | tokens, notifications, subscriptions, SSH/GPG keys, organizations, teams, or admin operations | | Actions, packages, projects | `api` | always: these APIs evolve independently and need the live Swagger schema or native package client | For a generic call, first read the target server's Swagger operation, copy its method and required fields exactly, then dry-run the request. Add `--force` only after reviewing the plan. If the endpoint returns a list, include `--page`, `--limit`, and `--include-response`. -
troubleshooting.md 1.4 KB
# Troubleshooting Forgejo API calls | Symptom | Check | Safe next action | | --- | --- | --- | | `No API token available` | Required environment variable is absent | Export the intended token or provide a deliberate `Authorization` header for the one request | | 401 | Token type, expiry, server URL, or authentication scheme | Run a read-only `user show`; do not retry mutations blindly | | 403 | Token scope, repository access, or server policy | Inspect the target endpoint's required scope and permissions; use a narrower correctly scoped token rather than escalating indiscriminately | | 404 | Owner/repo/path or server-version mismatch | Check `/api/v1/version` and the server's Swagger document before changing the path | | 422 | Valid route but invalid payload | Compare the complete JSON body against the live Swagger schema; dry-run first-class calls to inspect generated fields | | Missing list results | Pagination | Add `--page`, `--limit`, and `--include-response`; follow the `link` header | | Connection error | DNS, TLS, proxy, or server availability | Verify the exact `--server` URL with a harmless version request; do not expose tokens in diagnostic output | Use `--verbose` only to inspect method and URL. It deliberately does not print tokens or request bodies. For mutation failures, retain the dry-run JSON plan and the status/message, but redact credentials before sharing either.
-
-
scripts
-
forgejo-cli 21.3 KB · in bundle
-
-
tests
-
test_cli.py 5.5 KB
import importlib.machinery import io import json import pathlib from types import SimpleNamespace import unittest from contextlib import redirect_stderr, redirect_stdout SCRIPT = pathlib.Path(__file__).parents[1] / "scripts" / "forgejo-cli" cli = importlib.machinery.SourceFileLoader("forgejo_cli", str(SCRIPT)).load_module() class CliTests(unittest.TestCase): def run_cli(self, args): out, err = io.StringIO(), io.StringIO() with redirect_stdout(out), redirect_stderr(err): try: cli.main(args) except SystemExit as exc: return exc.code, out.getvalue(), err.getvalue() return 0, out.getvalue(), err.getvalue() def plan(self, args): code, out, err = self.run_cli(["--dry-run", "--json"] + args) self.assertEqual(code, 0, err) return json.loads(out) def test_help_needs_no_credentials(self): self.assertEqual(self.run_cli(["--help"])[0], 0) self.assertEqual(self.run_cli(["issue", "--help"])[0], 0) def test_issue_create_plan(self): plan = self.plan(["issue", "create", "--owner", "me", "--repo", "x", "--title", "hello"]) self.assertEqual((plan["method"], plan["path"]), ("POST", "/api/v1/repos/me/x/issues")) self.assertEqual(plan["body"]["title"], "hello") def test_mutation_requires_force(self): code, _, err = self.run_cli(["repo", "create", "--name", "x"]) self.assertNotEqual(code, 0) self.assertIn("mutation", err) def test_live_request_requires_a_server(self): old = cli.DEFAULT_SERVER cli.DEFAULT_SERVER = "" try: code, _, err = self.run_cli(["user", "show"]) finally: cli.DEFAULT_SERVER = old self.assertNotEqual(code, 0) self.assertIn("No Forgejo server selected", err) def test_api_path_guard_and_plan(self): self.assertNotEqual(self.run_cli(["api", "--method", "GET", "--path", "/bad"])[0], 0) plan = self.plan(["api", "--method", "PATCH", "--path", "/api/v1/user/settings", "--query", "theme=dark", "--data", '{"language":"en"}']) self.assertEqual(plan["query"], {"theme": "dark"}) self.assertEqual(plan["body"], {"language": "en"}) def test_representative_groups(self): cases = [ (["pr", "create", "--owner", "me", "--repo", "x", "--title", "t", "--head", "h", "--base", "main"], "POST", "/api/v1/repos/me/x/pulls"), (["release", "create", "--owner", "me", "--repo", "x", "--tag-name", "v2"], "POST", "/api/v1/repos/me/x/releases"), (["content", "update", "--owner", "me", "--repo", "x", "--path", "a b.txt", "--content", "eA==", "--sha", "abc"], "PUT", "/api/v1/repos/me/x/contents/a%20b.txt"), (["hook", "create", "--owner", "me", "--repo", "x", "--url", "https://hook"], "POST", "/api/v1/repos/me/x/hooks"), ] for args, method, path in cases: plan = self.plan(args) self.assertEqual((plan["method"], plan["path"]), (method, path)) def test_merge_hook_and_release_payloads(self): merge = self.plan(["pr", "merge", "--owner", "me", "--repo", "x", "--index", "1", "--style", "squash"]) self.assertEqual(merge["body"], {"Do": "squash"}) hook = self.plan(["hook", "create", "--owner", "me", "--repo", "x", "--url", "https://hook", "--events", "push"]) self.assertEqual(hook["body"]["config"]["url"], "https://hook") self.assertEqual(hook["body"]["type"], "forgejo") release = self.plan(["release", "create", "--owner", "me", "--repo", "x", "--tag-name", "v2", "--name", "Version 2"]) self.assertEqual(release["body"], {"tag_name": "v2", "name": "Version 2"}) def test_repo_creation_needs_no_owner(self): self.assertEqual(self.plan(["repo", "create", "--name", "demo", "--private"])["path"], "/api/v1/user/repos") def test_nested_content_path_and_pagination_plan(self): plan = self.plan(["--page", "2", "--limit", "75", "content", "get", "--owner", "me", "--repo", "x", "--path", "dir/a b.txt"]) self.assertEqual(plan["path"], "/api/v1/repos/me/x/contents/dir/a%20b.txt") self.assertEqual(plan["query"], {"page": 2, "limit": 75}) def test_form_transport_custom_authorization_and_response_metadata(self): class Response: status_code = 200 content = b'{"ok":true}' text = '{"ok":true}' headers = {"Link": '<https://forge.example/api/v1/user/repos?page=2>; rel="next"', "X-Total-Count": "51"} def json(self): return {"ok": True} class Requests: RequestException = Exception call = None @classmethod def request(cls, *args, **kwargs): cls.call = (args, kwargs) return Response() original = cli.requests cli.requests = Requests try: args = SimpleNamespace(server="https://forge.example", dry_run=False, verbose=False, user=False) result = cli.Client(args).request( "POST", "/api/v1/repos/me/x/releases/1/assets", headers={"Authorization": "Basic test"}, form={"external_url": "https://example.invalid/file"}, include_response=True) finally: cli.requests = original self.assertEqual(Requests.call[1]["data"], {"external_url": "https://example.invalid/file"}) self.assertEqual(result["data"], {"ok": True}) self.assertEqual(result["headers"]["x-total-count"], "51") if __name__ == "__main__": unittest.main()
-
-
README.md 2.5 KB
# Forgejo CLI v2 — safe repository automation Manage a Forgejo server from the terminal without hand-written `curl` or accidental mutations. It covers daily repository work—issues, pull requests, repositories, contents, metadata, webhooks, and settings—and has a guarded API escape hatch for the rest. ## Why Install This Skill The CLI gives agents one predictable safety contract: JSON is machine-readable, diagnostics stay off stdout, mutations require confirmation, and dry runs never need a token or network access. For version-specific features such as Actions runners and variables, packages, organizations, teams, admin APIs, notifications, and permissions, use the generic API command with your server's Swagger schema. It deliberately does not try to duplicate every API endpoint. Instead, it offers guarded first-class commands for common repository work and a generic client for the rest. The references explain when to use each, how to select a compatible schema, and how to handle pagination and token scopes. ## What You Get | Contents | Purpose | | --- | --- | | `scripts/forgejo-cli` | Argparse Forgejo API v1 client | | `references/command-reference.md` | Endpoint and payload guide | | `references/api-usage.md` | Authentication, pagination, versioning, and schema-discovery procedure | | `references/endpoint-routing.md` | Decision guide for first-class commands versus generic API calls | | `references/troubleshooting.md` | Safe diagnosis of API and transport failures | | `V2-SPEC.md` | v2 acceptance criteria | | `tests/` | Offline stdlib contract tests | ## Quick Start Set `FORGEJO_AGENT_TOKEN` (default) or `FORGEJO_USER_TOKEN`, then run: ```bash python3 scripts/forgejo-cli --dry-run --json repo create --name demo --private python3 scripts/forgejo-cli --server https://forge.example api --method GET --path /api/v1/user --json python3 scripts/forgejo-cli --server https://forge.example --page 1 --limit 50 --include-response issue list --owner acme --repo app --json ``` ## Triggers - Managing Forgejo/Gitea issues, PRs, repos, file contents, releases, or hooks. - Calling a version-specific `/api/v1/` endpoint safely. - Previewing a Forgejo mutation. ## Requirements Python 3.8+ and `requests` for live API calls. `--help` and `--dry-run` need no token or dependency. Set `FORGEJO_AGENT_TOKEN` or `FORGEJO_USER_TOKEN` for token authentication. A deliberate `Authorization` header supports other documented schemes, but avoid putting secrets directly in shell history. Consult your Forgejo server's `/api/swagger` or `/swagger.v1.json` for exact schemas. -
SKILL.md 2.5 KB
--- name: forgejo-cli description: >- Use when managing a Forgejo or Gitea server from the terminal: issues, pull requests, repositories, file contents, labels, milestones, releases, webhooks, user settings, or any /api/v1 endpoint through a safe generic API command. Do not use this skill for unrelated requests; route to the nearest named specialist. license: MIT compatibility: Python 3.8+; requests is required only for live API calls. metadata: version: 2.0.0 tags: forgejo, gitea, git, api, code-review --- # Forgejo CLI v2 Run `python3 scripts/forgejo-cli`. `--agent` (default) uses `FORGEJO_AGENT_TOKEN`; `--user` uses `FORGEJO_USER_TOKEN`; `--server URL` selects an installation. Set `FORGEJO_SERVER` in your shell if your wrapper supplies it, otherwise pass `--server` explicitly. ## Safety - Mutations require `--force`/`--yes`/`-y`, or `--dry-run`. - `--dry-run --json` emits one plan with `method`, `path`, `query`, and `body`; it makes no network request. - `--json` writes exactly one JSON value to stdout; diagnostics go to stderr. - `--page` and `--limit` work for any list/search request. Add `--include-response` to receive the HTTP status plus `link` and `x-total-count` pagination headers. - `--help` does not read credentials or contact a server. Path segments are encoded. ## Common workflows ```bash python3 scripts/forgejo-cli issue list --owner acme --repo app --json python3 scripts/forgejo-cli --dry-run --json repo create --name demo --private python3 scripts/forgejo-cli --dry-run --json api --method POST \ --path /api/v1/repos/acme/app/actions/variables --data '{"name":"KEY","value":"value"}' ``` First-class groups: `issue`, `pr`, `repo`, `content`, `label`, `milestone`, `release`, `hook`, and `user`. `content` expects base64 and update/delete require the current SHA. Use `api` for any other `/api/v1/` endpoint; it supports JSON, raw files, multipart uploads/forms, and custom headers. Consult `/api/swagger` or `/swagger.v1.json` on the selected server. See [command reference](references/command-reference.md). ## Choosing a command Use a first-class command for its covered daily workflow. Use `api` when the operation is absent, requires version-specific fields, or needs a schema not represented by a simple flag. Before using `api`, read [endpoint routing](references/endpoint-routing.md); read [API usage](references/api-usage.md) for authentication, pagination, compatibility, and safe schema discovery. Read [troubleshooting](references/troubleshooting.md) for 401/403/422 responses and transport failures. -
V2-SPEC.md 819 B
# Forgejo CLI v2 implementation specification Provide polished collaboration and repository commands plus a safe generic `/api/v1/` escape hatch. The CLI must require confirmation for mutations, produce credential-free dry-run plans, encode path segments, and keep JSON stdout machine-readable. Acceptance: tests verify help, mutation gating, generic path validation, JSON plans, repository creation without owner/repo, and representative issue, PR, release, content, and webhook requests. Live transport tests must cover multipart or form delivery, caller-provided authentication, response pagination metadata, missing-server failure, and nested content paths. Documentation must explain version-aware Swagger discovery, scope-aware authentication, pagination, and when a generic endpoint is the appropriate choice.
Comments (0)
Sign in to join the conversation.
Reviews (0)
No reviews yet.
No comments yet.