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
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,11 +92,11 @@ The tool looks for task and rule files in the following locations, in order of p
**Rules:**
The tool searches for a variety of files and directories, including:
- `CLAUDE.local.md`
- `.agents/rules`, `.cursor/rules`, `.augment/rules`, `.windsurf/rules`
- `.agents/rules`, `.cursor/rules`, `.augment/rules`, `.windsurf/rules`, `.opencode/agent`, `.opencode/command`
- `.github/copilot-instructions.md`, `.gemini/styleguide.md`
- `AGENTS.md`, `CLAUDE.md`, `GEMINI.md` (and in parent directories)
- User-specific rules in `~/.agents/rules`, `~/.claude/CLAUDE.md`, etc.
- System-wide rules in `/etc/agents/rules`.
- User-specific rules in `~/.agents/rules`, `~/.claude/CLAUDE.md`, `~/.opencode/rules`, etc.
- System-wide rules in `/etc/agents/rules`, `/etc/opencode/rules`.

## File Formats

Expand Down
81 changes: 80 additions & 1 deletion integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ Please help with this task.
outputStr := string(output)
bootstrapIdx := strings.Index(outputStr, "Running bootstrap")
setupIdx := strings.Index(outputStr, "# Development Setup")

if bootstrapIdx == -1 {
t.Errorf("bootstrap output not found in stdout")
}
Expand Down Expand Up @@ -632,3 +632,82 @@ Please help with this task.
t.Errorf("bootstrap file should be executable after run, but has mode: %v", fileInfo.Mode())
}
}

func TestOpenCodeRulesSupport(t *testing.T) {
// Build the binary
binaryPath := filepath.Join(t.TempDir(), "coding-context")
cmd := exec.Command("go", "build", "-o", binaryPath, ".")
if output, err := cmd.CombinedOutput(); err != nil {
t.Fatalf("failed to build binary: %v\n%s", err, output)
}

// Create a temporary directory structure
tmpDir := t.TempDir()
openCodeAgentDir := filepath.Join(tmpDir, ".opencode", "agent")
openCodeCommandDir := filepath.Join(tmpDir, ".opencode", "command")
tasksDir := filepath.Join(tmpDir, ".agents", "tasks")

if err := os.MkdirAll(openCodeAgentDir, 0755); err != nil {
t.Fatalf("failed to create opencode agent dir: %v", err)
}
if err := os.MkdirAll(openCodeCommandDir, 0755); err != nil {
t.Fatalf("failed to create opencode command dir: %v", err)
}
if err := os.MkdirAll(tasksDir, 0755); err != nil {
t.Fatalf("failed to create tasks dir: %v", err)
}

// Create an agent rule file in .opencode/agent
agentFile := filepath.Join(openCodeAgentDir, "docs.md")
agentContent := `# Documentation Agent

This agent helps with documentation.
`
if err := os.WriteFile(agentFile, []byte(agentContent), 0644); err != nil {
t.Fatalf("failed to write agent file: %v", err)
}

// Create a command rule file in .opencode/command
commandFile := filepath.Join(openCodeCommandDir, "commit.md")
commandContent := `# Commit Command

This command helps create commits.
`
if err := os.WriteFile(commandFile, []byte(commandContent), 0644); err != nil {
t.Fatalf("failed to write command file: %v", err)
}

// Create a task file
taskFile := filepath.Join(tasksDir, "test-opencode.md")
taskContent := `# Test OpenCode Task

This is a test task.
`
if err := os.WriteFile(taskFile, []byte(taskContent), 0644); err != nil {
t.Fatalf("failed to write task file: %v", err)
}

// Run the binary
cmd = exec.Command(binaryPath, "-C", tmpDir, "test-opencode")
output, err := cmd.CombinedOutput()
if err != nil {
t.Fatalf("failed to run binary: %v\n%s", err, output)
}

outputStr := string(output)

// Check that agent rule content is present
if !strings.Contains(outputStr, "# Documentation Agent") {
t.Errorf("OpenCode agent rule content not found in stdout")
}

// Check that command rule content is present
if !strings.Contains(outputStr, "# Commit Command") {
t.Errorf("OpenCode command rule content not found in stdout")
}

// Check that task content is present
if !strings.Contains(outputStr, "# Test OpenCode Task") {
t.Errorf("task content not found in stdout")
}
}
4 changes: 4 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,8 @@ func run(ctx context.Context, args []string) error {
".cursor/rules",
".augment/rules",
".windsurf/rules",
".opencode/agent",
".opencode/command",

".github/copilot-instructions.md",
".gemini/styleguide.md",
Expand Down Expand Up @@ -118,9 +120,11 @@ func run(ctx context.Context, args []string) error {
filepath.Join(homeDir, ".claude", "CLAUDE.md"),
filepath.Join(homeDir, ".codex", "AGENTS.md"),
filepath.Join(homeDir, ".gemini", "GEMINI.md"),
filepath.Join(homeDir, ".opencode", "rules"),

// system
"/etc/agents/rules",
"/etc/opencode/rules",
} {

// Skip if the path doesn't exist
Expand Down