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
83 changes: 83 additions & 0 deletions integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package main

import (
"bytes"
"fmt"
"os"
"os/exec"
"path/filepath"
Expand Down Expand Up @@ -1145,3 +1146,85 @@ Please fix issue number ${1} with priority ${2}.
t.Errorf("positional arguments not substituted in content. Output:\n%s", output)
}
}

func TestManifestFile(t *testing.T) {
// Create main project directory
mainDir := t.TempDir()
mainRulesDir := filepath.Join(mainDir, ".agents", "rules")
mainTasksDir := filepath.Join(mainDir, ".agents", "tasks")

if err := os.MkdirAll(mainRulesDir, 0o755); err != nil {
t.Fatalf("failed to create main rules dir: %v", err)
}
if err := os.MkdirAll(mainTasksDir, 0o755); err != nil {
t.Fatalf("failed to create main tasks dir: %v", err)
}

// Create a task file in the main directory
taskFile := filepath.Join(mainTasksDir, "test-task.md")
taskContent := `---
task_name: test-task
---
# Test Task

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

// Create a rule file in the main directory (should be included)
mainRuleFile := filepath.Join(mainRulesDir, "main-rule.md")
mainRuleContent := `---
---
# Main Rule

This rule is in the main project.
`
if err := os.WriteFile(mainRuleFile, []byte(mainRuleContent), 0o644); err != nil {
t.Fatalf("failed to write main rule file: %v", err)
}

// Create a remote directory with rules
remoteDir := t.TempDir()
remoteRulesDir := filepath.Join(remoteDir, ".agents", "rules")
if err := os.MkdirAll(remoteRulesDir, 0o755); err != nil {
t.Fatalf("failed to create remote rules dir: %v", err)
}

remoteRuleFile := filepath.Join(remoteRulesDir, "remote-rule.md")
remoteRuleContent := `---
---
# Remote Rule

This rule is from a remote directory.
`
if err := os.WriteFile(remoteRuleFile, []byte(remoteRuleContent), 0o644); err != nil {
t.Fatalf("failed to write remote rule file: %v", err)
}

// Create a manifest file that references the remote directory
manifestFile := filepath.Join(t.TempDir(), "manifest.txt")
manifestContent := fmt.Sprintf("file://%s\n", remoteDir)
if err := os.WriteFile(manifestFile, []byte(manifestContent), 0o644); err != nil {
t.Fatalf("failed to write manifest file: %v", err)
}

// Run the tool with the manifest file
output := runTool(t, "-C", mainDir, "-m", "file://"+manifestFile, "/test-task")

// Check that the main rule is included
if !strings.Contains(output, "# Main Rule") {
t.Errorf("main rule not found in stdout. Output:\n%s", output)
}

// Check that the remote rule from the manifest is included
if !strings.Contains(output, "# Remote Rule") {
t.Errorf("remote rule from manifest not found in stdout. Output:\n%s", output)
}

// Check that the task is included
if !strings.Contains(output, "# Test Task") {
t.Errorf("task not found in stdout. Output:\n%s", output)
}
}
19 changes: 11 additions & 8 deletions pkg/codingcontext/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,14 @@ func (cc *Context) expandParams(content string) string {
// - A free-text prompt (used directly as task content)
// - A prompt containing a slash command (e.g., "/fix-bug 123") which triggers task lookup
func (cc *Context) Run(ctx context.Context, taskPrompt string) (*Result, error) {
// Parse manifest file first to get additional search paths
manifestPaths, err := cc.parseManifestFile(ctx)
if err != nil {
return nil, fmt.Errorf("failed to parse manifest file: %w", err)
}
cc.searchPaths = append(cc.searchPaths, manifestPaths...)

// Download all remote directories (including those from manifest)
if err := cc.downloadRemoteDirectories(ctx); err != nil {
return nil, fmt.Errorf("failed to download remote directories: %w", err)
}
Expand All @@ -130,12 +138,6 @@ func (cc *Context) Run(ctx context.Context, taskPrompt string) (*Result, error)
return nil, fmt.Errorf("failed to get user home directory: %w", err)
}

searchPaths, err := cc.parseManifestFile(ctx)
if err != nil {
return nil, fmt.Errorf("failed to parse manifest file: %w", err)
}
cc.searchPaths = append(cc.searchPaths, searchPaths...)

// Expand parameters in taskPrompt to allow slash commands in parameters
expandedTaskPrompt := cc.expandParams(taskPrompt)

Expand Down Expand Up @@ -226,8 +228,9 @@ func (cc *Context) parseManifestFile(ctx context.Context) ([]string, error) {

manifestFile := downloadDir(cc.manifestURL)

// Download the manifest file using go-getter
if _, err := getter.Get(ctx, manifestFile, cc.manifestURL); err != nil {
// Download the manifest file using go-getter's GetFile function
// GetFile is specifically for downloading single files (not directories)
if _, err := getter.GetFile(ctx, manifestFile, cc.manifestURL); err != nil {
return nil, fmt.Errorf("failed to download manifest file %s: %w", cc.manifestURL, err)
}
defer os.RemoveAll(manifestFile)
Expand Down
Loading