refactor: replace WithRemotePaths with WithSearchPaths in coding context#126
Conversation
alexec
commented
Nov 24, 2025
- Updated the main function to use WithSearchPaths instead of WithRemotePaths for better clarity.
- Modified tests to accommodate the new searchPaths structure, ensuring compatibility with existing functionality.
- Enhanced the cleanup and download logic to utilize searchPaths for remote directories.
- Removed the unused remote.go file and refactored related code for improved maintainability.
- Updated the main function to use WithSearchPaths instead of WithRemotePaths for better clarity. - Modified tests to accommodate the new searchPaths structure, ensuring compatibility with existing functionality. - Enhanced the cleanup and download logic to utilize searchPaths for remote directories. - Removed the unused remote.go file and refactored related code for improved maintainability.
- Changed variable name from remotePaths to searchPaths for clarity. - Updated the flag description for directory input to reflect the new naming. - Added logic to include user home directory and working directory in searchPaths. - Removed the AllAgents function from agent.go as it was unused, simplifying the codebase.
There was a problem hiding this comment.
Pull request overview
This PR refactors the remote directory handling by replacing WithRemotePaths with WithSearchPaths and consolidating path management. The goal is to unify how local and remote directories are handled through a single search paths mechanism. However, the refactoring introduces several critical bugs that break core functionality.
Key changes:
- Replaced
WithRemotePathswithWithSearchPathsto handle both local and remote directories uniformly - Removed
AllRulePathsandAllTaskSearchPathsfunctions, replacing them withrulePathsandtaskSearchPathsthat work on individual directories - Removed
remote.goand inlined download logic directly intocontext.go - Updated all tests to use
file://URLs for local paths
Reviewed changes
Copilot reviewed 12 out of 13 changed files in this pull request and generated 8 comments.
Show a summary per file
| File | Description |
|---|---|
| pkg/codingcontext/context.go | Core refactoring: replaced remotePaths/downloadedDirs with unified searchPaths, inlined download logic, but introduced bugs in path handling |
| pkg/codingcontext/paths.go | Removed exported path functions, replaced with unexported versions that work on single directories; lost support for ancestor directories and CLAUDE.local.md |
| main.go | Updated to use WithSearchPaths instead of WithRemotePaths; adds local paths but without proper file:// prefix |
| pkg/codingcontext/context_test.go | Updated all tests to use file:// URLs for local paths and call downloadRemoteDirectories explicitly |
| pkg/codingcontext/remote.go | Removed file entirely; download logic moved to context.go |
| pkg/codingcontext/example_test.go | Removed example test functions |
| pkg/codingcontext/agent.go | Removed unused AllAgents function |
| pkg/codingcontext/agent_test.go | Removed test for AllAgents function |
| pkg/codingcontext/rule_frontmatter.go | Whitespace-only formatting fixes |
| Makefile | Added unparam linting tool |
Comments suppressed due to low confidence (6)
pkg/codingcontext/context_test.go:1997
- [nitpick] In these inline function calls, errors from
filepath.Abs()are silently ignored withabs, _ := filepath.Abs(tmpDir). Iffilepath.Abs()fails,abswill be an empty string, resulting in an invalidfile://URL.
While this is test code and failure is unlikely, it's better practice to handle errors properly or at minimum add a comment explaining why the error is safe to ignore.
pkg/codingcontext/context.go:255
- The
downloadDirfunction computes a hash-based path for every searchPath. When local directories likeworkDirandhomeDirare added to searchPaths (lines 61-62 in main.go), this function will compute a hash-based temp directory for them. However,findTaskFileandfindExecuteRuleFileswill then look for files in these temp directories (which don't exist for local paths) instead of the actual local directories.
This breaks the ability to find local task and rule files. The code needs to handle local paths differently from remote paths - local paths should be used directly without the hash-based transformation.
if _, err := os.Stat(dir); os.IsNotExist(err) {
continue
} else if err != nil {
return fmt.Errorf("failed to stat task dir %s: %w", dir, err)
}
if err := filepath.Walk(dir, cc.taskFileWalker(taskName)); err != nil {
pkg/codingcontext/context.go:250
- The comment "Add downloaded remote directories to task search paths" is misleading. After the refactoring, this code processes all searchPaths (not just "downloaded remote directories"), and the current implementation incorrectly applies
downloadDir()to all paths including local ones. The comment should be updated to reflect the actual behavior or intended behavior.
continue
pkg/codingcontext/context.go:327
- The logic for determining whether a path is a home directory is incorrect. The code compares
path == homeDir, butpathat this point is a searchPath fromcc.searchPaths(which could be a file:// URL, remote URL, or local path), whilehomeDiris always a local filesystem path. This comparison will likely never match, meaning the home-specific rule paths will never be used.
Consider tracking which searchPaths represent the home directory separately, or normalize both paths before comparison.
continue
pkg/codingcontext/context.go:56
- The function name
WithSearchPath(singular) in the comment doesn't match the actual function nameWithSearchPaths(plural). Update the comment to match the function name.
func WithLogger(logger *slog.Logger) Option {
pkg/codingcontext/context.go:328
- The logic change removes the ability to search ancestor directories for
AGENTS.md,CLAUDE.md, andGEMINI.mdfiles. The originalAllRulePathsfunction (now removed) included paths likefilepath.Join(baseDir, "..", "AGENTS.md")andfilepath.Join(baseDir, "..", "..", "AGENTS.md")to search up to 2 parent directories. The new implementation usingrulePaths(workDir, false)only searches within the working directory itself.
This is a breaking change that may cause existing setups to stop finding rule files that were previously discovered in parent directories.
// Skip if this path should be excluded based on target agent
if cc.agent.ShouldExcludePath(rule) {
cc.logger.Info("Excluding rule path (target agent filtering)", "path", rule)
continue
}
You can also share your feedback on Copilot code review for a chance to win a $100 gift card. Take the survey.
- Added CLAUDE.local.md to the list of paths in rulePaths for better context handling. - Updated Makefile to include gofmt for code formatting during the lint process.
- Introduced a new flag for specifying a manifest URL that contains search paths. - Updated the main function to handle the new manifest URL and integrate it into the search paths. - Refactored the findTaskFile function to simplify its parameters. - Enhanced the coding context with a new method to parse the manifest file and retrieve search paths. - Updated tests to reflect changes in task file searching logic.
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 12 out of 13 changed files in this pull request and generated 10 comments.
You can also share your feedback on Copilot code review for a chance to win a $100 gift card. Take the survey.
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 12 out of 13 changed files in this pull request and generated 6 comments.
You can also share your feedback on Copilot code review for a chance to win a $100 gift card. Take the survey.
| searchPaths = append(searchPaths, s) | ||
| return nil | ||
| }) | ||
| flag.StringVar(&manifestURL, "m", "", "Go Getter URL to a manifest file containing search paths (one per line). Every line is included as-is.") |
There was a problem hiding this comment.
Documentation inaccuracy: The flag description states "Every line is included as-is", but the implementation in parseManifestFile uses bufio.Scanner.Text() which automatically trims leading and trailing whitespace from each line.
Update the description to be accurate:
flag.StringVar(&manifestURL, "m", "", "Go Getter URL to a manifest file containing search paths (one per line). Lines are trimmed of whitespace.")| flag.StringVar(&manifestURL, "m", "", "Go Getter URL to a manifest file containing search paths (one per line). Every line is included as-is.") | |
| flag.StringVar(&manifestURL, "m", "", "Go Getter URL to a manifest file containing search paths (one per line). Lines are trimmed of whitespace.") |
| var ruleSearchDirs []string | ||
| for _, path := range cc.searchPaths { | ||
| dst := downloadDir(path) | ||
| subPaths := rulePaths(dst, path == homeDir) |
There was a problem hiding this comment.
Potential bug: The comparison path == homeDir (line 372) will likely always be false because:
pathcomes fromcc.searchPaths, which contains URLs like"file:///home/user"(see main.go:64)homeDiris a plain filesystem path like"/home/user"(see line 128-131)
This means the home directory will never use the home-specific rule paths, resulting in user-specific locations like ~/.claude/CLAUDE.md, ~/.codex/AGENTS.md, and ~/.gemini/GEMINI.md not being discovered.
Suggested fix: Either normalize both paths before comparison, or track which search paths represent the home directory separately (e.g., using a struct with {path: string, isHome: bool}).
Example normalization approach:
// In parseManifestFile or a helper function
func normalizeSearchPath(path string) string {
// Strip file:// prefix if present
if strings.HasPrefix(path, "file://") {
return strings.TrimPrefix(path, "file://")
}
return path
}
// Then in findExecuteRuleFiles:
normalizedPath := normalizeSearchPath(path)
subPaths := rulePaths(dst, normalizedPath == homeDir)