package cmd import ( "fmt" "log" "github.com/david/knox/internal/db" "github.com/david/knox/internal/ingest" "github.com/spf13/cobra" ) func NewGitCmd(kdb *db.KnoxDB) *cobra.Command { var roots []string var recursive bool cmd := &cobra.Command{ Args: cobra.NoArgs, Use: "git", Short: "Ingest local git repository status into the knowledge index", Long: `Scans git repos under one or more root dirs (default ~/src) and records each project's status — branch, clean/dirty, ahead/behind, HEAD, last commit. With --recursive (default) repos are found at any depth, following symlinked directories, so nested repos like ~/assistant/kitmaker are picked up. Use 'knox git' for a one-shot ingest, or rely on the watch daemon's git timer.`, RunE: func(c *cobra.Command, args []string) error { ing := &ingest.GitIngester{Roots: roots, Recursive: recursive} log.Printf("[knox] ingesting git repo status...") results, err := ing.IngestAll() if err != nil { return fmt.Errorf("git ingest: %w", err) } if len(results) == 0 { fmt.Println("No git repos found.") return nil } ingest.SortResults(results) var newCount int for _, result := range results { _, isNew, err := kdb.RecordObservation(db.ObservationRecord{ Fingerprint: result.Fingerprint, SourceID: result.SourceID, SourcePath: result.SourcePath, Project: result.Project, ContentType: result.ContentType, Title: result.Title, Summary: result.Summary, CreatedAt: result.CreatedAt, Confidence: result.Confidence, IngesterVersion: result.IngesterVersion, Trigger: "git_ingest", Provenance: ingest.ProvenanceJSON(result.Provenance), }) if err != nil { log.Printf("[knox] db error: %v", err) continue } if isNew { newCount++ } fmt.Printf("%-24s %s\n", result.Project, result.Summary) } fmt.Printf("\nGit: %d repos (%d new)\n", len(results), newCount) return nil }, } cmd.Flags().StringSliceVarP(&roots, "root", "r", nil, "Directories to scan for git repos (default ~/src; repeat or comma-separate for multiple roots)") cmd.Flags().BoolVar(&recursive, "recursive", true, "Recurse into subdirectories (following symlinks) to find nested git repos") return cmd }