diff --git a/apps/agent-worker/README.md b/apps/agent-worker/README.md index 2b378520..2277f4c8 100644 --- a/apps/agent-worker/README.md +++ b/apps/agent-worker/README.md @@ -41,10 +41,10 @@ small current/version namespace records and mirrors the current version to `/workspace//uploads/` on the user's persistent Daytona volume before exposing it. An exact replay is idempotent; uploading new bytes at the same path creates a retained version and updates the working copy. First-run app scaffolding preserves the `uploads/` directory, and restored -template projects reuse their persistent dependency installation instead of rebuilding the -workspace. Project deletion removes the namespace during fenced workspace cleanup and the existing -resource-deletion prefix sweep removes every immutable object. Account deletion clears both through -the existing account state and R2 lifecycle phases. +template projects reuse a complete persistent dependency installation or repair an interrupted one +instead of rebuilding the workspace. Project deletion removes the namespace during fenced workspace +cleanup and the existing resource-deletion prefix sweep removes every immutable object. Account +deletion clears both through the existing account state and R2 lifecycle phases. Run creation validates the gateway payload with the shared `CreateRunSchema` from `packages/types` before selecting the run-scoped `AgentRun` Durable Object. The diff --git a/apps/agent-worker/src/durable-objects/agent-run-app-builder-scaffold.ts b/apps/agent-worker/src/durable-objects/agent-run-app-builder-scaffold.ts index 51e0b317..8c4dd27e 100644 --- a/apps/agent-worker/src/durable-objects/agent-run-app-builder-scaffold.ts +++ b/apps/agent-worker/src/durable-objects/agent-run-app-builder-scaffold.ts @@ -84,13 +84,13 @@ export async function installAppBuilderDependencies( dir: string, mobile = false, ): Promise { - const networkTimeoutMs = mobile ? 300_000 : 120_000; + const installTimeoutMs = mobile ? 300_000 : 120_000; try { await executeShellExec( { command: ["pnpm", "install", "--frozen-lockfile", "--offline"], cwd: dir, - timeoutMs: 120_000, + timeoutMs: installTimeoutMs, }, { sandbox }, ); @@ -111,7 +111,7 @@ export async function installAppBuilderDependencies( "4", ], cwd: dir, - timeoutMs: networkTimeoutMs, + timeoutMs: installTimeoutMs, }, { sandbox }, ); diff --git a/apps/agent-worker/src/durable-objects/agent-run-app-builder.ts b/apps/agent-worker/src/durable-objects/agent-run-app-builder.ts index 9ebec791..f97d18f8 100644 --- a/apps/agent-worker/src/durable-objects/agent-run-app-builder.ts +++ b/apps/agent-worker/src/durable-objects/agent-run-app-builder.ts @@ -196,7 +196,7 @@ async function prepareTemplateWorkspace( setRunStage(mobile ? "Preparing the Expo workspace." : "Preparing the Next.js workspace."); if (!shouldBootstrap) { setRunStage("Restoring the app workspace."); - if (!(await hasInstalledAppBuilderDependencies(sandbox, workspace.dir))) { + if (!(await hasInstalledAppBuilderDependencies(sandbox, workspace.dir, mobile))) { await installAppBuilderDependencies(sandbox, logger, workspace.dir, mobile); } if (mobile) { @@ -599,10 +599,19 @@ async function hasExistingAppBuilderWorkspace( async function hasInstalledAppBuilderDependencies( sandbox: ProjectSandboxStub, dir: string, + mobile: boolean, ): Promise { + const requiredPaths = mobile + ? [ + "node_modules/.pnpm", + "node_modules/@expo/metro-runtime", + "node_modules/react-dom", + "node_modules/react-native-web", + ] + : ["node_modules/.pnpm", "node_modules/next", "node_modules/react", "node_modules/react-dom"]; const result = await executeShellTerminal( { - command: `test -d ${dir}/node_modules/.pnpm`, + command: requiredPaths.map((path) => `test -d ${dir}/${path}`).join(" && "), cwd: "/workspace", timeoutMs: 10_000, },