upleb.uk

Public git repos — served from a NIP-34 GRASP relay at git.upleb.uk

summaryrefslogtreecommitdiff
path: root/skills/ngit/SKILL.md
diff options
context:
space:
mode:
authorDanConwayDev <DanConwayDev@protonmail.com>2026-03-05 10:11:05 +0000
committerDanConwayDev <DanConwayDev@protonmail.com>2026-03-05 10:11:05 +0000
commit243b563a3dc847a3a036a034dd7597685742c20c (patch)
tree263ee1043bfb931e318c31a99187bf16add1d3b4 /skills/ngit/SKILL.md
parent93c3e5fa18bc5ffb39b4e28b7b7b38bb6ce3fd93 (diff)
compact ngit skill to 168 lines for iterative refinement
Rewrite for conciseness: collapse concept sections to command references, remove prose explanations Claude already knows, merge workflows into inline examples, drop redundant comments.
Diffstat (limited to 'skills/ngit/SKILL.md')
-rw-r--r--skills/ngit/SKILL.md568
1 files changed, 74 insertions, 494 deletions
diff --git a/skills/ngit/SKILL.md b/skills/ngit/SKILL.md
index 918f310..5c4fc1c 100644
--- a/skills/ngit/SKILL.md
+++ b/skills/ngit/SKILL.md
@@ -8,581 +8,161 @@ metadata:
8 8
9# ngit — Nostr Plugin for Git 9# ngit — Nostr Plugin for Git
10 10
11ngit makes native git commands (`clone`, `fetch`, `push`) work with `nostr://` URLs and adds a CLI for pull requests, issues, and repository management — all over the decentralised Nostr protocol. No GitHub, no centralised forge. 11ngit makes `clone`, `fetch`, `push` work with `nostr://` URLs and adds a CLI for PRs, issues, and repo management over the decentralised Nostr protocol.
12 12
13- Homepage: https://ngit.dev 13- Install: `curl -Ls https://ngit.dev/install.sh | bash` (installs `ngit` and `git-remote-nostr`)
14- Source: `nostr://npub15qydau2hjma6ngxkl2cyar74wzyjshvl65za5k5rl69264ar2exs5cyejr/ngit` 14- Web UI: https://gitworkshop.dev
15- Web UI for browsing repos/PRs/issues: https://gitworkshop.dev
16 15
17## Installation 16## Key rules
18 17
19```bash 18- **Always use `--json`** on `ngit` commands when reading output — far easier to parse than human-readable text. `git` commands do not support `--json`.
20curl -Ls https://ngit.dev/install.sh | bash 19- **Use `--offline`** on all but the first `ngit` command in a session — reads from local cache instantly. `git fetch origin` also refreshes the cache.
21``` 20- **Never construct NIP-05 addresses** (`user@domain`). Use the `npub1...` form unless a NIP-05 address was explicitly provided.
22 21- **`<ID|nevent>`** accepts a 64-char hex event ID or a `nevent1...` bech32 string. Get IDs from `ngit pr list --json` or `ngit issue list --json`.
23This installs two binaries:
24
25- `ngit` — the main CLI
26- `git-remote-nostr` — a git remote helper that enables `nostr://` URLs to work transparently with git
27
28## Machine-readable output
29
30**All `ngit` commands support `--json` for structured output. Always use `--json` when scripting or parsing output** — it is far easier to process reliably than human-readable text. Standard `git` commands do not support `--json`; use them as normal.
31
32## Detecting a Nostr Repository
33 22
34Before running any `ngit` commands, check whether the current directory is a nostr repository: 23## Detecting a nostr repo
35
36```bash
37ngit repo --json --offline
38```
39
40Always exits 0. Returns `{"is_nostr_repo": false}` when not in a nostr repo, or the full repo info when it is.
41
42To check without loading the full repo details, grep for the key field:
43 24
44```bash 25```bash
26# Check if current directory is a nostr repo (always exits 0)
45ngit repo --json --offline | grep -q '"is_nostr_repo":true' 27ngit repo --json --offline | grep -q '"is_nostr_repo":true'
46``` 28```
47 29
48Script usage: 30Returns full repo info (including `nostr_url`, `maintainers`, `grasp_servers`) when true.
49
50```bash
51if ngit repo --json --offline | grep -q '"is_nostr_repo":true'; then
52 ngit pr list --json
53fi
54```
55
56---
57 31
58## Caching and --offline 32## nostr:// URLs
59
60Every `git fetch` and every `ngit` command that contacts relays fetches and caches the latest PRs, issues, and comments locally. This means **when running multiple ngit commands in quick succession, use `--offline`** on all but the first — it reads from the local cache and is instant.
61
62```bash
63# First command fetches from relays and populates the cache
64ngit pr list --json
65
66# Subsequent commands in the same session can skip the network
67ngit pr view <ID> --offline --comments
68ngit issue list --json --offline
69ngit repo --json --offline
70```
71
72`git fetch origin` also triggers a relay sync, so after a fetch all cached data is fresh.
73
74---
75
76## Core Concepts
77
78### What is a `nostr://` URL?
79
80A `nostr://` URL identifies a repository on the Nostr network. It encodes the maintainer's public key and a short repository identifier:
81 33
82``` 34```
83nostr://<npub>/<identifier> 35nostr://<npub>/<identifier>
84nostr://<npub>/<relay-hint>/<identifier> 36nostr://<npub>/<relay-hint>/<identifier> # relay-hint is bare domain, e.g. relay.ngit.dev
85```
86
87**`<npub>` is the only reliable form to construct yourself.** It is the bech32-encoded Nostr public key, always starting with `npub1`. Get it from `ngit repo --json` (the `maintainers` field) or `ngit account export-keys`.
88
89The relay hint is a bare domain (no `wss://`) and speeds up discovery — use the repo's grasp server. Get it from `ngit repo --json` (`grasp_servers[0]`).
90
91```
92nostr://npub15qydau2hjma6ngxkl2cyar74wzyjshvl65za5k5rl69264ar2exs5cyejr/relay.ngit.dev/ngit
93```
94
95**NIP-05 addresses** (`user@domain.com`) are also valid if the user has set one up, but they require a `/.well-known/nostr.json` file deployed to that domain — do not attempt to construct or guess them. Use the npub form unless a NIP-05 address has been explicitly provided to you.
96
97These URLs work directly with git — no special commands needed:
98
99```bash
100git clone nostr://npub15qydau2hjma6ngxkl2cyar74wzyjshvl65za5k5rl69264ar2exs5cyejr/relay.ngit.dev/ngit
101git fetch origin
102git push origin main
103```
104
105The `git-remote-nostr` helper resolves the URL to actual git servers behind the scenes.
106
107### How repositories work
108
109When a maintainer publishes a repo with `ngit init`, they broadcast a **repository announcement event** to Nostr relays. This event contains:
110
111- Repository name, description, and identifier
112- Git server URLs (where the actual git data lives)
113- Nostr relay URLs (where events like PRs and issues are published)
114- Maintainer public keys
115
116Anyone can clone using the `nostr://` URL. The remote helper fetches the announcement, finds the git servers, and performs the actual git operations.
117
118### Authentication
119
120ngit uses your Nostr private key (nsec) for signing events. See [CONCEPT 5: Account Management](#concept-5-account-management) for full details.
121
122---
123
124## CONCEPT 1: Publishing a Repository
125
126_"Making a git repo discoverable and collaborative on Nostr"_
127
128### First-time publish (from an existing git repo)
129
130```bash
131# Interactive (recommended for humans)
132ngit init
133
134# Non-interactive / scripted — uses sensible defaults
135ngit init --name "My Project" --description "What it does" -d
136
137# With explicit grasp server (hosted git+nostr infrastructure)
138ngit init --name "My Project" --description "What it does" \
139 --grasp-server https://relay.ngit.dev -d
140``` 37```
141 38
142After `ngit init`: 39Standard git commands work directly with these URLs — `git-remote-nostr` resolves them transparently.
143
144- A repository announcement is published to Nostr relays
145- The `origin` remote is updated to the `nostr://` URL
146- Your code is pushed to the configured git server(s)
147- You get a shareable URL like `https://gitworkshop.dev/npub.../myrepo`
148 40
149### Update repository metadata 41## Publishing a repo
150 42
151```bash 43```bash
152ngit repo edit --description "Updated description" 44ngit init # interactive
153ngit repo edit --hashtag rust --hashtag cli 45ngit init --name "My Project" --description "What it does" -d # non-interactive
46ngit repo edit --description "New description" # update metadata
47ngit repo --json --offline # view repo info (check nostr_url field)
154``` 48```
155 49
156### View repository info 50## Cloning
157
158```bash
159ngit repo
160```
161
162---
163
164## CONCEPT 2: Cloning and Working with a Repo
165
166_"Getting and staying in sync with a nostr repository"_
167 51
168```bash 52```bash
169# Clone using npub + relay hint + identifier (preferred — always works) 53git clone nostr://<npub>/<relay-hint>/<identifier> # preferred
170git clone nostr://npub15qydau2hjma6ngxkl2cyar74wzyjshvl65za5k5rl69264ar2exs5cyejr/relay.ngit.dev/ngit 54git clone nostr://<npub>/<identifier> # slower discovery, no relay hint
171 55git clone nostr://user@domain.com/<identifier> # NIP-05, only if given to you
172# Clone using npub + identifier (no relay hint — slightly slower discovery)
173git clone nostr://npub15qydau2hjma6ngxkl2cyar74wzyjshvl65za5k5rl69264ar2exs5cyejr/ngit
174
175# Clone using NIP-05 address if its already been given to you in the clone url.
176git clone nostr://dan@danconwaydev.com/ngit
177
178# Standard git operations work normally after cloning
179git fetch origin
180git pull origin main
181git push origin main
182``` 56```
183 57
184### Remote branches and PRs 58## Pull Requests
185
186When you fetch from a nostr remote, open and draft PRs appear as remote branches with the `pr/` prefix:
187
188```bash
189git fetch origin
190git branch -r
191# origin/main
192# origin/pr/fix-login-bug ← open PR
193# origin/pr/add-dark-mode ← open PR
194```
195 59
196You can check out a PR branch directly: 60### Open a PR
197
198```bash
199git checkout pr/fix-login-bug
200# or by event ID
201ngit pr checkout <ID|nevent>
202```
203
204---
205
206## CONCEPT 3: Pull Requests
207
208_"Proposing and reviewing changes"_
209
210### Opening a PR
211
212Create a branch with the `pr/` prefix and push it. Always include `-o title=` and `-o description=`:
213 61
214```bash 62```bash
215git checkout -b pr/my-feature 63git checkout -b pr/my-feature
216# ... make commits ... 64# ... commits ...
217git push -u origin pr/my-feature \ 65git push -u origin pr/my-feature \
218 -o 'title=Add dark mode' \ 66 -o 'title=My feature title' \
219 -o 'description=Implements a dark mode toggle in settings.\n\nAdds a toggle to the settings page and persists the preference.' 67 -o 'description=Summary.\n\nDetail here.'
220``` 68```
221 69
222Use `\n\n` in the description for paragraph breaks. 70Push options `title=` and `description=` are required. Use `\n\n` for paragraph breaks.
223 71
224### Opening a PR (advanced — `ngit send`) 72### Advanced: ngit send
225 73
226```bash 74```bash
227# Send commits ahead of main as a PR 75ngit send HEAD~2 --title "My Feature" --description "Details"
228ngit send HEAD~2 --title "My Feature" --description "Details here" 76ngit send --defaults # non-interactive
229 77ngit send HEAD~2 --in-reply-to <PR-event-id> # update existing PR
230# Non-interactive with defaults
231ngit send --defaults
232
233# Update an existing PR (new version/revision)
234ngit send HEAD~2 --in-reply-to <PR-event-id>
235``` 78```
236 79
237### Listing PRs 80### List / view / comment
238 81
239```bash 82```bash
240# List open and draft PRs (default)
241ngit pr list
242
243# List all statuses
244ngit pr list --status open,draft,closed,applied
245
246# Filter by label
247ngit pr list --label bug
248
249# Output as JSON (for scripting)
250ngit pr list --json 83ngit pr list --json
251``` 84ngit pr list --json --status open,draft,closed,applied
252 85ngit pr list --json --label bug
253### Viewing a PR
254
255```bash
256ngit pr view <ID|nevent>
257
258# Include full comment thread
259ngit pr view <ID|nevent> --comments
260
261# JSON output
262ngit pr view <ID|nevent> --json 86ngit pr view <ID|nevent> --json
87ngit pr view <ID|nevent> --json --comments
88ngit pr comment <ID|nevent> --body "Looks good"
89ngit pr comment <ID|nevent> --body "Fixed!" --reply-to <comment-ID>
263``` 90```
264 91
265### Reviewing a PR 92### Checkout / apply
266 93
267```bash 94```bash
268# Checkout the PR branch locally
269ngit pr checkout <ID|nevent> 95ngit pr checkout <ID|nevent>
270
271# Or apply patches to current branch
272ngit pr apply <ID|nevent> 96ngit pr apply <ID|nevent>
273``` 97```
274 98
275### Commenting on a PR 99### Merge (maintainer)
276
277```bash
278ngit pr comment <ID|nevent> --body "Looks good, just one nit..."
279
280# Reply to a specific comment
281ngit pr comment <ID|nevent> --body "Fixed!" --reply-to <comment-ID>
282```
283
284### Merging a PR (maintainer only)
285
286Prefer `git merge` then push — this creates the merge commit and the push updates the Nostr state automatically:
287 100
288```bash 101```bash
289# Checkout the PR branch, test it, then merge
290ngit pr checkout <ID|nevent> 102ngit pr checkout <ID|nevent>
291git checkout main 103git checkout main
292git merge pr/my-feature 104git merge pr/my-feature # or: git merge --squash pr/my-feature && git commit
293git push origin main 105git push origin main # push to nostr remote records the merge event
294# pushing to the nostr remote records the merge event on Nostr
295
296# Squash merge
297git merge --squash pr/my-feature
298git commit -m "feat: add dark mode"
299git push origin main
300``` 106```
301 107
302### PR lifecycle management 108### Lifecycle
303 109
304```bash 110```bash
305# Close a PR (author or maintainer)
306ngit pr close <ID|nevent> 111ngit pr close <ID|nevent>
307
308# Reopen a closed PR
309ngit pr reopen <ID|nevent> 112ngit pr reopen <ID|nevent>
310 113ngit pr ready <ID|nevent> # mark draft as ready for review
311# Mark a draft PR as ready for review
312ngit pr ready <ID|nevent>
313``` 114```
314 115
315--- 116## Issues
316
317## CONCEPT 4: Issues
318
319_"Tracking bugs, features, and tasks"_
320
321### Creating an issue
322 117
323```bash 118```bash
324# Interactive 119ngit issue create --title "Bug title" --body "Details" --label bug
325ngit issue create 120ngit issue create --title "Feature" --body "..." --label enhancement --label help-wanted
326
327# Non-interactive
328ngit issue create --title "Bug: login fails on mobile" \
329 --body "Steps to reproduce: ..." \
330 --label bug
331
332# Multiple labels
333ngit issue create --title "Add dark mode" \
334 --body "Feature request" \
335 --label enhancement --label help-wanted
336```
337
338### Listing issues
339
340```bash
341# List open issues (default)
342ngit issue list
343
344# Filter by status
345ngit issue list --status open
346ngit issue list --status closed
347
348# Filter by label
349ngit issue list --label bug
350
351# JSON output
352ngit issue list --json 121ngit issue list --json
353``` 122ngit issue list --json --status closed
354 123ngit issue list --json --label bug
355### Viewing an issue
356
357```bash
358ngit issue view <ID|nevent>
359
360# Include comment thread
361ngit issue view <ID|nevent> --comments
362
363# JSON output
364ngit issue view <ID|nevent> --json 124ngit issue view <ID|nevent> --json
365``` 125ngit issue view <ID|nevent> --json --comments
366 126ngit issue comment <ID|nevent> --body "Reproduced on v2.1"
367### Commenting on an issue 127ngit issue comment <ID|nevent> --body "Thanks!" --reply-to <comment-ID>
368
369```bash
370ngit issue comment <ID|nevent> --body "I can reproduce this on v1.2.3"
371
372# Reply to a specific comment
373ngit issue comment <ID|nevent> --body "Thanks for the report!" --reply-to <comment-ID>
374```
375
376### Closing and reopening issues
377
378```bash
379# Close (author or maintainer)
380ngit issue close <ID|nevent> 128ngit issue close <ID|nevent>
381
382# Reopen
383ngit issue reopen <ID|nevent> 129ngit issue reopen <ID|nevent>
384``` 130```
385 131
386--- 132## Account management
387
388## CONCEPT 5: Account Management
389
390_"Managing your Nostr identity"_
391
392All credentials are stored as git config keys. You can set them directly or via `ngit account login`.
393 133
394```bash 134```bash
395# Login interactively (stores credentials in global git config) 135ngit account login # interactive, stores nsec in global git config
396ngit account login 136ngit account login --bunker-url bunker://... # NIP-46 remote signer
397 137ngit account login --local # this repo only
398# Login with a bunker:// URL (remote signer / NIP-46)
399ngit account login --bunker-url bunker://...
400
401# Login only for this repository (local git config)
402ngit account login --local
403
404# Create a new account
405ngit account create --name "Alice" 138ngit account create --name "Alice"
406
407# Export keys (to use in other Nostr clients)
408ngit account export-keys 139ngit account export-keys
409
410# Logout (removes stored credentials from git config)
411ngit account logout 140ngit account logout
141git config --global nostr.nsec <nsec> # set directly
142ngit --nsec <nsec> <command> # inline for CI, no login needed
412``` 143```
413 144
414Credentials are stored as standard git config entries and can be set or inspected directly: 145## Sync
415
416```bash
417# Set nsec globally for all repos
418git config --global nostr.nsec <nsec>
419
420# Set nsec for this repo only
421git config nostr.nsec <nsec>
422
423# View stored npub
424git config --global nostr.npub
425```
426
427For CI/automation, pass `--nsec` inline — no login step required:
428
429```bash
430ngit --nsec <nsec> issue create --title "CI report" --body "..." -d
431```
432
433---
434
435## CONCEPT 6: Sync and Maintenance
436
437_"Keeping git servers in sync with Nostr state"_
438
439```bash
440# Sync all refs from nostr state to git servers
441ngit sync
442
443# Sync a specific ref
444ngit sync --ref-name main
445ngit sync --ref-name v1.5.2
446```
447
448Use `ngit sync` if git servers have fallen out of sync with the Nostr state (e.g. after relay-side changes).
449
450---
451
452## Common Workflows
453
454### Workflow: Publish a new repository
455
456```bash
457cd my-project
458git init
459git add .
460git commit -m "initial commit"
461ngit init --name "My Project" --description "A cool project" -d
462# origin is now set to nostr://... and code is pushed
463
464# Get the canonical nostr:// URL to share (npub + relay hint + identifier)
465ngit repo --json --offline
466# Look for the "nostr_url" field in the output
467# e.g. nostr://npub1abc.../relay.ngit.dev/my-project
468```
469
470### Workflow: Contribute a PR to someone else's repo
471
472```bash
473git clone nostr://npub15qydau2hjma6ngxkl2cyar74wzyjshvl65za5k5rl69264ar2exs5cyejr/relay.ngit.dev/ngit
474cd ngit
475git checkout -b pr/fix-typo
476# ... make changes ...
477git commit -m "fix: correct typo in README"
478git push -u origin pr/fix-typo \
479 -o 'title=Fix typo in README' \
480 -o 'description=Corrects a spelling mistake in the introduction.\n\nSmall copy fix, no functional changes.'
481# Verify the PR was created
482ngit pr list --json --offline
483```
484
485### Workflow: Review and merge a PR (maintainer)
486 146
487```bash 147```bash
488# See what's open 148ngit sync # sync all refs from nostr state to git servers
489ngit pr list --json 149ngit sync --ref-name main # sync specific ref
490
491# Review the PR
492ngit pr view <ID> --json --comments
493
494# Check it out and test locally
495ngit pr checkout <ID>
496# ... run tests ...
497
498# Merge via git and push — push records the merge on Nostr
499git checkout main
500git merge pr/my-feature
501git push origin main
502# Verify the PR is now closed/applied
503ngit pr view <ID> --json --offline
504``` 150```
505 151
506### Workflow: File and close an issue 152## Key flags
507
508```bash
509# File
510ngit issue create --title "Crash on startup" \
511 --body "Reproducible with v2.1 on Linux.\n\nSteps: run ngit init in an empty dir." \
512 --label bug
513# Verify the issue was created and note its ID
514ngit issue list --json --offline
515
516# Later, close it
517ngit issue close <ID>
518# Verify it is closed
519ngit issue view <ID> --json --offline
520```
521 153
522### Workflow: Non-interactive / CI scripting 154| Flag | Description |
155| --- | --- |
156| `-d`, `--defaults` | Non-interactive; use sensible defaults |
157| `--offline` | Local cache only, skip network |
158| `--json` | Structured output (ngit commands only) |
159| `-n`, `--nsec <NSEC>` | Provide nsec or hex private key inline |
160| `-f`, `--force` | Bypass safety guards |
161| `-v`, `--verbose` | Verbose output |
523 162
524Use `-d` / `--defaults` to skip all prompts and `--nsec` to provide credentials: 163## git config
525 164
526```bash 165```bash
527ngit --nsec <nsec> init --name "My Repo" --description "CI-published repo" -d 166ngit --customize # show all options
528ngit --nsec <nsec> issue create --title "Automated report" --body "..." -d 167git config nostr.repo-relay-only true # don't broadcast to personal relays
529```
530
531---
532
533## Reference: ID formats
534
535Many commands accept an `<ID|nevent>` argument. This can be:
536
537- A hex event ID: `a1b2c3d4...` (64 hex chars)
538- A bech32 nevent: `nevent1...`
539
540Get IDs from `ngit pr list --json` or `ngit issue list --json`.
541
542---
543
544## Reference: Push options for PRs
545
546When pushing a `pr/` branch, always set title and description via `-o` push options:
547
548| Option | Description |
549| -------------------- | ----------------------------------------------- |
550| `title=<text>` | PR title |
551| `description=<text>` | PR description; use `\n\n` for paragraph breaks |
552
553```bash
554git push -u origin pr/my-branch \
555 -o 'title=My PR Title' \
556 -o 'description=Summary of changes.\n\nMore detail here.'
557```
558
559---
560
561## Reference: Key flags
562
563| Flag | Description |
564| --------------------- | ----------------------------------------------------------- |
565| `-d`, `--defaults` | Non-interactive mode; use sensible defaults for all prompts |
566| `-i`, `--interactive` | Force interactive prompts (default behaviour) |
567| `-f`, `--force` | Bypass safety guards |
568| `-n`, `--nsec <NSEC>` | Provide nsec or hex private key inline |
569| `--offline` | Use local cache only, skip network fetch |
570| `--json` | Output as JSON (on commands that support it) |
571| `-v`, `--verbose` | Verbose output |
572
573---
574
575## Reference: git config customisation
576
577All ngit settings live in git config under the `nostr.*` namespace.
578
579```bash
580# Show all customisation options
581ngit --customize
582
583# Store credentials
584git config --global nostr.nsec <nsec>
585
586# Repo-only relay publishing (don't broadcast to personal relays)
587git config nostr.repo-relay-only true
588``` 168```