Coverage for little_loops / cli / issues / next_issue.py: 89%

28 statements  

« prev     ^ index     » next       coverage.py v7.12.0, created at 2026-05-22 16:19 -0500

1"""ll-issues next-issue: Print the highest-confidence active issue.""" 

2 

3from __future__ import annotations 

4 

5import argparse 

6import sys 

7from typing import TYPE_CHECKING 

8 

9if TYPE_CHECKING: 

10 from little_loops.config import BRConfig 

11 

12 

13def cmd_next_issue(config: BRConfig, args: argparse.Namespace) -> int: 

14 """Print the top-ranked active issue per ``config.issues.next_issue``. 

15 

16 The default ``confidence_first`` strategy is byte-identical to the prior 

17 hardcoded sort: ``(-outcome_confidence, -confidence_score, priority_int)``. 

18 

19 Args: 

20 config: Project configuration 

21 args: Parsed arguments with optional .json and .path flags 

22 

23 Returns: 

24 Exit code (0 = found, 1 = no issues or invalid sort config) 

25 """ 

26 from little_loops.cli.issues.search import build_sort_key 

27 from little_loops.cli.output import print_json 

28 from little_loops.cli_args import parse_issue_ids 

29 from little_loops.issue_parser import find_issues 

30 

31 try: 

32 sort_key = build_sort_key(config.issues.next_issue) 

33 except ValueError as e: 

34 print(f"Error: {e}", file=sys.stderr) 

35 return 1 

36 

37 skip_ids = parse_issue_ids(getattr(args, "skip", None)) 

38 issues = find_issues(config, skip_ids=skip_ids or None) 

39 if not issues: 

40 return 1 

41 

42 issues.sort(key=sort_key) 

43 

44 top = issues[0] 

45 

46 if getattr(args, "json", False): 

47 print_json( 

48 { 

49 "id": top.issue_id, 

50 "path": str(top.path), 

51 "outcome_confidence": top.outcome_confidence, 

52 "confidence_score": top.confidence_score, 

53 "priority": top.priority, 

54 } 

55 ) 

56 return 0 

57 

58 if getattr(args, "path", False): 

59 print(str(top.path)) 

60 return 0 

61 

62 print(top.issue_id) 

63 return 0