package main import ( "bufio" "bytes" "encoding/json" "log" "net/http" "os" "os/exec" ) type runRequest struct { Prompt string `json:"prompt"` } type runResponse struct { Success bool `json:"success"` Answer *string `json:"answer"` Usage interface{} `json:"usage"` Stderr string `json:"stderr"` } type event struct { Type string `json:"type"` Item map[string]interface{} `json:"item"` Usage interface{} `json:"usage"` } func main() { mux := http.NewServeMux() mux.HandleFunc("/run", runHandler) addr := ":8000" if port := os.Getenv("PORT"); port != "" { addr = ":" + port } log.Printf("listening on %s", addr) if err := http.ListenAndServe(addr, mux); err != nil { log.Fatal(err) } } func runHandler(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodPost { http.Error(w, "method not allowed", http.StatusMethodNotAllowed) return } var req runRequest if err := json.NewDecoder(r.Body).Decode(&req); err != nil { http.Error(w, "invalid json body", http.StatusBadRequest) return } cmd := exec.Command( "codex", "exec", "--skip-git-repo-check", "--full-auto", "--add-dir", "/tmp", "--json", req.Prompt, ) var stdout bytes.Buffer var stderr bytes.Buffer cmd.Stdout = &stdout cmd.Stderr = &stderr err := cmd.Run() var finalText *string var usage interface{} scanner := bufio.NewScanner(bytes.NewReader(stdout.Bytes())) for scanner.Scan() { line := bytes.TrimSpace(scanner.Bytes()) if len(line) == 0 { continue } var evt event if unmarshalErr := json.Unmarshal(line, &evt); unmarshalErr != nil { continue } if evt.Type == "item.completed" { itemType, _ := evt.Item["type"].(string) itemText, _ := evt.Item["text"].(string) if (itemType == "agent_message" || itemType == "message") && itemText != "" { textCopy := itemText finalText = &textCopy } } if evt.Type == "turn.completed" { usage = evt.Usage } } resp := runResponse{ Success: err == nil, Answer: finalText, Usage: usage, Stderr: stderr.String(), } w.Header().Set("Content-Type", "application/json") if encodeErr := json.NewEncoder(w).Encode(resp); encodeErr != nil { http.Error(w, encodeErr.Error(), http.StatusInternalServerError) } }