ghfs

GitHub issues/PRs as filesystem, for offline view and operations in batch. Designed for human and agents.

263
10
263
2
TypeScript
public

ghfs

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.

Web UI

ghfs ships a local web UI for browsing and acting on the synced mirror.

ghfs ui — single project

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 (default 7710).
  • --host <addr> — bind address (default 127.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.

ghfs hub — multi-project dashboard

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 ~/projects

The 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; press X to 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).

Saved replies

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.yml in the repository. ghfs supports the refined-saved-replies convention, 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.

Execute operations

ghfs also allows you to take actions on the issues and pull requests in batch.

ghfs execute merges operations from multiple sources:

  1. execute.md (human-friendly commands)
  2. per-issue markdown frontmatter changes (from .ghfs/issues/**/*.md and .ghfs/pulls/**/*.md)
  3. execute.yml (explicit YAML operations)

Note: execution merge order is execute.yml -> execute.md -> per-issue generated operations.

1) execute.md (recommended)

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 -> close
  • open -> reopen
  • close-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.

2) Per-issue operations

Edit frontmatter directly in issue/PR markdown files:

  • title
  • state (open / closed)
  • labels
  • assignees
  • milestone

ghfs execute will diff these values and generate operations automatically (for example set-title, close/reopen, label updates, assignee updates, milestone updates).

3) execute.yml

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

Agent Skill

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

Configuration

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...
})

TODOs

  • execute.md file with human-friendly instructions (close #123 #234, set-title #125 "New title"
  • Directly editing the <5-digit-number>-<slug>.md
  • Local Web UI for managing the local mirror (ghfs ui and ghfs hub
v0.3.3[beta]