testdriverai 7.9.56-test → 7.9.57-test

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,77 @@
1
+ /**
2
+ * Utilities for resolving TestDriver environment variables.
3
+ *
4
+ * These helpers centralise the "param > env var > default" fallback logic
5
+ * so the server handler stays clean and the logic can be unit-tested
6
+ * independently.
7
+ */
8
+
9
+ // ============================================================
10
+ // OS resolution
11
+ // ============================================================
12
+
13
+ const VALID_OS_VALUES = ["linux", "windows"] as const;
14
+ export type SandboxOs = (typeof VALID_OS_VALUES)[number];
15
+
16
+ /**
17
+ * Resolve the sandbox OS with the following priority:
18
+ * 1. Explicit `os` parameter passed to session_start
19
+ * 2. `TD_OS` environment variable (validated against supported values)
20
+ * 3. `"linux"` default
21
+ *
22
+ * Mirrors the behaviour in `hooks.mjs` so the MCP server and the
23
+ * Vitest integration are consistent.
24
+ *
25
+ * @param explicitOs - The value passed explicitly by the caller (may be undefined)
26
+ * @param env - The environment variables map (defaults to `process.env`)
27
+ * @returns - The resolved OS and a warning message if TD_OS was invalid
28
+ */
29
+ export function resolveOs(
30
+ explicitOs: SandboxOs | undefined,
31
+ env: NodeJS.ProcessEnv = process.env,
32
+ ): { os: SandboxOs; warning?: string } {
33
+ if (explicitOs) {
34
+ return { os: explicitOs };
35
+ }
36
+
37
+ const envOs = env.TD_OS;
38
+ if (envOs) {
39
+ if ((VALID_OS_VALUES as readonly string[]).includes(envOs)) {
40
+ return { os: envOs as SandboxOs };
41
+ }
42
+ return {
43
+ os: "linux",
44
+ warning: `TD_OS has unsupported value "${envOs}" (supported: ${VALID_OS_VALUES.join(", ")}), ignoring`,
45
+ };
46
+ }
47
+
48
+ return { os: "linux" };
49
+ }
50
+
51
+ // ============================================================
52
+ // E2B template ID resolution
53
+ // ============================================================
54
+
55
+ /**
56
+ * Resolve the E2B template ID with the following priority:
57
+ * 1. Explicit `e2bTemplateId` parameter passed to session_start
58
+ * 2. `TD_E2B_TEMPLATE_ID` environment variable
59
+ * 3. `undefined` (let the SDK use its own default)
60
+ *
61
+ * Mirrors the behaviour in `hooks.mjs`:
62
+ * ```js
63
+ * if (!config.e2bTemplateId && process.env.TD_E2B_TEMPLATE_ID) {
64
+ * config.e2bTemplateId = process.env.TD_E2B_TEMPLATE_ID;
65
+ * }
66
+ * ```
67
+ *
68
+ * @param explicitId - The value passed explicitly by the caller (may be undefined)
69
+ * @param env - The environment variables map (defaults to `process.env`)
70
+ * @returns - The resolved template ID, or undefined if none is set
71
+ */
72
+ export function resolveE2bTemplateId(
73
+ explicitId: string | undefined,
74
+ env: NodeJS.ProcessEnv = process.env,
75
+ ): string | undefined {
76
+ return explicitId || env.TD_E2B_TEMPLATE_ID;
77
+ }
@@ -143,7 +143,7 @@ export const SessionStartInputSchema = z.object({
143
143
 
144
144
  // Common session options
145
145
  /** Operating system for the sandbox */
146
- os: z.enum(["linux", "windows"]).default("linux").describe("Sandbox OS"),
146
+ os: z.enum(["linux", "windows"]).optional().describe("Sandbox OS (default: 'linux', or TD_OS environment variable if set)"),
147
147
  /** Keep sandbox alive duration in ms (default: 5 minutes) */
148
148
  keepAlive: z.number().default(300000).describe("Keep sandbox alive for this many ms"),
149
149
  /** Path to test file - when provided, you MUST append generated code to this file after each action */
@@ -157,6 +157,9 @@ export const SessionStartInputSchema = z.object({
157
157
  /** Direct IP address of self-hosted instance (bypasses cloud provisioning) */
158
158
  ip: z.string().optional().describe("Direct IP address of self-hosted Windows instance (e.g., from AWS). When provided, connects directly to this IP instead of using cloud provisioning."),
159
159
 
160
+ /** E2B sandbox template ID (overrides TD_E2B_TEMPLATE_ID env var) */
161
+ e2bTemplateId: z.string().optional().describe("E2B sandbox template ID. Overrides the TD_E2B_TEMPLATE_ID environment variable when provided."),
162
+
160
163
  // Debug mode - connect to existing sandbox
161
164
  /** Sandbox ID to connect to (for debug-on-failure mode). When provided, connects to an existing sandbox instead of creating a new one. Skip provisioning. */
162
165
  sandboxId: z.string().optional().describe("Existing sandbox ID to connect to (from debug-on-failure mode). Skips provisioning."),
@@ -22,6 +22,7 @@ import { fileURLToPath, pathToFileURL } from "url";
22
22
  import { z } from "zod";
23
23
 
24
24
  import { generateActionCode } from "./codegen.js";
25
+ import { resolveE2bTemplateId, resolveOs } from "./env-utils.js";
25
26
  import { getProvisionOptions, SessionStartInputSchema, type SessionStartInput } from "./provision-types.js";
26
27
  import { sessionManager, type SessionState } from "./session.js";
27
28
 
@@ -525,10 +526,27 @@ Debug mode (connect to existing sandbox):
525
526
  },
526
527
  async (params: SessionStartInput): Promise<CallToolResult> => {
527
528
  const startTime = Date.now();
529
+
530
+ // Resolve OS with priority: explicit param > TD_OS env var > "linux" default
531
+ // This mirrors the behavior of the Vitest hooks (hooks.mjs) which also reads TD_OS
532
+ const { os: resolvedOs, warning: osWarning } = resolveOs(params.os);
533
+ if (osWarning) {
534
+ logger.warn(`session_start: ${osWarning}`);
535
+ } else if (!params.os && resolvedOs !== "linux") {
536
+ logger.info("session_start: Using TD_OS environment variable", { os: resolvedOs });
537
+ }
538
+
539
+ // Resolve E2B template ID with priority: explicit param > TD_E2B_TEMPLATE_ID env var
540
+ // This mirrors the behavior of the Vitest hooks (hooks.mjs) which also reads TD_E2B_TEMPLATE_ID
541
+ const resolvedE2bTemplateId = resolveE2bTemplateId(params.e2bTemplateId);
542
+ if (!params.e2bTemplateId && resolvedE2bTemplateId) {
543
+ logger.info("session_start: Using TD_E2B_TEMPLATE_ID environment variable", { e2bTemplateId: resolvedE2bTemplateId });
544
+ }
545
+
528
546
  logger.info("session_start: Starting", {
529
547
  type: params.type,
530
548
  url: params.url,
531
- os: params.os,
549
+ os: resolvedOs,
532
550
  reconnect: params.reconnect,
533
551
  sandboxId: params.sandboxId,
534
552
  });
@@ -546,7 +564,7 @@ Debug mode (connect to existing sandbox):
546
564
 
547
565
  // Create new session
548
566
  const newSession = sessionManager.createSession({
549
- os: params.os,
567
+ os: resolvedOs,
550
568
  keepAlive: params.keepAlive,
551
569
  testFile: params.testFile,
552
570
  });
@@ -592,11 +610,12 @@ Debug mode (connect to existing sandbox):
592
610
  });
593
611
 
594
612
  sdk = new TestDriverSDK(apiKey, {
595
- os: params.os,
613
+ os: resolvedOs,
596
614
  logging: false,
597
615
  apiRoot,
598
616
  preview: previewMode as "browser" | "ide" | "none",
599
617
  ip: instanceIp,
618
+ e2bTemplateId: resolvedE2bTemplateId,
600
619
  });
601
620
 
602
621
  // Handle sandboxId mode - connect to existing sandbox (debug-on-failure mode)
@@ -12,5 +12,5 @@
12
12
  "resolveJsonModule": true
13
13
  },
14
14
  "include": ["src/**/*"],
15
- "exclude": ["node_modules", "dist", "src/mcp-app.ts", "src/mcp-app.css"]
15
+ "exclude": ["node_modules", "dist", "src/mcp-app.ts", "src/mcp-app.css", "src/**/*.test.ts"]
16
16
  }
@@ -0,0 +1,7 @@
1
+ import { defineConfig } from "vitest/config";
2
+
3
+ export default defineConfig({
4
+ test: {
5
+ include: ["src/**/*.test.ts"],
6
+ },
7
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "testdriverai",
3
- "version": "7.9.56-test",
3
+ "version": "7.9.57-test",
4
4
  "description": "Next generation autonomous AI agent for end-to-end testing of web & desktop",
5
5
  "main": "sdk.js",
6
6
  "types": "sdk.d.ts",