Update ngit skill to v1.18

This commit is contained in:
greenart7c3
2026-09-14 08:03:40 -03:00
parent f4865b406f
commit ad0a50c03b
18 changed files with 454 additions and 454 deletions
+68 -65
View File
@@ -1,32 +1,39 @@
--- ---
name: ngit name: ngit
description: Commands and workflows for NIP-34 git collaboration over Nostr with the ngit CLI and git-remote-nostr. Use in any repository with a nostr:// remote for generic collaboration requests (open an Issue, create or review a Pull Request (PR), comment, merge, clone) and whenever a task involves nostr:// URLs, ngit commands, Grasp servers, gitworkshop.dev, Nostr CI status and workflows, software releases and Zapstore publication, OCI container images, or nsite static sites published through Blossom. description:
Commands and workflows for NIP-34 git collaboration over Nostr with the ngit
CLI and git-remote-nostr. Use in any repository with a nostr:// remote for
generic collaboration requests (open an Issue, create or review a Pull Request
(PR), comment, merge, clone) and whenever a task involves nostr:// URLs, ngit
commands, Grasp servers, gitworkshop.dev, Nostr CI status and workflows,
software releases and Zapstore publication, OCI container images, or nsite
static sites published through Blossom.
license: CC-BY-SA-4.0 license: CC-BY-SA-4.0
metadata: metadata:
version: "1.17" version: "1.18"
--- ---
# ngit — Nostr Plugin for Git # ngit — Nostr Plugin for Git
ngit makes `git clone`, `fetch`, and `push` work with `nostr://` URLs and adds ngit makes `git clone`, `fetch`, and `push` work with `nostr://` URLs and adds a
a CLI for pull requests, issues, membership, CI results, releases, OCI CLI for pull requests, issues, membership, CI results, releases, OCI containers,
containers, and nsites. Repository state (which commit each ref points to) is and nsites. Repository state (which commit each ref points to) is published as
published as signed Nostr events and is the source of truth; git objects live signed Nostr events and is the source of truth; git objects live on ordinary git
on ordinary git servers, so servers are interchangeable. A grasp server bundles servers, so servers are interchangeable. A grasp server bundles a relay and a
a relay and a git server and creates the repository automatically when an git server and creates the repository automatically when an announcement lists
announcement lists it. Explanation: https://ngit.dev/how-it-works it. Explanation: https://ngit.dev/how-it-works
## Where to look ## Where to look
- **This skill documents ngit v3.** Run `ngit --version` first; the commands - **This skill documents ngit v3.** Run `ngit --version` first; the commands
here need 3.0.0 or later. If ngit is missing or older, report that and here need 3.0.0 or later. If ngit is missing or older, report that and offer
offer an install or update: `curl -fsSL https://ngit.dev/install.sh | bash` an install or update: `curl -fsSL https://ngit.dev/install.sh | bash` installs
installs or replaces `ngit` and `git-remote-nostr`, and `ngit update` works or replaces `ngit` and `git-remote-nostr`, and `ngit update` works on v3 or
on v3 or later. Other methods: https://ngit.dev/install later. Other methods: https://ngit.dev/install
- **`ngit <command> --help`** is the authority for the installed version's - **`ngit <command> --help`** is the authority for the installed version's flags
flags and defaults. and defaults.
- **https://ngit.dev** holds the guides. Any page is available as raw - **https://ngit.dev** holds the guides. Any page is available as raw Markdown
Markdown at `https://ngit.dev/markdown/<route>.md`; the index is at `https://ngit.dev/markdown/<route>.md`; the index is
https://ngit.dev/llms.txt. Web UI: https://gitworkshop.dev https://ngit.dev/llms.txt. Web UI: https://gitworkshop.dev
## Rules ## Rules
@@ -35,44 +42,40 @@ announcement lists it. Explanation: https://ngit.dev/how-it-works
policy. Carry through the selected signer, target, hosting, CI, and policy. Carry through the selected signer, target, hosting, CI, and
replication settings; do not add gates, waits, workflow edits, or replication settings; do not add gates, waits, workflow edits, or
configuration changes that the task or repository did not choose. configuration changes that the task or repository did not choose.
- **PR branches MUST start with `pr/`** (e.g. `pr/my-feature`). Any other - **PR branches MUST start with `pr/`** (e.g. `pr/my-feature`). Any other branch
branch name is a plain push and never creates a PR. name is a plain push and never creates a PR.
- **Read ngit output with `--json`.** It is a global option and works at any - **Read ngit output with `--json`.** It is a global option and works at any
position. Stdout is exactly one JSON document; progress and diagnostics go position. Stdout is exactly one JSON document; progress and diagnostics go to
to stderr. `git` commands have no `--json`. Top-level `command_status` is stderr. `git` commands have no `--json`. Top-level `command_status` is `ok`
`ok` for exit 0 and `error` otherwise; it never describes a nested domain for exit 0 and `error` otherwise; it never describes a nested domain result
result (`ngit ci status --json` reports `ok` with (`ngit ci status --json` reports `ok` with `ci.conclusion: "failure"` unless a
`ci.conclusion: "failure"` unless a gate was requested). gate was requested).
- **Add `--offline` after the first network read** in a session, on commands - **Add `--offline` after the first network read** in a session, on commands
that support it. `git fetch origin` also refreshes the cache. that support it. `git fetch origin` also refreshes the cache.
- **Identifiers.** `<ID|nevent>` accepts `nevent1…`, a 64-char hex ID, or a - **Identifiers.** `<ID|nevent>` accepts `nevent1…`, a 64-char hex ID, or a
unique hex prefix with an optional `#` (quote it: `'#deadbeef'`). JSON `id` unique hex prefix with an optional `#` (quote it: `'#deadbeef'`). JSON `id`
and `reply_to` fields are already `nevent1…`; container publication instead and `reply_to` fields are already `nevent1…`; container publication instead
returns a raw-hex `event_id` plus the repository `naddr`. Reference events returns a raw-hex `event_id` plus the repository `naddr`. Reference events
inside `--body` text as `nostr:nevent1…` or `nostr:naddr1…`, never as raw inside `--body` text as `nostr:nevent1…` or `nostr:naddr1…`, never as raw hex.
hex. Never construct a NIP-05 address (`user@domain`); use `npub1…` unless Never construct a NIP-05 address (`user@domain`); use `npub1…` unless a NIP-05
a NIP-05 address was given to you. address was given to you.
- **Multiline text.** `ngit` options such as `--body` and `--description` - **Multiline text.** `ngit` options such as `--body` and `--description` accept
accept real newlines: `--body "$(cat note.md)"`. Git push options cannot real newlines: `--body "$(cat note.md)"`. Git push options cannot carry
carry newlines: write literal `\n` in a short inline `-o description=…`, and newlines: write literal `\n` in a short inline `-o description=…`, and never
never convert a file into a push option (open the PR with `ngit send` convert a file into a push option (open the PR with `ngit send` instead).
instead).
- **Signers.** `--signer <alias|npub|profile-name>` selects a stored identity - **Signers.** `--signer <alias|npub|profile-name>` selects a stored identity
for one `ngit` command; `git -c nostr.signer=<alias|npub|profile-name> for one `ngit` command; `git -c nostr.signer=<alias|npub|profile-name> push …`
push …` does the same for one git command. Neither changes the configured does the same for one git command. Neither changes the configured login. Never
login. Never export or pass an nsec merely to switch between configured export or pass an nsec merely to switch between configured accounts.
accounts. - **CI.** A successful push says nothing about CI. Nostr CI runs workflows from
- **CI.** A successful push says nothing about CI. Nostr CI runs workflows `.ngit/act/workflows/`; another provider's directory is not evidence. When CI
from `.ngit/act/workflows/`; another provider's directory is not evidence. matters, query the exact commit or PR with `ngit ci status <target> --json`
When CI matters, query the exact commit or PR with and read `ci.state` and `ci.conclusion`, not `command_status`.
`ngit ci status <target> --json` and read `ci.state` and `ci.conclusion`,
not `command_status`.
- **Target repository.** With several `nostr://` remotes, pass global - **Target repository.** With several `nostr://` remotes, pass global
`--repo <REMOTE|NADDR|NOSTR-URL>`; a configured remote name, an naddr, and `--repo <REMOTE|NADDR|NOSTR-URL>`; a configured remote name, an naddr, and a
a nostr:// URL are all accepted. Without it ngit nostr:// URL are all accepted. Without it ngit infers the target from config
infers the target from config and branch tracking and fails rather than and branch tracking and fails rather than guesses. Before a signing command,
guesses. Before a signing command, check the check the `target repository: <naddr> (source: …)` line on stderr.
`target repository: <naddr> (source: …)` line on stderr.
## Detecting a nostr repo ## Detecting a nostr repo
@@ -81,11 +84,11 @@ git remote -v | grep -q 'nostr://' # primary check, no cache needed
ngit repo --json --offline # full metadata when needed ngit repo --json --offline # full metadata when needed
``` ```
`ngit repo` always exits 0, and `is_nostr_repo: false` can be a cold-cache `ngit repo` always exits 0, and `is_nostr_repo: false` can be a cold-cache false
false negative: if a remote shows `nostr://`, run `git fetch origin` and negative: if a remote shows `nostr://`, run `git fetch origin` and retry. The
retry. The output includes the roster (`members`, `lead_source`, `lead_path`, output includes the roster (`members`, `lead_source`, `lead_path`,
`pending_actions`, `health`); read `reference/repositories.md` before `pending_actions`, `health`); read `reference/repositories.md` before changing
changing membership or hosting. membership or hosting.
## nostr:// URLs ## nostr:// URLs
@@ -100,18 +103,18 @@ Standard git commands accept these URLs directly.
## Task index ## Task index
Read the bundled reference before performing that slice of work; the guide Read the bundled reference before performing that slice of work; the guide adds
adds tutorials and background. tutorials and background.
| Task | Bundled reference | ngit.dev guide | | Task | Bundled reference | ngit.dev guide |
| ---- | ----------------- | -------------- | | ---------------------------------------------------------- | --------------------------- | ------------------------------------ |
| Publish, clone, host repositories; maintainers, moderators | `reference/repositories.md` | `/repositories`, `/maintainers` | | Publish, clone, host repositories; maintainers, moderators | `reference/repositories.md` | `/repositories`, `/maintainers` |
| Open, update, stack, review, merge PRs | `reference/prs.md` | `/pull-requests` | | Open, update, stack, review, merge PRs | `reference/prs.md` | `/pull-requests` |
| Issues | `reference/issues.md` | `/issues` | | Issues | `reference/issues.md` | `/issues` |
| CI results, trust, workflows, ngit in CI jobs | `reference/ci.md` | `/ci`, `/ci/workflows/` | | CI results, trust, workflows, ngit in CI jobs | `reference/ci.md` | `/ci`, `/ci/workflows/` |
| Accounts, login, signers, secrets | `reference/accounts.md` | `/accounts` | | Accounts, login, signers, secrets | `reference/accounts.md` | `/accounts` |
| Sync, global flags, git config | `reference/sync-config.md` | `/configuration`, `/troubleshooting` | | Sync, global flags, git config | `reference/sync-config.md` | `/configuration`, `/troubleshooting` |
| Publish nsites (static sites) | `reference/nsites.md` | `/releases/nsites` | | Publish nsites (static sites) | `reference/nsites.md` | `/releases/nsites` |
| Publish OCI containers | `reference/containers.md` | `/releases` | | Publish OCI containers | `reference/containers.md` | `/releases` |
| Software releases | `ngit release --help` | `/releases` | | Software releases | `ngit release --help` | `/releases` |
| Automation contract, machine-readable docs | this file | `/agents/` | | Automation contract, machine-readable docs | this file | `/agents/` |
+8 -8
View File
@@ -1,8 +1,8 @@
# Accounts — identity, login, secrets # Accounts — identity, login, secrets
Read when managing accounts, logins, or credential storage. Read when managing accounts, logins, or credential storage. Guide:
Guide: https://ngit.dev/accounts (storage modes, pairing a remote signer for https://ngit.dev/accounts (storage modes, pairing a remote signer for CI,
CI, rotation). rotation).
```bash ```bash
ngit account whoami --json --offline # every usable signer with npub, aliases, scope, active state; `account list` is an alias ngit account whoami --json --offline # every usable signer with npub, aliases, scope, active state; `account list` is an alias
@@ -40,8 +40,8 @@ unaliased connection. Log in with `--alias` to keep an extra connection and
select it by alias. Older ngit versions ignore the exact-session binding and select it by alias. Older ngit versions ignore the exact-session binding and
select the identity's default connection. select the identity's default connection.
**nbunksec** is a portable established connection: remote-signer pubkey, **nbunksec** is a portable established connection: remote-signer pubkey, client
client secret, relays, and optional pairing secret. It holds no npub, so secret, relays, and optional pairing secret. It holds no npub, so one-shot use
one-shot use resolves the identity from the signer. The `--nbunksec-file` and resolves the identity from the signer. The `--nbunksec-file` and `--nsec-file`
`--nsec-file` forms keep secrets out of process arguments. A fresh pairing forms keep secrets out of process arguments. A fresh pairing needs interactive
needs interactive approval, so unattended runs use a stored connection. approval, so unattended runs use a stored connection.
+23 -23
View File
@@ -1,18 +1,18 @@
# Nostr CI # Nostr CI
Read when checking whether CI ran, interpreting a result, or writing a Read when checking whether CI ran, interpreting a result, or writing a workflow
workflow that uses ngit. Guides: https://ngit.dev/ci (coordinators, results, that uses ngit. Guides: https://ngit.dev/ci (coordinators, results, trust,
trust, secrets) and https://ngit.dev/ci/workflows/ (what the coordinator secrets) and https://ngit.dev/ci/workflows/ (what the coordinator accepts,
accepts, refuses, and adds compared with GitHub Actions). refuses, and adds compared with GitHub Actions).
## Workflows ## Workflows
Nostr CI (ngit-ci) runs workflows from `.ngit/act/workflows/` with Nostr CI (ngit-ci) runs workflows from `.ngit/act/workflows/` with GitHub
GitHub Actions syntax in Linux containers. `.github/workflows/` is run only by Actions syntax in Linux containers. `.github/workflows/` is run only by GitHub
GitHub Actions on a mirror; the directories are independent, so a check that Actions on a mirror; the directories are independent, so a check that must run
must run in both systems needs a file in each. ngit-ci refuses macOS and in both systems needs a file in each. ngit-ci refuses macOS and Windows
Windows `runs-on` labels and job-level `uses:` (reusable workflows); composite `runs-on` labels and job-level `uses:` (reusable workflows); composite actions
actions in steps work in both systems. in steps work in both systems.
Read the workflow at the commit under investigation and confirm that its Read the workflow at the commit under investigation and confirm that its
triggers and steps cover the check in question: triggers and steps cover the check in question:
@@ -28,7 +28,7 @@ checksum-pinned manifest:
```yaml ```yaml
- uses: danconwaydev/setup-ngit@v3 - uses: danconwaydev/setup-ngit@v3
with: with:
version: 3.0.0 # optional exact pin; the default `latest` resolves against the action's manifest, not the network version: 3.0.0 # optional exact pin; the default `latest` resolves against the action's manifest, not the network
``` ```
Source: Source:
@@ -43,25 +43,25 @@ ngit ci status <target> --json --offline # later cache
ngit ci status <target> --require-ci-trust maintainer-directed --json # exit non-zero unless green at this floor ngit ci status <target> --require-ci-trust maintainer-directed --json # exit non-zero unless green at this floor
``` ```
Query the exact commit that introduced the change. A PR target reports only Query the exact commit that introduced the change. A PR target reports only its
its latest revision. Read: latest revision. Read:
- `ci.state`: pending, running, or concluded. `ci.conclusion` counts only - `ci.state`: pending, running, or concluded. `ci.conclusion` counts only once
once the state is concluded. the state is concluded.
- `ci.conclusion`: success, failure, cancellation, or another outcome. - `ci.conclusion`: success, failure, cancellation, or another outcome.
`command_status: "ok"` means only that the query worked. `command_status: "ok"` means only that the query worked.
- `ci.runs[].workflow` and `ci.runs[].jobs`: which workflow and job passed or - `ci.runs[].workflow` and `ci.runs[].jobs`: which workflow and job passed or
failed. failed.
- `ci.runs[].integrity`: the commit is present locally and the workflow hash - `ci.runs[].integrity`: the commit is present locally and the workflow hash
matches. matches.
- `coverage` and each run's classification and evidence: how completely and - `coverage` and each run's classification and evidence: how completely and why
why the result is trusted. Partial coverage is not success. the result is trusted. Partial coverage is not success.
If no run appears, report that no matching Nostr CI event was found. Then If no run appears, report that no matching Nostr CI event was found. Then check
check that the workflow existed at that commit, its trigger matched, a that the workflow existed at that commit, its trigger matched, a coordinator
coordinator serves the repository, and the query refreshed the relays before serves the repository, and the query refreshed the relays before concluding that
concluding that CI did not run. CI did not run.
Trust floors are `maintainer-directed` and `operationally-associated`. Trust floors are `maintainer-directed` and `operationally-associated`.
`ngit pr merge --require-ci-trust <LEVEL>` applies the same gate to a merge `ngit pr merge --require-ci-trust <LEVEL>` applies the same gate to a merge when
when the caller wants one. the caller wants one.
+39 -40
View File
@@ -1,16 +1,16 @@
# Containers — publish OCI images # Containers — publish OCI images
Read before publishing an OCI image, updating a container tag, choosing Read before publishing an OCI image, updating a container tag, choosing Blossom
Blossom storage, or constructing a gateway pull reference. Protocol storage, or constructing a gateway pull reference. Protocol background:
background: https://ngit.dev/protocol/software-publishing https://ngit.dev/protocol/software-publishing
## Model ## Model
`ngit container publish` (alias `ngit oci publish`) uploads the OCI blobs `ngit container publish` (alias `ngit oci publish`) uploads the OCI blobs
reachable from the tagged entries of an OCI image layout to Blossom, then reachable from the tagged entries of an OCI image layout to Blossom, then signs
signs a kind-30624 addressable event mapping tags to manifest digests. The a kind-30624 addressable event mapping tags to manifest digests. The event is
event is bound to the current kind-30617 git repository, so run it inside that bound to the current kind-30617 git repository, so run it inside that repository
repository with a signer who is a confirmed maintainer. Gateways are read-only: with a signer who is a confirmed maintainer. Gateways are read-only:
```bash ```bash
docker pull ncontainer.io/<npub>/<repository>:<tag> docker pull ncontainer.io/<npub>/<repository>:<tag>
@@ -31,8 +31,8 @@ ngit container publish myimage \
--json --json
``` ```
A checked-in `.ngit/containers.yaml` lets `ngit container publish myimage A checked-in `.ngit/containers.yaml` lets
--json` select an entry: `ngit container publish myimage --json` select an entry:
```yaml ```yaml
schema: 1 schema: 1
@@ -47,10 +47,10 @@ containers:
Relative paths resolve from the repository root. `--manifest PATH` selects Relative paths resolve from the repository root. `--manifest PATH` selects
another file; `--no-manifest` ignores the default and requires `--layout`. A another file; `--no-manifest` ignores the default and requires `--layout`. A
loaded manifest must define `NAME`. CLI layout and metadata override the loaded manifest must define `NAME`. CLI layout and metadata override the entry,
entry, a non-empty CLI Blossom list replaces the configured list, and CLI a non-empty CLI Blossom list replaces the configured list, and CLI relays extend
relays extend configured relays. Signer selection, `--replace`, and output configured relays. Signer selection, `--replace`, and output mode stay on the
mode stay on the command line. command line.
Behaviour to know: Behaviour to know:
@@ -59,44 +59,43 @@ Behaviour to know:
`index.json`; filenames and git tags are irrelevant. `index.json` itself is `index.json`; filenames and git tags are irrelevant. `index.json` itself is
never uploaded; ngit merges the layout's tags into the tag map fetched from never uploaded; ngit merges the layout's tags into the tag map fetched from
the latest kind-30624 event. the latest kind-30624 event.
- Without `--blossom-server`, ngit uses the publisher's latest kind-10063 - Without `--blossom-server`, ngit uses the publisher's latest kind-10063 server
server list. A single server means no redundancy. Every blob is checked on list. A single server means no redundancy. Every blob is checked on every
every server, missing copies are uploaded with bounded retries and server, missing copies are uploaded with bounded retries and verified, and the
verified, and the event is signed once each blob has at least one confirmed event is signed once each blob has at least one confirmed copy; incomplete
copy; incomplete replication is reported per server. replication is reported per server.
- `--relay` extends the repository's relays; account and default relays are - `--relay` extends the repository's relays; account and default relays are not
not added. ngit reads the repository relays before and after uploading and added. ngit reads the repository relays before and after uploading and needs
needs at least one success each time. A total preflight failure or a at least one success each time. A total preflight failure or a
concurrent-update refusal is safe to retry: uploaded blobs are concurrent-update refusal is safe to retry: uploaded blobs are
content-addressed. Keep a known state-bearing repository relay reachable content-addressed. Keep a known state-bearing repository relay reachable when
when changing relay sets, because a healthy empty relay cannot reveal an changing relay sets, because a healthy empty relay cannot reveal an event
event stranded elsewhere and a publish could then omit old tags. stranded elsewhere and a publish could then omit old tags.
## Merge versus replace ## Merge versus replace
Ordinary publication updates the tags found in the new layout and retains Ordinary publication updates the tags found in the new layout and retains older
older tags, previous server hints, omitted metadata, and unknown event tags. tags, previous server hints, omitted metadata, and unknown event tags.
`--replace` publishes only the new layout's tags and selected servers, drops `--replace` publishes only the new layout's tags and selected servers, drops
omitted description, source, and unknown tags, and sets the title to omitted description, source, and unknown tags, and sets the title to `--title`
`--title` or `NAME`. Use it only when the user explicitly wants complete or `NAME`. Use it only when the user explicitly wants complete replacement.
replacement.
## JSON ## JSON
A successful result has `command: "container.publish"`, a `warnings` array, A successful result has `command: "container.publish"`, a `warnings` array, and
and `result` fields: `repository`, `git_repository`, `npub`, `name`, `naddr`, `result` fields: `repository`, `git_repository`, `npub`, `name`, `naddr`,
`manifest_path` (or `null`), raw-hex `event_id` (unlike collaboration `manifest_path` (or `null`), raw-hex `event_id` (unlike collaboration commands'
commands' `nevent` ids), `tags` and `updated_tags`, per-blob SHA-256, size, `nevent` ids), `tags` and `updated_tags`, per-blob SHA-256, size, and per-server
and per-server placement, final `blossom_servers`, and per-relay `accepted`. placement, final `blossom_servers`, and per-relay `accepted`. Success means at
Success means at least one relay accepted the event; inspect every least one relay accepted the event; inspect every `result.relays[].accepted`
`result.relays[].accepted` when full fanout matters. Failures use when full fanout matters. Failures use `command_status: "error"` with
`command_status: "error"` with `error.details` holding per-blob and `error.details` holding per-blob and per-server outcomes and possible orphan
per-server outcomes and possible orphan blobs. blobs.
## Limits ## Limits
ngit accepts OCI and Docker v2 manifests and indexes using SHA-256, uploads ngit accepts OCI and Docker v2 manifests and indexes using SHA-256, uploads only
only blobs reachable from tagged roots, and rejects missing, oversized, deeply blobs reachable from tagged roots, and rejects missing, oversized, deeply
nested, or mismatched graphs. It snapshots one blob at a time, so allow nested, or mismatched graphs. It snapshots one blob at a time, so allow
temporary disk roughly equal to the largest layer. It does not build images, temporary disk roughly equal to the largest layer. It does not build images,
push to registries, run a gateway, chunk layers, pull, list, or delete remote push to registries, run a gateway, chunk layers, pull, list, or delete remote
+4 -4
View File
@@ -17,13 +17,13 @@ ngit issue set-subject <ID|nevent> --subject "New title" --json
ngit issue set-cover-note <ID|nevent> --body "$(cat cover-note.md)" --json ngit issue set-cover-note <ID|nevent> --body "$(cat cover-note.md)" --json
``` ```
`resolved` records that the problem was fixed; `close` records that it will `resolved` records that the problem was fixed; `close` records that it will not
not be. Reference other events in `--body` as `nostr:nevent1…`. be. Reference other events in `--body` as `nostr:nevent1…`.
## Auto-resolve from commits ## Auto-resolve from commits
A commit pushed to the declared default branch resolves an issue when its A commit pushed to the declared default branch resolves an issue when its
message contains a form of `close`, `fix`, `resolve`, or `implement` followed message contains a form of `close`, `fix`, `resolve`, or `implement` followed by
by a unique hex ID or prefix or a `nostr:nevent1…` reference, for example a unique hex ID or prefix or a `nostr:nevent1…` reference, for example
`Fixes #deadbeef`. The status is published only when the pusher is the issue `Fixes #deadbeef`. The status is published only when the pusher is the issue
author or a confirmed repository member. author or a confirmed repository member.
+27 -28
View File
@@ -1,14 +1,14 @@
# Nsites — publish static sites # Nsites — publish static sites
Read before publishing an already-built website with `ngit nsite` or Read before publishing an already-built website with `ngit nsite` or diagnosing
diagnosing its Blossom uploads and NIP-5A manifest. its Blossom uploads and NIP-5A manifest. Guide: https://ngit.dev/releases/nsites
Guide: https://ngit.dev/releases/nsites (nsyte comparison, PR previews). (nsyte comparison, PR previews).
## Publish ## Publish
Pass the build output directory, not the source tree. ngit uploads every Pass the build output directory, not the source tree. ngit uploads every regular
regular file, runs no build, applies no ignore files, and rejects symlinks, file, runs no build, applies no ignore files, and rejects symlinks, unsafe
unsafe paths, and filenames without extensions. paths, and filenames without extensions.
```bash ```bash
ngit nsite publish dist --json # reads nsyte's .nsite/config.json when present ngit nsite publish dist --json # reads nsyte's .nsite/config.json when present
@@ -26,33 +26,32 @@ ngit --nbunksec-file /run/secrets/publisher-nbunksec nsite publish dist --json
- Config: `.nsite/config.json` (JSON, not YAML) fields `id`, `title`, - Config: `.nsite/config.json` (JSON, not YAML) fields `id`, `title`,
`description`, `source`, `fallback`, `servers`, and `relays` are read; `description`, `source`, `fallback`, `servers`, and `relays` are read;
`--config PATH` selects another file and `--no-config` ignores it. Explicit `--config PATH` selects another file and `--no-config` ignores it. Explicit
CLI values win, and any repeated `--blossom-server` or `--relay` replaces CLI values win, and any repeated `--blossom-server` or `--relay` replaces that
that whole config array. Unsupported nsyte publication options whole config array. Unsupported nsyte publication options (`publishProfile`,
(`publishProfile`, `publishRelayList`, `publishServerList`, `publishRelayList`, `publishServerList`, `publishAppHandler`) produce a
`publishAppHandler`) produce a warning; nsyte signer fields are ignored. warning; nsyte signer fields are ignored.
- Metadata: `--title`, `--description` or `--description-file`, and - Metadata: `--title`, `--description` or `--description-file`, and `--source`
`--source` (`https://` or `nostr://`; omitted, ngit infers the selected (`https://` or `nostr://`; omitted, ngit infers the selected public repository
public repository and never a private one). NIP-5A has no logo tag; ship a and never a private one). NIP-5A has no logo tag; ship a `favicon.ico` or
`favicon.ico` or `favicon.svg` in the build output. `favicon.svg` in the build output.
- `--fallback SITE_PATH` (or config `fallback`) maps an existing HTML file in - `--fallback SITE_PATH` (or config `fallback`) maps an existing HTML file in
the output to `/404.html` without another upload. the output to `/404.html` without another upload.
- Servers: omit `--blossom-server` to use the account's latest kind-10063 - Servers: omit `--blossom-server` to use the account's latest kind-10063 list;
list; repeat it for replication. `--concurrency` (default 4, range 1–64) is repeat it for replication. `--concurrency` (default 4, range 1–64) is a global
a global limit across presence checks and uploads. limit across presence checks and uploads.
## Guarantees ## Guarantees
ngit snapshots the directory before network work, deduplicates content, checks ngit snapshots the directory before network work, deduplicates content, checks
every blob on every selected server, and uploads missing copies with BUD-11 every blob on every selected server, and uploads missing copies with BUD-11
authorization. It signs the manifest only after every blob has at least one authorization. It signs the manifest only after every blob has at least one
confirmed copy, so a failed deployment cannot point the live manifest at confirmed copy, so a failed deployment cannot point the live manifest at missing
missing content. A server that fails three consecutive initial checks is content. A server that fails three consecutive initial checks is skipped for the
skipped for the rest of that pass while the others continue. rest of that pass while the others continue.
Rerun the same command after a failure: blobs already on a server are Rerun the same command after a failure: blobs already on a server are confirmed
confirmed with `HEAD` and skipped, so continuation is per blob and server. An with `HEAD` and skipped, so continuation is per blob and server. An unchanged
unchanged deployment reuses the current manifest without a new signature or deployment reuses the current manifest without a new signature or relay write.
relay write.
## JSON ## JSON
@@ -61,10 +60,10 @@ Check `command_status`, then:
- `result.changed`: publication versus an unchanged no-op; - `result.changed`: publication versus an unchanged no-op;
- `result.config_path`, `result.fallback`, `result.relays`: resolved settings; - `result.config_path`, `result.fallback`, `result.relays`: resolved settings;
- `result.blossom.blobs[].servers[]`: each blob and server outcome; - `result.blossom.blobs[].servers[]`: each blob and server outcome;
- `result.publication.relays[]`: manifest acknowledgements (at least one - `result.publication.relays[]`: manifest acknowledgements (at least one relay
relay must accept); must accept);
- `warnings[]`: unknown MIME types, unsupported config publications, and - `warnings[]`: unknown MIME types, unsupported config publications, and failed
failed uploads or post-upload verification per server. uploads or post-upload verification per server.
On a Blossom failure inspect `error.details.blobs` and On a Blossom failure inspect `error.details.blobs` and
`error.details.possible_orphan_blobs`, fix the server or signer problem, and `error.details.possible_orphan_blobs`, fix the server or signer problem, and
+20 -21
View File
@@ -1,12 +1,12 @@
# Pull requests — open, update, stack, review, merge # Pull requests — open, update, stack, review, merge
Read before opening, updating, reviewing, or merging PRs. Read before opening, updating, reviewing, or merging PRs. Guide:
Guide: https://ngit.dev/pull-requests https://ngit.dev/pull-requests
## Open or update a PR ## Open or update a PR
The branch name MUST start with `pr/`. No push option turns another branch The branch name MUST start with `pr/`. No push option turns another branch into
into a PR. a PR.
```bash ```bash
git checkout -b pr/my-feature git checkout -b pr/my-feature
@@ -21,18 +21,18 @@ git push --force origin pr/my-feature # update the PR after amend
- `-d`/`--defaults` accepts the single-commit title and description without a - `-d`/`--defaults` accepts the single-commit title and description without a
prompt. prompt.
- Do not use `$'…\n…'` for push options, and do not pre-escape a Markdown - Do not use `$'…\n…'` for push options, and do not pre-escape a Markdown file
file into `-o description=`; open the PR with `ngit send` instead. into `-o description=`; open the PR with `ngit send` instead.
- Stacks are inferred: a branch that contains the unique latest tip of one of - Stacks are inferred: a branch that contains the unique latest tip of one of
your other open or draft PRs becomes that PR's child and follows the parent your other open or draft PRs becomes that PR's child and follows the parent as
as it advances. Rebase the child onto the parent's latest tip before updating it advances. Rebase the child onto the parent's latest tip before updating it;
it; ngit refuses stale children and ambiguous candidates rather than ngit refuses stale children and ambiguous candidates rather than guessing. Use
guessing. Use `base=` for a cross-author, historical, or ambiguous parent, `base=` for a cross-author, historical, or ambiguous parent, and repeat it on
and repeat it on each update if the child should stay pinned. each update if the child should stay pinned.
- To push as another stored identity, use - To push as another stored identity, use
`git -c nostr.signer=<alias|npub|profile-name> push …`; `--signer` applies `git -c nostr.signer=<alias|npub|profile-name> push …`; `--signer` applies to
to `ngit` commands only. `ngit account login --local <alias>` makes an `ngit` commands only. `ngit account login --local <alias>` makes an identity
identity the repository default instead. the repository default instead.
## ngit send ## ngit send
@@ -70,13 +70,12 @@ ngit pr merge <ID|nevent> --exclude-description --json # summary line and
git push origin <target-branch> # publishes the merge and the applied status git push origin <target-branch> # publishes the merge and the applied status
``` ```
`ngit merge` is a compatibility alias with the same options. The merge lands `ngit merge` is a compatibility alias with the same options. The merge lands on
on the PR's declared target, or the default branch, resolved against the the PR's declared target, or the default branch, resolved against the latest
latest Nostr repository state rather than a local tracking ref, with the Nostr repository state rather than a local tracking ref, with the message
message `Merge #<8-hex>: <PR title>`. Closed and applied PRs are refused `Merge #<8-hex>: <PR title>`. Closed and applied PRs are refused before any git
before any git change. On conflicts, resolve them and run `git commit`; the change. On conflicts, resolve them and run `git commit`; the message is already
message is already prepared, and JSON reports `action: "conflicted"` instead prepared, and JSON reports `action: "conflicted"` instead of `"merged"`.
of `"merged"`.
Before merging or adding maintainer fixes, run Before merging or adding maintainer fixes, run
`git log --merges --oneline origin/<target>..HEAD`. A prior `Merge #…` means a `git log --merges --oneline origin/<target>..HEAD`. A prior `Merge #…` means a
+23 -23
View File
@@ -1,9 +1,9 @@
# Repositories — publish, clone, hosting, membership # Repositories — publish, clone, hosting, membership
Read when publishing or cloning a repository, resolving `nostr://` URL forms, Read when publishing or cloning a repository, resolving `nostr://` URL forms, or
or changing an announcement's hosting, metadata, or roster. Guides: changing an announcement's hosting, metadata, or roster. Guides:
https://ngit.dev/repositories (hosting choices, migrating from a forge, https://ngit.dev/repositories (hosting choices, migrating from a forge, mirrors,
mirrors, private repositories), https://ngit.dev/maintainers, and private repositories), https://ngit.dev/maintainers, and
https://ngit.dev/maintainers/going-deeper (leadless repositories, delegated https://ngit.dev/maintainers/going-deeper (leadless repositories, delegated
trust, removal, roster repair). trust, removal, roster repair).
@@ -36,9 +36,9 @@ ngit repo --json --offline # run git fetch origin first when the cache may
The output reports `nostr_url`, effective `git_servers`, `relays`, `hashtags`, The output reports `nostr_url`, effective `git_servers`, `relays`, `hashtags`,
and `grasp_servers` detected from paired clone and relay entries, plus the and `grasp_servers` detected from paired clone and relay entries, plus the
roster: `members`, `lead_source`, `lead_path`, `pending_actions`, and roster: `members`, `lead_source`, `lead_path`, `pending_actions`, and `health`.
`health`. Follow the actionable error or `pending_actions` rather than Follow the actionable error or `pending_actions` rather than replacing an
replacing an announcement wholesale. announcement wholesale.
## Publish and host ## Publish and host
@@ -66,30 +66,30 @@ Every announcement needs at least one relay and one git server; `init` and
announcement that already lacks one half. Repair it in the same command, e.g. announcement that already lacks one half. Repair it in the same command, e.g.
`ngit repo edit --name "New name" --add-grasp-server grasp.example.com`. `ngit repo edit --name "New name" --add-grasp-server grasp.example.com`.
`--identifier` is set at initial publication only: changing the `d` tag `--identifier` is set at initial publication only: changing the `d` tag creates
creates a different repository coordinate. a different repository coordinate.
## Edit ## Edit
`ngit repo edit` preserves omitted settings. Collections use targeted, `ngit repo edit` preserves omitted settings. Collections use targeted,
repeatable actions that can be combined in one command: repeatable actions that can be combined in one command:
| Setting | Add | Remove | | Setting | Add | Remove |
| ------- | --- | ------ | | ---------------- | ---------------------------- | ------------------------------- |
| Grasp server | `--add-grasp-server URL` | `--remove-grasp-server URL` | | Grasp server | `--add-grasp-server URL` | `--remove-grasp-server URL` |
| Additional relay | `--add-additional-relay URL` | `--remove-additional-relay URL` | | Additional relay | `--add-additional-relay URL` | `--remove-additional-relay URL` |
| Additional clone | `--add-additional-clone URL` | `--remove-additional-clone URL` | | Additional clone | `--add-additional-clone URL` | `--remove-additional-clone URL` |
| Hashtag | `--add-hashtag TAG` | `--remove-hashtag TAG` | | Hashtag | `--add-hashtag TAG` | `--remove-hashtag TAG` |
Scalars use replacement flags: `--name`, `--description`, `--web`, `--u`, Scalars use replacement flags: `--name`, `--description`, `--web`, `--u`,
`--earliest-unique-commit`. A grasp-derived relay or clone cannot be removed `--earliest-unique-commit`. A grasp-derived relay or clone cannot be removed as
as an additional entry; remove the grasp server and its pair goes with it. To an additional entry; remove the grasp server and its pair goes with it. To empty
empty a collection, remove every value currently reported. a collection, remove every value currently reported.
Each successful edit publishes a fresh announcement and, when the repository Each successful edit publishes a fresh announcement and, when the repository has
has Nostr state, republishes that state once so new relays and servers hold Nostr state, republishes that state once so new relays and servers hold the
the authoritative refs. If that fails, follow the reported `ngit sync` authoritative refs. If that fails, follow the reported `ngit sync` recovery
recovery guidance. guidance.
## Roles and membership ## Roles and membership
@@ -101,9 +101,9 @@ recovery guidance.
- **Moderator**: publishes issue, PR, and patch status events (including - **Moderator**: publishes issue, PR, and patch status events (including
recording an existing merge) but cannot publish git state or merge. recording an existing merge) but cannot publish git state or merge.
Membership is reciprocal: a listing is an invitation until the invitee Membership is reciprocal: a listing is an invitation until the invitee publishes
publishes an announcement acknowledging the role, and an invited member's an announcement acknowledging the role, and an invited member's events are not
events are not authoritative until then. authoritative until then.
```bash ```bash
ngit repo edit --add-maintainer <npub> --json # a sole maintainer's first add makes them lead ngit repo edit --add-maintainer <npub> --json # a sole maintainer's first add makes them lead
+15 -15
View File
@@ -1,7 +1,7 @@
# Sync, flags, and configuration # Sync, flags, and configuration
Read when syncing refs, choosing flags, or tuning git config. Read when syncing refs, choosing flags, or tuning git config. Guides:
Guides: https://ngit.dev/configuration and https://ngit.dev/troubleshooting https://ngit.dev/configuration and https://ngit.dev/troubleshooting
## Sync ## Sync
@@ -15,16 +15,16 @@ ngit sync --ref-name main --json # one ref
These accept any command position. `--offline` is per command; check These accept any command position. `--offline` is per command; check
`ngit <command> --help`. `ngit <command> --help`.
| Flag | Description | | Flag | Description |
| ---- | ----------- | | --------------------------------------- | ---------------------------------------------------------------------------------------------- |
| `--json` | One JSON document on stdout (ngit commands only) | | `--json` | One JSON document on stdout (ngit commands only) |
| `-d`, `--defaults` | Non-interactive; accept defaults | | `-d`, `--defaults` | Non-interactive; accept defaults |
| `-q`, `--quiet` | Hide non-essential stderr progress (not combinable with `-v`) | | `-q`, `--quiet` | Hide non-essential stderr progress (not combinable with `-v`) |
| `--repo <REMOTE\|NADDR\|NOSTR-URL>` | Select the target repository | | `--repo <REMOTE\|NADDR\|NOSTR-URL>` | Select the target repository |
| `--signer <ALIAS\|NPUB\|NAME>` | Use a stored signer for this command | | `--signer <ALIAS\|NPUB\|NAME>` | Use a stored signer for this command |
| `--nsec-file`, `--nbunksec-file <PATH>` | One-shot key or bunker session from a private file (`--nsec`, `--nbunksec` take inline values) | | `--nsec-file`, `--nbunksec-file <PATH>` | One-shot key or bunker session from a private file (`--nsec`, `--nbunksec` take inline values) |
| `--repo-relay-only` | Publish only to repository relays | | `--repo-relay-only` | Publish only to repository relays |
| `-f`, `--force` | Bypass safety guards | | `-f`, `--force` | Bypass safety guards |
## git config ## git config
@@ -39,11 +39,11 @@ git config nostr.http-io-timeout-ms 600000 # allow large grasp pushes
NGIT_CACHE_DIR=/writable/path ngit repo --json # override the global event-cache directory NGIT_CACHE_DIR=/writable/path ngit repo --json # override the global event-cache directory
``` ```
`nostr.auto-pr-branches` follows normal git config precedence. With the `nostr.auto-pr-branches` follows normal git config precedence. With the default
default `false`, PRs appear as branches only after `ngit pr checkout`; run `false`, PRs appear as branches only after `ngit pr checkout`; run
`git fetch --prune` once to drop branches fetched by an older version, or use `git fetch --prune` once to drop branches fetched by an older version, or use
`git clone --config nostr.auto-pr-branches=true <nostr-url>` to opt in from `git clone --config nostr.auto-pr-branches=true <nostr-url>` to opt in from the
the start. start.
If the global cache directory is unavailable ngit falls back to an in-memory If the global cache directory is unavailable ngit falls back to an in-memory
cache; the repository's git common directory must still be writable. cache; the repository's git common directory must still be writable.
+68 -65
View File
@@ -1,32 +1,39 @@
--- ---
name: ngit name: ngit
description: Commands and workflows for NIP-34 git collaboration over Nostr with the ngit CLI and git-remote-nostr. Use in any repository with a nostr:// remote for generic collaboration requests (open an Issue, create or review a Pull Request (PR), comment, merge, clone) and whenever a task involves nostr:// URLs, ngit commands, Grasp servers, gitworkshop.dev, Nostr CI status and workflows, software releases and Zapstore publication, OCI container images, or nsite static sites published through Blossom. description:
Commands and workflows for NIP-34 git collaboration over Nostr with the ngit
CLI and git-remote-nostr. Use in any repository with a nostr:// remote for
generic collaboration requests (open an Issue, create or review a Pull Request
(PR), comment, merge, clone) and whenever a task involves nostr:// URLs, ngit
commands, Grasp servers, gitworkshop.dev, Nostr CI status and workflows,
software releases and Zapstore publication, OCI container images, or nsite
static sites published through Blossom.
license: CC-BY-SA-4.0 license: CC-BY-SA-4.0
metadata: metadata:
version: "1.17" version: "1.18"
--- ---
# ngit — Nostr Plugin for Git # ngit — Nostr Plugin for Git
ngit makes `git clone`, `fetch`, and `push` work with `nostr://` URLs and adds ngit makes `git clone`, `fetch`, and `push` work with `nostr://` URLs and adds a
a CLI for pull requests, issues, membership, CI results, releases, OCI CLI for pull requests, issues, membership, CI results, releases, OCI containers,
containers, and nsites. Repository state (which commit each ref points to) is and nsites. Repository state (which commit each ref points to) is published as
published as signed Nostr events and is the source of truth; git objects live signed Nostr events and is the source of truth; git objects live on ordinary git
on ordinary git servers, so servers are interchangeable. A grasp server bundles servers, so servers are interchangeable. A grasp server bundles a relay and a
a relay and a git server and creates the repository automatically when an git server and creates the repository automatically when an announcement lists
announcement lists it. Explanation: https://ngit.dev/how-it-works it. Explanation: https://ngit.dev/how-it-works
## Where to look ## Where to look
- **This skill documents ngit v3.** Run `ngit --version` first; the commands - **This skill documents ngit v3.** Run `ngit --version` first; the commands
here need 3.0.0 or later. If ngit is missing or older, report that and here need 3.0.0 or later. If ngit is missing or older, report that and offer
offer an install or update: `curl -fsSL https://ngit.dev/install.sh | bash` an install or update: `curl -fsSL https://ngit.dev/install.sh | bash` installs
installs or replaces `ngit` and `git-remote-nostr`, and `ngit update` works or replaces `ngit` and `git-remote-nostr`, and `ngit update` works on v3 or
on v3 or later. Other methods: https://ngit.dev/install later. Other methods: https://ngit.dev/install
- **`ngit <command> --help`** is the authority for the installed version's - **`ngit <command> --help`** is the authority for the installed version's flags
flags and defaults. and defaults.
- **https://ngit.dev** holds the guides. Any page is available as raw - **https://ngit.dev** holds the guides. Any page is available as raw Markdown
Markdown at `https://ngit.dev/markdown/<route>.md`; the index is at `https://ngit.dev/markdown/<route>.md`; the index is
https://ngit.dev/llms.txt. Web UI: https://gitworkshop.dev https://ngit.dev/llms.txt. Web UI: https://gitworkshop.dev
## Rules ## Rules
@@ -35,44 +42,40 @@ announcement lists it. Explanation: https://ngit.dev/how-it-works
policy. Carry through the selected signer, target, hosting, CI, and policy. Carry through the selected signer, target, hosting, CI, and
replication settings; do not add gates, waits, workflow edits, or replication settings; do not add gates, waits, workflow edits, or
configuration changes that the task or repository did not choose. configuration changes that the task or repository did not choose.
- **PR branches MUST start with `pr/`** (e.g. `pr/my-feature`). Any other - **PR branches MUST start with `pr/`** (e.g. `pr/my-feature`). Any other branch
branch name is a plain push and never creates a PR. name is a plain push and never creates a PR.
- **Read ngit output with `--json`.** It is a global option and works at any - **Read ngit output with `--json`.** It is a global option and works at any
position. Stdout is exactly one JSON document; progress and diagnostics go position. Stdout is exactly one JSON document; progress and diagnostics go to
to stderr. `git` commands have no `--json`. Top-level `command_status` is stderr. `git` commands have no `--json`. Top-level `command_status` is `ok`
`ok` for exit 0 and `error` otherwise; it never describes a nested domain for exit 0 and `error` otherwise; it never describes a nested domain result
result (`ngit ci status --json` reports `ok` with (`ngit ci status --json` reports `ok` with `ci.conclusion: "failure"` unless a
`ci.conclusion: "failure"` unless a gate was requested). gate was requested).
- **Add `--offline` after the first network read** in a session, on commands - **Add `--offline` after the first network read** in a session, on commands
that support it. `git fetch origin` also refreshes the cache. that support it. `git fetch origin` also refreshes the cache.
- **Identifiers.** `<ID|nevent>` accepts `nevent1…`, a 64-char hex ID, or a - **Identifiers.** `<ID|nevent>` accepts `nevent1…`, a 64-char hex ID, or a
unique hex prefix with an optional `#` (quote it: `'#deadbeef'`). JSON `id` unique hex prefix with an optional `#` (quote it: `'#deadbeef'`). JSON `id`
and `reply_to` fields are already `nevent1…`; container publication instead and `reply_to` fields are already `nevent1…`; container publication instead
returns a raw-hex `event_id` plus the repository `naddr`. Reference events returns a raw-hex `event_id` plus the repository `naddr`. Reference events
inside `--body` text as `nostr:nevent1…` or `nostr:naddr1…`, never as raw inside `--body` text as `nostr:nevent1…` or `nostr:naddr1…`, never as raw hex.
hex. Never construct a NIP-05 address (`user@domain`); use `npub1…` unless Never construct a NIP-05 address (`user@domain`); use `npub1…` unless a NIP-05
a NIP-05 address was given to you. address was given to you.
- **Multiline text.** `ngit` options such as `--body` and `--description` - **Multiline text.** `ngit` options such as `--body` and `--description` accept
accept real newlines: `--body "$(cat note.md)"`. Git push options cannot real newlines: `--body "$(cat note.md)"`. Git push options cannot carry
carry newlines: write literal `\n` in a short inline `-o description=…`, and newlines: write literal `\n` in a short inline `-o description=…`, and never
never convert a file into a push option (open the PR with `ngit send` convert a file into a push option (open the PR with `ngit send` instead).
instead).
- **Signers.** `--signer <alias|npub|profile-name>` selects a stored identity - **Signers.** `--signer <alias|npub|profile-name>` selects a stored identity
for one `ngit` command; `git -c nostr.signer=<alias|npub|profile-name> for one `ngit` command; `git -c nostr.signer=<alias|npub|profile-name> push …`
push …` does the same for one git command. Neither changes the configured does the same for one git command. Neither changes the configured login. Never
login. Never export or pass an nsec merely to switch between configured export or pass an nsec merely to switch between configured accounts.
accounts. - **CI.** A successful push says nothing about CI. Nostr CI runs workflows from
- **CI.** A successful push says nothing about CI. Nostr CI runs workflows `.ngit/act/workflows/`; another provider's directory is not evidence. When CI
from `.ngit/act/workflows/`; another provider's directory is not evidence. matters, query the exact commit or PR with `ngit ci status <target> --json`
When CI matters, query the exact commit or PR with and read `ci.state` and `ci.conclusion`, not `command_status`.
`ngit ci status <target> --json` and read `ci.state` and `ci.conclusion`,
not `command_status`.
- **Target repository.** With several `nostr://` remotes, pass global - **Target repository.** With several `nostr://` remotes, pass global
`--repo <REMOTE|NADDR|NOSTR-URL>`; a configured remote name, an naddr, and `--repo <REMOTE|NADDR|NOSTR-URL>`; a configured remote name, an naddr, and a
a nostr:// URL are all accepted. Without it ngit nostr:// URL are all accepted. Without it ngit infers the target from config
infers the target from config and branch tracking and fails rather than and branch tracking and fails rather than guesses. Before a signing command,
guesses. Before a signing command, check the check the `target repository: <naddr> (source: …)` line on stderr.
`target repository: <naddr> (source: …)` line on stderr.
## Detecting a nostr repo ## Detecting a nostr repo
@@ -81,11 +84,11 @@ git remote -v | grep -q 'nostr://' # primary check, no cache needed
ngit repo --json --offline # full metadata when needed ngit repo --json --offline # full metadata when needed
``` ```
`ngit repo` always exits 0, and `is_nostr_repo: false` can be a cold-cache `ngit repo` always exits 0, and `is_nostr_repo: false` can be a cold-cache false
false negative: if a remote shows `nostr://`, run `git fetch origin` and negative: if a remote shows `nostr://`, run `git fetch origin` and retry. The
retry. The output includes the roster (`members`, `lead_source`, `lead_path`, output includes the roster (`members`, `lead_source`, `lead_path`,
`pending_actions`, `health`); read `reference/repositories.md` before `pending_actions`, `health`); read `reference/repositories.md` before changing
changing membership or hosting. membership or hosting.
## nostr:// URLs ## nostr:// URLs
@@ -100,18 +103,18 @@ Standard git commands accept these URLs directly.
## Task index ## Task index
Read the bundled reference before performing that slice of work; the guide Read the bundled reference before performing that slice of work; the guide adds
adds tutorials and background. tutorials and background.
| Task | Bundled reference | ngit.dev guide | | Task | Bundled reference | ngit.dev guide |
| ---- | ----------------- | -------------- | | ---------------------------------------------------------- | --------------------------- | ------------------------------------ |
| Publish, clone, host repositories; maintainers, moderators | `reference/repositories.md` | `/repositories`, `/maintainers` | | Publish, clone, host repositories; maintainers, moderators | `reference/repositories.md` | `/repositories`, `/maintainers` |
| Open, update, stack, review, merge PRs | `reference/prs.md` | `/pull-requests` | | Open, update, stack, review, merge PRs | `reference/prs.md` | `/pull-requests` |
| Issues | `reference/issues.md` | `/issues` | | Issues | `reference/issues.md` | `/issues` |
| CI results, trust, workflows, ngit in CI jobs | `reference/ci.md` | `/ci`, `/ci/workflows/` | | CI results, trust, workflows, ngit in CI jobs | `reference/ci.md` | `/ci`, `/ci/workflows/` |
| Accounts, login, signers, secrets | `reference/accounts.md` | `/accounts` | | Accounts, login, signers, secrets | `reference/accounts.md` | `/accounts` |
| Sync, global flags, git config | `reference/sync-config.md` | `/configuration`, `/troubleshooting` | | Sync, global flags, git config | `reference/sync-config.md` | `/configuration`, `/troubleshooting` |
| Publish nsites (static sites) | `reference/nsites.md` | `/releases/nsites` | | Publish nsites (static sites) | `reference/nsites.md` | `/releases/nsites` |
| Publish OCI containers | `reference/containers.md` | `/releases` | | Publish OCI containers | `reference/containers.md` | `/releases` |
| Software releases | `ngit release --help` | `/releases` | | Software releases | `ngit release --help` | `/releases` |
| Automation contract, machine-readable docs | this file | `/agents/` | | Automation contract, machine-readable docs | this file | `/agents/` |
+8 -8
View File
@@ -1,8 +1,8 @@
# Accounts — identity, login, secrets # Accounts — identity, login, secrets
Read when managing accounts, logins, or credential storage. Read when managing accounts, logins, or credential storage. Guide:
Guide: https://ngit.dev/accounts (storage modes, pairing a remote signer for https://ngit.dev/accounts (storage modes, pairing a remote signer for CI,
CI, rotation). rotation).
```bash ```bash
ngit account whoami --json --offline # every usable signer with npub, aliases, scope, active state; `account list` is an alias ngit account whoami --json --offline # every usable signer with npub, aliases, scope, active state; `account list` is an alias
@@ -40,8 +40,8 @@ unaliased connection. Log in with `--alias` to keep an extra connection and
select it by alias. Older ngit versions ignore the exact-session binding and select it by alias. Older ngit versions ignore the exact-session binding and
select the identity's default connection. select the identity's default connection.
**nbunksec** is a portable established connection: remote-signer pubkey, **nbunksec** is a portable established connection: remote-signer pubkey, client
client secret, relays, and optional pairing secret. It holds no npub, so secret, relays, and optional pairing secret. It holds no npub, so one-shot use
one-shot use resolves the identity from the signer. The `--nbunksec-file` and resolves the identity from the signer. The `--nbunksec-file` and `--nsec-file`
`--nsec-file` forms keep secrets out of process arguments. A fresh pairing forms keep secrets out of process arguments. A fresh pairing needs interactive
needs interactive approval, so unattended runs use a stored connection. approval, so unattended runs use a stored connection.
+23 -23
View File
@@ -1,18 +1,18 @@
# Nostr CI # Nostr CI
Read when checking whether CI ran, interpreting a result, or writing a Read when checking whether CI ran, interpreting a result, or writing a workflow
workflow that uses ngit. Guides: https://ngit.dev/ci (coordinators, results, that uses ngit. Guides: https://ngit.dev/ci (coordinators, results, trust,
trust, secrets) and https://ngit.dev/ci/workflows/ (what the coordinator secrets) and https://ngit.dev/ci/workflows/ (what the coordinator accepts,
accepts, refuses, and adds compared with GitHub Actions). refuses, and adds compared with GitHub Actions).
## Workflows ## Workflows
Nostr CI (ngit-ci) runs workflows from `.ngit/act/workflows/` with Nostr CI (ngit-ci) runs workflows from `.ngit/act/workflows/` with GitHub
GitHub Actions syntax in Linux containers. `.github/workflows/` is run only by Actions syntax in Linux containers. `.github/workflows/` is run only by GitHub
GitHub Actions on a mirror; the directories are independent, so a check that Actions on a mirror; the directories are independent, so a check that must run
must run in both systems needs a file in each. ngit-ci refuses macOS and in both systems needs a file in each. ngit-ci refuses macOS and Windows
Windows `runs-on` labels and job-level `uses:` (reusable workflows); composite `runs-on` labels and job-level `uses:` (reusable workflows); composite actions
actions in steps work in both systems. in steps work in both systems.
Read the workflow at the commit under investigation and confirm that its Read the workflow at the commit under investigation and confirm that its
triggers and steps cover the check in question: triggers and steps cover the check in question:
@@ -28,7 +28,7 @@ checksum-pinned manifest:
```yaml ```yaml
- uses: danconwaydev/setup-ngit@v3 - uses: danconwaydev/setup-ngit@v3
with: with:
version: 3.0.0 # optional exact pin; the default `latest` resolves against the action's manifest, not the network version: 3.0.0 # optional exact pin; the default `latest` resolves against the action's manifest, not the network
``` ```
Source: Source:
@@ -43,25 +43,25 @@ ngit ci status <target> --json --offline # later cache
ngit ci status <target> --require-ci-trust maintainer-directed --json # exit non-zero unless green at this floor ngit ci status <target> --require-ci-trust maintainer-directed --json # exit non-zero unless green at this floor
``` ```
Query the exact commit that introduced the change. A PR target reports only Query the exact commit that introduced the change. A PR target reports only its
its latest revision. Read: latest revision. Read:
- `ci.state`: pending, running, or concluded. `ci.conclusion` counts only - `ci.state`: pending, running, or concluded. `ci.conclusion` counts only once
once the state is concluded. the state is concluded.
- `ci.conclusion`: success, failure, cancellation, or another outcome. - `ci.conclusion`: success, failure, cancellation, or another outcome.
`command_status: "ok"` means only that the query worked. `command_status: "ok"` means only that the query worked.
- `ci.runs[].workflow` and `ci.runs[].jobs`: which workflow and job passed or - `ci.runs[].workflow` and `ci.runs[].jobs`: which workflow and job passed or
failed. failed.
- `ci.runs[].integrity`: the commit is present locally and the workflow hash - `ci.runs[].integrity`: the commit is present locally and the workflow hash
matches. matches.
- `coverage` and each run's classification and evidence: how completely and - `coverage` and each run's classification and evidence: how completely and why
why the result is trusted. Partial coverage is not success. the result is trusted. Partial coverage is not success.
If no run appears, report that no matching Nostr CI event was found. Then If no run appears, report that no matching Nostr CI event was found. Then check
check that the workflow existed at that commit, its trigger matched, a that the workflow existed at that commit, its trigger matched, a coordinator
coordinator serves the repository, and the query refreshed the relays before serves the repository, and the query refreshed the relays before concluding that
concluding that CI did not run. CI did not run.
Trust floors are `maintainer-directed` and `operationally-associated`. Trust floors are `maintainer-directed` and `operationally-associated`.
`ngit pr merge --require-ci-trust <LEVEL>` applies the same gate to a merge `ngit pr merge --require-ci-trust <LEVEL>` applies the same gate to a merge when
when the caller wants one. the caller wants one.
+39 -40
View File
@@ -1,16 +1,16 @@
# Containers — publish OCI images # Containers — publish OCI images
Read before publishing an OCI image, updating a container tag, choosing Read before publishing an OCI image, updating a container tag, choosing Blossom
Blossom storage, or constructing a gateway pull reference. Protocol storage, or constructing a gateway pull reference. Protocol background:
background: https://ngit.dev/protocol/software-publishing https://ngit.dev/protocol/software-publishing
## Model ## Model
`ngit container publish` (alias `ngit oci publish`) uploads the OCI blobs `ngit container publish` (alias `ngit oci publish`) uploads the OCI blobs
reachable from the tagged entries of an OCI image layout to Blossom, then reachable from the tagged entries of an OCI image layout to Blossom, then signs
signs a kind-30624 addressable event mapping tags to manifest digests. The a kind-30624 addressable event mapping tags to manifest digests. The event is
event is bound to the current kind-30617 git repository, so run it inside that bound to the current kind-30617 git repository, so run it inside that repository
repository with a signer who is a confirmed maintainer. Gateways are read-only: with a signer who is a confirmed maintainer. Gateways are read-only:
```bash ```bash
docker pull ncontainer.io/<npub>/<repository>:<tag> docker pull ncontainer.io/<npub>/<repository>:<tag>
@@ -31,8 +31,8 @@ ngit container publish myimage \
--json --json
``` ```
A checked-in `.ngit/containers.yaml` lets `ngit container publish myimage A checked-in `.ngit/containers.yaml` lets
--json` select an entry: `ngit container publish myimage --json` select an entry:
```yaml ```yaml
schema: 1 schema: 1
@@ -47,10 +47,10 @@ containers:
Relative paths resolve from the repository root. `--manifest PATH` selects Relative paths resolve from the repository root. `--manifest PATH` selects
another file; `--no-manifest` ignores the default and requires `--layout`. A another file; `--no-manifest` ignores the default and requires `--layout`. A
loaded manifest must define `NAME`. CLI layout and metadata override the loaded manifest must define `NAME`. CLI layout and metadata override the entry,
entry, a non-empty CLI Blossom list replaces the configured list, and CLI a non-empty CLI Blossom list replaces the configured list, and CLI relays extend
relays extend configured relays. Signer selection, `--replace`, and output configured relays. Signer selection, `--replace`, and output mode stay on the
mode stay on the command line. command line.
Behaviour to know: Behaviour to know:
@@ -59,44 +59,43 @@ Behaviour to know:
`index.json`; filenames and git tags are irrelevant. `index.json` itself is `index.json`; filenames and git tags are irrelevant. `index.json` itself is
never uploaded; ngit merges the layout's tags into the tag map fetched from never uploaded; ngit merges the layout's tags into the tag map fetched from
the latest kind-30624 event. the latest kind-30624 event.
- Without `--blossom-server`, ngit uses the publisher's latest kind-10063 - Without `--blossom-server`, ngit uses the publisher's latest kind-10063 server
server list. A single server means no redundancy. Every blob is checked on list. A single server means no redundancy. Every blob is checked on every
every server, missing copies are uploaded with bounded retries and server, missing copies are uploaded with bounded retries and verified, and the
verified, and the event is signed once each blob has at least one confirmed event is signed once each blob has at least one confirmed copy; incomplete
copy; incomplete replication is reported per server. replication is reported per server.
- `--relay` extends the repository's relays; account and default relays are - `--relay` extends the repository's relays; account and default relays are not
not added. ngit reads the repository relays before and after uploading and added. ngit reads the repository relays before and after uploading and needs
needs at least one success each time. A total preflight failure or a at least one success each time. A total preflight failure or a
concurrent-update refusal is safe to retry: uploaded blobs are concurrent-update refusal is safe to retry: uploaded blobs are
content-addressed. Keep a known state-bearing repository relay reachable content-addressed. Keep a known state-bearing repository relay reachable when
when changing relay sets, because a healthy empty relay cannot reveal an changing relay sets, because a healthy empty relay cannot reveal an event
event stranded elsewhere and a publish could then omit old tags. stranded elsewhere and a publish could then omit old tags.
## Merge versus replace ## Merge versus replace
Ordinary publication updates the tags found in the new layout and retains Ordinary publication updates the tags found in the new layout and retains older
older tags, previous server hints, omitted metadata, and unknown event tags. tags, previous server hints, omitted metadata, and unknown event tags.
`--replace` publishes only the new layout's tags and selected servers, drops `--replace` publishes only the new layout's tags and selected servers, drops
omitted description, source, and unknown tags, and sets the title to omitted description, source, and unknown tags, and sets the title to `--title`
`--title` or `NAME`. Use it only when the user explicitly wants complete or `NAME`. Use it only when the user explicitly wants complete replacement.
replacement.
## JSON ## JSON
A successful result has `command: "container.publish"`, a `warnings` array, A successful result has `command: "container.publish"`, a `warnings` array, and
and `result` fields: `repository`, `git_repository`, `npub`, `name`, `naddr`, `result` fields: `repository`, `git_repository`, `npub`, `name`, `naddr`,
`manifest_path` (or `null`), raw-hex `event_id` (unlike collaboration `manifest_path` (or `null`), raw-hex `event_id` (unlike collaboration commands'
commands' `nevent` ids), `tags` and `updated_tags`, per-blob SHA-256, size, `nevent` ids), `tags` and `updated_tags`, per-blob SHA-256, size, and per-server
and per-server placement, final `blossom_servers`, and per-relay `accepted`. placement, final `blossom_servers`, and per-relay `accepted`. Success means at
Success means at least one relay accepted the event; inspect every least one relay accepted the event; inspect every `result.relays[].accepted`
`result.relays[].accepted` when full fanout matters. Failures use when full fanout matters. Failures use `command_status: "error"` with
`command_status: "error"` with `error.details` holding per-blob and `error.details` holding per-blob and per-server outcomes and possible orphan
per-server outcomes and possible orphan blobs. blobs.
## Limits ## Limits
ngit accepts OCI and Docker v2 manifests and indexes using SHA-256, uploads ngit accepts OCI and Docker v2 manifests and indexes using SHA-256, uploads only
only blobs reachable from tagged roots, and rejects missing, oversized, deeply blobs reachable from tagged roots, and rejects missing, oversized, deeply
nested, or mismatched graphs. It snapshots one blob at a time, so allow nested, or mismatched graphs. It snapshots one blob at a time, so allow
temporary disk roughly equal to the largest layer. It does not build images, temporary disk roughly equal to the largest layer. It does not build images,
push to registries, run a gateway, chunk layers, pull, list, or delete remote push to registries, run a gateway, chunk layers, pull, list, or delete remote
+4 -4
View File
@@ -17,13 +17,13 @@ ngit issue set-subject <ID|nevent> --subject "New title" --json
ngit issue set-cover-note <ID|nevent> --body "$(cat cover-note.md)" --json ngit issue set-cover-note <ID|nevent> --body "$(cat cover-note.md)" --json
``` ```
`resolved` records that the problem was fixed; `close` records that it will `resolved` records that the problem was fixed; `close` records that it will not
not be. Reference other events in `--body` as `nostr:nevent1…`. be. Reference other events in `--body` as `nostr:nevent1…`.
## Auto-resolve from commits ## Auto-resolve from commits
A commit pushed to the declared default branch resolves an issue when its A commit pushed to the declared default branch resolves an issue when its
message contains a form of `close`, `fix`, `resolve`, or `implement` followed message contains a form of `close`, `fix`, `resolve`, or `implement` followed by
by a unique hex ID or prefix or a `nostr:nevent1…` reference, for example a unique hex ID or prefix or a `nostr:nevent1…` reference, for example
`Fixes #deadbeef`. The status is published only when the pusher is the issue `Fixes #deadbeef`. The status is published only when the pusher is the issue
author or a confirmed repository member. author or a confirmed repository member.
+27 -28
View File
@@ -1,14 +1,14 @@
# Nsites — publish static sites # Nsites — publish static sites
Read before publishing an already-built website with `ngit nsite` or Read before publishing an already-built website with `ngit nsite` or diagnosing
diagnosing its Blossom uploads and NIP-5A manifest. its Blossom uploads and NIP-5A manifest. Guide: https://ngit.dev/releases/nsites
Guide: https://ngit.dev/releases/nsites (nsyte comparison, PR previews). (nsyte comparison, PR previews).
## Publish ## Publish
Pass the build output directory, not the source tree. ngit uploads every Pass the build output directory, not the source tree. ngit uploads every regular
regular file, runs no build, applies no ignore files, and rejects symlinks, file, runs no build, applies no ignore files, and rejects symlinks, unsafe
unsafe paths, and filenames without extensions. paths, and filenames without extensions.
```bash ```bash
ngit nsite publish dist --json # reads nsyte's .nsite/config.json when present ngit nsite publish dist --json # reads nsyte's .nsite/config.json when present
@@ -26,33 +26,32 @@ ngit --nbunksec-file /run/secrets/publisher-nbunksec nsite publish dist --json
- Config: `.nsite/config.json` (JSON, not YAML) fields `id`, `title`, - Config: `.nsite/config.json` (JSON, not YAML) fields `id`, `title`,
`description`, `source`, `fallback`, `servers`, and `relays` are read; `description`, `source`, `fallback`, `servers`, and `relays` are read;
`--config PATH` selects another file and `--no-config` ignores it. Explicit `--config PATH` selects another file and `--no-config` ignores it. Explicit
CLI values win, and any repeated `--blossom-server` or `--relay` replaces CLI values win, and any repeated `--blossom-server` or `--relay` replaces that
that whole config array. Unsupported nsyte publication options whole config array. Unsupported nsyte publication options (`publishProfile`,
(`publishProfile`, `publishRelayList`, `publishServerList`, `publishRelayList`, `publishServerList`, `publishAppHandler`) produce a
`publishAppHandler`) produce a warning; nsyte signer fields are ignored. warning; nsyte signer fields are ignored.
- Metadata: `--title`, `--description` or `--description-file`, and - Metadata: `--title`, `--description` or `--description-file`, and `--source`
`--source` (`https://` or `nostr://`; omitted, ngit infers the selected (`https://` or `nostr://`; omitted, ngit infers the selected public repository
public repository and never a private one). NIP-5A has no logo tag; ship a and never a private one). NIP-5A has no logo tag; ship a `favicon.ico` or
`favicon.ico` or `favicon.svg` in the build output. `favicon.svg` in the build output.
- `--fallback SITE_PATH` (or config `fallback`) maps an existing HTML file in - `--fallback SITE_PATH` (or config `fallback`) maps an existing HTML file in
the output to `/404.html` without another upload. the output to `/404.html` without another upload.
- Servers: omit `--blossom-server` to use the account's latest kind-10063 - Servers: omit `--blossom-server` to use the account's latest kind-10063 list;
list; repeat it for replication. `--concurrency` (default 4, range 1–64) is repeat it for replication. `--concurrency` (default 4, range 1–64) is a global
a global limit across presence checks and uploads. limit across presence checks and uploads.
## Guarantees ## Guarantees
ngit snapshots the directory before network work, deduplicates content, checks ngit snapshots the directory before network work, deduplicates content, checks
every blob on every selected server, and uploads missing copies with BUD-11 every blob on every selected server, and uploads missing copies with BUD-11
authorization. It signs the manifest only after every blob has at least one authorization. It signs the manifest only after every blob has at least one
confirmed copy, so a failed deployment cannot point the live manifest at confirmed copy, so a failed deployment cannot point the live manifest at missing
missing content. A server that fails three consecutive initial checks is content. A server that fails three consecutive initial checks is skipped for the
skipped for the rest of that pass while the others continue. rest of that pass while the others continue.
Rerun the same command after a failure: blobs already on a server are Rerun the same command after a failure: blobs already on a server are confirmed
confirmed with `HEAD` and skipped, so continuation is per blob and server. An with `HEAD` and skipped, so continuation is per blob and server. An unchanged
unchanged deployment reuses the current manifest without a new signature or deployment reuses the current manifest without a new signature or relay write.
relay write.
## JSON ## JSON
@@ -61,10 +60,10 @@ Check `command_status`, then:
- `result.changed`: publication versus an unchanged no-op; - `result.changed`: publication versus an unchanged no-op;
- `result.config_path`, `result.fallback`, `result.relays`: resolved settings; - `result.config_path`, `result.fallback`, `result.relays`: resolved settings;
- `result.blossom.blobs[].servers[]`: each blob and server outcome; - `result.blossom.blobs[].servers[]`: each blob and server outcome;
- `result.publication.relays[]`: manifest acknowledgements (at least one - `result.publication.relays[]`: manifest acknowledgements (at least one relay
relay must accept); must accept);
- `warnings[]`: unknown MIME types, unsupported config publications, and - `warnings[]`: unknown MIME types, unsupported config publications, and failed
failed uploads or post-upload verification per server. uploads or post-upload verification per server.
On a Blossom failure inspect `error.details.blobs` and On a Blossom failure inspect `error.details.blobs` and
`error.details.possible_orphan_blobs`, fix the server or signer problem, and `error.details.possible_orphan_blobs`, fix the server or signer problem, and
+20 -21
View File
@@ -1,12 +1,12 @@
# Pull requests — open, update, stack, review, merge # Pull requests — open, update, stack, review, merge
Read before opening, updating, reviewing, or merging PRs. Read before opening, updating, reviewing, or merging PRs. Guide:
Guide: https://ngit.dev/pull-requests https://ngit.dev/pull-requests
## Open or update a PR ## Open or update a PR
The branch name MUST start with `pr/`. No push option turns another branch The branch name MUST start with `pr/`. No push option turns another branch into
into a PR. a PR.
```bash ```bash
git checkout -b pr/my-feature git checkout -b pr/my-feature
@@ -21,18 +21,18 @@ git push --force origin pr/my-feature # update the PR after amend
- `-d`/`--defaults` accepts the single-commit title and description without a - `-d`/`--defaults` accepts the single-commit title and description without a
prompt. prompt.
- Do not use `$'…\n…'` for push options, and do not pre-escape a Markdown - Do not use `$'…\n…'` for push options, and do not pre-escape a Markdown file
file into `-o description=`; open the PR with `ngit send` instead. into `-o description=`; open the PR with `ngit send` instead.
- Stacks are inferred: a branch that contains the unique latest tip of one of - Stacks are inferred: a branch that contains the unique latest tip of one of
your other open or draft PRs becomes that PR's child and follows the parent your other open or draft PRs becomes that PR's child and follows the parent as
as it advances. Rebase the child onto the parent's latest tip before updating it advances. Rebase the child onto the parent's latest tip before updating it;
it; ngit refuses stale children and ambiguous candidates rather than ngit refuses stale children and ambiguous candidates rather than guessing. Use
guessing. Use `base=` for a cross-author, historical, or ambiguous parent, `base=` for a cross-author, historical, or ambiguous parent, and repeat it on
and repeat it on each update if the child should stay pinned. each update if the child should stay pinned.
- To push as another stored identity, use - To push as another stored identity, use
`git -c nostr.signer=<alias|npub|profile-name> push …`; `--signer` applies `git -c nostr.signer=<alias|npub|profile-name> push …`; `--signer` applies to
to `ngit` commands only. `ngit account login --local <alias>` makes an `ngit` commands only. `ngit account login --local <alias>` makes an identity
identity the repository default instead. the repository default instead.
## ngit send ## ngit send
@@ -70,13 +70,12 @@ ngit pr merge <ID|nevent> --exclude-description --json # summary line and
git push origin <target-branch> # publishes the merge and the applied status git push origin <target-branch> # publishes the merge and the applied status
``` ```
`ngit merge` is a compatibility alias with the same options. The merge lands `ngit merge` is a compatibility alias with the same options. The merge lands on
on the PR's declared target, or the default branch, resolved against the the PR's declared target, or the default branch, resolved against the latest
latest Nostr repository state rather than a local tracking ref, with the Nostr repository state rather than a local tracking ref, with the message
message `Merge #<8-hex>: <PR title>`. Closed and applied PRs are refused `Merge #<8-hex>: <PR title>`. Closed and applied PRs are refused before any git
before any git change. On conflicts, resolve them and run `git commit`; the change. On conflicts, resolve them and run `git commit`; the message is already
message is already prepared, and JSON reports `action: "conflicted"` instead prepared, and JSON reports `action: "conflicted"` instead of `"merged"`.
of `"merged"`.
Before merging or adding maintainer fixes, run Before merging or adding maintainer fixes, run
`git log --merges --oneline origin/<target>..HEAD`. A prior `Merge #…` means a `git log --merges --oneline origin/<target>..HEAD`. A prior `Merge #…` means a
+23 -23
View File
@@ -1,9 +1,9 @@
# Repositories — publish, clone, hosting, membership # Repositories — publish, clone, hosting, membership
Read when publishing or cloning a repository, resolving `nostr://` URL forms, Read when publishing or cloning a repository, resolving `nostr://` URL forms, or
or changing an announcement's hosting, metadata, or roster. Guides: changing an announcement's hosting, metadata, or roster. Guides:
https://ngit.dev/repositories (hosting choices, migrating from a forge, https://ngit.dev/repositories (hosting choices, migrating from a forge, mirrors,
mirrors, private repositories), https://ngit.dev/maintainers, and private repositories), https://ngit.dev/maintainers, and
https://ngit.dev/maintainers/going-deeper (leadless repositories, delegated https://ngit.dev/maintainers/going-deeper (leadless repositories, delegated
trust, removal, roster repair). trust, removal, roster repair).
@@ -36,9 +36,9 @@ ngit repo --json --offline # run git fetch origin first when the cache may
The output reports `nostr_url`, effective `git_servers`, `relays`, `hashtags`, The output reports `nostr_url`, effective `git_servers`, `relays`, `hashtags`,
and `grasp_servers` detected from paired clone and relay entries, plus the and `grasp_servers` detected from paired clone and relay entries, plus the
roster: `members`, `lead_source`, `lead_path`, `pending_actions`, and roster: `members`, `lead_source`, `lead_path`, `pending_actions`, and `health`.
`health`. Follow the actionable error or `pending_actions` rather than Follow the actionable error or `pending_actions` rather than replacing an
replacing an announcement wholesale. announcement wholesale.
## Publish and host ## Publish and host
@@ -66,30 +66,30 @@ Every announcement needs at least one relay and one git server; `init` and
announcement that already lacks one half. Repair it in the same command, e.g. announcement that already lacks one half. Repair it in the same command, e.g.
`ngit repo edit --name "New name" --add-grasp-server grasp.example.com`. `ngit repo edit --name "New name" --add-grasp-server grasp.example.com`.
`--identifier` is set at initial publication only: changing the `d` tag `--identifier` is set at initial publication only: changing the `d` tag creates
creates a different repository coordinate. a different repository coordinate.
## Edit ## Edit
`ngit repo edit` preserves omitted settings. Collections use targeted, `ngit repo edit` preserves omitted settings. Collections use targeted,
repeatable actions that can be combined in one command: repeatable actions that can be combined in one command:
| Setting | Add | Remove | | Setting | Add | Remove |
| ------- | --- | ------ | | ---------------- | ---------------------------- | ------------------------------- |
| Grasp server | `--add-grasp-server URL` | `--remove-grasp-server URL` | | Grasp server | `--add-grasp-server URL` | `--remove-grasp-server URL` |
| Additional relay | `--add-additional-relay URL` | `--remove-additional-relay URL` | | Additional relay | `--add-additional-relay URL` | `--remove-additional-relay URL` |
| Additional clone | `--add-additional-clone URL` | `--remove-additional-clone URL` | | Additional clone | `--add-additional-clone URL` | `--remove-additional-clone URL` |
| Hashtag | `--add-hashtag TAG` | `--remove-hashtag TAG` | | Hashtag | `--add-hashtag TAG` | `--remove-hashtag TAG` |
Scalars use replacement flags: `--name`, `--description`, `--web`, `--u`, Scalars use replacement flags: `--name`, `--description`, `--web`, `--u`,
`--earliest-unique-commit`. A grasp-derived relay or clone cannot be removed `--earliest-unique-commit`. A grasp-derived relay or clone cannot be removed as
as an additional entry; remove the grasp server and its pair goes with it. To an additional entry; remove the grasp server and its pair goes with it. To empty
empty a collection, remove every value currently reported. a collection, remove every value currently reported.
Each successful edit publishes a fresh announcement and, when the repository Each successful edit publishes a fresh announcement and, when the repository has
has Nostr state, republishes that state once so new relays and servers hold Nostr state, republishes that state once so new relays and servers hold the
the authoritative refs. If that fails, follow the reported `ngit sync` authoritative refs. If that fails, follow the reported `ngit sync` recovery
recovery guidance. guidance.
## Roles and membership ## Roles and membership
@@ -101,9 +101,9 @@ recovery guidance.
- **Moderator**: publishes issue, PR, and patch status events (including - **Moderator**: publishes issue, PR, and patch status events (including
recording an existing merge) but cannot publish git state or merge. recording an existing merge) but cannot publish git state or merge.
Membership is reciprocal: a listing is an invitation until the invitee Membership is reciprocal: a listing is an invitation until the invitee publishes
publishes an announcement acknowledging the role, and an invited member's an announcement acknowledging the role, and an invited member's events are not
events are not authoritative until then. authoritative until then.
```bash ```bash
ngit repo edit --add-maintainer <npub> --json # a sole maintainer's first add makes them lead ngit repo edit --add-maintainer <npub> --json # a sole maintainer's first add makes them lead
+15 -15
View File
@@ -1,7 +1,7 @@
# Sync, flags, and configuration # Sync, flags, and configuration
Read when syncing refs, choosing flags, or tuning git config. Read when syncing refs, choosing flags, or tuning git config. Guides:
Guides: https://ngit.dev/configuration and https://ngit.dev/troubleshooting https://ngit.dev/configuration and https://ngit.dev/troubleshooting
## Sync ## Sync
@@ -15,16 +15,16 @@ ngit sync --ref-name main --json # one ref
These accept any command position. `--offline` is per command; check These accept any command position. `--offline` is per command; check
`ngit <command> --help`. `ngit <command> --help`.
| Flag | Description | | Flag | Description |
| ---- | ----------- | | --------------------------------------- | ---------------------------------------------------------------------------------------------- |
| `--json` | One JSON document on stdout (ngit commands only) | | `--json` | One JSON document on stdout (ngit commands only) |
| `-d`, `--defaults` | Non-interactive; accept defaults | | `-d`, `--defaults` | Non-interactive; accept defaults |
| `-q`, `--quiet` | Hide non-essential stderr progress (not combinable with `-v`) | | `-q`, `--quiet` | Hide non-essential stderr progress (not combinable with `-v`) |
| `--repo <REMOTE\|NADDR\|NOSTR-URL>` | Select the target repository | | `--repo <REMOTE\|NADDR\|NOSTR-URL>` | Select the target repository |
| `--signer <ALIAS\|NPUB\|NAME>` | Use a stored signer for this command | | `--signer <ALIAS\|NPUB\|NAME>` | Use a stored signer for this command |
| `--nsec-file`, `--nbunksec-file <PATH>` | One-shot key or bunker session from a private file (`--nsec`, `--nbunksec` take inline values) | | `--nsec-file`, `--nbunksec-file <PATH>` | One-shot key or bunker session from a private file (`--nsec`, `--nbunksec` take inline values) |
| `--repo-relay-only` | Publish only to repository relays | | `--repo-relay-only` | Publish only to repository relays |
| `-f`, `--force` | Bypass safety guards | | `-f`, `--force` | Bypass safety guards |
## git config ## git config
@@ -39,11 +39,11 @@ git config nostr.http-io-timeout-ms 600000 # allow large grasp pushes
NGIT_CACHE_DIR=/writable/path ngit repo --json # override the global event-cache directory NGIT_CACHE_DIR=/writable/path ngit repo --json # override the global event-cache directory
``` ```
`nostr.auto-pr-branches` follows normal git config precedence. With the `nostr.auto-pr-branches` follows normal git config precedence. With the default
default `false`, PRs appear as branches only after `ngit pr checkout`; run `false`, PRs appear as branches only after `ngit pr checkout`; run
`git fetch --prune` once to drop branches fetched by an older version, or use `git fetch --prune` once to drop branches fetched by an older version, or use
`git clone --config nostr.auto-pr-branches=true <nostr-url>` to opt in from `git clone --config nostr.auto-pr-branches=true <nostr-url>` to opt in from the
the start. start.
If the global cache directory is unavailable ngit falls back to an in-memory If the global cache directory is unavailable ngit falls back to an in-memory
cache; the repository's git common directory must still be writable. cache; the repository's git common directory must still be writable.