From a4658bccc70c5b75ca3ceda6d6b5007aad983527 Mon Sep 17 00:00:00 2001 From: Coding-Dev-Tools Date: Sun, 21 Jun 2026 00:55:33 -0400 Subject: [PATCH 1/5] fix(cli): correct command names (show/rotate/revoke/verify/export/audit/stats) and fix Windows UTF-8 encoding MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 7 commands were registered with name='list' instead of their proper names, causing silent overwrites — only the last registered 'list' command worked - Add sys.stdout/stderr.reconfigure(encoding='utf-8') on Windows to prevent cp1252 encoding crashes with Rich library Unicode symbols --- src/apiauth/cli.py | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/src/apiauth/cli.py b/src/apiauth/cli.py index 759ee5c..72099a6 100644 --- a/src/apiauth/cli.py +++ b/src/apiauth/cli.py @@ -9,6 +9,14 @@ from rich.table import Table from typing import Any +# Ensure UTF-8 output on Windows consoles that default to cp1252 +if sys.platform == "win32": + try: + sys.stdout.reconfigure(encoding="utf-8") + sys.stderr.reconfigure(encoding="utf-8") + except Exception: + pass + from . import __version__ from .keygen import create_api_key_entry, create_jwt_entry, rotate_jwt, rotate_key from .keystore import Keystore @@ -176,7 +184,7 @@ def list_keys(ctx: click.Context, service: str | None, json_output: bool, show_e # ── show ────────────────────────────────────────────────────────────── -@cli.command(name="list") +@cli.command(name="show") @click.argument("key_id") @click.pass_context def show(ctx: click.Context, key_id: str) -> None: @@ -199,7 +207,7 @@ def show(ctx: click.Context, key_id: str) -> None: # ── rotate ──────────────────────────────────────────────────────────── -@cli.command(name="list") +@cli.command(name="rotate") @click.argument("key_id") @click.option("--expiry-days", "-e", type=int, default=None, help="New expiry in days") @click.pass_context @@ -230,7 +238,7 @@ def rotate(ctx: click.Context, key_id: str, expiry_days: int | None) -> None: # ── revoke ──────────────────────────────────────────────────────────── -@cli.command(name="list") +@cli.command(name="revoke") @click.argument("key_id") @click.pass_context def revoke(ctx: click.Context, key_id: str) -> None: @@ -249,7 +257,7 @@ def revoke(ctx: click.Context, key_id: str) -> None: # ── verify ──────────────────────────────────────────────────────────── -@cli.command(name="list") +@cli.command(name="verify") @click.argument("api_key") @click.option("--json-output", "-j", is_flag=True, help="Output as JSON") @click.pass_context @@ -347,7 +355,7 @@ def import_key( # ── export ──────────────────────────────────────────────────────────── -@cli.command(name="list") +@cli.command(name="export") @click.option("--format", "-f", "fmt", type=click.Choice(["env", "json", "dotenv", "github-actions"]), default="env") @click.option("--service", "-s", default=None, help="Filter by service") @click.pass_context @@ -432,7 +440,7 @@ def _export_github_actions(active: list[dict]) -> None: # ── audit ───────────────────────────────────────────────────────────── -@cli.command(name="list") +@cli.command(name="audit") @click.pass_context def audit(ctx: click.Context) -> None: """Audit keystore: find expired, expiring, and revoked keys.""" @@ -491,7 +499,7 @@ def audit(ctx: click.Context) -> None: # ── stats ───────────────────────────────────────────────────────────── -@cli.command(name="list") +@cli.command(name="stats") @click.pass_context def stats(ctx: click.Context) -> None: """Show keystore statistics.""" From cb52ec03f8cf05e9bd787d1e3bfde5451f404a55 Mon Sep 17 00:00:00 2001 From: Coding-Dev-Tools Date: Tue, 23 Jun 2026 02:38:16 -0400 Subject: [PATCH 2/5] docs: add AGENTS.md for agent discoverability --- .gitignore | 1 - AGENTS.md | 30 ++++++++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) create mode 100644 AGENTS.md diff --git a/.gitignore b/.gitignore index 18afbeb..4013739 100644 --- a/.gitignore +++ b/.gitignore @@ -20,6 +20,5 @@ Thumbs.db .ruff_cache/ # Local opencode config -AGENTS.md .agents/ diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..b703b8d --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,30 @@ +# apiauth + +## Purpose +CLI tool for API key and JWT lifecycle management with encrypted local store — generate, store, verify, rotate, and revoke keys with an encrypted local keystore. + +## Build & Test Commands +- Install: `pip install -e .` or `pip install apiauth` +- Test: `pytest tests/` (or `python -m pytest tests/ -v --tb=short`) +- Lint: `ruff check src/ --target-version py310` +- Build: `pip wheel . --wheel-dir dist/` +- CLI check: `apiauth --version && apiauth --help` + +## Architecture +Key directories: +- `src/apiauth/` — Main package (CLI, keystore, crypto, commands) +- `tests/` — Test suite +- `.github/workflows/` — CI/CD (auto-code-review.yml, ci.yml, publish.yml) +- `dist/` — Built distributions + +## Conventions +- Language: Python 3.10+ +- Test framework: pytest +- CI: GitHub Actions (matrix: Python 3.10, 3.11, 3.12, 3.13) +- Linting: ruff (line-length 120, target py310) +- Formatting: ruff +- Package layout: src/ layout with setuptools +- Type checking: py.typed included +- Dependencies: click, cryptography, pyjwt, rich, python-dateutil +- CLI entry point: apiauth.cli:cli +- Master branch: master \ No newline at end of file From d12b42bb3138f949f2318305a3623712e5f57797 Mon Sep 17 00:00:00 2001 From: Coding-Dev-Tools Date: Tue, 23 Jun 2026 21:09:48 -0400 Subject: [PATCH 3/5] fix: add missing newline at EOF in dependabot.yml --- .github/dependabot.yml | Bin 271 -> 264 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index da6115bedfa394604598f5c92a2c1b2ef88bd9a0..028a26d5821f8941eb82b3e4b77ebc7b049beac2 100644 GIT binary patch delta 129 zcmeBY>R=KsOD!tS%+Iq@FybmLNJ%V7Ew-B2E5TflSuoL1Sd~iw2#S+4Qd3HEQmw!| n1%=GKlGLKI#2hPy^3>GqoXUysH5=Qp4YC?b)N(nKzlYqYCF_={gRr1g8)? z4n&5E^Q)U-;Inj5Y?ca_qazAj;WgK8X}U~jCVoL^5#RX%aZ=RXMN2PWjs3)OK{BPq dXeyo!qGBR%td{OSe`nUEJ&g1EQI$U`+} Date: Tue, 23 Jun 2026 21:34:41 -0400 Subject: [PATCH 4/5] improve: update dependency versions for security and compatibility - click>=8.4.1 (from 8.1.0) - cryptography>=48.0.1 (from 46.0.6) - addresses GHSA-537c-gmf6-5ccf - python-dateutil>=2.9.0.post0 (from 2.8.0) --- pyproject.toml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 245b54b..d05b18d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -24,11 +24,11 @@ classifiers = [ "Programming Language :: Python :: 3.13", ] dependencies = [ - "click>=8.1.0", - "cryptography>=46.0.6", + "click>=8.4.1", + "cryptography>=48.0.1", "pyjwt>=2.12.0", "rich>=13.0.0", - "python-dateutil>=2.8.0", + "python-dateutil>=2.9.0.post0", ] [project.urls] From 91a9b800779bee968f01e1f140e8e0076fd30e6b Mon Sep 17 00:00:00 2001 From: Coding-Dev-Tools Date: Tue, 23 Jun 2026 22:42:03 -0400 Subject: [PATCH 5/5] improve: update dependency versions for security and compatibility --- pyproject.toml | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index d05b18d..8f55c1c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -25,7 +25,7 @@ classifiers = [ ] dependencies = [ "click>=8.4.1", - "cryptography>=48.0.1", + "cryptography>=49.0.0", "pyjwt>=2.12.0", "rich>=13.0.0", "python-dateutil>=2.9.0.post0", @@ -40,11 +40,12 @@ Changelog = "https://github.com/Coding-Dev-Tools/apiauth/releases" [project.optional-dependencies] dev = [ - "pytest>=7.0.0", - "pytest-cov>=4.0.0", - "ruff>=0.4.0", - "httpx>=0.27.0", - "freezegun>=1.2.0", + "pytest>=9.1.1", + "pytest-cov>=7.1.0", + "ruff>=0.15.19", + "httpx>=0.28.1", + "freezegun>=1.5.5", + "pytest-asyncio>=1.4.0", ] [project.scripts]