Skip to content

Conversation

@AnnatarHe
Copy link
Contributor

Summary

  • Add new shelltime rg command with grep alias to search server-synced commands via GraphQL API
  • Supports table (default) and JSON output formats
  • Full filtering support: shell, hostname, username, exit code, main command, session ID, time range
  • Includes pagination with --limit and --offset flags

Test plan

  • Run shelltime rg --help to verify command registration
  • Test basic search: shelltime rg "docker"
  • Test with filters: shelltime rg "git" --shell zsh --result 0
  • Test JSON output: shelltime rg "npm" -f json
  • Test pagination: shelltime rg "test" --limit 10 --offset 5

🤖 Generated with Claude Code

Add new `shelltime rg` command (with `grep` alias) to search server-synced
commands via GraphQL API. Supports table/JSON output and multiple filters:
- shell, hostname, username
- exit code, main command, session ID
- time range (since/until)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @AnnatarHe, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly enhances the shelltime CLI by introducing a powerful new command, rg (or grep), which allows users to search through their historical, server-synced shell commands. This feature provides robust filtering capabilities and flexible output options, making it easier for users to retrieve and analyze their command history directly from the command line.

Highlights

  • New rg command: Introduced a new shelltime rg command, aliased as grep, to search server-synced commands via the GraphQL API.
  • Comprehensive Filtering: The rg command supports extensive filtering options including shell, hostname, username, exit code, main command, session ID, and time range.
  • Output Formats: Results can be displayed in either a human-readable table format (default) or a machine-readable JSON format.
  • Pagination Support: The command includes --limit and --offset flags for efficient pagination of search results.
  • CLI Integration: The new RgCommand has been registered in the main CLI application, making it accessible to users.
  • Documentation Update: The README.md file has been updated to include the new shelltime rg command in the command list.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@codecov
Copy link

codecov bot commented Jan 3, 2026

Codecov Report

❌ Patch coverage is 0% with 181 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
commands/grep.go 0.00% 148 Missing ⚠️
model/command_search.go 0.00% 32 Missing ⚠️
cmd/cli/main.go 0.00% 1 Missing ⚠️
Flag Coverage Δ
unittests 18.96% <0.00%> (?)

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
cmd/cli/main.go 0.00% <0.00%> (ø)
model/command_search.go 0.00% <0.00%> (ø)
commands/grep.go 0.00% <0.00%> (ø)

... and 1 file with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a new rg command (with a grep alias) for searching synced commands, which is a great addition to the CLI's functionality. The implementation is solid, covering filtering, pagination, and multiple output formats (table and JSON).

I've left a couple of comments for improvement:

  1. A medium-severity comment regarding platform-independent path construction, to align with the repository's general rules and improve portability.
  2. A high-severity comment about error handling for time-based filters, which currently fails silently on invalid input. Addressing this will improve user experience and prevent confusion.

Overall, this is a well-implemented feature. Nice work!

commands/rg.go Outdated
Comment on lines 252 to 263
if since := c.String("since"); since != "" {
t, err := time.Parse(time.RFC3339, since)
if err == nil {
timeFilters = append(timeFilters, float64(t.UnixMilli()))
}
}
if until := c.String("until"); until != "" {
t, err := time.Parse(time.RFC3339, until)
if err == nil {
timeFilters = append(timeFilters, float64(t.UnixMilli()))
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The code for parsing since and until time filters silently ignores any parsing errors. If a user provides an invalid time format (e.g., not RFC3339), the filter is simply not applied, and the user receives no feedback. This can lead to confusing search results.

I recommend refactoring buildCommandFilter to return an error. This way, you can propagate the parsing error up to commandRg and inform the user about the invalid input.

For example:

func buildCommandFilter(c *cli.Context, searchText string) (map[string]interface{}, error) {
	// ...
	if since := c.String("since"); since != "" {
		t, err := time.Parse(time.RFC3339, since)
		if err != nil {
			return nil, fmt.Errorf("invalid 'since' time format: %w. Use RFC3339 format (e.g. '2006-01-02T15:04:05Z07:00')", err)
		}
		timeFilters = append(timeFilters, float64(t.UnixMilli()))
	}
	// ... similar for 'until'
	// ...
	return filter, nil
}

And then in commandRg, you would handle the error:

	filter, err := buildCommandFilter(c, searchText)
	if err != nil {
		return err
	}

commands/rg.go Outdated
ctx, span := commandTracer.Start(c.Context, "rg", trace.WithSpanKind(trace.SpanKindClient))
defer span.End()

SetupLogger(os.ExpandEnv("$HOME/" + model.COMMAND_BASE_STORAGE_FOLDER))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The path for the logger is constructed using os.ExpandEnv with a hardcoded path separator. This is not platform-independent. You should use os.UserHomeDir() to get the user's home directory and filepath.Join to construct paths. This ensures the code works correctly on different operating systems (e.g., Windows).

You'll also need to import the path/filepath package.

homeDir, err := os.UserHomeDir()
if err != nil {
	return fmt.Errorf("could not get user home directory: %w", err)
}
SetupLogger(filepath.Join(homeDir, model.COMMAND_BASE_STORAGE_FOLDER))
References
  1. For platform-independent paths, use filepath.Join to combine segments and os.UserHomeDir() to get the home directory, rather than hardcoding path separators or environment variables like $HOME.

AnnatarHe and others added 4 commits January 3, 2026 23:37
- Move API types and FetchCommandsFromServer to model/command_search.go
- Rename commands/rg.go to commands/grep.go
- Remove sessionId from filter and output
- Support flexible date formats for --since/--until (2024, 2024-01, 2024-01-15)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Show a spinner with "Searching commands..." while fetching data from
the server, then hide it when results are received.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Change from offset-based pagination to cursor-based pagination using
lastId as required by the server's InputPagination type. Also add ID
column to table output for pagination reference.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Show errors as formatted output instead of returning them:
- JSON format: output {"error": "message"}
- Table format: print error in red

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@AnnatarHe AnnatarHe merged commit 8a55de2 into main Jan 3, 2026
2 of 3 checks passed
@AnnatarHe AnnatarHe deleted the feat/add-rg-grep-command branch January 3, 2026 16:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants