Skip to content

Commit 7f82083

Browse files
lucifer1004claude
andcommitted
feat(cli): add --scope for journal and --pro/--con/--reject-reason for alternatives
- Add --scope option to work add for journal entries (per ADR-0026) - Add --pro, --con, --reject-reason options to adr add for alternatives (per ADR-0027) - --pro and --con can be specified multiple times to add multiple pros/cons - If --reject-reason is provided, status is automatically set to rejected Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent dca028d commit 7f82083

File tree

4 files changed

+69
-16
lines changed

4 files changed

+69
-16
lines changed
Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,26 @@
11
[govctl]
22
schema = 1
33
id = "WI-2026-02-25-002"
4-
title = "Improve CLI help text for work item fields"
4+
title = "Support new ADR/WI fields"
55
status = "done"
66
created = "2026-02-25"
77
started = "2026-02-25"
88
completed = "2026-02-25"
99

1010
[content]
11-
description = """
12-
Describe the work to be done.
13-
What is the goal? What are the acceptance criteria?"""
11+
description = """Add concrete support for new ADR/WI fields"""
1412

1513
[[content.acceptance_criteria]]
1614
text = "Add semantic field descriptions to work set help"
1715
status = "done"
18-
category = "chore"
16+
category = "fixed"
17+
18+
[[content.acceptance_criteria]]
19+
text = "Add CLI option to set ADR alternative pros/cons/reject_reason"
20+
status = "pending"
21+
category = "fixed"
22+
23+
[[content.acceptance_criteria]]
24+
text = "Add CLI option to set WI journal's scope"
25+
status = "pending"
26+
category = "fixed"

src/cmd/edit.rs

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -550,6 +550,10 @@ pub fn add_to_field(
550550
value: Option<&str>,
551551
stdin: bool,
552552
category_override: Option<crate::model::ChangelogCategory>,
553+
scope_override: Option<&str>,
554+
pros: Option<Vec<String>>,
555+
cons: Option<Vec<String>>,
556+
reject_reason: Option<String>,
553557
op: WriteOp,
554558
) -> anyhow::Result<Vec<Diagnostic>> {
555559
let field = normalize_field(field);
@@ -598,19 +602,31 @@ pub fn add_to_field(
598602
match field {
599603
"refs" => push_unique(&mut entry.spec.govctl.refs, value),
600604
"alternatives" => {
601-
use crate::model::Alternative;
605+
use crate::model::{Alternative, AlternativeStatus};
602606
if !entry
603607
.spec
604608
.content
605609
.alternatives
606610
.iter()
607611
.any(|a| a.text == value)
608612
{
613+
// Determine status based on reject_reason
614+
let status = if reject_reason.is_some() {
615+
AlternativeStatus::Rejected
616+
} else {
617+
AlternativeStatus::Considered
618+
};
609619
entry
610620
.spec
611621
.content
612622
.alternatives
613-
.push(Alternative::new(value));
623+
.push(Alternative {
624+
text: value.to_string(),
625+
status,
626+
pros: pros.unwrap_or_default(),
627+
cons: cons.unwrap_or_default(),
628+
rejection_reason: reject_reason,
629+
});
614630
}
615631
}
616632
_ => {
@@ -676,7 +692,7 @@ pub fn add_to_field(
676692
use crate::write::today;
677693
entry.spec.content.journal.push(JournalEntry {
678694
date: today(),
679-
scope: None,
695+
scope: scope_override.map(String::from),
680696
content: value.to_string(),
681697
});
682698
}

src/command_router.rs

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,9 @@ pub enum CanonicalCommand {
204204
field: String,
205205
value: Option<String>,
206206
stdin: bool,
207+
pro: Vec<String>,
208+
con: Vec<String>,
209+
reject_reason: Option<String>,
207210
},
208211
AdrRemove {
209212
id: String,
@@ -268,6 +271,7 @@ pub enum CanonicalCommand {
268271
value: Option<String>,
269272
stdin: bool,
270273
category: Option<ChangelogCategory>,
274+
scope: Option<String>,
271275
},
272276
WorkRemove {
273277
id: String,
@@ -562,7 +566,10 @@ impl CanonicalCommand {
562566
field,
563567
value,
564568
stdin,
565-
} => cmd::edit::add_to_field(config, id, field, value.as_deref(), *stdin, None, op),
569+
pro,
570+
con,
571+
reject_reason,
572+
} => cmd::edit::add_to_field(config, id, field, value.as_deref(), *stdin, None, None, Some(pro.clone()), Some(con.clone()), reject_reason.clone(), op),
566573
Self::AdrRemove {
567574
id,
568575
field,
@@ -618,8 +625,9 @@ impl CanonicalCommand {
618625
value,
619626
stdin,
620627
category,
628+
scope,
621629
} => {
622-
cmd::edit::add_to_field(config, id, field, value.as_deref(), *stdin, *category, op)
630+
cmd::edit::add_to_field(config, id, field, value.as_deref(), *stdin, *category, scope.as_deref(), None, None, None, op)
623631
}
624632
Self::WorkRemove {
625633
id,
@@ -849,11 +857,17 @@ impl CanonicalCommand {
849857
field,
850858
value,
851859
stdin,
860+
pro: adr_pro,
861+
con: adr_con,
862+
reject_reason,
852863
} => Self::AdrAdd {
853864
id: id.clone(),
854865
field: field.clone(),
855866
value: value.clone(),
856867
stdin: *stdin,
868+
pro: adr_pro.to_vec(),
869+
con: adr_con.to_vec(),
870+
reject_reason: reject_reason.clone(),
857871
},
858872
AdrCommand::Remove {
859873
id,
@@ -960,12 +974,14 @@ impl CanonicalCommand {
960974
value,
961975
stdin,
962976
category,
977+
scope,
963978
} => Self::WorkAdd {
964979
id: id.clone(),
965980
field: field.clone(),
966981
value: value.clone(),
967982
stdin: *stdin,
968983
category: *category,
984+
scope: scope.clone(),
969985
},
970986
WorkCommand::Remove {
971987
id,

src/main.rs

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -632,15 +632,15 @@ ALTERNATIVES FORMAT (per ADR-0027):
632632
Each alternative has:
633633
- text: Description of the option (required)
634634
- status: considered | accepted | rejected
635-
- pros: List of advantages (edit via adr.json directly)
636-
- cons: List of disadvantages (edit via adr.json directly)
637-
- rejection_reason: Why rejected (if status=rejected)
638-
639-
Note: pros/cons/rejection_reason require direct TOML editing.
635+
- pros: Advantages (use --pro to add)
636+
- cons: Disadvantages (use --con to add)
637+
- rejection_reason: Why rejected (use --reject-reason)
640638
641639
EXAMPLES:
642640
govctl adr add ADR-0001 refs RFC-0001
643641
govctl adr add ADR-0001 alternatives \"Option A: Use PostgreSQL\"
642+
govctl adr add ADR-0001 alternatives \"Option B: Use Redis\" --pro \"Fast caching\" --con \"Additional infrastructure\"
643+
govctl adr add ADR-0001 alternatives \"Option C: No cache\" --reject-reason \"Performance issues\"
644644
")]
645645
Add {
646646
/// ADR ID
@@ -652,6 +652,15 @@ EXAMPLES:
652652
/// Read value from stdin
653653
#[arg(long)]
654654
stdin: bool,
655+
/// Pro/advantage for this alternative (can be specified multiple times)
656+
#[arg(long)]
657+
pro: Vec<String>,
658+
/// Con/disadvantage for this alternative (can be specified multiple times)
659+
#[arg(long)]
660+
con: Vec<String>,
661+
/// Reason for rejection (if rejected)
662+
#[arg(long)]
663+
reject_reason: Option<String>,
655664
},
656665
/// Remove value from ADR array field
657666
#[command(after_help = "\
@@ -864,6 +873,7 @@ FIELD SEMANTICS:
864873
- journal: Execution tracking - append on each progress
865874
* Each entry has: date (auto-filled), scope (optional), content
866875
* Use --stdin for multi-line entries
876+
* Use --scope to set the scope/topic
867877
- notes: Ad-hoc points - add anytime, keep concise
868878
869879
ACCEPTANCE CRITERIA FORMAT:
@@ -876,7 +886,7 @@ ACCEPTANCE CRITERIA FORMAT:
876886
EXAMPLES:
877887
govctl work add WI-001 refs RFC-0001
878888
govctl work add WI-001 acceptance_criteria \"add: Implement feature\"
879-
govctl work add WI-001 journal --stdin <<'EOF'
889+
govctl work add WI-001 journal --scope typub-html --stdin <<'EOF'
880890
Progress update for today...
881891
EOF
882892
govctl work add WI-001 notes \"Remember to test edge cases\"
@@ -894,6 +904,9 @@ EXAMPLES:
894904
/// Changelog category for acceptance_criteria (alternative to prefix)
895905
#[arg(short = 'c', long, value_enum)]
896906
category: Option<model::ChangelogCategory>,
907+
/// Scope/topic for journal entry (e.g., "backend", "frontend", "docs")
908+
#[arg(long)]
909+
scope: Option<String>,
897910
},
898911
/// Remove value from work item array field
899912
#[command(after_help = "\

0 commit comments

Comments
 (0)