Keep setup execution and output owned by the workspace (#7473)

* perf(workspaces): stop duplicating setup output in progress snapshots

Keep the required combined log field empty for setup clients, which display per-command output. Preserve concatenation only for legacy agent bootstrap timeline cards whose released renderers still read it directly.

* refactor(workspaces): own setup exclusively at the workspace boundary

Preserve keyed modern agent worktree creation while retiring legacy placement that selected an agent-owned setup lifecycle. Keep output in per-command workspace snapshots and retain empty strings required by existing wire schemas.

* fix(server): avoid duplicate cwd in worktree provisioning request

* test(e2e): keep developer toasts out of concurrent app assertions

Concurrent layout measurements could invoke the same Playwright locator handler before its first dismissal finished, leaving checks waiting for a removed button. Hide only the Expo toast host through test styling while retaining console error capture.
This commit is contained in:
Mohamed Boudra
2026-10-21 14:16:24 +07:00
committed by GitHub
parent a891155b82
commit fbd90cb88d
52 changed files with 869 additions and 3459 deletions
@@ -474,3 +474,54 @@ test("usage entries accept older failures and additive successful snapshots", ()
}).success,
).toBe(false);
});
// Frozen setup detail shape from v0.8.0: log is required, command output is optional.
const ReleasedSetupDetailSchema = z.object({
type: z.literal("worktree_setup"),
worktreePath: z.string(),
branchName: z.string(),
log: z.string(),
commands: z.array(
z.object({
index: z.number().int().positive(),
command: z.string(),
cwd: z.string(),
log: z.string().optional().default(""),
status: z.enum(["running", "completed", "failed"]),
exitCode: z.number().nullable(),
durationMs: z.number().nonnegative().optional(),
}),
),
truncated: z.boolean().optional(),
});
test("released setup clients parse empty combined logs and retain command output", () => {
const detail = {
type: "worktree_setup",
worktreePath: "/workspace",
branchName: "feature",
log: "",
commands: [
{
index: 1,
command: "echo ready",
cwd: "/workspace",
log: "ready\n",
status: "completed",
exitCode: 0,
},
],
};
const parsed = ReleasedSetupDetailSchema.parse(JSON.parse(JSON.stringify(detail)));
expect(parsed).toEqual(detail);
expect(parsed.commands[0]?.log).toBe("ready\n");
const { log: _log, ...withoutLegacyField } = detail;
expect(ReleasedSetupDetailSchema.safeParse(withoutLegacyField).success).toBe(false);
expect(
WorkspaceSetupSnapshotSchema.parse({
status: "completed",
detail: { ...detail, log: "old daemon combined output" },
error: null,
}).detail.log,
).toBe("old daemon combined output");
});