(params: WorkspaceCreationParams)
| 417 | } |
| 418 | |
| 419 | async createWorkspace(params: WorkspaceCreationParams): Promise<WorkspaceCreationResult> { |
| 420 | const { projectPath, directoryName } = params; |
| 421 | |
| 422 | // Container identity should follow the workspace entry name rather than the git branch. |
| 423 | // The two are usually equal today, but the runtime contract keeps them distinct. |
| 424 | const containerName = getContainerName(projectPath, directoryName); |
| 425 | |
| 426 | // Check if container already exists (collision detection) |
| 427 | const checkResult = await runDockerCommand(`docker inspect ${containerName}`, 10000); |
| 428 | if (checkResult.exitCode === 0) { |
| 429 | return { |
| 430 | success: false, |
| 431 | error: `Workspace already exists: container ${containerName}`, |
| 432 | }; |
| 433 | } |
| 434 | // Distinguish "container doesn't exist" from actual Docker errors |
| 435 | if (!checkResult.stderr.toLowerCase().includes("no such object")) { |
| 436 | return { |
| 437 | success: false, |
| 438 | error: `Docker error: ${checkResult.stderr || checkResult.stdout || "unknown error"}`, |
| 439 | }; |
| 440 | } |
| 441 | |
| 442 | // Store container name - actual container creation happens in postCreateSetup |
| 443 | // so that image pull progress is visible in the init section |
| 444 | this.containerName = containerName; |
| 445 | |
| 446 | return { |
| 447 | success: true, |
| 448 | workspacePath: CONTAINER_SRC_DIR, |
| 449 | }; |
| 450 | } |
| 451 | |
| 452 | /** |
| 453 | * Post-create setup: provision container OR detect fork and setup credentials. |
nothing calls this directly
no test coverage detected