Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions cli/cmd/log.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (
"github.com/cordon-co/cordon-cli/cli/internal/flags"
"github.com/cordon-co/cordon-cli/cli/internal/reporoot"
"github.com/cordon-co/cordon-cli/cli/internal/store"
"github.com/cordon-co/cordon-cli/cli/internal/tui"
"github.com/spf13/cobra"
)

Expand All @@ -31,6 +32,7 @@ var logSince string
var logDate string
var logAgent string
var logFollow bool
var logInteractive bool
var logExport string

// logCmd — named logCmd to avoid shadowing the standard library "log" package.
Expand All @@ -51,6 +53,7 @@ func init() {
logCmd.Flags().StringVar(&logDate, "date", "", "Show entries for a specific date (e.g. 2026-03-22)")
logCmd.Flags().StringVar(&logAgent, "agent", "", "Filter by agent platform (e.g. claude-code, cursor)")
logCmd.Flags().BoolVarP(&logFollow, "follow", "f", false, "Stream new entries in real-time")
logCmd.Flags().BoolVarP(&logInteractive, "interactive", "i", false, "Open live interactive log viewer")
logCmd.Flags().StringVar(&logExport, "export", "", "Export format: csv")
}

Expand All @@ -62,6 +65,15 @@ func runLog(cmd *cobra.Command, args []string) error {
if logFollow && logExport != "" {
return fmt.Errorf("log: --follow and --export are mutually exclusive")
}
if logInteractive && logExport != "" {
return fmt.Errorf("log: --interactive and --export are mutually exclusive")
}
if logInteractive && logFollow {
return fmt.Errorf("log: --interactive and --follow are mutually exclusive")
}
if logInteractive && flags.JSON {
return fmt.Errorf("log: --interactive cannot be used with --json")
}

root, warn, err := reporoot.Find()
if err != nil {
Expand Down Expand Up @@ -115,8 +127,22 @@ func runLog(cmd *cobra.Command, args []string) error {
}

if logFollow {
// Follow mode is an unfiltered live stream of all event types.
// Ignore category and attribute filters so policy, pass, allow, and deny
// entries all appear in a single feed.
filter.File = ""
filter.Agent = ""
filter.Allow = false
filter.Deny = false
filter.Granted = false
filter.Pass = false
filter.Since = time.Time{}
filter.Until = time.Time{}
return runLogFollow(db, filter)
}
if logInteractive {
return tui.LiveLog(db, filter)
}

entries, err := store.ListUnifiedLog(db, filter)
if err != nil {
Expand Down
Loading
Loading