upleb.uk

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

summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDanConwayDev <DanConwayDev@protonmail.com>2026-03-05 12:12:21 +0000
committerDanConwayDev <DanConwayDev@protonmail.com>2026-03-05 12:12:21 +0000
commitad6c39abdc35603f58e9b71993b5632c976deac1 (patch)
tree2ee43d79216226c5f5bada4818a8c2458b8348a0
parentb0ad2fd720d0cd335c07f22767844f571e3306ff (diff)
feat(status): add --reason to all pr and issue status commands
All status transitions (pr close/reopen/ready/draft, issue close/reopen/ resolved) now accept an optional --reason flag stored in the event content.
-rw-r--r--skills/ngit/SKILL.md12
-rw-r--r--src/bin/ngit/cli.rs15
-rw-r--r--src/bin/ngit/main.rs20
-rw-r--r--src/bin/ngit/sub_commands/issue_status.rs4
-rw-r--r--src/bin/ngit/sub_commands/pr_status.rs16
5 files changed, 41 insertions, 26 deletions
diff --git a/skills/ngit/SKILL.md b/skills/ngit/SKILL.md
index b097cdf..c316c1e 100644
--- a/skills/ngit/SKILL.md
+++ b/skills/ngit/SKILL.md
@@ -119,10 +119,10 @@ git push origin main # push to nostr remote records the merge event
119### Lifecycle 119### Lifecycle
120 120
121```bash 121```bash
122ngit pr close <ID|nevent> 122ngit pr close <ID|nevent> --reason "blocked by upstream"
123ngit pr reopen <ID|nevent> 123ngit pr reopen <ID|nevent> --reason "fix was incomplete"
124ngit pr ready <ID|nevent> # mark draft as ready for review 124ngit pr ready <ID|nevent> --reason "addressed review feedback"
125ngit pr draft <ID|nevent> # convert back to draft 125ngit pr draft <ID|nevent> --reason "needs more work"
126ngit pr label <ID|nevent> --label bug --label enhancement 126ngit pr label <ID|nevent> --label bug --label enhancement
127``` 127```
128 128
@@ -138,9 +138,9 @@ ngit issue view <ID|nevent> --json
138ngit issue view <ID|nevent> --json --comments 138ngit issue view <ID|nevent> --json --comments
139ngit issue comment <ID|nevent> --body "Reproduced on v2.1" 139ngit issue comment <ID|nevent> --body "Reproduced on v2.1"
140ngit issue comment <ID|nevent> --body "Thanks!" --reply-to <comment-ID|nevent> 140ngit issue comment <ID|nevent> --body "Thanks!" --reply-to <comment-ID|nevent>
141ngit issue close <ID|nevent> --reason "wontfix" # closed without resolution 141ngit issue close <ID|nevent> --reason "wontfix"
142ngit issue resolved <ID|nevent> --reason "fixed in abc123" 142ngit issue resolved <ID|nevent> --reason "fixed in abc123"
143ngit issue reopen <ID|nevent> 143ngit issue reopen <ID|nevent> --reason "regression in v2.3"
144ngit issue label <ID|nevent> --label bug --label enhancement 144ngit issue label <ID|nevent> --label bug --label enhancement
145``` 145```
146 146
diff --git a/src/bin/ngit/cli.rs b/src/bin/ngit/cli.rs
index 37d85a2..a240597 100644
--- a/src/bin/ngit/cli.rs
+++ b/src/bin/ngit/cli.rs
@@ -248,6 +248,9 @@ pub enum PrCommands {
248 /// Proposal event-id (hex) or nevent (bech32) 248 /// Proposal event-id (hex) or nevent (bech32)
249 #[arg(value_name = "ID|nevent")] 249 #[arg(value_name = "ID|nevent")]
250 id: String, 250 id: String,
251 /// Optional reason stored in event content
252 #[arg(long)]
253 reason: Option<String>,
251 /// Use local cache only, skip network fetch 254 /// Use local cache only, skip network fetch
252 #[arg(long)] 255 #[arg(long)]
253 offline: bool, 256 offline: bool,
@@ -257,6 +260,9 @@ pub enum PrCommands {
257 /// Proposal event-id (hex) or nevent (bech32) 260 /// Proposal event-id (hex) or nevent (bech32)
258 #[arg(value_name = "ID|nevent")] 261 #[arg(value_name = "ID|nevent")]
259 id: String, 262 id: String,
263 /// Optional reason stored in event content
264 #[arg(long)]
265 reason: Option<String>,
260 /// Use local cache only, skip network fetch 266 /// Use local cache only, skip network fetch
261 #[arg(long)] 267 #[arg(long)]
262 offline: bool, 268 offline: bool,
@@ -266,6 +272,9 @@ pub enum PrCommands {
266 /// Proposal event-id (hex) or nevent (bech32) 272 /// Proposal event-id (hex) or nevent (bech32)
267 #[arg(value_name = "ID|nevent")] 273 #[arg(value_name = "ID|nevent")]
268 id: String, 274 id: String,
275 /// Optional reason stored in event content
276 #[arg(long)]
277 reason: Option<String>,
269 /// Use local cache only, skip network fetch 278 /// Use local cache only, skip network fetch
270 #[arg(long)] 279 #[arg(long)]
271 offline: bool, 280 offline: bool,
@@ -275,6 +284,9 @@ pub enum PrCommands {
275 /// Proposal event-id (hex) or nevent (bech32) 284 /// Proposal event-id (hex) or nevent (bech32)
276 #[arg(value_name = "ID|nevent")] 285 #[arg(value_name = "ID|nevent")]
277 id: String, 286 id: String,
287 /// Optional reason stored in event content
288 #[arg(long)]
289 reason: Option<String>,
278 /// Use local cache only, skip network fetch 290 /// Use local cache only, skip network fetch
279 #[arg(long)] 291 #[arg(long)]
280 offline: bool, 292 offline: bool,
@@ -414,6 +426,9 @@ pub enum IssueCommands {
414 /// Issue event-id (hex) or nevent (bech32) 426 /// Issue event-id (hex) or nevent (bech32)
415 #[arg(value_name = "ID|nevent")] 427 #[arg(value_name = "ID|nevent")]
416 id: String, 428 id: String,
429 /// Optional reason stored in event content
430 #[arg(long)]
431 reason: Option<String>,
417 /// Use local cache only, skip network fetch 432 /// Use local cache only, skip network fetch
418 #[arg(long)] 433 #[arg(long)]
419 offline: bool, 434 offline: bool,
diff --git a/src/bin/ngit/main.rs b/src/bin/ngit/main.rs
index a0cb3e6..3686011 100644
--- a/src/bin/ngit/main.rs
+++ b/src/bin/ngit/main.rs
@@ -102,17 +102,17 @@ async fn main() {
102 PrCommands::Send(sub_args) => { 102 PrCommands::Send(sub_args) => {
103 sub_commands::send::launch(&cli, sub_args, false).await 103 sub_commands::send::launch(&cli, sub_args, false).await
104 } 104 }
105 PrCommands::Close { id, offline } => { 105 PrCommands::Close { id, reason, offline } => {
106 sub_commands::pr_status::launch_close(id, *offline).await 106 sub_commands::pr_status::launch_close(id, *offline, reason.as_deref()).await
107 } 107 }
108 PrCommands::Reopen { id, offline } => { 108 PrCommands::Reopen { id, reason, offline } => {
109 sub_commands::pr_status::launch_reopen(id, *offline).await 109 sub_commands::pr_status::launch_reopen(id, *offline, reason.as_deref()).await
110 } 110 }
111 PrCommands::Ready { id, offline } => { 111 PrCommands::Ready { id, reason, offline } => {
112 sub_commands::pr_status::launch_ready(id, *offline).await 112 sub_commands::pr_status::launch_ready(id, *offline, reason.as_deref()).await
113 } 113 }
114 PrCommands::Draft { id, offline } => { 114 PrCommands::Draft { id, reason, offline } => {
115 sub_commands::pr_status::launch_draft(id, *offline).await 115 sub_commands::pr_status::launch_draft(id, *offline, reason.as_deref()).await
116 } 116 }
117 PrCommands::Comment { 117 PrCommands::Comment {
118 id, 118 id,
@@ -188,8 +188,8 @@ async fn main() {
188 sub_commands::issue_status::launch_resolved(id, *offline, reason.as_deref()) 188 sub_commands::issue_status::launch_resolved(id, *offline, reason.as_deref())
189 .await 189 .await
190 } 190 }
191 IssueCommands::Reopen { id, offline } => { 191 IssueCommands::Reopen { id, reason, offline } => {
192 sub_commands::issue_status::launch_reopen(id, *offline).await 192 sub_commands::issue_status::launch_reopen(id, *offline, reason.as_deref()).await
193 } 193 }
194 IssueCommands::Comment { 194 IssueCommands::Comment {
195 id, 195 id,
diff --git a/src/bin/ngit/sub_commands/issue_status.rs b/src/bin/ngit/sub_commands/issue_status.rs
index 840ab8e..99b4fa6 100644
--- a/src/bin/ngit/sub_commands/issue_status.rs
+++ b/src/bin/ngit/sub_commands/issue_status.rs
@@ -183,8 +183,8 @@ pub async fn launch_close(id: &str, offline: bool, reason: Option<&str>) -> Resu
183 launch_status(id, offline, Kind::GitStatusClosed, "closed", reason).await 183 launch_status(id, offline, Kind::GitStatusClosed, "closed", reason).await
184} 184}
185 185
186pub async fn launch_reopen(id: &str, offline: bool) -> Result<()> { 186pub async fn launch_reopen(id: &str, offline: bool, reason: Option<&str>) -> Result<()> {
187 launch_status(id, offline, Kind::GitStatusOpen, "reopened", None).await 187 launch_status(id, offline, Kind::GitStatusOpen, "reopened", reason).await
188} 188}
189 189
190pub async fn launch_resolved(id: &str, offline: bool, reason: Option<&str>) -> Result<()> { 190pub async fn launch_resolved(id: &str, offline: bool, reason: Option<&str>) -> Result<()> {
diff --git a/src/bin/ngit/sub_commands/pr_status.rs b/src/bin/ngit/sub_commands/pr_status.rs
index 12aafb7..4a51bb3 100644
--- a/src/bin/ngit/sub_commands/pr_status.rs
+++ b/src/bin/ngit/sub_commands/pr_status.rs
@@ -193,18 +193,18 @@ async fn launch_status(
193 Ok(()) 193 Ok(())
194} 194}
195 195
196pub async fn launch_close(id: &str, offline: bool) -> Result<()> { 196pub async fn launch_close(id: &str, offline: bool, reason: Option<&str>) -> Result<()> {
197 launch_status(id, offline, Kind::GitStatusClosed, "closed", None).await 197 launch_status(id, offline, Kind::GitStatusClosed, "closed", reason).await
198} 198}
199 199
200pub async fn launch_reopen(id: &str, offline: bool) -> Result<()> { 200pub async fn launch_reopen(id: &str, offline: bool, reason: Option<&str>) -> Result<()> {
201 launch_status(id, offline, Kind::GitStatusOpen, "reopened", None).await 201 launch_status(id, offline, Kind::GitStatusOpen, "reopened", reason).await
202} 202}
203 203
204pub async fn launch_ready(id: &str, offline: bool) -> Result<()> { 204pub async fn launch_ready(id: &str, offline: bool, reason: Option<&str>) -> Result<()> {
205 launch_status(id, offline, Kind::GitStatusOpen, "marked as ready", None).await 205 launch_status(id, offline, Kind::GitStatusOpen, "marked as ready", reason).await
206} 206}
207 207
208pub async fn launch_draft(id: &str, offline: bool) -> Result<()> { 208pub async fn launch_draft(id: &str, offline: bool, reason: Option<&str>) -> Result<()> {
209 launch_status(id, offline, Kind::GitStatusDraft, "converted to draft", None).await 209 launch_status(id, offline, Kind::GitStatusDraft, "converted to draft", reason).await
210} 210}