Skip to content
flarebytePublic

About

Hit your GitHub target every time with this utility to copy files

Topics

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

12 Commits

Folders and files

Repository files navigation

gh-arrow

A Go GitHub CLI extension to copy, display, synchronise, and discover files in GitHub repositories and mapped local projects. Invoke it as gh arrow.

Install

Release installation requires GitHub CLI and a published release with an artifact for your platform. To build from this checkout, use the development setup. When a release is available, run:

gh extension install flarebyte/gh-arrow
gh arrow --version
gh arrow --help
gh arrow cat github:flarebyte:gh-arrow:README.md

To pin a specific published tag, replace <release-tag> below:

gh extension install flarebyte/gh-arrow --pin '<release-tag>'

Configured release builds target darwin-arm64, linux-amd64, and windows-amd64.

Usage

gh arrow cp github:owner:project:path/to/file.yaml ./local.yaml
gh arrow cat local:project2:file.md
gh arrow cat github:owner:project:README.md --ref main
gh arrow ls 'github:owner:project:docs/**/*.md'
gh arrow ls --org tools-org --topic cli README.md --json

Sources use github:<owner>:<repo>:<path> or local:<alias>:<path>. Paths use forward slashes; colon is reserved. Quote shell globs. ls supports filename * and recursive directory **; cat and cp treat filename metacharacters literally. Organization/user discovery checks exact file paths.

GitHub sources prefer configured local working trees. A mapping deliberately selects local files: missing mapped files fail without a remote fallback. --ref selects a remote branch, tag, or commit and is rejected for mapped sources and discovery.

Mappings are loaded from the global CUE file ~/.gh-arrow, or from --config <path>. Arrow never discovers repository mappings in a checkout; sync reads its separate project manifest. Roots must be absolute local paths. A missing default config means no mappings; a missing explicitly selected config is an error. No separate CUE executable is needed.

local: mappings: [{
    repo: "project2"
    root: "/absolute/path/to/project2"
}]

The embedded schema rejects unknown fields and incomplete values; imports are not allowed. See the full configuration example. Keep credentials out of this file.

Remote access uses GitHub.com and existing gh credentials. For private repositories, authenticate separately with gh auth login. Arrow never prompts, launches a browser, or stores tokens in its config. Public access can work without stored credentials. GitHub Enterprise hosts are outside this version's scope.

cp copies one file, requires an existing destination parent, and refuses an existing destination unless --force is given. It stages complete bytes before publication and rejects symlink destinations. Source permissions and timestamps are not copied; new files use private permissions.

cat writes exact bytes, with no added newline. Successful cp writes no stdout. Listings are sorted; text escapes control characters, while --json preserves Unicode path values. JSON listings are arrays, including [] for no matches; discovery records additionally contain repository. Diagnostics go to stderr with stable ARROW_* codes. Exit status is 0 for success, 1 for I/O/network/authentication failures, 2 for invalid arguments or configuration, and 3 for sync check drift.

Synchronise project files

Declare the files your project consumes in sync.gh-arrow.cue:

version: 1
files: [{
    source:      "github:owner:project:path/to/file.yaml"
    destination: "local.yaml"
}]

Run from that project directory:

gh arrow sync status          # List unchanged, modified, or missing files
gh arrow sync diff            # Review local-to-upstream differences
gh arrow sync --dry-run       # Preview without writing
gh arrow sync                 # Create missing files and replace changed files
gh arrow sync check --json    # Audit: exit 0 when in sync, 3 for drift

Use --file <path> to select another manifest. Destinations are relative to its directory; parents must already exist. Sync handles exact files only, rejects symlinks, traversal and duplicate destinations, and never deletes undeclared files. A declaration authorises replacement of local edits; sync does not merge.

Mapped sources read the current working tree, including uncommitted changes; unmapped GitHub sources read the current default branch. Sync does not accept ref or --ref. Each remote repository resolves once per run. --config still selects machine-local repository mappings; status output identifies the selected local or github backend. --json is available for status, check, dry-run and apply; records contain source, destination, status, and backend, sorted by destination. Apply reports the statuses observed before writing.

All sources are staged before any destination changes. Each changed file is replaced atomically; publication failure can leave earlier files applied, with the applied count in the diagnostic. Binary differences, text containing unsafe terminal controls, and missing empty files receive a notice; text diffs use a unified replacement hunk with three lines of surrounding context. Files exceeding 8 MiB per side receive a difference notice instead of a patch.

Documentation

AI agents should start with AGENTS.md. This project includes an MIT license.

About

Hit your GitHub target every time with this utility to copy files

Topics

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages