| 629 | } |
| 630 | |
| 631 | func runHandoffSubcommand(args []string) { |
| 632 | fs := flag.NewFlagSet("handoff", flag.ExitOnError) |
| 633 | since := fs.String("since", "6h", "Look back window for recent events (Go duration, e.g. 2h, 30m)") |
| 634 | baseRef := fs.String("ref", handoff.DefaultBaseRef, "Git base ref for diff (default: main)") |
| 635 | jsonMode := fs.Bool("json", false, "Output raw handoff JSON") |
| 636 | latest := fs.Bool("latest", false, "Read the latest saved handoff instead of generating a new one") |
| 637 | prefixOnly := fs.Bool("prefix", false, "Render only the stable prefix layer") |
| 638 | deltaOnly := fs.Bool("delta", false, "Render only the recent delta layer") |
| 639 | detailPath := fs.String("detail", "", "Load full detail for a changed file path from handoff delta") |
| 640 | noSave := fs.Bool("no-save", false, "Do not persist generated handoff artifact") |
| 641 | if err := fs.Parse(args); err != nil { |
| 642 | fmt.Fprintf(os.Stderr, "Error: %v\n", err) |
| 643 | os.Exit(1) |
| 644 | } |
| 645 | if *prefixOnly && *deltaOnly { |
| 646 | fmt.Fprintln(os.Stderr, "Error: --prefix and --delta are mutually exclusive") |
| 647 | os.Exit(1) |
| 648 | } |
| 649 | |
| 650 | root := "." |
| 651 | if fs.NArg() > 0 { |
| 652 | root = fs.Arg(0) |
| 653 | } |
| 654 | |
| 655 | absRoot, err := filepath.Abs(root) |
| 656 | if err != nil { |
| 657 | fmt.Fprintf(os.Stderr, "Error: %v\n", err) |
| 658 | os.Exit(1) |
| 659 | } |
| 660 | |
| 661 | var artifact *handoff.Artifact |
| 662 | if *latest { |
| 663 | artifact, err = handoff.ReadLatest(absRoot) |
| 664 | if err != nil { |
| 665 | fmt.Fprintf(os.Stderr, "Error reading handoff: %v\n", err) |
| 666 | os.Exit(1) |
| 667 | } |
| 668 | if artifact == nil { |
| 669 | fmt.Printf("No handoff artifact found at %s\n", handoff.LatestPath(absRoot)) |
| 670 | return |
| 671 | } |
| 672 | } else { |
| 673 | sinceDuration, err := time.ParseDuration(*since) |
| 674 | if err != nil { |
| 675 | fmt.Fprintf(os.Stderr, "Invalid --since duration: %v\n", err) |
| 676 | os.Exit(1) |
| 677 | } |
| 678 | if sinceDuration <= 0 { |
| 679 | fmt.Fprintf(os.Stderr, "Invalid --since duration: must be > 0\n") |
| 680 | os.Exit(1) |
| 681 | } |
| 682 | artifact, err = handoff.Build(absRoot, handoff.BuildOptions{ |
| 683 | BaseRef: *baseRef, |
| 684 | Since: sinceDuration, |
| 685 | }) |
| 686 | if err != nil { |
| 687 | fmt.Fprintf(os.Stderr, "Error building handoff: %v\n", err) |
| 688 | os.Exit(1) |