Fix Foundry UI bugs: org names, hanging sessions, and wrong repo creation

- Fix org display name using GitHub description instead of name field
- Fix createWorkbenchSession hanging when sandbox is provisioning
- Fix auto-session creation retry storm on errors
- Fix task creation using wrong repo due to React state race conditions
- Remove Bun hot-reload from backend Dockerfile (causes port drift)
- Add GitHub sync/install status to dev panel

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
This commit is contained in:
Nathan Flurry 2026-03-13 20:46:50 -07:00
parent 14d5413f8a
commit 689d968397
17 changed files with 2569 additions and 479 deletions

View file

@ -168,12 +168,16 @@ const commandHandlers: Record<TaskQueueName, WorkflowHandler> = {
},
"task.command.workbench.create_session": async (loopCtx, msg) => {
const created = await loopCtx.step({
name: "workbench-create-session",
timeout: 30_000,
run: async () => createWorkbenchSession(loopCtx, msg.body?.model),
});
await msg.complete(created);
try {
const created = await loopCtx.step({
name: "workbench-create-session",
timeout: 30_000,
run: async () => createWorkbenchSession(loopCtx, msg.body?.model),
});
await msg.complete(created);
} catch (error) {
await msg.complete({ error: resolveErrorMessage(error) });
}
},
"task.command.workbench.ensure_session": async (loopCtx, msg) => {

View file

@ -636,6 +636,12 @@ export async function syncGithubOrganizationRepos(c: any, input: { sessionId: st
installationStatus,
lastSyncLabel: repositories.length > 0 ? "Synced just now" : "No repositories available",
});
// Broadcast updated app snapshot so connected clients see the new repos
c.broadcast("appUpdated", {
type: "appUpdated",
snapshot: await buildAppSnapshot(c, input.sessionId),
});
} catch (error) {
const installationStatus =
error instanceof GitHubAppError && (error.status === 403 || error.status === 404)
@ -645,6 +651,12 @@ export async function syncGithubOrganizationRepos(c: any, input: { sessionId: st
message: error instanceof Error ? error.message : "GitHub import failed",
installationStatus,
});
// Broadcast sync failure so the client updates status
c.broadcast("appUpdated", {
type: "appUpdated",
snapshot: await buildAppSnapshot(c, input.sessionId),
});
}
}

View file

@ -2,4 +2,5 @@ import { createFoundryLogger } from "@sandbox-agent/foundry-shared";
export const logger = createFoundryLogger({
service: "foundry-backend",
format: "logfmt",
});

View file

@ -262,11 +262,11 @@ export class GitHubAppClient {
}
async listOrganizations(accessToken: string): Promise<GitHubOrgIdentity[]> {
const organizations = await this.paginate<{ id: number; login: string; description?: string | null }>("/user/orgs?per_page=100", accessToken);
const organizations = await this.paginate<{ id: number; login: string; name?: string | null }>("/user/orgs?per_page=100", accessToken);
return organizations.map((organization) => ({
id: String(organization.id),
login: organization.login,
name: organization.description?.trim() || organization.login,
name: organization.name?.trim() || organization.login,
}));
}