fix: use raw JSON responses in claudebox server
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed

The claudebox sidecar was using api.WriteJSON which wraps responses in
{data: ..., meta: ...} format. The claudebox HTTP client expects raw
JSON responses without wrapping.

This caused git clone to appear to fail - the HTTP request succeeded
and returned {data: {success: true, cloned: true}, meta: {...}}, but
the client decoded success=false because it couldn't find the fields
at the top level.

Added writeRawJSON helper and replaced all api.WriteJSON calls with it
for actual responses. Error responses still use api.WriteBadRequest
which returns proper error format.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
jordan 2026-02-07 16:41:21 -07:00
parent af91bad0ff
commit b41e0dfbf9

View File

@ -14,6 +14,14 @@ import (
"github.com/orchard9/rdev/pkg/api"
)
// writeRawJSON writes a raw JSON response without the rdev-api wrapper.
// The claudebox sidecar uses direct JSON responses, not the {data, meta} format.
func writeRawJSON(w http.ResponseWriter, status int, data any) {
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(status)
_ = json.NewEncoder(w).Encode(data)
}
// Server handles HTTP requests for claudebox operations.
type Server struct {
executor *Executor
@ -65,7 +73,7 @@ func (s *Server) handleHealth(w http.ResponseWriter, r *http.Request) {
Timestamp: time.Now().UTC().Format(time.RFC3339),
WorkDir: s.executor.workDir,
}
api.WriteJSON(w, r, http.StatusOK, resp)
writeRawJSON(w, http.StatusOK, resp)
}
// ExecuteRequest is the request to execute Claude Code.
@ -120,7 +128,7 @@ func (s *Server) handleExecute(w http.ResponseWriter, r *http.Request) {
resp.Error = result.Error.Error()
}
api.WriteJSON(w, r, http.StatusOK, resp)
writeRawJSON(w, http.StatusOK, resp)
}
// StreamEvent is an SSE event for streaming execution.
@ -234,7 +242,7 @@ func (s *Server) handleGitClone(w http.ResponseWriter, r *http.Request) {
resp.Error = result.Error.Error()
}
api.WriteJSON(w, r, http.StatusOK, resp)
writeRawJSON(w, http.StatusOK, resp)
}
// GitCommitAndPushRequest is the request to commit and push changes.
@ -286,7 +294,7 @@ func (s *Server) handleGitCommitAndPush(w http.ResponseWriter, r *http.Request)
resp.Error = result.Error.Error()
}
api.WriteJSON(w, r, http.StatusOK, resp)
writeRawJSON(w, http.StatusOK, resp)
}
// GitStatusResponse is the response from git status.
@ -309,14 +317,14 @@ func (s *Server) handleGitStatus(w http.ResponseWriter, r *http.Request) {
status, err := s.gitOps.Status(ctx, workDir)
if err != nil {
api.WriteJSON(w, r, http.StatusOK, GitStatusResponse{
writeRawJSON(w, http.StatusOK, GitStatusResponse{
IsRepo: false,
Error: err.Error(),
})
return
}
api.WriteJSON(w, r, http.StatusOK, status)
writeRawJSON(w, http.StatusOK, status)
}
// SDLCRequest is the request to run an SDLC command.
@ -364,5 +372,5 @@ func (s *Server) handleSDLC(w http.ResponseWriter, r *http.Request) {
resp.Error = result.Error.Error()
}
api.WriteJSON(w, r, http.StatusOK, resp)
writeRawJSON(w, http.StatusOK, resp)
}