GitHub issues/PRs as filesystem, for offline view and operations in batch. Designed for human and agents.
Important
Still working in progress, not usable yet.
pnpm install @ghfs/cli
and then run the command inside a repository directory:
ghfs
It will sync the open issues and pull requests to the local filesystem under .ghfs directory, like:
.ghfs/ repo.json # repository basic information issues.md # index of fetched issues pulls.md # index of fetched pull requests execute.md # queued operations issues/ 00134-some-bug.md closed/ 00135-fixed-crash.md pulls/ 00042-add-cache.md 00042-add-cache.patch closed/ 00043-release-cleanup.md
Then you can view them offline, or ask your local agent to summarize them for you.
ghfs ships a local web UI for browsing and acting on the synced mirror.
Run inside a repository directory after a sync. Opens a browser tab with a two-pane (list + detail) view of the project's issues and PRs.
ghfs ui
Flags:
--port <number>— port to listen on (default7710).--host <addr>— bind address (default127.0.0.1).--cwd <path>— project directory; defaults to the current working directory.--no-open— don't auto-open the browser (useful for headless setups).
The UI is read-and-queue: edits made in the interface are queued to .ghfs/execute.yml and .ghfs/execute.md — you still apply them with ghfs execute --run.
Point at a directory that contains multiple project checkouts and ghfs hub scans for git repositories, lets you enable the ones you want, and exposes them all in one dashboard.
ghfs hub --cwd ~/projectsThe hub keeps its enabled-project list and auto-sync interval in ~/.config/ghfs/hub.json, keyed by the hub root. Switching roots remembers each root's selection independently.
Features:
- Project cards with activity sparkline, open issue / PR counts, last updated and last synced badges.
/recent— cross-project list of recently-updated issues and PRs.- Queue drawer (
q) — aggregated queue across all enabled projects with per-project execute; pressXto execute everything. - Settings dialog (
,) for hub root and an optional auto-sync interval (1–60 minutes).
Flags mirror ghfs ui (--port, --host, --cwd, --no-open).
Insert canned replies into the comment composer with one click — or press ⌘ . (Ctrl . on Linux/Windows) when the composer is focused. Replies come from two scopes, surfaced in a single picker with a per-item indicator:
- This repo —
.github/replies.ymlin the repository. ghfs supports therefined-saved-repliesconvention, so the same file works in the refined-saved-replies browser extension and any other tool that adopts it. Commit the file so the whole team shares them. - Global — per-user replies stored in
~/.config/ghfs/hub.json.
Edit either set from the Settings dialog (,) under the Saved replies tab. Bodies support a small set of placeholders, replaced at insertion time against the issue/PR being viewed:
| Placeholder | Resolves to |
|---|---|
{{author}} |
@<login> of the item's author |
{{number}} |
The issue / PR number |
{{title}} |
The item's title |
Example .github/replies.yml:
- title: Thanks body: | Thanks for the report, {{author}}! We'll take a look at #{{number}}. - title: Needs reproduction body: Could you share a minimal reproduction?
GitHub's own user "saved replies" (at github.com/settings/replies) have no public REST API, so ghfs can't sync them — global templates are managed entirely through ghfs.
ghfs also allows you to take actions on the issues and pull requests in batch.
ghfs execute merges operations from multiple sources:
execute.md(human-friendly commands)per-issuemarkdown frontmatter changes (from.ghfs/issues/**/*.mdand.ghfs/pulls/**/*.md)execute.yml(explicit YAML operations)
Note: execution merge order is execute.yml -> execute.md -> per-issue generated operations.
execute.md is best for quick/manual batching:
close #123 #234 set-title #125 "New title" label #125 bug, enhancement close-comment #126 "Closing this as completed"
Action names in both execute.yml and execute.md are case-insensitive and support aliases, including:
closes->closeopen->reopenclose-comment/comment-close/close-and-comment/comment-and-close->close-with-comment
execute.md also supports comment lines with # and //, plus HTML comment blocks using <!-- ... -->. These comments are preserved when operations are rewritten.
Edit frontmatter directly in issue/PR markdown files:
titlestate(open/closed)labelsassigneesmilestone
ghfs execute will diff these values and generate operations automatically (for example set-title, close/reopen, label updates, assignee updates, milestone updates).
ghfs sync or ghfs execute will auto-create .ghfs/execute.yml and .ghfs/schema/execute.schema.json if missing.
Use execute.yml for explicit/low-level operations:
# close the issue #123 - action: close number: 123 # change the title of the issue #125 to "New title" - action: set-title number: 125 title: New title # add the labels "bug" and "feature" to the issue #125 - action: add-labels number: 125 labels: [bug, feature]
Then run ghfs execute to preview, and ghfs execute --run to execute.
ghfs execute ghfs execute --run
This repository ships an agent skill at skills/ghfs/SKILL.md.
Install with skills CLI:
pnpx skills add antfu/ghfs
The @ghfs/cli also ship the skills into the npm package that you can have it also installed with skills-npm:
pnpm i -D @ghfs/cli pnpx skills-npm
You can configure by creating a ghfs.config.ts file in the root of the repository.
import type { GhfsUserConfig } from '@ghfs/cli' export default defineConfig({ repo: 'owner/name', sync: { issues: true, // set false to skip issue sync pulls: true, // set false to skip pull request sync }, // other options... })
-
execute.mdfile with human-friendly instructions (close #123 #234,set-title #125 "New title"). - Directly editing the
<5-digit-number>-<slug>.mdfile to apply the operations. - Add a VS Code extension for guided sync/execute.
- Documentation.
- Index page, and basic repo info
- Agent Skills.
- Local Web UI for managing the local mirror (
ghfs uiandghfs hub).