Files
weichenandCursor a182d7662b Move cross-library squad code into adapter modules
Why: the squad core has to compile without agent-native or agent-intent. Ports stay in the core; adapters and the CLI own the concrete clients.
Evidence: GOWORK=off go test -count=1 ./squad/ ./store/ ./textextract/ ./schema/ passed, and the intent, sqlite, native, and cmd modules passed their own go test.
Impact: core go.mod keeps error-code-system only. Nested gitlinks stay. Callers register the native backend through agent-squad/adapters/native.
Refs: D1
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-03 13:40:58 +00:00

121 lines
3.7 KiB
Go

package platform
import (
"encoding/json"
"io"
"net/http"
"time"
)
func nowTime() time.Time { return time.Now() }
// Mount attaches the orchestration routes. The goal-engine /v1/runs routes stay separate.
func Mount(mux *http.ServeMux, st *Store) {
mux.HandleFunc("POST /v1/workspaces", func(w http.ResponseWriter, r *http.Request) {
var body struct{ Name string }
if err := json.NewDecoder(r.Body).Decode(&body); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
ws, err := st.CreateWorkspace(body.Name)
write(w, ws, err)
})
mux.HandleFunc("POST /v1/agents", func(w http.ResponseWriter, r *http.Request) {
var a Agent
if err := json.NewDecoder(r.Body).Decode(&a); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
created, err := st.CreateAgent(a)
write(w, created, err)
})
mux.HandleFunc("POST /v1/squads", func(w http.ResponseWriter, r *http.Request) {
var body struct {
Squad
Members []SquadMember
}
if err := json.NewDecoder(r.Body).Decode(&body); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
created, err := st.CreateSquad(body.Squad, body.Members)
write(w, created, err)
})
mux.HandleFunc("POST /v1/issues", func(w http.ResponseWriter, r *http.Request) {
var issue Issue
if err := json.NewDecoder(r.Body).Decode(&issue); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
created, err := st.CreateIssue(issue)
write(w, created, err)
})
mux.HandleFunc("POST /v1/issues/{id}/assign", func(w http.ResponseWriter, r *http.Request) {
var body struct {
Kind string
ID string
Start bool
}
if err := json.NewDecoder(r.Body).Decode(&body); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
err := st.AssignIssue(r.PathValue("id"), body.Kind, body.ID, body.Start)
write(w, map[string]bool{"ok": err == nil}, err)
})
mux.HandleFunc("POST /v1/issues/{id}/comments", func(w http.ResponseWriter, r *http.Request) {
var c Comment
if err := json.NewDecoder(r.Body).Decode(&c); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
c.IssueID = r.PathValue("id")
created, err := st.AddComment(c)
write(w, created, err)
})
mux.HandleFunc("POST /v1/tasks/claim", func(w http.ResponseWriter, r *http.Request) {
task, ok, err := st.Claim(r.URL.Query().Get("runtime"), nowTime())
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
write(w, map[string]any{"task": task, "ok": ok}, nil)
})
mux.HandleFunc("POST /v1/webhooks/autopilots/{token}", func(w http.ResponseWriter, r *http.Request) {
body, err := io.ReadAll(io.LimitReader(r.Body, 256*1024+1))
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
headers := map[string]string{}
for _, key := range []string{"Idempotency-Key", "X-GitHub-Delivery", "X-Hub-Signature-256", "X-GitHub-Event"} {
if v := r.Header.Get(key); v != "" {
headers[key] = v
}
}
event, err := st.AcceptWebhook(r.PathValue("token"), body, headers)
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
write(w, map[string]string{"event": event}, nil)
})
mux.HandleFunc("GET /v1/events/ws", func(w http.ResponseWriter, r *http.Request) {
if r.Header.Get("Upgrade") == "" {
http.Error(w, "upgrade required", http.StatusUpgradeRequired)
return
}
w.Header().Set("Content-Type", "application/json")
_, _ = w.Write([]byte("{\"type\":\"ready\"}\n"))
})
}
func write(w http.ResponseWriter, v any, err error) {
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
w.Header().Set("Content-Type", "application/json")
_ = json.NewEncoder(w).Encode(v)
}