fix: surface session branch in frontend (#358)
Co-authored-by: Swyam Sharma <cruzer@Swyams-MacBook-Pro.local>
This commit is contained in:
parent
78cdc6d5ca
commit
34a9fdb736
|
|
@ -1261,6 +1261,8 @@ components:
|
|||
properties:
|
||||
activity:
|
||||
$ref: '#/components/schemas/DomainActivity'
|
||||
branch:
|
||||
type: string
|
||||
createdAt:
|
||||
format: date-time
|
||||
type: string
|
||||
|
|
|
|||
|
|
@ -112,12 +112,14 @@ type CleanupSessionsQuery struct {
|
|||
}
|
||||
|
||||
// SessionView is the session wire shape: the domain read model plus the
|
||||
// session's attributed pull requests in the curated SessionPRFacts shape. One
|
||||
// session can own many PRs (e.g. a stack), so prs is a list. The embedded
|
||||
// domain.Session.PRs field is json:"-"; this curated prs is what serializes.
|
||||
// display-safe branch name and the session's attributed pull requests in the
|
||||
// curated SessionPRFacts shape. One session can own many PRs (e.g. a stack), so
|
||||
// prs is a list. The embedded domain.Session.Metadata and domain.Session.PRs
|
||||
// fields are json:"-"; these curated fields are what serialize.
|
||||
type SessionView struct {
|
||||
domain.Session
|
||||
PRs []SessionPRFacts `json:"prs"`
|
||||
Branch string `json:"branch,omitempty"`
|
||||
PRs []SessionPRFacts `json:"prs"`
|
||||
}
|
||||
|
||||
// ListSessionsResponse is the body of GET /api/v1/sessions.
|
||||
|
|
|
|||
|
|
@ -427,7 +427,7 @@ func writeSessionPRError(w http.ResponseWriter, r *http.Request, err error) {
|
|||
}
|
||||
|
||||
func sessionView(s domain.Session) SessionView {
|
||||
return SessionView{Session: s, PRs: sessionPRFacts(s.PRs)}
|
||||
return SessionView{Session: s, Branch: s.Metadata.Branch, PRs: sessionPRFacts(s.PRs)}
|
||||
}
|
||||
|
||||
func sessionViews(sessions []domain.Session) []SessionView {
|
||||
|
|
|
|||
|
|
@ -170,6 +170,9 @@ func TestSessionsRoutes_DefaultToStubsWithoutService(t *testing.T) {
|
|||
|
||||
func TestSessionsAPI_ListSpawnGetAndActions(t *testing.T) {
|
||||
svc := newFakeSessionService()
|
||||
s := svc.sessions["ao-1"]
|
||||
s.Metadata = domain.SessionMetadata{Branch: "qa/modal-worker", WorkspacePath: "/tmp/private-worktree", RuntimeHandleID: "runtime-1", Prompt: "private prompt"}
|
||||
svc.sessions["ao-1"] = s
|
||||
srv := newSessionTestServer(t, svc)
|
||||
|
||||
body, status, _ := doRequest(t, srv, "GET", "/api/v1/sessions?project=ao", "")
|
||||
|
|
@ -183,6 +186,22 @@ func TestSessionsAPI_ListSpawnGetAndActions(t *testing.T) {
|
|||
if len(list.Sessions) != 1 || list.Sessions[0].ID != "ao-1" || list.Sessions[0].Status != string(domain.StatusIdle) || list.Sessions[0].TerminalHandleID != "ao-1/terminal_0" {
|
||||
t.Fatalf("list = %#v", list)
|
||||
}
|
||||
if list.Sessions[0].Branch != "qa/modal-worker" {
|
||||
t.Fatalf("branch = %q, want qa/modal-worker", list.Sessions[0].Branch)
|
||||
}
|
||||
var rawList struct {
|
||||
Sessions []map[string]any `json:"sessions"`
|
||||
}
|
||||
mustJSON(t, body, &rawList)
|
||||
if _, ok := rawList.Sessions[0]["metadata"]; ok {
|
||||
t.Fatalf("list leaked metadata: %s", body)
|
||||
}
|
||||
if _, ok := rawList.Sessions[0]["workspacePath"]; ok {
|
||||
t.Fatalf("list leaked workspacePath: %s", body)
|
||||
}
|
||||
if _, ok := rawList.Sessions[0]["prompt"]; ok {
|
||||
t.Fatalf("list leaked prompt: %s", body)
|
||||
}
|
||||
|
||||
body, status, _ = doRequest(t, srv, "POST", "/api/v1/sessions", `{"projectId":"ao","issueId":"ISS-1","kind":"worker","harness":"codex","prompt":"fix"}`)
|
||||
if status != http.StatusCreated {
|
||||
|
|
@ -388,6 +407,7 @@ type sessionBody struct {
|
|||
Kind string `json:"kind"`
|
||||
Harness string `json:"harness"`
|
||||
DisplayName string `json:"displayName"`
|
||||
Branch string `json:"branch"`
|
||||
Status string `json:"status"`
|
||||
TerminalHandleID string `json:"terminalHandleId"`
|
||||
}
|
||||
|
|
|
|||
|
|
@ -446,6 +446,7 @@ export interface components {
|
|||
};
|
||||
ControllersSessionView: {
|
||||
activity: components["schemas"]["DomainActivity"];
|
||||
branch?: string;
|
||||
/** Format: date-time */
|
||||
createdAt: string;
|
||||
displayName?: string;
|
||||
|
|
|
|||
|
|
@ -63,6 +63,7 @@ describe("useWorkspaceQuery", () => {
|
|||
terminalHandleId: "term-1",
|
||||
displayName: "fix-bug",
|
||||
harness: "claude-code",
|
||||
branch: "qa/modal-worker",
|
||||
status: "mergeable",
|
||||
isTerminated: false,
|
||||
updatedAt: "2026-06-10T16:15:04Z",
|
||||
|
|
@ -96,12 +97,14 @@ describe("useWorkspaceQuery", () => {
|
|||
terminalHandleId: "term-1",
|
||||
title: "fix-bug",
|
||||
provider: "claude-code",
|
||||
branch: "qa/modal-worker",
|
||||
status: "mergeable",
|
||||
});
|
||||
expect(workspace.sessions[1]).toMatchObject({
|
||||
id: "sess-2",
|
||||
title: "sess-2",
|
||||
provider: "codex",
|
||||
branch: "session/sess-2",
|
||||
status: "working",
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ async function fetchWorkspaces(): Promise<WorkspaceSummary[]> {
|
|||
title: session.displayName ?? session.issueId ?? session.id,
|
||||
provider: toAgentProvider(session.harness),
|
||||
kind: session.kind === "orchestrator" ? "orchestrator" : session.kind === "worker" ? "worker" : undefined,
|
||||
branch: `session/${session.id}`,
|
||||
branch: session.branch ?? `session/${session.id}`,
|
||||
status: toSessionStatus(session.status, session.isTerminated),
|
||||
createdAt: session.createdAt,
|
||||
updatedAt: session.updatedAt,
|
||||
|
|
|
|||
Loading…
Reference in New Issue