Skip to content

Conversation

@quanru
Copy link
Collaborator

@quanru quanru commented Jan 9, 2026

Summary

  • Add new ts-runner module for running TypeScript automation scripts directly from CLI
  • Implement AgentProxy class providing a simplified interface for browser automation
  • Support both CDP connection (connect to existing browser) and browser launch modes
  • Include comprehensive unit tests with 33 test cases covering all methods and edge cases

Test plan

  • Run pnpm run lint - passes with no errors
  • Run unit tests for ts-runner module - all 33 tests pass
  • Manual testing: run example scripts with midscene run examples/ai-todo.mts
  • Verify CDP connection mode with Chrome DevTools debugging enabled
  • Verify headless browser launch mode

@netlify
Copy link

netlify bot commented Jan 9, 2026

Deploy Preview for midscene ready!

Name Link
🔨 Latest commit 39ce6a9
🔍 Latest deploy log https://app.netlify.com/projects/midscene/deploys/6969f61ddeb5a300088ef8e1
😎 Deploy Preview https://deploy-preview-1754--midscene.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@quanru quanru marked this pull request as draft January 9, 2026 12:51
@quanru quanru force-pushed the feat/cli-ts-runner branch from 2632609 to 4045ba2 Compare January 9, 2026 12:53
@quanru quanru requested a review from Copilot January 9, 2026 12:53
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR introduces a TypeScript runner module for the CLI package that enables direct execution of TypeScript automation scripts from the command line. The implementation provides a simplified AgentProxy interface for browser automation with support for both CDP connections and browser launches.

Key changes:

  • New ts-runner module with AgentProxy class providing simplified browser automation APIs
  • CLI enhancement to detect and run TypeScript files using tsx
  • Support for both imperative (top-level await) and declarative (export-based) script styles

Reviewed changes

Copilot reviewed 15 out of 18 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
packages/cli/bin/midscene Enhanced CLI entry point to detect and run TypeScript files via tsx
packages/cli/src/ts-runner/agent-proxy.ts Core AgentProxy class implementing browser connection and AI automation methods
packages/cli/src/ts-runner/runner.ts Runner module that loads user scripts and manages agent lifecycle
packages/cli/src/ts-runner/types.ts Type definitions for CDP and Launch configurations
packages/cli/src/ts-runner/global.d.ts Global type declarations for user scripts
packages/cli/src/ts-runner/index.ts Module exports for ts-runner
packages/cli/package.json Added tsx and dotenv as dependencies, configured exports
packages/cli/rslib.config.ts Added build entries for ts-runner modules
packages/cli/tsconfig.json Added path alias and included examples directory
packages/cli/examples/*.mts Example automation scripts demonstrating usage patterns
packages/cli/tests/unit-test/ts-runner/*.test.ts Comprehensive unit tests with 33 test cases
pnpm-lock.yaml Updated lockfile with dotenv version consolidation
Files not reviewed (1)
  • pnpm-lock.yaml: Language not supported

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@quanru quanru force-pushed the feat/cli-ts-runner branch 2 times, most recently from b986c9e to d91da44 Compare January 9, 2026 14:30
@quanru quanru requested a review from Copilot January 9, 2026 15:35
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 15 out of 18 changed files in this pull request and generated 10 comments.

Files not reviewed (1)
  • pnpm-lock.yaml: Language not supported
Comments suppressed due to low confidence (1)

packages/cli/src/ts-runner/runner.ts:61

  • The runner.ts module has side effects on import - it immediately sets up process event handlers and calls run() at lines 21-33 and 57-61. This makes the module difficult to test and import safely. The auto-execution at line 57-61 will run whenever this module is imported, even in test environments. Consider separating the side-effect code into a separate entry point or making the module purely functional with explicit initialization.
config();

const agentInstance = new AgentProxy();
(globalThis as any).agent = agentInstance;

export async function cleanup(): Promise<void> {
  await agentInstance.destroy().catch(() => {});
}

process.on('beforeExit', cleanup);

process.on('uncaughtException', (error) => {
  console.error('Uncaught Exception:', error);
  cleanup().finally(() => process.exit(1));
});

process.on('unhandledRejection', (reason) => {
  console.error('Unhandled Rejection:', reason);
  cleanup().finally(() => process.exit(1));
});

export async function run(scriptPath?: string): Promise<void> {
  const path = scriptPath ?? process.argv[2];
  if (!path) {
    console.error('Usage: midscene <script.ts>');
    process.exit(1);
    return; // Required for test mocking where process.exit doesn't terminate
  }

  const absolutePath = resolve(process.cwd(), path);
  const userModule = (await import(absolutePath)) as UserScriptExports;

  if (userModule.launch) {
    await agentInstance.launch(userModule.launch);
  } else if (userModule.cdp) {
    await agentInstance.connect(userModule.cdp);
  }

  if (typeof userModule.run === 'function') {
    await userModule.run(agentInstance);
  }
}

// Auto-run when executed as entry point
run().catch((error) => {
  console.error(error);
  process.exit(1);
});


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 15 out of 18 changed files in this pull request and generated 10 comments.

Files not reviewed (1)
  • pnpm-lock.yaml: Language not supported

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@quanru quanru marked this pull request as ready for review January 12, 2026 08:01
quanru added 12 commits January 16, 2026 16:25
Add a new ts-runner module that enables running TypeScript automation scripts
directly from the CLI. The AgentProxy class provides a simplified interface
for browser automation with CDP connection or browser launch support.
- Use synchronous event handlers with .finally() for uncaughtException
  and unhandledRejection to ensure cleanup completes before exit
- Remove unused runnerModule variables in runner.test.ts
- Add cleanup before connect/launch to prevent connection leaks
- Add WebSocket URL validation (ws:// or wss://)
- Add explicit null check in createAgent instead of non-null assertion
- Log errors in cleanup function instead of silent catch
- Improve Chrome connection error message with documentation link
- Add warning when both launch and cdp exports are present
- Add test cases for URL validation and cleanup behavior
…onvention

Users can now call agent.launch() or agent.connect() directly inside
their run function, instead of exporting launch/cdp config separately.

Before:
  export const launch = { headed: true };
  export async function run(agent) { ... }

After:
  export async function run(agent) {
    await agent.launch({ headed: true });
    ...
  }

This provides more flexibility and a cleaner API for users.
The run function now uses the global agent variable instead of receiving
it as a parameter. This unifies the API with top-level await style.

Before:
  export async function run(agent: AgentProxy) {
    await agent.launch({...});
  }

After:
  export async function run() {
    await agent.launch({...});  // uses global agent
  }
… scripts and improve error handling in agent connection
Simplified script-basic.mts to only use agent.aiAct() instead of
accessing agent.page directly. This prevents "Cannot read properties
of undefined" errors in CI when the mock agent doesn't have a page
property.
@quanru quanru force-pushed the feat/cli-ts-runner branch from a7bb2b7 to 39ce6a9 Compare January 16, 2026 08:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants