on main help sign in
feat: crush dirs (#551)

Signed-off-by: Carlos Alexandro Becker <caarlos0@users.noreply.github.com> Co-authored-by: Christian Rocha <christian@rocha.is>

commitafa10c5eb9c84e8a78233446ec4c2803b1c868d8 authorCarlos Alexandro Becker <caarlos0@users.noreply.github.com> dateTue 30 Sep 2025, 17:53 (1 year ago) parente5e01d5
5 files changed+76−9
internal/cmd/dirs.go+66 internal/cmd/logs.go−1 internal/cmd/root.go+7−2 internal/cmd/schema.go−4 internal/config/load.go+3−2
internal/cmd/dirs.gonew file+66
@@ -0,0 +1,66 @@
1+package cmd
2+
3+import (
4+ "os"
5+ "path/filepath"
6+
7+ "github.com/charmbracelet/crush/internal/config"
8+ "github.com/charmbracelet/lipgloss/v2"
9+ "github.com/charmbracelet/lipgloss/v2/table"
10+ "github.com/charmbracelet/x/term"
11+ "github.com/spf13/cobra"
12+)
13+
14+var dirsCmd = &cobra.Command{
15+ Use: "dirs",
16+ Short: "Print directories used by Crush",
17+ Long: `Print the directories where Crush stores its configuration and data files.
18+This includes the global configuration directory and data directory.`,
19+ Example: `
20+# Print all directories
21+crush dirs
22+
23+# Print only the config directory
24+crush dirs config
25+
26+# Print only the data directory
27+crush dirs data
28+ `,
29+ Run: func(cmd *cobra.Command, args []string) {
30+ if term.IsTerminal(os.Stdout.Fd()) {
31+ // We're in a TTY: make it fancy.
32+ t := table.New().
33+ Border(lipgloss.RoundedBorder()).
34+ StyleFunc(func(row, col int) lipgloss.Style {
35+ return lipgloss.NewStyle().Padding(0, 2)
36+ }).
37+ Row("Config", filepath.Dir(config.GlobalConfig())).
38+ Row("Data", filepath.Dir(config.GlobalConfigData()))
39+ lipgloss.Println(t)
40+ return
41+ }
42+ // Not a TTY.
43+ cmd.Println(filepath.Dir(config.GlobalConfig()))
44+ cmd.Println(filepath.Dir(config.GlobalConfigData()))
45+ },
46+}
47+
48+var configDirCmd = &cobra.Command{
49+ Use: "config",
50+ Short: "Print the configuration directory used by Crush",
51+ Run: func(cmd *cobra.Command, args []string) {
52+ cmd.Println(filepath.Dir(config.GlobalConfig()))
53+ },
54+}
55+
56+var dataDirCmd = &cobra.Command{
57+ Use: "data",
58+ Short: "Print the datauration directory used by Crush",
59+ Run: func(cmd *cobra.Command, args []string) {
60+ cmd.Println(filepath.Dir(config.GlobalConfigData()))
61+ },
62+}
63+
64+func init() {
65+ dirsCmd.AddCommand(configDirCmd, dataDirCmd)
66+}
internal/cmd/logs.go−1
@@ -68,7 +68,6 @@ var logsCmd = &cobra.Command{
6868func init() {
6969 logsCmd.Flags().BoolP("follow", "f", false, "Follow log output")
7070 logsCmd.Flags().IntP("tail", "t", defaultTailLines, "Show only the last N lines default: 1000 for performance")
71− rootCmd.AddCommand(logsCmd)
7271}
7372
7473func followLogs(ctx context.Context, logsFile string, tailLines int) error {
internal/cmd/root.go+7−2
@@ -33,8 +33,13 @@ func init() {
3333 rootCmd.Flags().BoolP("help", "h", false, "Help")
3434 rootCmd.Flags().BoolP("yolo", "y", false, "Automatically accept all permissions (dangerous mode)")
3535
36− rootCmd.AddCommand(runCmd)
37− rootCmd.AddCommand(updateProvidersCmd)
36+ rootCmd.AddCommand(
37+ runCmd,
38+ dirsCmd,
39+ updateProvidersCmd,
40+ logsCmd,
41+ schemaCmd,
42+ )
3843}
3944
4045var rootCmd = &cobra.Command{
internal/cmd/schema.go−4
@@ -24,7 +24,3 @@ var schemaCmd = &cobra.Command{
2424 return nil
2525 },
2626}
27−
28−func init() {
29− rootCmd.AddCommand(schemaCmd)
30−}
internal/config/load.go+3−2
@@ -520,7 +520,7 @@ func (c *Config) configureSelectedModels(knownProviders []catwalk.Provider) erro
520520func lookupConfigs(cwd string) []string {
521521 // prepend default config paths
522522 configPaths := []string{
523− globalConfig(),
523+ GlobalConfig(),
524524 GlobalConfigData(),
525525 }
526526
@@ -596,7 +596,8 @@ func hasAWSCredentials(env env.Env) bool {
596596 return false
597597}
598598
599−func globalConfig() string {
599+// GlobalConfig returns the global configuration file path for the application.
600+func GlobalConfig() string {
600601 xdgConfigHome := os.Getenv("XDG_CONFIG_HOME")
601602 if xdgConfigHome != "" {
602603 return filepath.Join(xdgConfigHome, appName, fmt.Sprintf("%s.json", appName))