fix(web): fix lint/prettier and TypeScript errors in proxy route
All checks were successful
ci/woodpecker/push/ci Pipeline was successful

- Remove unnecessary null-coalesce on request.nextUrl.search
- Fix body typing: use null instead of undefined for no-body requests
- Use conditional spread to satisfy fetch() overload types
- Auto-fix prettier formatting across all changed files
This commit is contained in:
2026-03-08 11:54:11 -05:00
parent 23036cb1dd
commit 811a32eb61
8 changed files with 82 additions and 44 deletions

View File

@@ -39,7 +39,7 @@ async function proxyToOrchestrator(
const { path } = await context.params; const { path } = await context.params;
const upstreamPath = `/${path.join("/")}`; const upstreamPath = `/${path.join("/")}`;
const search = request.nextUrl.search ?? ""; const search = request.nextUrl.search;
const upstreamUrl = `${getOrchestratorUrl()}${upstreamPath}${search}`; const upstreamUrl = `${getOrchestratorUrl()}${upstreamPath}${search}`;
const controller = new AbortController(); const controller = new AbortController();
@@ -57,15 +57,13 @@ async function proxyToOrchestrator(
headers["Content-Type"] = contentType; headers["Content-Type"] = contentType;
} }
const body = const hasBody = request.method !== "GET" && request.method !== "HEAD";
request.method !== "GET" && request.method !== "HEAD" const body = hasBody ? await request.text() : null;
? await request.text()
: undefined;
const upstream = await fetch(upstreamUrl, { const upstream = await fetch(upstreamUrl, {
method: request.method, method: request.method,
headers, headers,
body, ...(body !== null ? { body } : {}),
cache: "no-store", cache: "no-store",
signal: controller.signal, signal: controller.signal,
}); });
@@ -74,8 +72,7 @@ async function proxyToOrchestrator(
return new NextResponse(responseText, { return new NextResponse(responseText, {
status: upstream.status, status: upstream.status,
headers: { headers: {
"Content-Type": "Content-Type": upstream.headers.get("Content-Type") ?? "application/json",
upstream.headers.get("Content-Type") ?? "application/json",
}, },
}); });
} catch (error) { } catch (error) {

View File

@@ -158,7 +158,9 @@ async function fetchAuditLog(
} }
try { try {
return await apiGet<AuditLogResponse>(`/api/orchestrator/api/mission-control/audit-log?${params.toString()}`); return await apiGet<AuditLogResponse>(
`/api/orchestrator/api/mission-control/audit-log?${params.toString()}`
);
} catch (error) { } catch (error) {
if (isRateLimitError(error)) { if (isRateLimitError(error)) {
return createEmptyAuditLogResponse(page, "Rate limited - retrying..."); return createEmptyAuditLogResponse(page, "Rate limited - retrying...");

View File

@@ -59,9 +59,12 @@ describe("BargeInInput", (): void => {
await user.click(screen.getByRole("button", { name: "Send" })); await user.click(screen.getByRole("button", { name: "Send" }));
await waitFor((): void => { await waitFor((): void => {
expect(mockApiPost).toHaveBeenCalledWith("/api/orchestrator/api/mission-control/sessions/session-1/inject", { expect(mockApiPost).toHaveBeenCalledWith(
"/api/orchestrator/api/mission-control/sessions/session-1/inject",
{
content: "execute plan", content: "execute plan",
}); }
);
}); });
expect(onSent).toHaveBeenCalledTimes(1); expect(onSent).toHaveBeenCalledTimes(1);
@@ -83,12 +86,18 @@ describe("BargeInInput", (): void => {
const calls = mockApiPost.mock.calls as [string, unknown?][]; const calls = mockApiPost.mock.calls as [string, unknown?][];
expect(calls[0]).toEqual(["/api/orchestrator/api/mission-control/sessions/session-2/pause", undefined]); expect(calls[0]).toEqual([
"/api/orchestrator/api/mission-control/sessions/session-2/pause",
undefined,
]);
expect(calls[1]).toEqual([ expect(calls[1]).toEqual([
"/api/orchestrator/api/mission-control/sessions/session-2/inject", "/api/orchestrator/api/mission-control/sessions/session-2/inject",
{ content: "hello world" }, { content: "hello world" },
]); ]);
expect(calls[2]).toEqual(["/api/orchestrator/api/mission-control/sessions/session-2/resume", undefined]); expect(calls[2]).toEqual([
"/api/orchestrator/api/mission-control/sessions/session-2/resume",
undefined,
]);
}); });
it("submits with Enter and does not submit on Shift+Enter", async (): Promise<void> => { it("submits with Enter and does not submit on Shift+Enter", async (): Promise<void> => {
@@ -105,9 +114,12 @@ describe("BargeInInput", (): void => {
fireEvent.keyDown(textarea, { key: "Enter", code: "Enter", shiftKey: false }); fireEvent.keyDown(textarea, { key: "Enter", code: "Enter", shiftKey: false });
await waitFor((): void => { await waitFor((): void => {
expect(mockApiPost).toHaveBeenCalledWith("/api/orchestrator/api/mission-control/sessions/session-3/inject", { expect(mockApiPost).toHaveBeenCalledWith(
"/api/orchestrator/api/mission-control/sessions/session-3/inject",
{
content: "first", content: "first",
}); }
);
}); });
}); });

View File

@@ -177,9 +177,12 @@ describe("GlobalAgentRoster", (): void => {
fireEvent.click(screen.getByRole("button", { name: "Kill session killme12" })); fireEvent.click(screen.getByRole("button", { name: "Kill session killme12" }));
await waitFor((): void => { await waitFor((): void => {
expect(mockApiPost).toHaveBeenCalledWith("/api/orchestrator/api/mission-control/sessions/killme123456/kill", { expect(mockApiPost).toHaveBeenCalledWith(
"/api/orchestrator/api/mission-control/sessions/killme123456/kill",
{
force: false, force: false,
}); }
);
}); });
}); });

View File

@@ -118,9 +118,12 @@ export function GlobalAgentRoster({
const killMutation = useMutation({ const killMutation = useMutation({
mutationFn: async (sessionId: string): Promise<string> => { mutationFn: async (sessionId: string): Promise<string> => {
await apiPost<{ message: string }>(`/api/orchestrator/api/mission-control/sessions/${sessionId}/kill`, { await apiPost<{ message: string }>(
`/api/orchestrator/api/mission-control/sessions/${sessionId}/kill`,
{
force: false, force: false,
}); }
);
return sessionId; return sessionId;
}, },
onSuccess: (): void => { onSuccess: (): void => {

View File

@@ -112,14 +112,20 @@ describe("KillAllDialog", (): void => {
await user.click(screen.getByRole("button", { name: "Kill All Agents" })); await user.click(screen.getByRole("button", { name: "Kill All Agents" }));
await waitFor((): void => { await waitFor((): void => {
expect(mockApiPost).toHaveBeenCalledWith("/api/orchestrator/api/mission-control/sessions/internal-1/kill", { expect(mockApiPost).toHaveBeenCalledWith(
"/api/orchestrator/api/mission-control/sessions/internal-1/kill",
{
force: true, force: true,
}); }
);
}); });
expect(mockApiPost).not.toHaveBeenCalledWith("/api/orchestrator/api/mission-control/sessions/external-1/kill", { expect(mockApiPost).not.toHaveBeenCalledWith(
"/api/orchestrator/api/mission-control/sessions/external-1/kill",
{
force: true, force: true,
}); }
);
expect(onComplete).toHaveBeenCalledTimes(1); expect(onComplete).toHaveBeenCalledTimes(1);
}); });
@@ -141,12 +147,18 @@ describe("KillAllDialog", (): void => {
await user.click(screen.getByRole("button", { name: "Kill All Agents" })); await user.click(screen.getByRole("button", { name: "Kill All Agents" }));
await waitFor((): void => { await waitFor((): void => {
expect(mockApiPost).toHaveBeenCalledWith("/api/orchestrator/api/mission-control/sessions/internal-2/kill", { expect(mockApiPost).toHaveBeenCalledWith(
"/api/orchestrator/api/mission-control/sessions/internal-2/kill",
{
force: true, force: true,
}); }
expect(mockApiPost).toHaveBeenCalledWith("/api/orchestrator/api/mission-control/sessions/external-2/kill", { );
expect(mockApiPost).toHaveBeenCalledWith(
"/api/orchestrator/api/mission-control/sessions/external-2/kill",
{
force: true, force: true,
}); }
);
}); });
}); });

View File

@@ -96,9 +96,12 @@ export function KillAllDialog({ sessions, onComplete }: KillAllDialogProps): Rea
const killRequests = targetSessions.map(async (session) => { const killRequests = targetSessions.map(async (session) => {
try { try {
await apiPost<{ message: string }>(`/api/orchestrator/api/mission-control/sessions/${session.id}/kill`, { await apiPost<{ message: string }>(
`/api/orchestrator/api/mission-control/sessions/${session.id}/kill`,
{
force: true, force: true,
}); }
);
return true; return true;
} catch { } catch {
return false; return false;

View File

@@ -114,9 +114,12 @@ describe("PanelControls", (): void => {
await user.click(screen.getByRole("button", { name: "Confirm" })); await user.click(screen.getByRole("button", { name: "Confirm" }));
await waitFor((): void => { await waitFor((): void => {
expect(mockApiPost).toHaveBeenCalledWith("/api/orchestrator/api/mission-control/sessions/session-4/kill", { expect(mockApiPost).toHaveBeenCalledWith(
"/api/orchestrator/api/mission-control/sessions/session-4/kill",
{
force: false, force: false,
}); }
);
}); });
expect(onStatusChange).toHaveBeenCalledWith("killed"); expect(onStatusChange).toHaveBeenCalledWith("killed");
@@ -137,9 +140,12 @@ describe("PanelControls", (): void => {
await user.click(screen.getByRole("button", { name: "Confirm" })); await user.click(screen.getByRole("button", { name: "Confirm" }));
await waitFor((): void => { await waitFor((): void => {
expect(mockApiPost).toHaveBeenCalledWith("/api/orchestrator/api/mission-control/sessions/session-5/kill", { expect(mockApiPost).toHaveBeenCalledWith(
"/api/orchestrator/api/mission-control/sessions/session-5/kill",
{
force: true, force: true,
}); }
);
}); });
expect(onStatusChange).toHaveBeenCalledWith("killed"); expect(onStatusChange).toHaveBeenCalledWith("killed");