()
| 535 | |
| 536 | |
| 537 | def main(): |
| 538 | parser = argparse.ArgumentParser(description="Query GitHub issues from local JSON data.") |
| 539 | parser.add_argument("-d", "--data", default=str(DEFAULT_DATA), help="Path to issues JSON file") |
| 540 | sub = parser.add_subparsers(dest="command", required=True) |
| 541 | |
| 542 | # list |
| 543 | p_list = sub.add_parser("list", help="List issues (one line each)") |
| 544 | p_list.add_argument("--state", choices=["open", "closed"], help="Filter by state (default: open)") |
| 545 | p_list.add_argument("--label", help="Filter by label name") |
| 546 | p_list.add_argument("--unlabeled", action="store_true", help="Only show unlabeled issues") |
| 547 | p_list.add_argument( |
| 548 | "--sort", choices=["updated", "created", "comments", "reactions"], help="Sort order (default: updated)" |
| 549 | ) |
| 550 | p_list.add_argument("--limit", type=int, help="Max results") |
| 551 | |
| 552 | # search |
| 553 | p_search = sub.add_parser("search", help="Keyword search") |
| 554 | p_search.add_argument("query", help="Search terms") |
| 555 | p_search.add_argument("--title-only", action="store_true", help="Search title only (default: title + body)") |
| 556 | p_search.add_argument("--state", choices=["open", "closed"], help="Filter by state") |
| 557 | p_search.add_argument("--label", help="Filter by label name") |
| 558 | p_search.add_argument("--limit", type=int, help="Max results (default 20)") |
| 559 | |
| 560 | # related |
| 561 | p_related = sub.add_parser("related", help="Find related issues") |
| 562 | p_related.add_argument("number", type=int, help="Issue number to find related issues for") |
| 563 | p_related.add_argument("--state", choices=["open", "closed"], help="Only show open or closed") |
| 564 | p_related.add_argument("--limit", type=int, help="Max results (default 15)") |
| 565 | p_related.add_argument( |
| 566 | "-v", "--verbose", action="store_true", help="Show body preview and last comment for each result" |
| 567 | ) |
| 568 | |
| 569 | # batch-related |
| 570 | p_batch = sub.add_parser("batch-related", help="Find related issues for multiple issues at once") |
| 571 | p_batch.add_argument("numbers", type=int, nargs="+", help="Issue numbers") |
| 572 | p_batch.add_argument("--state", choices=["open", "closed"], help="Only show open or closed") |
| 573 | p_batch.add_argument("--limit", type=int, help="Max results per issue (default 5)") |
| 574 | p_batch.add_argument( |
| 575 | "-v", "--verbose", action="store_true", help="Show body preview and last comment for each result" |
| 576 | ) |
| 577 | |
| 578 | # show |
| 579 | p_show = sub.add_parser("show", help="Show full issue detail (body + comments)") |
| 580 | p_show.add_argument("numbers", type=int, nargs="+", help="Issue number(s)") |
| 581 | p_show.add_argument("--brief", action="store_true", help="Truncated body, first+last comment only") |
| 582 | |
| 583 | # top |
| 584 | p_top = sub.add_parser("top", help="Top open issues by reactions") |
| 585 | p_top.add_argument("--label", help="Filter by label") |
| 586 | p_top.add_argument("--limit", type=int, help="Max results (default 20)") |
| 587 | |
| 588 | # stats |
| 589 | sub.add_parser("stats", help="Summary statistics") |
| 590 | |
| 591 | args = parser.parse_args() |
| 592 | data = load_data(args.data) |
| 593 | |
| 594 | cmds = { |
no test coverage detected