upleb.uk

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

summaryrefslogtreecommitdiff
path: root/src/bin
AgeCommit message (Collapse)Author
2026-05-01fix: filter run_list state candidates by current remote's maintainersDanConwayDev
when a repo has multiple nostr:// remotes sharing the same identifier, relays can return state events authored by maintainers of the other remote. without filtering, the newest event wins regardless of author, pointing refs at the wrong commits. state event candidates in run_list are now filtered to maintainers of the current remote's repo announcement.
2026-04-22fix: prevent fatal clone/fetch errors when PR git data unavailableDanConwayDev
Only advertise `refs/heads/pr/*` branches once their tip OIDs are confirmed present locally; prevents `fatal: bad object` / `remote did not send all necessary objects` errors during clone/fetch when a PR tip lives on a different git server than the one that won the bulk prefetch race. After the bulk prefetch, collect remaining missing PR tip OIDs and do one batch fetch per repo git server using only the OIDs that server has advertised; break early once all are satisfied and skip servers that carry none. Avoids batch-poisoning (a server rejects the whole request if any single OID is absent) and redundant connections. Restrict mop-up fetches and run_fetch to the repo's declared git servers; do not fetch from clone-tag URLs in PR events - they are submitter-supplied and could let a malicious or slow server stall every clone/fetch operation. Also apply rustfmt and fix clippy warnings.
2026-03-09fix(push): gracefully handle errors identifying potential PR mergesDanConwayDev
Errors from get_merged_status_events no longer abort the push; the call site now uses if let Ok(...) so failures are silently skipped. Also replace an .unwrap() in create_merge_events with a safe .map().unwrap_or_default() to avoid any panic in that path.
2026-03-05fix(pr-checkout): require --force on diverged proposal branchDanConwayDev
checkout_patch() previously re-applied the patch chain whenever the local branch tip didn't match the published tip, silently overwriting local amendments and rebased revisions without warning. Now detects the relationship between local and published tips: - up to date: check out as-is - behind (local is ancestor of published): fast-forward, no flag needed - local commits on top (published is ancestor of local): check out as-is - diverged (neither ancestor): bail with guidance, --force to overwrite - published tip not found locally and branch exists: same as diverged Also adds --force flag to `ngit pr checkout` to explicitly opt in to overwriting a diverged branch, covering both local amendments and author force-pushes. Bug discovered during test implementation in tests/ngit_pr_checkout.rs.
2026-03-05refactor(set-subject): remove alt tag from subject label eventDanConwayDev
2026-03-05fix(issue): add --comments flag to issue list commandDanConwayDev
--comments was supported by 'issue view' but not 'issue list', making 'ngit issue list <id> --comments' fail while the equivalent 'view' command worked fine.
2026-03-05fix(comment): pass git_repo to login so local config takes precedenceDanConwayDev
publish_comment was calling login_or_signup with &None for git_repo, causing the GitLocal source to be skipped entirely. This meant the global git config (including any bunker-uri) was used instead of the local nsec, ignoring the local login. Pass the discovered Repo through CommentArgs so local config correctly takes precedence over global.
2026-03-05fix(whoami): detect and fall back to system git config for nostr loginDanConwayDev
Add GitSystem to SignerInfoSource so credentials stored in the system git config (/etc/gitconfig) are included in the priority fallback chain (local > global > system) and shown as a separate level in whoami output.
2026-03-05feat(cover-note): add kind-1624 cover notes for PRs, patches, and issuesDanConwayDev
Implements experimental kind-1624 cover note events: - KIND_COVER_NOTE constant and process_cover_note() in git_events.rs; replaceable semantics (latest created_at, hex-id tiebreak), author or maintainer only - kind-1624 events fetched alongside labels in the fetch pipeline; cover_notes count added to FetchReport display - ngit pr/issue view: cover note displayed in place of description with a clear 'Cover Note:' header; maintainer-authored notes identify the author; original description shown only with --comments; cover_note object included in --json output - ngit pr set-cover-note / ngit issue set-cover-note: publish a kind-1624 event; nostr: mentions in --body converted to q/p tags via tags_from_content (same rules as issue --body) - Fix pre-existing clippy::too_many_lines on repo/mod.rs show_info
2026-03-05feat(json): emit nevent1 bech32 IDs in --json outputDanConwayDev
All id and reply_to fields in --json output now use nevent1... bech32 encoding (with relay hint when available) instead of raw hex, making them directly usable as nostr: URI references in --body text. Update SKILL.md to document the nevent1 ID format and enforce use of nostr:nevent1... URIs when cross-referencing events in body text.
2026-03-05refactor(subject): standardise on subject over title in CLI and outputDanConwayDev
- JSON output fields renamed from title to subject in pr list/view and issue list/view - Printed view output changed from Title: to Subject: - ngit issue create --subject (alias --title) - ngit send --subject (alias --title) - Error messages and interactive prompts updated to match
2026-03-05feat(subject): add pr/issue set-subject via NIP-32 kind-1985 labelsDanConwayDev
Adds the ability to update the displayed title of a PR or issue after creation using a kind-1985 label event with the #subject namespace. Only the author or a repository maintainer may set the subject. The latest authorised event wins with tiebreak by lexicographically larger event ID (NIP-1 replaceable event semantics). Branch names and commit messages are never affected. - Split get_labels() into process_labels() (additive #t) and process_subject() (replaceable-style #subject), with a shared get_labels_and_subject() entry point that processes both from a single pre-fetched slice of kind-1985 events - All list/view/JSON display paths apply the subject override silently - New ngit pr set-subject <id> --subject <text> command - New ngit issue set-subject <id> --subject <text> command
2026-03-05feat(status): add --reason to all pr and issue status commandsDanConwayDev
All status transitions (pr close/reopen/ready/draft, issue close/reopen/ resolved) now accept an optional --reason flag stored in the event content.
2026-03-05feat(status): add pr draft, issue resolved, and --reason for issue closeDanConwayDev
Add `ngit pr draft <id>` to convert a PR back to draft (kind-1632). Add `ngit issue resolved <id> [--reason <text>]` to mark an issue as fixed (kind-1631 GitStatusApplied), distinct from close which signals wontfix/duplicate/invalid. Add `--reason <text>` to `ngit issue close` — stored in event content. Also fix success/error message wording in pr_status and issue_status to use consistent past-tense action strings.
2026-03-05feat(label): add `ngit issue label` and `ngit pr label` commandsDanConwayDev
Publishes a NIP-32 kind-1985 label event referencing the target issue or PR. Only the event author or a repository maintainer may apply labels. Duplicate labels (already present via t-tags or prior kind-1985 events) are silently skipped. The new event is saved to the local cache before broadcasting so subsequent reads reflect the change immediately. CLI: ngit issue label <id> --label <L> [--label <L>...] ngit pr label <id> --label <L> [--label <L>...]
2026-03-05feat(labels): fetch and apply NIP-32 kind-1985 label eventsDanConwayDev
- Add KIND_LABEL (kind 1985) constant to git_events.rs - Add get_labels() merging inline t-tags with external kind-1985 events, gating each on author-or-maintainer permission - Extend get_fetch_filters() to request kind-1985 events for all known issue and proposal IDs - Track label event counts in FetchReport (field + Display + consolidation) - Update issue_list.rs and list.rs to fetch label events from cache and pass them through get_labels() instead of reading t-tags inline
2026-03-05add `ngit account whoami` commandDanConwayDev
Shows currently logged-in account(s) with name and npub. When both a local (repo-scoped) and global account are configured, displays both with local marked as active. Supports --json (returns local, global, and active objects each with name, npub, nip05, scope) and --offline (reads from cache only, no network). Fixes doc_markdown clippy warning in cli.rs.
2026-03-04add `ngit repo --json` for machine-readable repo detectionDanConwayDev
Outputs {"is_nostr_repo": false} when not in a nostr repository, or full structured JSON (name, identifier, description, nostr_url, coordinate, maintainers, grasp_servers, git_servers, relays, hashtags) when it is. Always exits 0. Also adds --title as an alias for --name on `ngit init`.
2026-03-04add NIP-21 content tags (q/p) to issues, comments, PRs and patchesDanConwayDev
- parse nostr: URI mentions in issue bodies, comment bodies, PR descriptions, patch commit messages and cover letters - npub/nprofile mentions produce p tags; note/nevent/naddr mentions produce q tags per NIP-22 - naddr q tag value uses raw <kind>:<pubkey-hex>:<identifier> format - nevent pubkey field populated from embedded author or local cache lookup - dedup_tags() removes duplicate p tags and suppresses q tags whose event-id is already covered by an existing e threading tag - all parsing errors are non-fatal: invalid nostr: tokens are skipped
2026-03-04standardise on --label; add label filter and display to pr list/viewDanConwayDev
- rename --hashtag (comma-separated) to --label (repeatable) on issue list, matching the --label flag already used on issue create - add --label filter to pr list with the same OR semantics (matching GitHub) - display labels column in pr list table and Labels: line in pr view - include labels array in all JSON outputs (list and view for both issue and pr) - rename internal 'hashtags' -> 'labels' throughout issue_list.rs and list.rs
2026-03-04add --comments flag to issue/pr view; show reply threadingDanConwayDev
- issue view and pr view now show only a comment count by default - pass --comments to include the full thread - JSON output always includes comment_count; comments array only with --comments - each comment in the thread includes reply_to (null for top-level, parent comment id for replies) - human-readable view shows a dim '↳ reply to <short-id>' line on replies
2026-03-04fix NIP-22 compliance and add --reply-to flag for issue/PR commentsDanConwayDev
- Add missing P and p tags (root and parent author pubkeys) - Fix E tag 4th element to be root pubkey (was empty string) - Fix e tag 4th element to be parent pubkey (was "reply", a NIP-10 convention) - Add --reply-to <ID|nevent> flag to both issue and PR comment commands - When --reply-to is set, look up the parent comment from cache and use it as the parent scope (e/k/p); root scope (E/K/P) always stays the issue/PR - When --reply-to is omitted, parent == root (existing top-level behaviour)
2026-03-04show full comment content in pr view and issue viewDanConwayDev
ngit pr view <id> and ngit issue view <id> now fetch and display all NIP-22 comments in chronological order with author npub and timestamp, rather than just a count. JSON output includes the full comment array. Also updates list table hint text to reference ngit pr subcommands.
2026-03-04restructure CLI around ngit pr/issue subcommand groupsDanConwayDev
Introduce ngit pr subcommand group (list, view, checkout, apply, send, close, reopen, ready, comment, merge) replacing the former top-level ngit list/checkout/apply commands. ngit send is kept at the top level. Expand ngit issue with view, create, close, reopen, comment subcommands. Status changes (close/reopen/ready) are gated to the PR/issue author or a repository maintainer. ngit pr merge is maintainer-only and publishes a GitStatusApplied event immediately after the git merge.
2026-03-04feat: fetch and display NIP-22 comment counts on issues and proposalsDanConwayDev
Download kind-1111 NIP-22 comments from relays and show a comment count in the detail view of `ngit list <id>` and `ngit issue list <id>`. - git_events: add KIND_COMMENT constant (kind 1111) - client: import KIND_COMMENT; add `comments` field to FetchReport; route kind-1111 events into report.comments in process_fetched_events; consolidate comments across relay reports; display "N comment(s)" in FetchReport; add a #E-tagged kind-1111 filter in get_fetch_filters covering all known issue and proposal root IDs - issue_list: add get_comment_counts() to query the local cache for kind-1111 events by #E tag and count per issue; extend the filtered tuple with comment_count; show a CMTS column in the table, a "Comments: N" line in the detail view, and a "comments" field in JSON - list: add KIND_COMMENT import; add resolve_event_id() helper and get_comment_count_for_proposal() to look up the count for a single proposal from the local cache; pass comment_count into show_proposal_details(); display "Comments: N" in plain text and "comments" in JSON; align detail-view labels
2026-03-04feat: add ngit issue list commandDanConwayDev
Non-interactive listing of NIP-34 issues (kind 1621) with status resolution, hashtag display, and detail view. - get_issues_from_cache: fetch GitIssue events from local cache by repo coordinate, mirroring get_proposals_and_revisions_from_cache - ngit issue list: table output of ID, status, title and hashtags at end of each row; status resolved via existing get_status() logic - --status: comma-separated filter (open,draft,closed,applied; default: open) - --hashtag: comma-separated label filter (case-insensitive, OR match) - --json: machine-readable output including hashtags and description - --offline: skip network fetch, use local cache only - <id>: optional positional argument (hex event-id or nevent) to show full details of a specific issue including body content
2026-03-04add nostr.repo-relay-only config to limit publishing to repo relaysDanConwayDev
Adds a git config key nostr.repo-relay-only that, when set to true, causes nostr events to be sent only to the repository's own relays, skipping the user's personal write relays and default/blaster relays. Useful for repositories that should not broadcast to the maintainer's personal relay set. Set persistently via \`git config nostr.repo-relay-only true\` or in one step with \`ngit init --repo-relay-only\`.
2026-02-27fix: skip ^{} peeled-tag refs in sync to prevent invalid refspec crashDanConwayDev
Regression introduced in 28ad5440: ngit sync crashed with 'invalid refspec refs/remotes/origin/v1.4.4^{}:refs/tags/v1.4.4^{}' on repos with annotated tags. Fixed by guarding all three iteration sites in sync.rs and identify_remote_sync_issues in list.rs; also corrected the always-false logic bug in invalid_nostr_state_ref.
2026-02-27feat: ngit sync --force republishes state event even with no ref changesDanConwayDev
allows users to repair repos whose state event is missing ^{} peeled refs for annotated tags (or any other corruption) without needing to push a new ref. the new event is signed with a fresh timestamp and broadcast to all repo relays and the user's write relays.
2026-02-27fix: annotated tags missing from list due to dropped peeled refsDanConwayDev
RepoState::try_from was explicitly discarding all refs/tags/*^{} entries ("peeled" refs) when parsing the nostr state event. This meant the list command only advertised the tag object OID, but git requires two lines for annotated tags: <tag-object-oid> refs/tags/v1.0.0 <commit-oid> refs/tags/v1.0.0^{} Without the ^{} peeled line git cannot resolve the tag to a commit, so git fetch --prune treats it as unresolvable and deletes it. The nostr state event already stores both entries correctly (written by generate_updated_state in push.rs). The fix simply stops try_from from discarding the ^{} entries on read, so they flow through to the list output unchanged.
2026-02-27feat: add --bunker-url to account login for non-interactive useDanConwayDev
allows non-interactive bunker:// URL login without requiring --nsec, by connecting to the remote signer and saving credentials to git config
2026-02-26fix: correct merge-base in PR events from git push of pr/ branchDanConwayDev
When pushing a pr/ branch, the ahead slice is reversed by callers before being passed to generate_patches_or_pr_event_or_pr_updates, making it oldest-first. The tip/first_commit assignments were backwards (using first()/last() as if the slice were youngest-first), so the merge-base was computed as the parent of the PR tip rather than the parent of the oldest commit. Multi-commit PRs therefore showed only 1 commit when applied via ngit apply. Adds an integration test that pushes a two-commit large-file PR branch and asserts the merge-base tag equals the main branch tip.
2026-02-26fix: store tag object OID in tracking ref for annotated tags after pushDanConwayDev
update_remote_refs_pushed was calling peel_to_commit() for all refs, discarding the tag object OID for annotated tags. This caused a mismatch with generate_updated_state, which correctly stores the tag object OID in the nostr state event. ngit sync would then push the commit OID to grasp servers that expected the tag object OID, causing rejections.
2026-02-26fix: advertise only state events with resolvable git objectsDanConwayDev
git-remote-nostr now walks the per-relay state events captured in FetchReport::state_per_relay (newest first) and advertises the first one whose every OID is either present on at least one git server (confirmed via list_refs) or already available locally. If no such state event exists it falls back to the raw git server state. Previously the latest nostr state event was always used regardless of whether its OIDs had been pushed to any server, causing catastrophic missing-object errors during clone or fetch when a state event was published ahead of the corresponding git push.
2026-02-26fix: strip refs/tags/ prefix when computing remote tracking ref nameDanConwayDev
refspec_remote_ref_name() only stripped refs/heads/, so tag refspecs produced refs/remotes/origin/refs/tags/v1.0.0 instead of refs/remotes/origin/v1.0.0. ngit sync reads the latter form, so the tracking ref was never found and sync failed with 'src refspec does not match any existing object'.
2026-02-26feat: publish state event to stale grasp relays before sync pushDanConwayDev
FetchReport now captures the full state event seen on each relay during the nostr fetch (state_per_relay: HashMap<RelayUrl, Option<Event>>). ngit sync uses this to identify grasp server relays with a missing or outdated state event and publishes the current state event to them before attempting git pushes, preventing rejections. An existing login is loaded silently (no prompt, no profile fetch) to provide a signer for NIP-42 auth if requested.
2026-02-26fix: rollback local state event cache on total push failureDanConwayDev
When all git servers reject or skip a push, delete the newly-published state event from the local nostr cache and restore the previous state event (if any), so that a subsequent retry starts from a clean baseline rather than a state that no server ever accepted.
2026-02-26fix: skip grasp servers whose relay did not receive state eventDanConwayDev
When publishing the nostr state event before a git push, use the relay results from send_events to skip any grasp server whose internal relay did not receive the event. Print a clear warning for each skipped server and emit error lines for all refs if no git servers remain to push to.
2026-02-26fix: report per-relay publish results in send_events summaryDanConwayDev
Change send_events() return type from Result<()> to Result<Vec<(String, bool)>> so callers can inspect which relays accepted events. Update the finish message to show "Published to X/N relays (failed: ...)" instead of the unconditional "Published ... to nostr relays".
2026-02-26fix: correct refspec source in ngit sync to strip refs/heads/ prefixDanConwayDev
When syncing, the nostr state stores refs with full names like refs/heads/master and refs/tags/v1.0.0. Git tracking refs strip the refs/heads/ prefix, so the tracking ref lives at refs/remotes/origin/master not refs/remotes/origin/refs/heads/master. The sync code was interpolating the full nostr_ref_name into the source side of the refspec, producing the invalid double-prefixed path. Strip refs/heads/ or refs/tags/ before constructing the tracking ref segment, consistent with how git_remote_nostr/push.rs already handles this.
2026-02-26feat: forward unrecognised push options to git serversDanConwayDev
Any -o option passed to `git push` that is not handled by ngit (title, description) is forwarded verbatim to the git server via git2::PushOptions::remote_push_options. This allows options such as `-o secret-scanning.skip` to pass through transparently. `ngit send` gains a matching -o / --push-option flag for the same purpose.
2026-02-20show subcommand hint at top of `ngit repo` output before fetchDanConwayDev
- print hint line immediately, before coordinate lookup and relay fetch - users see available subcommands (init, edit, accept) without waiting
2026-02-20improve `ngit repo` output stylingDanConwayDev
- make repo name bold yellow as a title; section headings bold dim - add dim horizontal rules above and below the name/description block - move earliest unique commit to the bottom (after additional relays) - add --offline flag to skip network fetch and use local cache only
2026-02-20improve `ngit repo` output formattingDanConwayDev
- suppress fetch summary (no updates / updates: X) - write blank line to stderr after relay errors for clear separation - show identifier below title only when it differs from name - show earliest unique commit (root_commit) in metadata - restructure infrastructure into grasp servers / additional git servers / additional relays sections - display grasp servers by domain only (strip scheme, npub, repo path) - strip wss:// prefix from relay display - show maintainer names from metadata cache; fall back to short npub - append (you) next to the current user's name wherever it appears - show [name] attribution and the maintainer model note only when there is more than one maintainer
2026-02-20add `ngit repo` subcommand groupDanConwayDev
- `ngit repo` (no subcommand): show repository info including maintainer tree, per-maintainer infrastructure attribution, and a note explaining the union-vs-personal field model and recursive maintainer sets - `ngit repo init`: alias for `ngit init` - `ngit repo edit`: same as init but signals intent to update an existing repository announcement - `ngit repo accept`: scoped command for co-maintainers to publish their announcement; errors with clear messages for all other states (trusted maintainer, already accepted, not invited, no repo found)
2026-02-20use trusted maintainer's grasp servers as fallback for co-maintainersDanConwayDev
when a co-maintainer has no grasp servers of their own, fall back to the trusted maintainer's grasp servers rather than jumping straight to system defaults. if the trusted maintainer only uses a single grasp server, the first system default is appended for redundancy. system defaults are only used when neither the user nor the trusted maintainer has any grasp servers configured.
2026-02-20update relay prompt to reflect grasp servers are sufficientDanConwayDev
Public relays are no longer recommended; grasp servers cover relay needs. The interactive prompt now reflects this.
2026-02-20drop default relays from announcement eventsDanConwayDev
ngit init and accept_maintainership_with_defaults no longer seed relay lists from the client default set. The relay list in a Kind:30617 announcement now contains only grasp-server-derived relay URLs; no additional public relays are suggested or added automatically.
2026-02-20extract grasp/maintainership helpers to lib and auto-accept on pushDanConwayDev
move apply_grasp_infrastructure, latest_event_repo_ref to lib/repo_ref.rs and wait_for_grasp_servers + grasp_servers_from_user_or_fallback to a new lib/accept_maintainership.rs so both binaries can share them. add accept_maintainership_with_defaults which publishes the co-maintainer's own Kind:30617 announcement with defaults (user grasp servers, shared metadata from existing events) then waits for grasp server provisioning and updates nostr.repo config and origin remote. replace the push error block with a call to accept_maintainership_with_defaults so pushing now silently accepts co-maintainership instead of failing.
2026-02-20improve ngit init messaging for co-maintainership acceptanceDanConwayDev
when a co-maintainer runs ngit init, it now clearly states upfront that they are accepting a co-maintainership offer (not creating a new repo), shows who offered it, and on completion confirms the acceptance and explains they can now push. updating an existing co-maintainer announcement also gets its own clear message.
2026-02-20improve push error when co-maintainer has no announcementDanConwayDev
the previous message said 'run ngit init' with no explanation of why or what it does. the new message explains the user has been offered co-maintainership, names the repo, and points to 'ngit init -d' for a fast non-interactive acceptance path.
2026-02-20fix: show ID|nevent in usage for apply, checkout and list commandsDanConwayDev
Adds value_name attribute to the id argument so the usage line reads `<ID|nevent>` instead of `<ID>`, making nevent bech32 support discoverable without reading --help.
2026-02-18fix: remove outdated patch_supports gate and fix fetch parent fallbackDanConwayDev
Remove the patch_supports_commit_ids gates in checkout.rs and list.rs that pre-dated the mbox fallback logic. apply_patch_chain already handles all fallback cases. Also replace the main-branch TODO fallback in make_commits_for_proposal with get_parent_commit_from_patch, which uses timestamp-based best-guess when the parent-commit tag is absent.
2026-02-18feat: handle missing optional patch tags for pr/ flowDanConwayDev
- Add mbox_parser module to extract metadata from patch content - Extract author/committer from From: and Date: headers when tags missing - Extract commit message body as fallback for description tag - Implement best-guess parent commit logic using committer timestamps - Update patch_supports_commit_ids to accept mbox-parseable patches - Enable patches without optional tags to appear as pr/ branches
2026-02-18feat: support PR-format proposals in ngit applyDanConwayDev
Instead of erroring when a proposal uses PR format (kind 1618/1619), ngit apply now fetches the tip commit from git servers, determines the base commit via the merge-base tag or by walking ahead of main, generates patch text for each commit using git2, and applies via git am. Also fixes a bug where clone-tag server hints were silently skipped in the fetch fallback, and refactors the git-am invocation into a shared helper to avoid duplication between the patch and PR code paths.
2026-02-18fix: preserve grasp server order in relay hint for nostr urlDanConwayDev
apply_grasp_infrastructure was inserting each grasp relay at index 0, causing later servers to displace earlier ones. the last server in the list ended up as relays[0] and thus the url relay hint, reversing the intended priority order.
2026-02-18report event kinds in publish progress messagesDanConwayDev
instead of generic 'Publishing to nostr relays...' messages, describe what is being published e.g. 'Publishing 3 patches to nostr relays...' or 'Publishing 1 announcement and 1 state event to nostr relays...'
2026-02-18poll grasp servers for readiness instead of fixed 5s waitDanConwayDev
Replace arbitrary 5-second countdown with active polling of grasp servers during ngit init. Servers are checked every 1s with a 7s timeout (2s in tests). Shows progress like '1/2 grasp servers ready'. Grasp servers return 404 until the repo is provisioned, so we poll until they accept git connections. Proceeds anyway on timeout rather than failing, since some servers may still be initializing.
2026-02-17add --signer-relay option to ngit account loginDanConwayDev
Allow users to specify custom signer relays for nostrconnect login. Relay URLs are auto-prefixed with wss:// if no scheme is provided.
2026-02-17fix: place grasp-derived relays first in relay list during initDanConwayDev
Ensures the relay hint is always a grasp server when configured.
2026-02-17fix: handle git c-style quoting of push-option values with backslashesDanConwayDev
Git wraps push-option values in double quotes and doubles backslashes when the value contains special characters. This broke \\n escape decoding because the key arrived as '"description' instead of 'description'. Added strip_git_quoting() to reverse git's quoting before parsing the key=value pair.
2026-02-17improve CLI help text and subcommand descriptionsDanConwayDev
- mention remote helper in main help so users know native git commands work - fix inconsistent indentation in main help template - update init about to lead with 'publish a repository' - add 'create' to account subcommand about - add long_about to send referencing simpler pr/ push flow - update list about to remove legacy interactive-mode language - add long_about to checkout/apply pointing to ngit list
2026-02-17fix: show help menu when ngit is run without argumentsDanConwayDev
Previously, running ngit without any command would show an error message. Now it displays the help menu, which is more user-friendly and follows standard CLI tool conventions.
2026-02-17fix: apply push-options to patch series generationDanConwayDev
The title and description push-options were previously only applied to PR creation but not to patch series generation. When force-pushing to update an existing patch series, the custom title and description were ignored. This change passes the title_description parameter to the patch generation function, allowing users to customize patch series cover letters via: git push --force --push-option=title="Title" \ --push-option=description="Description" origin branch Includes integration test for force-pushing patches with custom cover letter.
2026-02-17feat: support multiline descriptions in push-options via \n escapeDanConwayDev
Git push-options are line-based so literal newlines cannot be sent. Users can now write the two-character sequence \n which is decoded into real newlines before publishing. Use \\n for a literal backslash-n. Includes unit tests, integration test, help text, and changelog entry.
2026-02-17fix: require both title and description push-options or neitherDanConwayDev
Previously, providing only one of title or description would silently ignore both. Now returns a clear error message.
2026-02-17feat: add push-options for title and description to git-remote-nostrDanConwayDev
Allows setting PR title and description via git push options: git push --push-option=title="My PR" \ --push-option=description="Details" origin pr/branch
2026-02-17feat: add --offline flag to list, checkout, apply commandsDanConwayDev
Skip network fetch when --offline is set, using only local cache
2026-02-17style: make hint lines yellow in ngit list outputDanConwayDev
Use console::style().yellow() for 'To view/checkout/apply' hints to match git CLI hint styling.
2026-02-16Show active filter in ngit list outputDanConwayDev
Users may not be aware that ngit list defaults to filtering by open,draft status. Display the active filter at the top of the output to make this clear.
2026-02-16feat: add 'To view' hint to ngit list outputDanConwayDev
Shows 'To view: ngit list <id>' when listing proposals without an id, helping users discover they can view individual proposals in detail.
2026-02-16test: dont use git fetch during testsDanConwayDev
this prevents cli output errors on tests such as: finds_based_on_naddr_on_embeded_relay_and_added_as_origin_remote
2026-02-16fix: report wording consistancy in publishingDanConwayDev
always report publishing and finish with published
2026-02-16fix: fetch report ouputDanConwayDev
so that report gets removed when not in verbose mode and fix removal so summary displayed instead 1st line of original report.
2026-02-16test: verbose always on for remote testsDanConwayDev
to ensure verbose mode is used during tests
2026-02-13fix: preserve progress bars on relay errors during cloneDanConwayDev
fetching_with_report_for_helper unconditionally cleared the progress reporter, wiping error bars that showed relay timeouts. Only clear when all relays succeeded (or in verbose mode where bars were always visible), matching the pattern in fetching_with_report.
2026-02-13feat: add spinner for git fetch in non-verbose modeDanConwayDev
Shows a progress spinner when fetching from git remotes in non-verbose mode. Suppresses git fetch output and listing messages when not in verbose mode. Uses NGITTEST environment variable for test timeouts.
2026-02-13feat: add --verbose/-v flag for detailed outputDanConwayDev
Adds a global --verbose/-v flag that sets NGIT_VERBOSE environment variable. Also sets NGIT_VERBOSE automatically when NGIT_TEST is set.
2026-02-13fix: clear progress reporters on successful completionDanConwayDev
Progress reporters were not being cleared after successful operations, leaving progress bars visible in the terminal output. Now they are properly cleared when all operations complete without errors.
2026-02-12fix: show full event IDs in ngit list outputDanConwayDev
Truncated IDs cannot be used with --id flag for checkout or apply commands.
2026-02-12style: apply cargo clippy and fmt fixesDanConwayDev
Reorganize imports and fix formatting issues flagged by clippy and rustfmt.
2026-02-12fix: handle existing local branch that is behind when checking out PRDanConwayDev
When a PR branch already exists locally, the previous code would silently move the branch pointer without checking for tracking or fast-forward safety. Now: - If branch has tracking: checkout and warn user to git pull - If no tracking and fast-forward: safely move pointer - If no tracking and diverged: show copy-paste commands for reset/rebase - If commit not found locally: suggest fetching Uses console crate for yellow output instead of hardcoded ANSI codes.
2026-02-12fix: set up branch tracking when checking out proposalsDanConwayDev
When a nostr:// remote exists, run git fetch instead of internal fetch to populate remote tracking refs. Then checkout the remote branch with proper upstream tracking so git pull works correctly.
2026-02-12feat: make ngit list non-interactive by defaultDanConwayDev
- Add --status flag for filtering (default: open,draft) - Add --json flag for JSON output - Add optional <id> argument for showing proposal details - Rename interactive logic to launch_interactive() - Non-interactive mode outputs table format by default - Use -i flag for interactive mode Phase 3 of non-interactive ngit list implementation.
2026-02-12feat: add ngit apply command for non-interactive patch applicationDanConwayDev
Adds a new 'ngit apply <event-id>' command that applies proposal patches to the current branch. Supports --stdout flag to output patches for piping to git am. Phase 2 of non-interactive ngit list implementation.
2026-02-12feat: add ngit checkout command for non-interactive proposal checkoutDanConwayDev
Adds a new 'ngit checkout <event-id|nevent>' command that creates or updates a proposal branch and checks it out. Supports both PRs and patches with parent-commit references. Phase 1 of non-interactive ngit list implementation.
2026-02-12fix: fail fast in ngit init before network fetchDanConwayDev
When user is the maintainer and runs ngit init without args, validate against cached repo_ref before making network requests. This avoids unnecessary relay timeouts when the error would be 'no arguments specified, use --force'.
2026-02-11fix: force interactive mode for list commandDanConwayDev
The list command is inherently interactive - it presents menus for browsing and selecting proposals. Without interactive mode, all choice() calls auto-select default index 0, causing the first proposal to be checked out immediately without user input.
2026-02-11add --hashtag flag to ngit initDanConwayDev
multi-input flag that inherits from the latest pushed announcement event, defaulting to empty when no existing hashtags are found
2026-02-11remove --blossoms from ngit initDanConwayDev
alas an idea before its time has yet come.
2026-02-11rename --relays flag to --relayDanConwayDev
Allow multiple values via repeated --relay flags instead of the less intuitive plural --relays form.
2026-02-11rename --grasp-servers flag to --grasp-serverDanConwayDev
Allow multiple values via repeated --grasp-server flags instead of the less intuitive plural --grasp-servers form.
2026-02-11feat: use fallback relays for bootstrapping onlyDanConwayDev
- Add --relay flag to 'ngit account create' allowing users to specify relay URLs (repeatable). Defaults to relay-default-set when not provided. - Remove fallback relays from fetch when repo context exists (repo coordinate provided). Only use them for bootstrapping (profile discovery with no repo context). - Remove fallback relays from publish when repo or user relays exist. Only use them when neither is available (e.g. new account signup). - Update --customize help text to reflect new relay-default-set behavior.
2026-02-10feat: update ngit send for non-interactive modeDanConwayDev
Rewrite ngit send to support non-interactive mode: - Add validation for required arguments (title/description) - Add --force flag to bypass commit suitability checks - Add --no-cover-letter flag to skip cover letter - Improve error messages for missing required fields - Update title/description/cover-letter logic for non-interactive mode - Add comprehensive tests for non-interactive behavior
2026-02-10feat: update ngit init for non-interactive modeDanConwayDev
Complete rewrite of ngit init to support non-interactive mode by default. Key changes: - Implement hybrid validation (validate all args upfront, fail fast) - Add --grasp-servers flag for specifying git servers - Prefer --name over --identifier for better UX - Add comprehensive validation with helpful error messages - Support both clone and init-from-existing-repo workflows - Add --force flag to bypass safety checks - Update tests for new non-interactive behavior - Add test utilities for non-interactive testing
2026-02-10feat: update ngit account login for non-interactive modeDanConwayDev
Update login flow to support non-interactive mode with --nsec flag. Refactor login logic to handle both interactive and non-interactive cases. Add better error handling and validation.
2026-02-10feat: add ngit account create commandDanConwayDev
Add new 'ngit account create' subcommand to create nostr accounts. This replaces the previous 'signup' command and supports both interactive and non-interactive modes.
2026-02-10fix: make git-remote-nostr push non-interactiveDanConwayDev
Update push operations to use non-interactive mode by default, removing prompts that would block automated git operations.
2026-02-10feat: add global CLI flags for non-interactive modeDanConwayDev
Add --defaults, --interactive, and --force flags to support non-interactive operation. Non-interactive mode is now the default behavior, with interactive mode enabled via the -i/--interactive flag. Also add CliError handling in main() to support styled error output from subcommands.
2025-11-14chore: bump rust-nostr v0.44DanConwayDev
fix breaking changes