Coverage for little_loops / cli / issues / next_issues.py: 90%

29 statements  

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

1"""ll-issues next-issues: Print all active issues in ranked order.""" 

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_issues(config: BRConfig, args: argparse.Namespace) -> int: 

14 """Print all active issues ranked 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, .path flags and .count 

22 

23 Returns: 

24 Exit code (0 = at least one 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.issue_parser import find_issues 

29 

30 try: 

31 sort_key = build_sort_key(config.issues.next_issue) 

32 except ValueError as e: 

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

34 return 1 

35 

36 issues = find_issues(config) 

37 if not issues: 

38 return 1 

39 

40 issues.sort(key=sort_key) 

41 

42 count = getattr(args, "count", None) 

43 ranked = issues[:count] if count else issues 

44 

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

46 print_json( 

47 [ 

48 { 

49 "id": i.issue_id, 

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

51 "outcome_confidence": i.outcome_confidence, 

52 "confidence_score": i.confidence_score, 

53 "priority": i.priority, 

54 } 

55 for i in ranked 

56 ] 

57 ) 

58 return 0 

59 

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

61 for i in ranked: 

62 print(str(i.path)) 

63 return 0 

64 

65 for i in ranked: 

66 print(i.issue_id) 

67 return 0