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