@ghfs/cli 0.0.0 → 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.md +21 -0
- package/README.md +101 -72
- package/package.json +39 -13
- package/skills/ghfs/SKILL.md +98 -0
- package/dist/cli.d.mts +0 -1
- package/dist/cli.mjs +0 -1276
- package/dist/index.d.mts +0 -53
- package/dist/index.mjs +0 -7
package/LICENSE.md
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025-PRESENT Anthony Fu <https://github.com/antfu>
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,97 +1,126 @@
|
|
|
1
1
|
# ghfs
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
GitHub issues/PRs as filesystem, for offline view and operations in batch. Designed for human and agents.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
> [!IMPORTANT]
|
|
6
|
+
> Still working in progress, not usable yet.
|
|
6
7
|
|
|
7
8
|
```bash
|
|
8
|
-
pnpm install
|
|
9
|
-
pnpm build
|
|
9
|
+
pnpm install @ghfs/cli
|
|
10
10
|
```
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
and then run the command inside a repository directory:
|
|
13
13
|
|
|
14
14
|
```bash
|
|
15
|
-
ghfs
|
|
16
|
-
ghfs sync [--repo owner/name] [--since ISO] [--full]
|
|
17
|
-
ghfs execute [--file .ghfs/execute.yml] [--apply] [--non-interactive] [--continue-on-error]
|
|
18
|
-
ghfs status
|
|
19
|
-
ghfs schema
|
|
15
|
+
ghfs
|
|
20
16
|
```
|
|
21
17
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
```ts
|
|
25
|
-
import { defineConfig } from '@ghfs/cli'
|
|
26
|
-
|
|
27
|
-
export default defineConfig({
|
|
28
|
-
repo: 'owner/name',
|
|
29
|
-
storageDir: '.ghfs',
|
|
30
|
-
executeFile: '.ghfs/execute.yml',
|
|
31
|
-
})
|
|
32
|
-
```
|
|
33
|
-
|
|
34
|
-
Precedence: `CLI flags > ghfs.config.ts > auto-detect (.git/package.json) > .ghfs/.sync.json`.
|
|
35
|
-
|
|
36
|
-
## Local Files
|
|
18
|
+
It will sync the open issues and pull requests to the local filesystem under `.ghfs` directory, like:
|
|
37
19
|
|
|
38
20
|
```txt
|
|
39
21
|
.ghfs/
|
|
40
|
-
.
|
|
41
|
-
|
|
42
|
-
|
|
22
|
+
repo.json # repository basic information
|
|
23
|
+
issues.md # index of fetched issues
|
|
24
|
+
pulls.md # index of fetched pull requests
|
|
43
25
|
issues/
|
|
44
|
-
|
|
45
|
-
123.patch
|
|
26
|
+
00134-some-bug.md
|
|
46
27
|
closed/
|
|
47
|
-
|
|
28
|
+
00135-fixed-crash.md
|
|
29
|
+
pulls/
|
|
30
|
+
00042-add-cache.md
|
|
31
|
+
00042-add-cache.patch
|
|
32
|
+
closed/
|
|
33
|
+
00043-release-cleanup.md
|
|
48
34
|
```
|
|
49
35
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
- `
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
- `set-assignees`
|
|
69
|
-
- `set-milestone`
|
|
70
|
-
- `clear-milestone`
|
|
71
|
-
- `lock`
|
|
72
|
-
- `unlock`
|
|
73
|
-
- `request-reviewers` (PR)
|
|
74
|
-
- `remove-reviewers` (PR)
|
|
75
|
-
- `mark-ready-for-review` (PR)
|
|
76
|
-
- `convert-to-draft` (PR)
|
|
77
|
-
|
|
78
|
-
Each entry is one action object with `action`, `number`, and action-specific payload fields.
|
|
79
|
-
|
|
80
|
-
## Execute File Example
|
|
36
|
+
Then you can view them offline, or ask your local agent to summarize them for you.
|
|
37
|
+
|
|
38
|
+
## CLI feedback
|
|
39
|
+
|
|
40
|
+
`ghfs` now provides stage-based sync feedback.
|
|
41
|
+
|
|
42
|
+
- In interactive terminals (TTY), `ghfs` uses rich progress indicators.
|
|
43
|
+
- In CI or piped output, `ghfs` prints deterministic plain-text progress lines.
|
|
44
|
+
- `ghfs sync --full` bypasses metadata early-return and runs full pagination.
|
|
45
|
+
|
|
46
|
+
`ghfs status` now also includes diagnostics from the latest sync run (duration, request count, counters, and stage timings) from `.ghfs/.sync.json`.
|
|
47
|
+
|
|
48
|
+
## Execute operations
|
|
49
|
+
|
|
50
|
+
`ghfs` also allows you to take actions on the issues and pull requests in batch.
|
|
51
|
+
|
|
52
|
+
`ghfs sync` or `ghfs execute` will auto-create `.ghfs/execute.yml` and `.ghfs/schema/execute.schema.json` if missing.
|
|
53
|
+
Then edit `.ghfs/execute.yml` with content like:
|
|
81
54
|
|
|
82
55
|
```yaml
|
|
56
|
+
# close the issue #123
|
|
57
|
+
- action: close
|
|
58
|
+
number: 123
|
|
59
|
+
|
|
60
|
+
# change the title of the issue #125 to "New title"
|
|
61
|
+
- action: set-title
|
|
62
|
+
number: 125
|
|
63
|
+
title: New title
|
|
64
|
+
|
|
65
|
+
# add the labels "bug" and "feature" to the issue #125
|
|
83
66
|
- action: add-labels
|
|
84
|
-
number:
|
|
85
|
-
labels: [
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
67
|
+
number: 125
|
|
68
|
+
labels: [bug, feature]
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
Then run
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
ghfs execute
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
to execute the operations in batch.
|
|
78
|
+
|
|
79
|
+
When running `ghfs execute --apply`:
|
|
80
|
+
- Each successfully applied operation is removed from `.ghfs/execute.yml`.
|
|
81
|
+
- After execution, `ghfs` runs a targeted sync only for affected issue/PR numbers.
|
|
82
|
+
|
|
83
|
+
> TODO: directly editing the `<5-digit-number>-<slug>.md` file to apply the operations will be rolled out in the future.
|
|
84
|
+
|
|
85
|
+
## Agent Skill
|
|
86
|
+
|
|
87
|
+
This repository ships an [agent skill](https://agentskills.io/home) at [`skills/ghfs/SKILL.md`](skills/ghfs/SKILL.md).
|
|
88
|
+
|
|
89
|
+
Install with [`skills`](https://github.com/vercel-labs/skills) CLI:
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
pnpx skills add antfu/ghfs
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
The `@ghfs/cli` also ship the skills into the npm package that you can have it also installed with [`skills-npm`](https://github.com/antfu/skills-npm):
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
pnpm i -D @ghfs/cli
|
|
99
|
+
pnpx skills-npm
|
|
89
100
|
```
|
|
90
101
|
|
|
91
|
-
##
|
|
102
|
+
## Configuration
|
|
103
|
+
|
|
104
|
+
You can configure by creating a `ghfs.config.ts` file in the root of the repository.
|
|
105
|
+
|
|
106
|
+
```ts
|
|
107
|
+
import type { GhfsUserConfig } from '@ghfs/cli'
|
|
108
|
+
|
|
109
|
+
export default defineConfig({
|
|
110
|
+
repo: 'owner/name',
|
|
111
|
+
sync: {
|
|
112
|
+
issues: true, // set false to skip issue sync
|
|
113
|
+
pulls: true, // set false to skip pull request sync
|
|
114
|
+
},
|
|
115
|
+
// other options...
|
|
116
|
+
})
|
|
117
|
+
```
|
|
92
118
|
|
|
93
|
-
|
|
94
|
-
2. `GH_TOKEN` / `GITHUB_TOKEN`
|
|
95
|
-
3. TTY prompt on first run
|
|
119
|
+
## TODOs
|
|
96
120
|
|
|
97
|
-
|
|
121
|
+
- [ ] `execute.md` file with human-friendly instructions (`close #123 #234`, `set-title #125 "New title"`).
|
|
122
|
+
- [x] Directly editing the `<5-digit-number>-<slug>.md` file to apply the operations.
|
|
123
|
+
- [ ] Add a VS Code extension for guided sync/execute.
|
|
124
|
+
- [ ] Documentation.
|
|
125
|
+
- [x] Index page, and basic repo info
|
|
126
|
+
- [x] Agent Skills.
|
package/package.json
CHANGED
|
@@ -1,9 +1,21 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ghfs/cli",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.0.
|
|
5
|
-
"
|
|
6
|
-
"
|
|
4
|
+
"version": "0.0.1",
|
|
5
|
+
"description": "GitHub issues/PRs as filesystem, for offline view and operations in batch. Designed for human and agents.",
|
|
6
|
+
"author": "Anthony Fu <anthonyfu117@hotmail.com>",
|
|
7
|
+
"license": "MIT",
|
|
8
|
+
"funding": "https://github.com/sponsors/antfu",
|
|
9
|
+
"homepage": "https://github.com/antfu/ghfs",
|
|
10
|
+
"repository": "https://github.com/antfu/ghfs",
|
|
11
|
+
"bugs": "https://github.com/antfu/ghfs/issues",
|
|
12
|
+
"keywords": [
|
|
13
|
+
"github",
|
|
14
|
+
"issues",
|
|
15
|
+
"pull requests",
|
|
16
|
+
"markdown",
|
|
17
|
+
"cli"
|
|
18
|
+
],
|
|
7
19
|
"exports": {
|
|
8
20
|
".": "./dist/index.mjs",
|
|
9
21
|
"./cli": "./dist/cli.mjs",
|
|
@@ -14,33 +26,47 @@
|
|
|
14
26
|
"ghfs": "./dist/cli.mjs"
|
|
15
27
|
},
|
|
16
28
|
"files": [
|
|
17
|
-
"dist"
|
|
29
|
+
"dist",
|
|
30
|
+
"skills/ghfs"
|
|
18
31
|
],
|
|
19
|
-
"scripts": {
|
|
20
|
-
"build": "tsdown",
|
|
21
|
-
"start": "tsx src/cli.ts",
|
|
22
|
-
"typecheck": "tsc --noEmit",
|
|
23
|
-
"test": "vitest run",
|
|
24
|
-
"lint": "eslint",
|
|
25
|
-
"schema": "tsx src/cli.ts schema"
|
|
26
|
-
},
|
|
27
32
|
"dependencies": {
|
|
28
33
|
"@clack/prompts": "^1.1.0",
|
|
29
34
|
"@octokit/plugin-retry": "^8.1.0",
|
|
30
35
|
"@octokit/plugin-throttling": "^11.0.3",
|
|
36
|
+
"ansis": "^4.2.0",
|
|
31
37
|
"cac": "^7.0.0",
|
|
38
|
+
"dotenv": "^17.3.1",
|
|
32
39
|
"jiti": "^2.6.1",
|
|
33
40
|
"octokit": "^5.0.5",
|
|
41
|
+
"pathe": "^2.0.3",
|
|
34
42
|
"valibot": "^1.1.0",
|
|
35
43
|
"yaml": "^2.8.2"
|
|
36
44
|
},
|
|
37
45
|
"devDependencies": {
|
|
38
46
|
"@antfu/eslint-config": "^7.6.1",
|
|
39
47
|
"@types/node": "^25.3.3",
|
|
48
|
+
"bumpp": "^10.4.1",
|
|
40
49
|
"eslint": "^10.0.2",
|
|
50
|
+
"lint-staged": "^16.3.2",
|
|
51
|
+
"simple-git-hooks": "^2.13.1",
|
|
41
52
|
"tsdown": "^0.20.3",
|
|
42
53
|
"tsx": "^4.21.0",
|
|
43
54
|
"typescript": "^5.9.3",
|
|
44
55
|
"vitest": "^4.0.18"
|
|
56
|
+
},
|
|
57
|
+
"simple-git-hooks": {
|
|
58
|
+
"pre-commit": "pnpm i --frozen-lockfile --ignore-scripts --offline && npx lint-staged"
|
|
59
|
+
},
|
|
60
|
+
"lint-staged": {
|
|
61
|
+
"*": "eslint --fix"
|
|
62
|
+
},
|
|
63
|
+
"scripts": {
|
|
64
|
+
"build": "tsdown",
|
|
65
|
+
"start": "tsx src/cli.ts",
|
|
66
|
+
"typecheck": "tsc --noEmit",
|
|
67
|
+
"test": "vitest run",
|
|
68
|
+
"lint": "eslint",
|
|
69
|
+
"release": "bumpp",
|
|
70
|
+
"play": "cd playgrounds/ni && tsx ../../src/cli.ts"
|
|
45
71
|
}
|
|
46
|
-
}
|
|
72
|
+
}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: ghfs
|
|
3
|
+
description: Manages ghfs local mirror files in `.ghfs/`, especially translating user instructions into valid `.ghfs/execute.yml` operations, running `ghfs execute` / `ghfs sync`, and validating issue/PR batch edits. Use when tasks involve editing issues/PRs through `.ghfs` artifacts, reconciling sync state, or applying queued GitHub operations.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Ghfs
|
|
7
|
+
|
|
8
|
+
## Overview
|
|
9
|
+
|
|
10
|
+
Use this skill to operate ghfs as a local filesystem mirror for GitHub issues and pull requests.
|
|
11
|
+
|
|
12
|
+
- `ghfs sync` mirrors remote content into `.ghfs/`.
|
|
13
|
+
- `ghfs execute` reads `.ghfs/execute.yml` and plans or applies mutations.
|
|
14
|
+
- Default execute mode is dry-run. Use `--apply` to mutate GitHub.
|
|
15
|
+
|
|
16
|
+
Key `.ghfs` files:
|
|
17
|
+
- `execute.yml`: queued operations (YAML array)
|
|
18
|
+
- `schema/execute.schema.json`: schema for `execute.yml`
|
|
19
|
+
- `.sync.json`: sync and execution run history (skip reading it)
|
|
20
|
+
- `issues.md`, `pulls.md`, `repo.json`: aggregated mirror views
|
|
21
|
+
- `issues/**/*.md`, `pulls/**/*.md`: per-item mirrors
|
|
22
|
+
|
|
23
|
+
## Main Workflow
|
|
24
|
+
|
|
25
|
+
1. Sync first when local data may be stale: run `ghfs sync`.
|
|
26
|
+
2. Update `.ghfs/execute.yml` from user instructions.
|
|
27
|
+
3. Validate and preview with `ghfs execute`.
|
|
28
|
+
4. Apply only on explicit user intent: `ghfs execute --apply`.
|
|
29
|
+
5. Report results and remaining queued operations.
|
|
30
|
+
|
|
31
|
+
Execution behavior to remember:
|
|
32
|
+
- Operations run in file order.
|
|
33
|
+
- On `--apply`, each successful operation is removed from `execute.yml`.
|
|
34
|
+
- Failed and not-yet-run operations stay in `execute.yml`.
|
|
35
|
+
- After apply, ghfs runs targeted sync for affected numbers automatically.
|
|
36
|
+
|
|
37
|
+
## Update `.ghfs/execute.yml` Correctly
|
|
38
|
+
|
|
39
|
+
Keep root as a YAML array and include `number` + `action` for every entry.
|
|
40
|
+
|
|
41
|
+
```yaml
|
|
42
|
+
# yaml-language-server: $schema=./schema/execute.schema.json
|
|
43
|
+
- number: 125
|
|
44
|
+
action: set-title
|
|
45
|
+
title: Improve sync summary output
|
|
46
|
+
|
|
47
|
+
- number: 125
|
|
48
|
+
action: add-labels
|
|
49
|
+
labels: [enhancement, cli]
|
|
50
|
+
|
|
51
|
+
- number: 126
|
|
52
|
+
action: request-reviewers
|
|
53
|
+
reviewers: [octocat]
|
|
54
|
+
ifUnchangedSince: '2026-03-05T04:10:00Z'
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Map user intent to action fields:
|
|
58
|
+
|
|
59
|
+
| User intent | action | Required extra fields |
|
|
60
|
+
| --- | --- | --- |
|
|
61
|
+
| Close / reopen | `close`, `reopen` | none |
|
|
62
|
+
| Change title | `set-title` | `title` |
|
|
63
|
+
| Replace body | `set-body` | `body` |
|
|
64
|
+
| Add comment | `add-comment` | `body` |
|
|
65
|
+
| Add/remove/set labels | `add-labels`, `remove-labels`, `set-labels` | `labels` (non-empty string array) |
|
|
66
|
+
| Add/remove/set assignees | `add-assignees`, `remove-assignees`, `set-assignees` | `assignees` (non-empty string array) |
|
|
67
|
+
| Set/clear milestone | `set-milestone`, `clear-milestone` | `milestone` for set |
|
|
68
|
+
| Lock/unlock conversation | `lock`, `unlock` | optional `reason` for lock |
|
|
69
|
+
| PR reviewer actions | `request-reviewers`, `remove-reviewers` | `reviewers` (non-empty string array) |
|
|
70
|
+
| PR draft state | `mark-ready-for-review`, `convert-to-draft` | none |
|
|
71
|
+
|
|
72
|
+
Rules:
|
|
73
|
+
- `number` must be a positive integer.
|
|
74
|
+
- `ifUnchangedSince` must be ISO datetime when present.
|
|
75
|
+
- `request-reviewers`, `remove-reviewers`, `mark-ready-for-review`, and `convert-to-draft` are PR-only.
|
|
76
|
+
- Keep operation order aligned with user intent because execution is sequential.
|
|
77
|
+
- Append operations unless user explicitly asks to replace or clear the queue.
|
|
78
|
+
|
|
79
|
+
Practical number resolution:
|
|
80
|
+
- Parse from filenames such as `.ghfs/issues/00123-foo.md` -> `number: 123`.
|
|
81
|
+
- Use `.ghfs/issues.md` / `.ghfs/pulls.md` when matching by title.
|
|
82
|
+
|
|
83
|
+
## Run Sync and Execute via CLI
|
|
84
|
+
|
|
85
|
+
Preferred commands:
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
ghfs sync
|
|
89
|
+
ghfs sync --full
|
|
90
|
+
ghfs sync --since 2026-03-01T00:00:00Z
|
|
91
|
+
ghfs execute
|
|
92
|
+
ghfs execute --apply
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
Useful flags:
|
|
96
|
+
- `--repo owner/name` when repo cannot be auto-resolved.
|
|
97
|
+
- `--non-interactive` for scripted runs.
|
|
98
|
+
- `--continue-on-error` to keep applying later ops after a failure.
|
package/dist/cli.d.mts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { };
|