diff --git a/docs/known-issues.md b/docs/known-issues.md index 7274d08..76796ec 100644 --- a/docs/known-issues.md +++ b/docs/known-issues.md @@ -21,6 +21,11 @@ trade-offs or enhancement requests, not bugs. - `defaultBranch` falls back to `main`/`master` when `origin/HEAD` unavailable. Acceptable — covers 99% of repos. - `CODE_PATH` interpreted differently by `syncRepos` (repo root) vs rest of tooling (`CODE_PATH/core`). Known inconsistency. +## Async Bridge Returns (brain/provider.go) + +- `provider.go:247` — recall HTTP handler forwards to bridge but returns empty `RecallOutput`. Results arrive async via WebSocket — by design for the IDE bridge path. +- `provider.go:297` — list HTTP handler same pattern. Only affects bridge-mode clients, not DirectSubsystem. + ## Compile Issues - `pkg/setup` doesn't compile — calls `lib.RenderFile`, `lib.ListDirTemplates`, `lib.ExtractDir` which don't exist yet. Package is not imported by anything. diff --git a/pkg/agentic/prep.go b/pkg/agentic/prep.go index bffd698..a6ea481 100644 --- a/pkg/agentic/prep.go +++ b/pkg/agentic/prep.go @@ -169,8 +169,12 @@ func (s *PrepSubsystem) prepWorkspace(ctx context.Context, _ *mcp.CallToolReques out := PrepOutput{WorkspaceDir: wsDir} - // Source repo path - repoPath := filepath.Join(s.codePath, "core", input.Repo) + // Source repo path — sanitise to prevent path traversal + repoName := filepath.Base(input.Repo) // strips ../ and absolute paths + if repoName == "." || repoName == ".." || repoName == "" { + return nil, PrepOutput{}, coreerr.E("prep", "invalid repo name: "+input.Repo, nil) + } + repoPath := filepath.Join(s.codePath, "core", repoName) // 1. Clone repo into src/ and create feature branch srcDir := filepath.Join(wsDir, "src") diff --git a/pkg/agentic/review_queue.go b/pkg/agentic/review_queue.go index 013abc5..2612cf3 100644 --- a/pkg/agentic/review_queue.go +++ b/pkg/agentic/review_queue.go @@ -231,8 +231,12 @@ func (s *PrepSubsystem) reviewRepo(ctx context.Context, repoDir, repo, reviewer "Commit: fix(coderabbit): address review findings\n\nFindings summary (%d issues):\n%s", result.Findings, truncate(output, 1500)) - s.dispatchFixFromQueue(ctx, repo, task) - result.Action = "fix_dispatched" + if err := s.dispatchFixFromQueue(ctx, repo, task); err != nil { + result.Action = "fix_dispatch_failed" + result.Detail = err.Error() + } else { + result.Action = "fix_dispatched" + } } return result @@ -263,14 +267,21 @@ func (s *PrepSubsystem) pushAndMerge(ctx context.Context, repoDir, repo string) } // dispatchFixFromQueue dispatches an opus agent to fix CodeRabbit findings. -func (s *PrepSubsystem) dispatchFixFromQueue(ctx context.Context, repo, task string) { +func (s *PrepSubsystem) dispatchFixFromQueue(ctx context.Context, repo, task string) error { // Use the dispatch system — creates workspace, spawns agent input := DispatchInput{ Repo: repo, Task: task, Agent: "claude:opus", } - s.dispatch(ctx, nil, input) + _, out, err := s.dispatch(ctx, nil, input) + if err != nil { + return err + } + if !out.Success { + return coreerr.E("dispatchFixFromQueue", "dispatch failed for "+repo, nil) + } + return nil } // countFindings estimates the number of findings in CodeRabbit output. diff --git a/pkg/monitor/sync.go b/pkg/monitor/sync.go index 19d9474..4722e06 100644 --- a/pkg/monitor/sync.go +++ b/pkg/monitor/sync.go @@ -94,7 +94,12 @@ func (m *Subsystem) syncRepos() string { var pulled []string for _, repo := range checkin.Changed { - repoDir := filepath.Join(basePath, repo.Repo) + // Sanitise repo name to prevent path traversal from API response + repoName := filepath.Base(repo.Repo) + if repoName == "." || repoName == ".." || repoName == "" { + continue + } + repoDir := filepath.Join(basePath, repoName) if _, err := os.Stat(repoDir); err != nil { continue }