gh-issue-sync CLI
A Go tool for GitHub issues: Markdown files on disk that an agent edits in bulk and the push command sends back.
- 169 ★ on the repository
- Last commit
- Apache-2.0
Extended access
Why this level
- `push` creates and changes issues, labels and milestones on GitHub in your name; edits stay local until you send them.
Install
- Works in
Manual install
curl -sSfL https://github.com/mitsuhiko/gh-issue-sync/releases/latest/download/install.sh | shThe first README option for macOS and Linux; an authenticated `gh` is required.
Access and checks
How we reviewExtended accessThe tool runs code or makes network calls and only reads external data.
- `push` creates and changes issues, labels and milestones on GitHub in your name; edits stay local until you send them.
This is third-party code. Review the repository files before installing.
What it does
`gh-issue-sync` mirrors a repository's issues into an `.issues/` folder as Markdown files with a YAML header: title, labels, assignees, milestone and state. Files sit in `open/` and `closed/`, and the number comes from the file name. You edit them in an editor or hand them to an agent, then `gh-issue-sync push` sends the changes to GitHub and `pull` fetches others' changes. New issues are created locally with temporary numbers like `T42`, receive real ones after the push, and references such as `#T42` in other files are rewritten automatically. Sync compares three versions (local, original and remote) and skips a file with a warning on conflict. The `write-skill` command drops a ready skill into the Claude Code, Codex, OpenCode, Pi or Amp directory so the agent knows the commands. It runs on top of an authenticated `gh`.
Who it is for. Maintainers with a pile of issues who want to polish wording with Claude Code or Codex and send the edits in one operation.
Good fit when
- Fifty issues need consistent titles and labels, and an agent edits them locally.
- A backlog has to be triaged offline, with text and label search running over files on disk.
- A dozen new issues grow out of notes and are drafted without numbers.
- An agent closes duplicates: moving a file from `open/` to `closed/` or `close --reason not_planned`.
- You want a readable backup of every open issue inside the repository.
Not a fit when
- Several people edit issues at the same time: on divergence a file is skipped and conflicts are resolved by hand.
- An agent needs only point actions in GitHub: wrapping `gh` or connecting the GitHub MCP server is simpler.
- There is no authenticated `gh`: the tool relies on it and does nothing without a login.
Example request
Pull the issues, find duplicates and empty requests among the open ones, fill them in under `.issues/open/` and show `gh-issue-sync status` before pushing.Limitations
Needs an installed and authenticated GitHub CLI `gh`; syncing Projects requires `gh auth refresh -s project`. Conflicts between local and remote edits are not merged automatically: the file is skipped with a warning (overwriting is enabled with `--force`). The author states that the code was written entirely by an LLM and that whether it can be copyrighted is unclear. The latest commit in the repository is from March 2026.
How to disable. Delete the `gh-issue-sync` binary, the `.issues/` folder in the repository and the skill from the agent's directory (`write-skill` prints the install path).
FAQ
How do I install gh-issue-sync?
Run `curl -sSfL https://github.com/mitsuhiko/gh-issue-sync/releases/latest/download/install.sh | sh` on macOS or Linux. There is also `go install github.com/mitsuhiko/gh-issue-sync/cmd/gh-issue-sync@latest` and prebuilt binaries in releases.
How do I teach Claude Code to use it?
Run `gh-issue-sync write-skill --agent claude`. The skill lands in `~/.claude/skills/`, or in the project's `.claude/skills/` with `--scope project`.
What happens when edits conflict?
If a file changed both locally and on GitHub, `pull` and `push` skip it with a warning. Use `--force` to overwrite the local version with the remote one.
How do I create an issue without a number?
Run `gh-issue-sync new "Title"` or add a file whose name starts with `T`, such as `T1a2b3c-my-issue.md`. After `push` the file gets a real number and `#T1a2b3c` references are updated.
How do I filter issues?
`gh-issue-sync list --label bug --assignee alice` or a GitHub-style query: `--search "error no:assignee sort:created-asc"`. The `--all` flag adds closed issues.
Discussion
No questions or reviews yet.
Related
CLI toolsGitHub CLI skills
GitHub CLI skills (gh, gh-skill)
Official GitHub CLI skills: how an agent should call gh correctly and how to manage skills with gh skill
A GitHub CLI extension and agent skill that uploads screenshots, PDFs, archives and logs to issues and pull requests and returns a ready link
The GitHub CLI extension gh stack and an agent skill: a chain of dependent branches and PRs with rebase, submit and merge of the whole stack
The terminal GitHub dashboard shows issues and pull requests so users can review agent work in configurable sections.
A CLI and MCP server that search package and repository source, read exact files and return examples with cited sources.
The author's personal set: shared agent rules and dozens of skills for GitHub, the browser, macOS, messaging and releases, plus a sync script
Comparison with similar tools
Cards that share the main search query, and how they differ.
| Tool | Official | Authentication | Repository stars | Main difference |
|---|---|---|---|---|
| gh-issue-sync (this card) | no | 169 | ||
| gh-axi | no | 359 | a `gh` wrapper with compact output for online work; here issues are stored as files and edited offline | |
| GitHub MCP Server | no | key is optional | 34,279 | gives an agent GitHub API calls; `gh-issue-sync` syncs issues with a local Markdown folder |
README in short
The README explains why to work on issues locally and leads from installation through a quickstart to search syntax, temporary numbers and a conflict-resolution table. A separate section covers installing the skill into different agents.
README badge
Original SKILL.md
--- name: gh-issue-sync description: "Manage GitHub issues locally as Markdown files. Use for triaging, searching, editing, and creating issues without leaving your editor or terminal." --- # gh-issue-sync Syncs GitHub issues to local Markdown files in `.issues/open/` and `.issues/closed/`. ## Commands ``` gh-issue-sync init # Initialize in git repo gh-issue-sync pull # Fetch open issues (--all for closed too) gh-issue-sync push # Push local changes (--dry-run to preview) gh-issue-sync list # List issues (supports gh issue list flags + --search) gh-issue-sync new "Title" # Create issue (--label, --edit) gh-issue-sync close 42 # Close (--reason completed|not_planned) gh-issue-sync reopen 42 gh-issue-sync status # Show local changes gh-issue-sync diff 42 # Show diff (--remote to re-fetch) ``` ## File Format `.issues/open/42-fix-login-bug.md`: ```markdown --- title: Fix login bug labels: [bug, priority:high] assignees: [alice] milestone: v1.0 state: open # For closed: state_reason: completed|not_planned # Optional: parent: 10, blocked_by: [11, 12], blocks: [15] --- Issue body in Markdown. ``` Issue number is derived from the filename, not stored in frontmatter. ## Temporary Issues New issues get a `T`-prefixed ID (e.g., `T1a2b3c`). The filename must start with `T`: ``` .issues/open/T1a2b3c-my-new-issue.md ``` On `push`, the file is renamed to the real issue number (e.g., `42-my-new-issue.md`) and `number:` in frontmatter is updated. Any `#T1a2b3c` references in other issues are also updated to `#42`.