Skip to content
Open
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
17 changes: 17 additions & 0 deletions cmd/agentsview/activity.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ type ActivityReportConfig struct {
Timezone string
Bucket string
Project string
Branch string
Agent string
Machine string
JSON bool
Expand All @@ -36,6 +37,12 @@ type ActivityReportConfig struct {
// runActivityReport syncs, resolves the range, runs the report, and prints it.
func runActivityReport(cfg ActivityReportConfig) {
ctx := context.Background()
// Validate the (project, branch) flag combo up front so a bad combination
// fails before we resolve a backend, which may sync or start a daemon.
if _, err := branchFilterToken(cfg.Project, cfg.Branch); err != nil {
fmt.Fprintf(os.Stderr, "error: %v\n", err)
os.Exit(1)
}
backend, cleanup, err := resolveArchiveQueryBackend(ctx, archiveQueryPolicy{
Offline: cfg.Offline,
NoSync: cfg.NoSync,
Expand Down Expand Up @@ -89,6 +96,11 @@ func fetchHTTPActivityReport(
setIfNotEmpty("project", cfg.Project)
setIfNotEmpty("agent", cfg.Agent)
setIfNotEmpty("machine", cfg.Machine)
gitBranch, err := branchFilterToken(cfg.Project, cfg.Branch)
if err != nil {
return activity.Report{}, err
}
setIfNotEmpty("git_branch", gitBranch)

endpoint := strings.TrimSuffix(tr.URL, "/") +
"/api/v1/activity/report?" + q.Encode()
Expand Down Expand Up @@ -159,9 +171,14 @@ func resolveActivityReport(
return activity.Report{}, err
}

gitBranch, err := branchFilterToken(cfg.Project, cfg.Branch)
if err != nil {
return activity.Report{}, err
}
f := db.AnalyticsFilter{
Timezone: tz,
Project: cfg.Project,
GitBranch: gitBranch,
Agent: cfg.Agent,
Machine: cfg.Machine,
ExcludeOneShot: false,
Expand Down
13 changes: 13 additions & 0 deletions cmd/agentsview/cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,18 @@ const (

const dataVersionTooNewExitCode = 3

// branchFilterToken builds the (project, branch) filter token; a branch needs a
// project to scope it (like the MCP tools), so it errors without --project.
func branchFilterToken(project, branch string) (string, error) {
if branch == "" {
return "", nil
}
if project == "" {
return "", fmt.Errorf("--branch requires --project")
}
return db.EncodeBranchFilterToken(project, branch), nil
}

type cliExitError struct {
code int
err error
Expand Down Expand Up @@ -518,6 +530,7 @@ func newActivityReportCommand() *cobra.Command {
cmd.Flags().StringVar(&cfg.Timezone, "timezone", "", "IANA timezone for range bucketing")
cmd.Flags().StringVar(&cfg.Bucket, "bucket", "", "Bucket size: 5m, 15m, 1h, 1d, 1w")
cmd.Flags().StringVar(&cfg.Project, "project", "", "Filter by project")
cmd.Flags().StringVar(&cfg.Branch, "branch", "", "Filter by git branch name (requires --project)")
cmd.Flags().StringVar(&cfg.Agent, "agent", "", "Filter by agent name")
cmd.Flags().StringVar(&cfg.Machine, "machine", "", "Filter by machine name")
registerFormatFlags(cmd.Flags())
Expand Down
13 changes: 13 additions & 0 deletions cmd/agentsview/cli_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -316,3 +316,16 @@ func TestSyncHelpMentionsConfiguredHosts(t *testing.T) {
assert.Contains(t, help, want, "sync help missing %q", want)
}
}

func TestBranchFilterToken(t *testing.T) {
tok, err := branchFilterToken("proj", "")
require.NoError(t, err)
assert.Empty(t, tok, "empty branch yields no token")

_, err = branchFilterToken("", "main")
assert.Error(t, err, "branch without project must error")

tok, err = branchFilterToken("proj", "main")
require.NoError(t, err)
assert.Equal(t, db.EncodeBranchFilterToken("proj", "main"), tok)
}
3 changes: 3 additions & 0 deletions cmd/agentsview/session_get.go
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,9 @@ func printSessionDetailHuman(w io.Writer, s *service.SessionDetail) error {
fmt.Fprintf(w, "%s %s\n", label("ID"), sanitizeTerminal(s.ID))
fmt.Fprintf(w, "%s %s\n", label("Name"), sanitizeTerminal(name))
fmt.Fprintf(w, "%s %s\n", label("Project"), sanitizeTerminal(s.Project))
if s.GitBranch != "" {
fmt.Fprintf(w, "%s %s\n", label("Branch"), sanitizeTerminal(s.GitBranch))
}
fmt.Fprintf(w, "%s %s\n", label("Agent"), sanitizeTerminal(s.Agent))
fmt.Fprintf(w, "%s %s\n", label("Machine"), sanitizeTerminal(s.Machine))
fmt.Fprintf(w, "%s %s\n",
Expand Down
8 changes: 8 additions & 0 deletions cmd/agentsview/session_list.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (
func newSessionListCommand() *cobra.Command {
var (
project, excludeProject, machine, agent string
branch string
date, dateFrom, dateTo, activeSince string
minMessages, maxMessages int
minUserMessages int
Expand All @@ -39,6 +40,10 @@ func newSessionListCommand() *cobra.Command {
Args: cobra.NoArgs,
SilenceUsage: true,
RunE: func(cmd *cobra.Command, args []string) error {
gitBranch, err := branchFilterToken(project, branch)
if err != nil {
return err
}
svc, cleanup, err := resolveService(cmd)
if err != nil {
return err
Expand All @@ -49,6 +54,7 @@ func newSessionListCommand() *cobra.Command {
Project: project,
ExcludeProject: excludeProject,
Machine: machine,
GitBranch: gitBranch,
Agent: agent,
Date: date,
DateFrom: dateFrom,
Expand Down Expand Up @@ -123,6 +129,8 @@ func newSessionListCommand() *cobra.Command {
"Exclude sessions from the given project")
flags.StringVar(&machine, "machine", "",
"Filter by machine name")
flags.StringVar(&branch, "branch", "",
"Filter by git branch name (requires --project)")
flags.StringVar(&agent, "agent", "",
"Filter by agent (claude, codex, cursor, ...)")
flags.StringVar(&date, "date", "",
Expand Down
9 changes: 8 additions & 1 deletion cmd/agentsview/session_search.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ func newSessionSearchCommand() *cobra.Command {
in string
excludeSystem, reveal bool
project, excludeProject, agent string
machine, date, dateFrom, dateTo string
machine, branch string
date, dateFrom, dateTo string
activeSince string
includeChildren, includeAutomated bool
includeOneShot bool
Expand Down Expand Up @@ -54,6 +55,10 @@ func newSessionSearchCommand() *cobra.Command {
case useFTS:
mode = "fts"
}
gitBranch, err := branchFilterToken(project, branch)
if err != nil {
return err
}
svc, cleanup, err := resolveService(cmd)
if err != nil {
return err
Expand All @@ -69,6 +74,7 @@ func newSessionSearchCommand() *cobra.Command {
Project: project,
ExcludeProject: excludeProject,
Machine: machine,
GitBranch: gitBranch,
Agent: agent,
Date: date,
DateFrom: dateFrom,
Expand Down Expand Up @@ -105,6 +111,7 @@ func newSessionSearchCommand() *cobra.Command {
flags.StringVar(&project, "project", "", "Filter by project name")
flags.StringVar(&excludeProject, "exclude-project", "", "Exclude project")
flags.StringVar(&machine, "machine", "", "Filter by machine")
flags.StringVar(&branch, "branch", "", "Filter by git branch name (requires --project)")
flags.StringVar(&agent, "agent", "", "Filter by agent")
flags.StringVar(&date, "date", "", "Sessions started on YYYY-MM-DD")
flags.StringVar(&dateFrom, "date-from", "", "Sessions on or after YYYY-MM-DD")
Expand Down
5 changes: 5 additions & 0 deletions frontend/messages/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -378,6 +378,9 @@
"sidebar_filters_machine": "Machine",
"sidebar_filters_search_machines": "Search machines...",
"sidebar_filters_no_machines": "No machines",
"sidebar_filters_branch": "Branch",
"sidebar_filters_search_branches": "Search branches...",
"sidebar_filters_no_branches": "No branches",
"sidebar_filters_min_prompts": "Min Prompts",
"sidebar_filters_clear_filters": "Clear filters",
"sidebar_row_expand": "Expand",
Expand All @@ -396,6 +399,7 @@
"shared_active_filters_label": "Filters:",
"shared_active_filters_clear_project": "Clear project filter",
"shared_active_filters_remove_machine": "Remove {machine} filter",
"shared_active_filters_remove_branch": "Remove {branch} filter",
"shared_active_filters_remove_agent": "Remove {agent} filter",
"shared_active_filters_clear_min_prompts": "Clear min prompts filter",
"shared_active_filters_min_prompts": "≥{count} prompts",
Expand Down Expand Up @@ -460,6 +464,7 @@
"shared_no_sessions_in_range": "No sessions in range",
"shared_none": "None",
"shared_other": "Other",
"shared_no_branch": "(no branch)",
"shared_unknown": "unknown",
"analytics_refresh": "Refresh analytics",
"analytics_export_csv": "Export CSV",
Expand Down
5 changes: 5 additions & 0 deletions frontend/messages/zh-CN.json
Original file line number Diff line number Diff line change
Expand Up @@ -368,6 +368,9 @@
"sidebar_filters_machine": "Machine",
"sidebar_filters_search_machines": "搜索 machines...",
"sidebar_filters_no_machines": "无 machines",
"sidebar_filters_branch": "分支",
"sidebar_filters_search_branches": "搜索分支...",
"sidebar_filters_no_branches": "无分支",
"sidebar_filters_min_prompts": "最少提示数",
"sidebar_filters_clear_filters": "清除筛选器",
"sidebar_row_expand": "展开",
Expand All @@ -386,6 +389,7 @@
"shared_active_filters_label": "筛选器:",
"shared_active_filters_clear_project": "清除项目筛选器",
"shared_active_filters_remove_machine": "移除 {machine} 筛选器",
"shared_active_filters_remove_branch": "移除 {branch} 筛选器",
"shared_active_filters_remove_agent": "移除 {agent} 筛选器",
"shared_active_filters_clear_min_prompts": "清除最少提示数筛选器",
"shared_active_filters_min_prompts": "≥{count} 条提示",
Expand Down Expand Up @@ -449,6 +453,7 @@
"shared_no_sessions_in_range": "此范围内无会话",
"shared_none": "无",
"shared_other": "其他",
"shared_no_branch": "(无分支)",
"shared_unknown": "未知",
"analytics_refresh": "刷新分析",
"analytics_export_csv": "导出 CSV",
Expand Down
2 changes: 2 additions & 0 deletions frontend/src/lib/api/generated/index.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions frontend/src/lib/api/generated/models/BranchesResponse.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 10 additions & 0 deletions frontend/src/lib/api/generated/models/DbBranchInfo.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions frontend/src/lib/api/generated/services/ActivityService.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading