2026-05-31 Repository implementation Issue gh-forgejo-shim-uku

Built the initial gh-forgejo-shim V1 package

This turn converted the repository from a Beads-initialized shell into a stdlib-only Python CLI package with an opt-in gh wrapper for Codex.app workflows in Forgejo repositories.

Packagepipx-ready Python project with the gh-forgejo-shim command.
RoutingSupported Forgejo PR commands route locally, other commands delegate to real gh.
Validation32 unit tests, compile check, CLI smoke test, and venv package install passed.

Summary

Implemented V1 of gh-forgejo-shim: a Python 3.11+ package with no runtime dependencies, a durable management CLI, a reversible generated gh wrapper, opt-in Forgejo host routing, PR create/view/status behavior, GitHub-shaped JSON normalization, docs, and tests.

Changes Made

Packaging and CLI

Added pyproject.toml, package metadata, console script registration, version output, and a management command surface for shim install, uninstall, doctor, config, and version.

Config and routing

Added TOML config loading, env override merging, explicit host allowlisting, repository detection from -R, GH_REPO, GH_HOST, and git remotes, plus delegation to the real GitHub CLI when a command or host is out of scope.

Forgejo PR behavior

Added PR create flag parsing, unsupported metadata flag errors, REST client calls, current branch view/status lookup, no-current-branch empty success behavior, and normalized JSON fields.

Docs and tests

Added README, configuration docs, rollback docs, contributing notes, Python ignore rules, and a focused stdlib unittest suite.

Context

Codex.app expects GitHub-like PR commands in repositories. Forgejo repositories do not speak the full GitHub CLI contract, so this project narrows the surface area to commands Codex is likely to call and leaves everything else with the real gh. This keeps GitHub behavior intact while making Forgejo repos less brittle under automation.

The repository uses Beads. The implementation issue is gh-forgejo-shim-uku. Two follow-up Beads tasks were opened for work that should remain outside this V1 pass.

Important Implementation Details

Relevant Diff Snippets

The snippets below use the Diffs FileDiff component, following the documented model of rendering two versions of a file into a container. If the external renderer is unavailable, the static fallback code blocks remain visible. Reference: Diffs documentation.

Package entry point

[project.scripts]
gh-forgejo-shim = "gh_forgejo_shim.cli:main"

Forgejo routing decision

if len(argv) < 2 or argv[0] != "pr" or argv[1] not in SUPPORTED_PR_COMMANDS:
    return RouteDecision("delegate", "unsupported command")

detection = detect_repo(argv, env=env, cwd=cwd)
if detection.repo is None:
    return RouteDecision("delegate", "no repository detected")
if not config.is_forgejo_host(detection.repo.host):
    return RouteDecision("delegate", f"host {detection.repo.host} is not allowlisted", detection.repo)
return RouteDecision("forgejo", detection.source, detection.repo)

No-current-branch PR compatibility

if pull is None:
    if parsed.json_fields:
        print("{}", file=stdout)
    return 0

Expected Impact for End-Users

Users can install the package with pipx, explicitly allowlist Forgejo hosts, and install the reversible gh wrapper. Codex.app can then run common PR create/status/view commands in Forgejo repositories without breaking normal GitHub repositories on the same machine.

Validation

Issues, Limitations, and Mitigations

Follow-up Work