WIP: workspace execution refactor + notification routing + setup store updates

This commit is contained in:
Mohamed Boudra
2026-04-01 21:28:07 +07:00
parent d8243bfb72
commit a7d5ab2497
29 changed files with 1064 additions and 197 deletions
@@ -180,6 +180,7 @@ export type CreateAgentRequestOptions = {
config?: AgentSessionConfig;
provider?: AgentProvider;
cwd?: string;
workspaceId?: number;
initialPrompt?: string;
clientMessageId?: string;
outputSchema?: Record<string, unknown>;
@@ -1383,6 +1384,7 @@ export class DaemonClient {
type: "create_agent_request",
requestId,
config,
...(typeof options.workspaceId === "number" ? { workspaceId: options.workspaceId } : {}),
...(options.initialPrompt ? { initialPrompt: options.initialPrompt } : {}),
...(options.clientMessageId ? { clientMessageId: options.clientMessageId } : {}),
...(options.outputSchema ? { outputSchema: options.outputSchema } : {}),
@@ -3633,6 +3635,7 @@ function resolveAgentConfig(options: CreateAgentRequestOptions): AgentSessionCon
config,
provider,
cwd,
workspaceId: _workspaceId,
initialPrompt: _initialPrompt,
images: _images,
git: _git,
+1 -1
View File
@@ -2522,7 +2522,7 @@ export class Session {
);
await this.forwardAgentUpdate(snapshot);
if (sessionConfig.terminal) {
void this.emitInitialTerminalsChangedSnapshot(sessionConfig.cwd);
void this.emitInitialTerminalsChangedSnapshot(resolvedWorkspace.directory);
}
if (requestId) {
@@ -630,6 +630,108 @@ describe("workspace aggregation", () => {
});
});
test("create_agent_request uses workspaceId as the execution authority", async () => {
const { session, emitted, projects, workspaces } = createSessionForWorkspaceTests();
seedProject({
projects,
id: 5,
directory: "/tmp/repo",
displayName: "repo",
kind: "git",
});
seedWorkspace({
workspaces,
id: 50,
projectId: 5,
directory: "/tmp/repo/.paseo/worktrees/feature",
displayName: "feature",
kind: "worktree",
});
const createdAgent = makeAgent({
id: "agent-1",
cwd: "/tmp/repo/.paseo/worktrees/feature",
status: "idle",
updatedAt: "2026-03-01T12:00:00.000Z",
});
const createAgent = vi.fn(async () => createdAgent as any);
(session as any).agentManager = {
createAgent,
getAgent: vi.fn(() => createdAgent as any),
};
(session as any).forwardAgentUpdate = vi.fn(async () => undefined);
(session as any).getAgentPayloadById = vi.fn(async () => createdAgent);
(session as any).buildAgentSessionConfig = vi.fn(async (config: any) => ({
sessionConfig: config,
worktreeConfig: null,
}));
await (session as any).handleCreateAgentRequest({
type: "create_agent_request",
requestId: "req-create-agent",
workspaceId: 50,
config: {
provider: "codex",
cwd: "/tmp/repo",
modeId: "default",
},
labels: {},
});
expect(createAgent).toHaveBeenCalledWith(
expect.objectContaining({
cwd: "/tmp/repo/.paseo/worktrees/feature",
}),
undefined,
expect.objectContaining({
workspaceId: 50,
}),
);
const response = emitted.find((message) => message.type === "status") as any;
expect(response?.payload).toMatchObject({
status: "agent_created",
requestId: "req-create-agent",
agent: {
cwd: "/tmp/repo/.paseo/worktrees/feature",
},
});
});
test("create_agent_request fails for an unknown workspaceId", async () => {
const { session, emitted } = createSessionForWorkspaceTests();
const createAgent = vi.fn();
(session as any).agentManager = {
createAgent,
getAgent: vi.fn(() => null),
};
(session as any).buildAgentSessionConfig = vi.fn(async (config: any) => ({
sessionConfig: config,
worktreeConfig: null,
}));
await (session as any).handleCreateAgentRequest({
type: "create_agent_request",
requestId: "req-create-agent-fail",
workspaceId: 999,
config: {
provider: "codex",
cwd: "/tmp/repo",
modeId: "default",
},
labels: {},
});
expect(createAgent).not.toHaveBeenCalled();
const response = emitted.find((message) => message.type === "status") as any;
expect(response?.payload).toMatchObject({
status: "agent_create_failed",
requestId: "req-create-agent-fail",
});
expect((response?.payload as any)?.error).toContain("Workspace not found: 999");
});
test("open_project_request creates git projects with GitHub owner/repo and branch names", async () => {
const { session, emitted, projects, workspaces } = createSessionForWorkspaceTests();
const { tempDir, repoDir } = createTempGitRepo({
@@ -573,6 +573,13 @@ export async function handleCreatePaseoWorktreeRequest(
worktreePath,
branchName: normalizedSlug,
});
await createAgentWorktree({
cwd: repoRoot,
branchName: normalizedSlug,
baseBranch,
worktreeSlug: normalizedSlug,
paseoHome: dependencies.paseoHome,
});
const descriptor = await dependencies.describeWorkspaceRecord(workspace);
dependencies.emit({
type: "create_paseo_worktree_response",
@@ -622,14 +629,6 @@ export async function createPaseoWorktreeInBackground(
let setupTerminalId: string | null = null;
try {
await createAgentWorktree({
cwd: options.repoRoot,
branchName: options.slug,
baseBranch: options.baseBranch,
worktreeSlug: options.slug,
paseoHome: dependencies.paseoHome,
});
const setupCommands = getWorktreeSetupCommands(options.worktreePath);
if (setupCommands.length > 0 && dependencies.terminalManager) {
const runtimeEnv = await resolveWorktreeRuntimeEnv({