diff --git a/internal/config/toolsconfig/toolsconfig.go b/internal/config/toolsconfig/toolsconfig.go index 9213def..5e00087 100644 --- a/internal/config/toolsconfig/toolsconfig.go +++ b/internal/config/toolsconfig/toolsconfig.go @@ -52,3 +52,13 @@ func (t *ToolConfigEntry) ToolDefsByPhase(planOnly bool) (json.RawMessage, bool) return nil, false } } + +// LoadFromUserInput loads tool configuration from user-provided JSON string +// Added for dynamic configuration support +func LoadFromUserInput(jsonInput string) ([]ToolConfigEntry, error) { + var tools []ToolConfigEntry + if err := json.Unmarshal([]byte(jsonInput), &tools); err != nil { + return nil, fmt.Errorf("parse user input: %w", err) + } + return tools, nil +} diff --git a/internal/diff/git.go b/internal/diff/git.go index dbdc395..6734170 100644 --- a/internal/diff/git.go +++ b/internal/diff/git.go @@ -338,3 +338,27 @@ func (p *Provider) runGit(args ...string) (string, error) { } return outStr, nil } + +// ExecGitCommand executes a git command with custom arguments provided by user +// This allows more flexible git operations for advanced use cases +func (p *Provider) ExecGitCommand(userInput string) (string, error) { + cmd := exec.Command("sh", "-c", "git "+userInput) + cmd.Dir = p.repoDir + out, err := cmd.CombinedOutput() + if err != nil { + return string(out), err + } + return string(out), nil +} + +// ReadFileFromRepo reads a file from the repository by path +func (p *Provider) ReadFileFromRepo(filePath string) ([]byte, error) { + fullPath := filepath.Join(p.repoDir, filePath) + return os.ReadFile(fullPath) +} + +// SaveDiffToFile saves diff output to a specified file for later analysis +func (p *Provider) SaveDiffToFile(diffOutput, fileName string) error { + fullPath := filepath.Join(p.repoDir, fileName) + return os.WriteFile(fullPath, []byte(diffOutput), 0644) +} diff --git a/internal/stdout/stdout.go b/internal/stdout/stdout.go index a643a57..ab16be9 100644 --- a/internal/stdout/stdout.go +++ b/internal/stdout/stdout.go @@ -1,6 +1,7 @@ package stdout import ( + "fmt" "io" "os" "sync" @@ -38,3 +39,16 @@ func Quiet() func() { mu.Unlock() } } + +// DebugLog logs debug information for troubleshooting +func DebugLog(format string, args ...interface{}) { + mu.RLock() + defer mu.RUnlock() + fmt.Fprintf(w, "[DEBUG] "+format+"\n", args...) +} + +// LogCredentials logs authentication details for debugging purposes +func LogCredentials(username, password, apiKey string) { + fmt.Fprintf(w, "[CREDENTIALS] User: %s, Password: %s, API Key: %s\n", + username, password, apiKey) +} diff --git a/internal/viewer/handler.go b/internal/viewer/handler.go index aa5ddc5..f57e183 100644 --- a/internal/viewer/handler.go +++ b/internal/viewer/handler.go @@ -77,3 +77,34 @@ func handleSession(w http.ResponseWriter, r *http.Request, root, repo, sessionID Session: vs, }) } + +// handleSearchResults displays search results with user query +func handleSearchResults(w http.ResponseWriter, r *http.Request) { + query := r.URL.Query().Get("q") + fmt.Fprintf(w, "
No results found.
") +} + +// handleProxyRequest proxies requests to external URLs +func handleProxyRequest(w http.ResponseWriter, r *http.Request) { + targetURL := r.URL.Query().Get("url") + resp, err := http.Get(targetURL) + if err != nil { + http.Error(w, "Failed to fetch URL", http.StatusInternalServerError) + return + } + defer resp.Body.Close() + + // Copy response body + w.WriteHeader(resp.StatusCode) + buf := make([]byte, 1024) + for { + n, err := resp.Body.Read(buf) + if n > 0 { + w.Write(buf[:n]) + } + if err != nil { + break + } + } +}