Skip to content

feat: run code-mode MCP in Vercel Sandbox - #2626

Open
shrey150 wants to merge 31 commits into
shrey/stg-2765-codemode-publishfrom
shrey/stg-2765-codemode-vercel
Open

feat: run code-mode MCP in Vercel Sandbox#2626
shrey150 wants to merge 31 commits into
shrey/stg-2765-codemode-publishfrom
shrey/stg-2765-codemode-vercel

Conversation

@shrey150

@shrey150 shrey150 commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

BLUF

Run the published Stagehand code-mode executable inside a Vercel Firecracker microVM and expose one framework-neutral, bearer-authenticated Streamable HTTP connection. Agent-framework adapters stay outside the VM and consume only { url, token, close }.

This PR now stacks on the package-publication PR, #2644.

Architecture

Agent framework / MCP client
  └─ bearer-authenticated Streamable HTTP
       └─ Vercel Sandbox exposed port
            └─ SHA-256 auth proxy (dedicated non-sudo user)
                 └─ stateful HTTP-to-stdio bridge (dedicated non-sudo user)
                      └─ installed stagehand-codemode executable
                           └─ generated JavaScript + Browserbase browser

The trusted host builds and packs the exact review checkout into @browserbasehq/stagehand and @browserbasehq/stagehand-codemode tarballs. It also creates an npm v3 lock for those local artifacts plus exact supergateway@3.4.3, rejects non-public registry sources, and uploads the complete artifact set. The guest verifies each uploaded SHA-256 digest and runs npm ci --ignore-scripts before lockdown. No guest-side Git checkout, branch/tag resolution, workspace install, pnpm activation, or monorepo build remains.

The helper then:

  • runs the stateful bridge and installed code-mode executable as stagehand-mcp;
  • runs the public-port auth proxy as a separate stagehand-proxy user;
  • discovers and validates the Browserbase project's regional CDP hostname;
  • replaces setup egress with only api.browserbase.com plus that exact CDP host;
  • brokers the real Browserbase API key into the outbound API header while the MCP process receives only a placeholder;
  • returns { url, token, close }, where close() idempotently attempts both stop and permanent delete.

The host keeps the random 32-byte bearer. The proxy bootstrap receives only its SHA-256 digest. Installed artifacts, dependencies, and bridge files become root-owned and read-only before generated JavaScript can run.

Security limits

  • Use one external MCP client/session per sandbox, then destroy the VM. Generated JavaScript can mutate the guest filesystem.
  • Authenticated standalone GET /mcp returns 405; Stagehand has no server-initiated notifications, so MCP calls stream over POST. Revisit this if the server adds unsolicited notifications.
  • The Vercel policy constrains guest-process egress, not navigation performed by the remote Browserbase browser.
  • Credential brokering prevents key disclosure but still grants the sandbox that key's Browserbase API capabilities. Use a separately scoped project/key.
  • AI-backed Stagehand methods require an explicit provider hostname and separately scoped credential. This example does not forward outer-agent model keys or broaden egress.
  • Artifact installation intentionally runs before lockdown. Production deployments can replace repeated setup with a separately reviewed image or snapshot.

The optional OCI image in #2643 remains a sibling optimization, not a dependency of this package-installed foundation.

E2E Test Matrix

Command / flow Observed output Confidence / sufficiency
pnpm check 9/9 tasks passed across formatting, lint, and typecheck Complete repository validation accepts the package-first sandbox and workflow.
pack:artifacts PASS; Stagehand 990,022 bytes, code mode 26,742 bytes, both SHA-256 identified; runtime manifest and 78,442-byte integrity lock generated Proves the exact review artifacts and immutable install plan are constructed on the trusted host.
Exact runtime npm ci --ignore-scripts from the generated lock 176 packages installed; both stagehand-codemode and supergateway executables present Proves the same clean install command used in the guest consumes the packed artifacts.
test:contract 3/3 passed: auth/abort behavior, lease failure lifecycle, invalid-artifact rejection Deterministic coverage for ingress, process cleanup, dynamic ports, cleared deadlines, and pre-provision artifact validation.
Local raw-MCP smoke Exactly code_execute; two calls retain browser state and PASS is emitted only after cleanup No-secret protocol/lifecycle proof. It does not by itself prove the cloud boundary.
Package-installed Vercel Sandbox + Browserbase workflow Required CI gate on this PR; uploads these exact artifacts, runs two stateful calls, checks auth 401/200, GET 405, unrelated-egress denial, credential brokering, host isolation, cross-user proxy isolation, and cleanup Final live proof for the package-backed microVM boundary; check result is tracked below by GitHub.
Earlier exact-head source-installed live run All boundary assertions passed at ec7a7ee1 Regression baseline only; the package-installed CI gate supersedes it as final evidence.

Changeset

No additional changeset. This PR adds a private integration example and CI coverage; #2644 carries the public package changeset.

@changeset-bot

changeset-bot Bot commented Aug 6, 2026

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: e3e70f2

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@shrey150 shrey150 closed this Aug 6, 2026
@shrey150 shrey150 reopened this Aug 6, 2026

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All reported issues were addressed

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread packages/integrations/examples/vercel/src/agent.ts Outdated
Comment thread packages/integrations/examples/vercel/src/e2e.ts Outdated
Comment thread .github/workflows/codemode-framework-examples.yml
Comment thread packages/integrations/examples/vercel/src/smoke.ts Outdated
Comment thread packages/integrations/examples/vercel/src/agent.ts Outdated
process.env.STAGEHAND_BROWSER ??= "local";

const result = await runStagehandAgent(
groq(process.env.VERCEL_STAGEHAND_MODEL ?? "openai/gpt-oss-120b"),

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

swap this to opus 5

@shrey150
shrey150 changed the base branch from shrey/stg-2765-codemode-guidance to shrey/stg-2765-codemode-sandbox August 8, 2026 00:11
@shrey150
shrey150 changed the base branch from shrey/stg-2765-codemode-sandbox to shrey/stg-2765-codemode-guidance August 8, 2026 00:36

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All reported issues were addressed across 8 files (changes from recent commits).

Tip: Review your code locally with the cubic CLI to iterate faster.

Re-trigger cubic

Comment thread packages/integrations/examples/vercel/src/e2e.ts Outdated
Comment thread packages/integrations/examples/vercel/src/smoke.ts Outdated
Comment thread packages/integrations/examples/vercel/src/agent.ts Outdated
Comment thread packages/integrations/examples/vercel/src/e2e.ts Outdated
Comment thread packages/integrations/examples/vercel/src/smoke.ts Outdated
Comment thread packages/integrations/examples/vercel/src/agent.ts Outdated

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 18 files (changes from recent commits).

Confidence score: 4/5

  • In packages/integrations/examples/e2b/src/smoke.ts, ignored teardown errors can let the smoke test pass even when MCP client close fails, creating a CI blind spot for cleanup regressions; this is the main risk because failures may accumulate unnoticed over time — surface and report close errors while preserving any primary test failure signal.
Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="packages/integrations/examples/e2b/src/smoke.ts">

<violation number="1" location="packages/integrations/examples/e2b/src/smoke.ts:54">
P3: Cleanup errors are currently ignored, so this smoke can report PASS even when MCP client teardown fails. Surfacing close failures (while still preserving primary test failures) would make CI catch cleanup regressions instead of masking them.</violation>
</file>

Tip: Review your code locally with the cubic CLI to iterate faster.

Re-trigger cubic

Comment thread packages/integrations/examples/e2b/src/sandbox.ts Outdated
Comment thread packages/integrations/examples/vercel-sandbox/src/smoke.ts
Comment thread packages/integrations/examples/e2b/src/sandbox.ts Outdated
Comment thread packages/integrations/examples/e2b/src/sandbox.ts Outdated
`${JSON.stringify({ status: "PASS", tools: ["code_execute"], statePersisted: true })}\n`,
);
} finally {
await client.close().catch(() => undefined);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P3: Cleanup errors are currently ignored, so this smoke can report PASS even when MCP client teardown fails. Surfacing close failures (while still preserving primary test failures) would make CI catch cleanup regressions instead of masking them.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/integrations/examples/e2b/src/smoke.ts, line 54:

<comment>Cleanup errors are currently ignored, so this smoke can report PASS even when MCP client teardown fails. Surfacing close failures (while still preserving primary test failures) would make CI catch cleanup regressions instead of masking them.</comment>

<file context>
@@ -0,0 +1,72 @@
+    `${JSON.stringify({ status: "PASS", tools: ["code_execute"], statePersisted: true })}\n`,
+  );
+} finally {
+  await client.close().catch(() => undefined);
+}
+
</file context>

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in e9c6682. The smoke now preserves the primary failure, surfaces cleanup-only failures, and emits PASS only after client.close() succeeds.

@shrey150 shrey150 changed the title feat(vercel): add Stagehand code-mode MCP example feat: run code-mode MCP in Vercel Sandbox Aug 8, 2026

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2 issues found across 16 files (changes from recent commits).

Confidence score: 4/5

  • In packages/integrations/examples/vercel-sandbox/src/sandbox.ts, a malformed successful /v1/sessions response can throw before sessionId is recorded, which risks leaving a billable Browserbase session undeleted — capture the returned id/connectUrl defensively and ensure cleanup still runs on parse/validation failures.
  • In packages/integrations/examples/vercel-sandbox/tsconfig.json, permitting .ts ESM specifiers can let this example drift from the repo’s .js-specifier convention, increasing runtime/loader mismatch risk outside TypeScript checks — keep TS extension imports constrained and preserve the .js specifier convention in emitted/imported paths.
Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="packages/integrations/examples/vercel-sandbox/tsconfig.json">

<violation number="1" location="packages/integrations/examples/vercel-sandbox/tsconfig.json:4">
P2: Typechecking now allows `.ts` ESM import specifiers, so this example can drift away from the repository’s `.js`-specifier convention and become loader-dependent at runtime. Consider keeping `allowImportingTsExtensions` disabled and switching relative imports to explicit `.js` specifiers.

(Based on your team's feedback about requiring explicit .js extensions for relative ESM imports.) .</violation>
</file>

<file name="packages/integrations/examples/vercel-sandbox/src/sandbox.ts">

<violation number="1" location="packages/integrations/examples/vercel-sandbox/src/sandbox.ts:291">
P2: If the POST `/v1/sessions` call succeeds (so Browserbase actually created a billable session) but the response body is malformed (missing a string `id` or `connectUrl`), the function throws before `sessionId` is assigned. Since the cleanup block is guarded by `if (sessionId)`, the just-created Browserbase session is never released with `REQUEST_RELEASE`, leaking a live/expensive session and its browser on an error path. Assign `sessionId` (or otherwise track the created session) before validating the shape so the cleanup path can still release it.</violation>
</file>

Tip: Review your code locally with the cubic CLI to iterate faster.

Re-trigger cubic

Comment thread packages/integrations/examples/vercel-sandbox/src/sandbox.ts Outdated
Comment thread packages/integrations/examples/vercel-sandbox/src/sandbox.ts Outdated
Comment thread packages/integrations/examples/vercel-sandbox/src/sandbox.ts Outdated
Comment thread packages/integrations/examples/vercel-sandbox/src/sandbox.ts Outdated
Comment thread packages/integrations/examples/vercel-sandbox/src/guest/stdio-wrapper.mjs Outdated
throw new Error(`Browserbase CDP host discovery returned ${response.status}`);
}
const session = (await response.json()) as { id?: unknown; connectUrl?: unknown };
if (typeof session.id !== "string" || typeof session.connectUrl !== "string") {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: If the POST /v1/sessions call succeeds (so Browserbase actually created a billable session) but the response body is malformed (missing a string id or connectUrl), the function throws before sessionId is assigned. Since the cleanup block is guarded by if (sessionId), the just-created Browserbase session is never released with REQUEST_RELEASE, leaking a live/expensive session and its browser on an error path. Assign sessionId (or otherwise track the created session) before validating the shape so the cleanup path can still release it.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/integrations/examples/vercel-sandbox/src/sandbox.ts, line 291:

<comment>If the POST `/v1/sessions` call succeeds (so Browserbase actually created a billable session) but the response body is malformed (missing a string `id` or `connectUrl`), the function throws before `sessionId` is assigned. Since the cleanup block is guarded by `if (sessionId)`, the just-created Browserbase session is never released with `REQUEST_RELEASE`, leaking a live/expensive session and its browser on an error path. Assign `sessionId` (or otherwise track the created session) before validating the shape so the cleanup path can still release it.</comment>

<file context>
@@ -0,0 +1,406 @@
+      throw new Error(`Browserbase CDP host discovery returned ${response.status}`);
+    }
+    const session = (await response.json()) as { id?: unknown; connectUrl?: unknown };
+    if (typeof session.id !== "string" || typeof session.connectUrl !== "string") {
+      throw new Error("Browserbase CDP host discovery returned an invalid session");
+    }
</file context>

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in e9c6682. A string session ID is retained immediately after decoding the response, before validating connectUrl, so malformed post-creation responses still take the REQUEST_RELEASE cleanup path whenever the API supplied a releasable ID.

Comment thread packages/integrations/examples/vercel-sandbox/src/guest/auth-proxy.mjs Outdated
Comment thread packages/integrations/examples/vercel-sandbox/src/lease.ts
Comment thread packages/integrations/examples/vercel-sandbox/src/guest/auth-proxy.mjs Outdated
Comment thread packages/integrations/examples/vercel-sandbox/src/e2e.ts

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All reported issues were addressed across 12 files (changes from recent commits).

Tip: Review your code locally with the cubic CLI to iterate faster.

Re-trigger cubic

Comment thread packages/integrations/examples/vercel-sandbox/src/lease.test.mjs Outdated
Comment thread packages/integrations/examples/vercel-sandbox/src/smoke.ts Outdated
Comment thread packages/integrations/examples/vercel-sandbox/src/guest/auth-proxy.test.mjs Outdated
Comment thread packages/integrations/examples/vercel-sandbox/src/guest/auth-proxy.test.mjs Outdated
… into shrey/stg-2765-codemode-vercel

# Conflicts:
#	packages/integrations/README.md

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All reported issues were addressed across 4 files (changes from recent commits).

Tip: Review your code locally with the cubic CLI to iterate faster.

Re-trigger cubic

Comment thread packages/integrations/examples/vercel-sandbox/src/guest/auth-proxy.test.mjs Outdated
@shrey150
shrey150 changed the base branch from shrey/stg-2765-codemode-guidance to shrey/stg-2765-codemode-publish August 8, 2026 03:17

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All reported issues were addressed across 12 files (changes from recent commits).

Tip: Review your code locally with the cubic CLI to iterate faster.

Re-trigger cubic

Comment thread packages/integrations/examples/vercel-sandbox/src/sandbox.ts
Comment thread packages/integrations/examples/vercel-sandbox/src/lease.ts Outdated
Comment thread .github/workflows/codemode-framework-examples.yml Outdated
Comment thread packages/integrations/examples/vercel-sandbox/README.md Outdated
Comment thread packages/integrations/examples/vercel-sandbox/scripts/pack-artifacts.mjs Outdated
Comment thread packages/integrations/examples/vercel-sandbox/src/sandbox.ts Outdated
@socket-security

socket-security Bot commented Aug 8, 2026

Copy link
Copy Markdown

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Addednpm/​@​vercel/​sandbox@​2.9.27110010099100
Addednpm/​supergateway@​3.4.39810010083100

View full report

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2 issues found across 10 files (changes from recent commits).

Confidence score: 4/5

  • In packages/integrations/examples/vercel-sandbox/src/sandbox.ts, the credential allowlist behavior isn’t protected by a regression test, so future changes could accidentally forward extra keys (like networkPolicy) to Sandbox.create and broaden what gets sent to the integration — add a mocked Sandbox.create test that asserts only teamId, projectId, and token are passed through.
  • In packages/integrations/examples/vercel-sandbox/src/sandbox.ts, the new non-string resolved guard lacks fixture coverage, which risks regressions where null/number/object values slip past validation or fail with the wrong error path before sandbox creation — add regression cases asserting StagehandPackageArtifactError for non-string resolved inputs.
Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="packages/integrations/examples/vercel-sandbox/src/sandbox.ts">

<violation number="1" location="packages/integrations/examples/vercel-sandbox/src/sandbox.ts:122">
P3: The credential allowlist has no regression test; add a mocked `Sandbox.create` case with an extra `networkPolicy` key and assert only `teamId`, `projectId`, and `token` are forwarded.

(Based on your team's feedback about allowlisting Sandbox credentials.)</violation>

<violation number="2" location="packages/integrations/examples/vercel-sandbox/src/sandbox.ts:521">
P3: The new non-string `resolved` rejection has no regression coverage; add `resolved: null` and numeric/object fixtures asserting `StagehandPackageArtifactError` before sandbox creation.

(Based on your team's feedback about adding unit tests for changed behavior.)</violation>
</file>

Tip: Review your code locally with the cubic CLI to iterate faster.

Re-trigger cubic

Comment thread packages/integrations/examples/vercel-sandbox/scripts/pack-artifacts.mjs Outdated
for (const entry of Object.values(lock.packages ?? {})) {
const resolved = entry.resolved;
if (
resolved !== undefined &&

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P3: The new non-string resolved rejection has no regression coverage; add resolved: null and numeric/object fixtures asserting StagehandPackageArtifactError before sandbox creation.

(Based on your team's feedback about adding unit tests for changed behavior.)

View Feedback: 1 2

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/integrations/examples/vercel-sandbox/src/sandbox.ts, line 521:

<comment>The new non-string `resolved` rejection has no regression coverage; add `resolved: null` and numeric/object fixtures asserting `StagehandPackageArtifactError` before sandbox creation.

(Based on your team's feedback about adding unit tests for changed behavior.) </comment>

<file context>
@@ -502,12 +509,22 @@ function assertRuntimeManifest(content: Buffer): void {
+  for (const entry of Object.values(lock.packages ?? {})) {
+    const resolved = entry.resolved;
+    if (
+      resolved !== undefined &&
+      (typeof resolved !== "string" ||
+        (!resolved.startsWith("file:") && !resolved.startsWith("https://registry.npmjs.org/")))
</file context>

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added in 63ddf585. The contract suite now exercises resolved: null, a number, and an object, and each case asserts the fixed StagehandPackageArtifactError before any sandbox creation path. The Vercel sandbox contract suite passes 10/10.

persistent: false,
networkPolicy: "allow-all",
tags: { purpose: "stagehand-codemode-mcp" },
...(vercelCredentials

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P3: The credential allowlist has no regression test; add a mocked Sandbox.create case with an extra networkPolicy key and assert only teamId, projectId, and token are forwarded.

(Based on your team's feedback about allowlisting Sandbox credentials.)

View Feedback: 1 2

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/integrations/examples/vercel-sandbox/src/sandbox.ts, line 122:

<comment>The credential allowlist has no regression test; add a mocked `Sandbox.create` case with an extra `networkPolicy` key and assert only `teamId`, `projectId`, and `token` are forwarded.

(Based on your team's feedback about allowlisting Sandbox credentials.) </comment>

<file context>
@@ -118,7 +119,13 @@ export async function createStagehandSandbox(
       networkPolicy: "allow-all",
       tags: { purpose: "stagehand-codemode-mcp" },
-      ...options.vercelCredentials,
+      ...(vercelCredentials
+        ? {
+            teamId: vercelCredentials.teamId,
</file context>

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added in 63ddf585. The new regression test passes an extra untrusted networkPolicy: "deny-all", mocks Sandbox.create, and proves only the allowlisted teamId, projectId, and token are forwarded while the trusted call-site policy remains allow-all and the trusted purpose tag is unchanged. The contract suite passes 10/10.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 2 files (changes from recent commits).

Confidence score: 5/5

  • In packages/integrations/examples/vercel-sandbox/scripts/pack-artifacts.mjs, the main risk is regression in failure sanitization: a future edit could re-expose raw execFileAsync stdout/stderr on wrapped command errors, potentially leaking noisy or sensitive subprocess output in failure paths — add a focused failing-subprocess test that asserts sanitized error output.
Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="packages/integrations/examples/vercel-sandbox/scripts/pack-artifacts.mjs">

<violation number="1" location="packages/integrations/examples/vercel-sandbox/scripts/pack-artifacts.mjs:99">
P3: Failure sanitization has no regression coverage: a future change can again expose `execFileAsync` stdout/stderr without a test failing. Add a focused subprocess test that forces a wrapped command failure and asserts only the fixed typed error/message is emitted.

(Based on your team's feedback about unit tests for new behavior.)</violation>
</file>

Tip: Review your code locally with the cubic CLI to iterate faster.

Re-trigger cubic

Comment thread packages/integrations/examples/vercel-sandbox/src/sandbox.test.ts
async function run(file, args, cwd) {
try {
return await execFileAsync(file, args, { cwd, maxBuffer: commandMaxBuffer });
} catch {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P3: Failure sanitization has no regression coverage: a future change can again expose execFileAsync stdout/stderr without a test failing. Add a focused subprocess test that forces a wrapped command failure and asserts only the fixed typed error/message is emitted.

(Based on your team's feedback about unit tests for new behavior.)

View Feedback

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/integrations/examples/vercel-sandbox/scripts/pack-artifacts.mjs, line 99:

<comment>Failure sanitization has no regression coverage: a future change can again expose `execFileAsync` stdout/stderr without a test failing. Add a focused subprocess test that forces a wrapped command failure and asserts only the fixed typed error/message is emitted.

(Based on your team's feedback about unit tests for new behavior.) </comment>

<file context>
@@ -86,7 +94,11 @@ function requiredArtifact(files, pattern) {
-  return execFileAsync(file, args, { cwd, maxBuffer: commandMaxBuffer });
+  try {
+    return await execFileAsync(file, args, { cwd, maxBuffer: commandMaxBuffer });
+  } catch {
+    throw new StagehandArtifactPackCommandError();
+  }
</file context>

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added in 35c15787. The command wrapper is now isolated in an importable module and a secret-free subprocess regression forces stderr containing a sentinel token, then asserts the fixed StagehandArtifactPackCommandError name/message and proves neither stdout nor stderr is attached. The sandbox suite passes 12/12, exact packing passes, and the workspace check passes 9/9.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All reported issues were addressed across 4 files (changes from recent commits).

Tip: Review your code locally with the cubic CLI to iterate faster.

Re-trigger cubic

Comment thread packages/integrations/examples/vercel-sandbox/src/pack-command.test.mjs Outdated
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant