( env: TestEnvironment, projectPath: string, branchName: string, runtimeConfig?: RuntimeConfig, waitForInit: boolean = false, isSSH: boolean = false )
| 253 | * Enhanced version that can wait for init hook completion (needed for runtime tests) |
| 254 | */ |
| 255 | export async function createWorkspaceWithInit( |
| 256 | env: TestEnvironment, |
| 257 | projectPath: string, |
| 258 | branchName: string, |
| 259 | runtimeConfig?: RuntimeConfig, |
| 260 | waitForInit: boolean = false, |
| 261 | isSSH: boolean = false |
| 262 | ): Promise<{ workspaceId: string; workspacePath: string; cleanup: () => Promise<void> }> { |
| 263 | const trunkBranch = await detectDefaultTrunkBranch(projectPath); |
| 264 | |
| 265 | // Trust the project so hooks and scripts can run during workspace creation |
| 266 | await trustProject(env, projectPath); |
| 267 | |
| 268 | const result = await env.orpc.workspace.create({ |
| 269 | projectPath, |
| 270 | branchName, |
| 271 | trunkBranch, |
| 272 | runtimeConfig, |
| 273 | }); |
| 274 | |
| 275 | if (!result.success) { |
| 276 | throw new Error(`Failed to create workspace: ${result.error}`); |
| 277 | } |
| 278 | |
| 279 | const workspaceId = result.metadata.id; |
| 280 | const workspacePath = result.metadata.namedWorkspacePath; |
| 281 | |
| 282 | // Wait for init hook to complete if requested |
| 283 | if (waitForInit) { |
| 284 | const initTimeout = isSSH ? SSH_INIT_WAIT_MS : INIT_HOOK_WAIT_MS; |
| 285 | |
| 286 | const collector = createStreamCollector(env.orpc, workspaceId); |
| 287 | collector.start(); |
| 288 | try { |
| 289 | await collector.waitForEvent("init-end", initTimeout); |
| 290 | } catch (err) { |
| 291 | // Init hook might not exist or might have already completed before we started waiting |
| 292 | // This is not necessarily an error - just log it |
| 293 | console.log( |
| 294 | `Note: init-end event not detected within ${initTimeout}ms (may have completed early)` |
| 295 | ); |
| 296 | } finally { |
| 297 | collector.stop(); |
| 298 | } |
| 299 | } |
| 300 | |
| 301 | const cleanup = async () => { |
| 302 | await env.orpc.workspace.remove({ workspaceId }); |
| 303 | }; |
| 304 | |
| 305 | return { workspaceId, workspacePath, cleanup }; |
| 306 | } |
| 307 | |
| 308 | /** |
| 309 | * Send message and wait for stream completion |
no test coverage detected