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
40 changes: 40 additions & 0 deletions cmd/formats.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package cmd

import (
"fmt"
"rules-cli/internal/formats"

"github.com/spf13/cobra"
)

// formatsCmd represents the formats command
var formatsCmd = &cobra.Command{
Use: "formats",
Short: "List all available render formats",
Long: `List all supported render formats for the 'rules render' command.
Each format represents a different AI code assistant platform with specific
folder structures and file extensions.`,
Example: ` rules formats`,
RunE: func(cmd *cobra.Command, args []string) error {
fmt.Println("Available render formats:")
fmt.Println()

formatList := formats.GetAllFormats()
for _, format := range formatList {
if format.IsSingleFile {
fmt.Printf("%-10s - %s (%s)\n", format.Name, format.SingleFilePath, format.Description)
} else {
fmt.Printf("%-10s - %s/*%s (%s)\n", format.Name, format.DirectoryPrefix, format.FileExtension, format.Description)
}
}

fmt.Println()
fmt.Println("Usage: rules render <format>")

return nil
},
}

func init() {
rootCmd.AddCommand(formatsCmd)
}
11 changes: 10 additions & 1 deletion cmd/render.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,16 @@ var renderCmd = &cobra.Command{
Copies all rules from the default location (.rules/) to the target format
as described in render-formats.md.

Supported formats: continue, cursor, windsurf, claude, copilot, codex, cline, cody, amp`,
Supported formats:
continue - .continue/rules/*.md (Continue Dev rules)
cursor - .cursor/rules/*.mdc (Cursor rules)
windsurf - .windsurf/rules/*.md (Windsurf rules)
claude - CLAUDE.md (Claude Code single file)
copilot - .github/instructions/*.instructions.md (GitHub Copilot instructions)
codex - AGENT.md (Codex single file)
cline - .clinerules/*.md (Cline rules)
cody - .sourcegraph/*.rule.md (Sourcegraph Cody rules)
amp - AGENT.md (Amp single file)`,
Example: ` rules render cursor
rules render continue`,
RunE: func(cmd *cobra.Command, args []string) error {
Expand Down
12 changes: 11 additions & 1 deletion docs/docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,17 @@ To use rules with your AI IDE of choice, you can "render" them to the necessary
rules render cursor
```

will copy all of the `.rules/` into a `.cursor/rules/` folder. `rules` currently supports the following formats: cursor, continue, windsurf, claude, copilot, codex, cline, cody, and amp.
will copy all of the `.rules/` into a `.cursor/rules/` folder. `rules` currently supports the following formats:

- **continue** - `.continue/rules/*.md` (Continue Dev rules)
- **cursor** - `.cursor/rules/*.mdc` (Cursor rules)
- **windsurf** - `.windsurf/rules/*.md` (Windsurf rules)
- **claude** - `CLAUDE.md` (Claude Code single file)
- **copilot** - `.github/instructions/*.instructions.md` (GitHub Copilot instructions)
- **codex** - `AGENT.md` (Codex single file)
- **cline** - `.clinerules/*.md` (Cline rules)
- **cody** - `.sourcegraph/*.rule.md` (Sourcegraph Cody rules)
- **amp** - `AGENT.md` (Amp single file)

## Publish rules

Expand Down
28 changes: 28 additions & 0 deletions internal/formats/formats.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ type Format struct {
FileExtension string
IsSingleFile bool
SingleFilePath string
Description string
}

// GetFormat returns a Format for the given format name
Expand All @@ -25,6 +26,7 @@ func GetFormat(formatName string) Format {
DirectoryPrefix: ".rules",
FileExtension: ".md",
IsSingleFile: false,
Description: "Default rules format",
}
}

Expand All @@ -36,20 +38,23 @@ func GetFormat(formatName string) Format {
DirectoryPrefix: ".continue/rules",
FileExtension: ".md",
IsSingleFile: false,
Description: "Continue Dev rules",
}
case "cursor":
return Format{
Name: "cursor",
DirectoryPrefix: ".cursor/rules",
FileExtension: ".mdc",
IsSingleFile: false,
Description: "Cursor rules",
}
case "windsurf":
return Format{
Name: "windsurf",
DirectoryPrefix: ".windsurf/rules",
FileExtension: ".md",
IsSingleFile: false,
Description: "Windsurf rules",
}
case "claude":
return Format{
Expand All @@ -58,13 +63,15 @@ func GetFormat(formatName string) Format {
FileExtension: ".md",
IsSingleFile: true,
SingleFilePath: "CLAUDE.md",
Description: "Claude Code single file",
}
case "copilot":
return Format{
Name: "copilot",
DirectoryPrefix: ".github/instructions",
FileExtension: ".instructions.md",
IsSingleFile: false,
Description: "GitHub Copilot instructions",
}
case "codex":
return Format{
Expand All @@ -73,20 +80,23 @@ func GetFormat(formatName string) Format {
FileExtension: ".md",
IsSingleFile: true,
SingleFilePath: "AGENT.md",
Description: "Codex single file",
}
case "cline":
return Format{
Name: "cline",
DirectoryPrefix: ".clinerules",
FileExtension: ".md",
IsSingleFile: false,
Description: "Cline rules",
}
case "cody":
return Format{
Name: "cody",
DirectoryPrefix: ".sourcegraph",
FileExtension: ".rule.md",
IsSingleFile: false,
Description: "Sourcegraph Cody rules",
}
case "amp":
return Format{
Expand All @@ -95,6 +105,7 @@ func GetFormat(formatName string) Format {
FileExtension: ".md",
IsSingleFile: true,
SingleFilePath: "AGENT.md",
Description: "Amp single file",
}
default:
// For any other format, use .<format>/rules
Expand All @@ -103,6 +114,7 @@ func GetFormat(formatName string) Format {
DirectoryPrefix: fmt.Sprintf(".%s/rules", formatName),
FileExtension: ".md",
IsSingleFile: false,
Description: fmt.Sprintf("%s rules", formatName),
}
}
}
Expand Down Expand Up @@ -197,3 +209,19 @@ func RenderRules(sourceDir string, targetFormat Format) error {
// Use the transformer to process the rule files
return ProcessRuleFiles(sourceDir, targetFormat)
}

// GetAllFormats returns a list of all supported formats
func GetAllFormats() []Format {
formats := []Format{
GetFormat("continue"),
GetFormat("cursor"),
GetFormat("windsurf"),
GetFormat("claude"),
GetFormat("copilot"),
GetFormat("codex"),
GetFormat("cline"),
GetFormat("cody"),
GetFormat("amp"),
}
return formats
}
20 changes: 20 additions & 0 deletions spec/commands/formats.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# `rules formats`

Lists all available render formats for the `rules render` command.

## Usage

```bash
rules formats
```

## Args

None

## Behavior

- Displays a list of all supported render formats
- Shows the target directory/file and description for each format
- Provides usage example for the `rules render` command
- Does not modify any files
1 change: 1 addition & 0 deletions tests/golden/h/help.golden
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ Available Commands:
add Add a rule from the registry
completion Generate the autocompletion script for the specified shell
create Create a new rule using Continue format
formats List all available render formats
help Help about any command
init Initialize a new rules directory
install Synchronize rules directory with rules.json
Expand Down