@@ -72,8 +72,14 @@ var statsCmd = &cobra.Command{
7272var changesCmd = & cobra.Command {
7373 Use : "changes" ,
7474 Short : "Show recent scope changes (default 50)" ,
75+ Long : `Show recent scope changes. Use --since and --until to filter by time range.
76+
77+ Supported time formats for --since and --until:
78+ today, yesterday, 7d, 30d, 90d, 1y, or YYYY-MM-DD` ,
7579 RunE : func (cmd * cobra.Command , _ []string ) error {
7680 limit , _ := cmd .Flags ().GetInt ("limit" )
81+ sinceStr , _ := cmd .Flags ().GetString ("since" )
82+ untilStr , _ := cmd .Flags ().GetString ("until" )
7783 dbURL , err := GetDBConnectionString ()
7884 if err != nil {
7985 return err
@@ -84,7 +90,21 @@ var changesCmd = &cobra.Command{
8490 return err
8591 }
8692 defer db .Close ()
87- changes , err := db .ListRecentChanges (context .Background (), limit )
93+
94+ since , err := parseTimeFlag (sinceStr )
95+ if err != nil {
96+ return fmt .Errorf ("invalid --since value: %w" , err )
97+ }
98+ until , err := parseTimeFlag (untilStr )
99+ if err != nil {
100+ return fmt .Errorf ("invalid --until value: %w" , err )
101+ }
102+ // When --until is a date, include the full day
103+ if ! until .IsZero () && untilStr != "" && ! strings .Contains (untilStr , "d" ) && untilStr != "today" && untilStr != "yesterday" {
104+ until = until .Add (23 * time .Hour + 59 * time .Minute + 59 * time .Second )
105+ }
106+
107+ changes , err := db .ListRecentChanges (context .Background (), limit , since , until )
88108 if err != nil {
89109 return err
90110 }
@@ -113,6 +133,37 @@ var changesCmd = &cobra.Command{
113133 },
114134}
115135
136+ // parseTimeFlag parses a user-friendly time string into a time.Time.
137+ // Supports: today, yesterday, 7d, 30d, 90d, 1y, YYYY-MM-DD, or empty string.
138+ func parseTimeFlag (s string ) (time.Time , error ) {
139+ s = strings .TrimSpace (s )
140+ if s == "" {
141+ return time.Time {}, nil
142+ }
143+ now := time .Now ()
144+ switch s {
145+ case "today" :
146+ return time .Date (now .Year (), now .Month (), now .Day (), 0 , 0 , 0 , 0 , now .Location ()), nil
147+ case "yesterday" :
148+ y := now .AddDate (0 , 0 , - 1 )
149+ return time .Date (y .Year (), y .Month (), y .Day (), 0 , 0 , 0 , 0 , y .Location ()), nil
150+ case "7d" :
151+ return now .AddDate (0 , 0 , - 7 ), nil
152+ case "30d" :
153+ return now .AddDate (0 , 0 , - 30 ), nil
154+ case "90d" :
155+ return now .AddDate (0 , 0 , - 90 ), nil
156+ case "1y" :
157+ return now .AddDate (- 1 , 0 , 0 ), nil
158+ default :
159+ t , err := time .Parse ("2006-01-02" , s )
160+ if err != nil {
161+ return time.Time {}, fmt .Errorf ("use today, yesterday, 7d, 30d, 90d, 1y, or YYYY-MM-DD" )
162+ }
163+ return t , nil
164+ }
165+ }
166+
116167var printCmd = & cobra.Command {
117168 Use : "print" ,
118169 Short : "Print scope data from the database" ,
@@ -377,6 +428,8 @@ func init() {
377428 addCmd .Flags ().StringP ("category" , "c" , "wildcard" , "Category of the target" )
378429 addCmd .Flags ().StringP ("program-url" , "u" , "custom" , "Program URL (default: 'custom')" )
379430 changesCmd .Flags ().Int ("limit" , 50 , "Number of recent changes to show" )
431+ changesCmd .Flags ().String ("since" , "" , "Show changes since: today, yesterday, 7d, 30d, 90d, 1y, or YYYY-MM-DD" )
432+ changesCmd .Flags ().String ("until" , "" , "Show changes until: today, yesterday, 7d, 30d, 90d, 1y, or YYYY-MM-DD" )
380433 printCmd .Flags ().String ("platform" , "all" , "Comma-separated platforms (h1,bc,it,ywh,immunefi) or 'all'" )
381434 printCmd .Flags ().String ("program" , "" , "Filter by program handle or full URL" )
382435 printCmd .Flags ().Bool ("oos" , false , "Include out-of-scope elements" )
0 commit comments