Skill: panchenbo/browser-opener-skill (version 1.0.0)

--- name: browser-opener description: Cross-platform browser opening skill that supports multiple browsers (Chrome, Firefox, Edge, Safari) with URL launching capabilities. Use when Codex needs to open web browsers programmatically for: (1) Launching default browser, (2) Opening specific browsers, (3) Opening URLs with default browser, (4) Opening URLs with specific browsers, (5) Cross-platform browser automation --- # Browser Opener Skill This skill provides cross-platform browser opening capabilities with support for multiple browsers. ## Quick Start Open a URL with the default browser: ```python # Using the browser opener script python scripts/open_browser.py --url https://www.google.com ``` Open a URL with a specific browser: ```python # Open with Chrome python scripts/open_browser.py --url https://www.google.com --browser chrome # Open with Firefox python scripts/open_browser.py --url https://www.google.com --browser firefox # Open with Edge python scripts/open_browser.py --url https://www.google.com --browser edge ``` ## Supported Browsers - **Chrome**: `chrome`, `google-chrome`, `google-chrome-stable` - **Firefox**: `firefox`, `mozilla-firefox` - **Edge**: `edge`, `microsoft-edge` - **Safari**: `safari`, `apple-safari` - **Default**: `default` (uses system default browser) ## Usage Examples See [examples/](examples/) for comprehensive usage examples including: - Basic URL opening - Browser-specific launching - Batch opening multiple URLs - Error handling scenarios ## Browser Support Details For detailed information about browser support on different platforms, see [references/browser_support.md](references/browser_support.md). ## Command Line Options The `scripts/open_browser.py` script supports the following options: - `--url`: URL to open (required) - `--browser`: Browser to use (optional, defaults to 'default') - `--new-window`: Open in new window (optional) - `--incognito`: Open in incognito/private mode (optional) - `--headless`: Open in headless mode (optional, for testing) ## Error Handling The script includes comprehensive error handling for: - Invalid URLs - Browser not found - Permission issues - Platform-specific errors

path: examples/basic_usage.py
content: #!/usr/bin/env python3
"""
Basic usage examples for the browser opener skill.
"""

import sys
import os
sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
from scripts.open_browser import BrowserOpener

def main():
    opener = BrowserOpener()
    
    # Example 1: Open URL with default browser
    print("Opening Google with default browser...")
    opener.open_url("https://www.google.com")
    
    # Example 2: Open URL with Chrome
    print("Opening Google with Chrome...")
    opener.open_url("https://www.google.com", browser_name="chrome")
    
    # Example 3: Open URL with Firefox in private mode
    print("Opening Google with Firefox in private mode...")
    opener.open_url("https://www.google.com", browser_name="firefox", incognito=True)
    
    # Example 4: Open URL with Edge in new window
    print("Opening Google with Edge in new window...")
    opener.open_url("https://www.google.com", browser_name="edge", new_window=True)

if __name__ == "__main__":
    main()

path: examples/batch_opening.py
content: #!/usr/bin/env python3
"""
Batch opening examples for the browser opener skill.
"""

from scripts.open_browser import BrowserOpener
import time

def open_multiple_urls(urls, browser_name="default", delay=1):
    """Open multiple URLs with optional delay between openings."""
    opener = BrowserOpener()
    
    print(f"Opening {len(urls)} URLs with {browser_name}...")
    
    for i, url in enumerate(urls, 1):
        print(f"Opening URL {i}/{len(urls)}: {url}")
        success = opener.open_url(url, browser_name=browser_name)
        
        if success:
            print(f"✓ Successfully opened {url}")
        else:
            print(f"✗ Failed to open {url}")
        
        if i < len(urls):
            print(f"Waiting {delay} second(s) before next URL...")
            time.sleep(delay)

def main():
    # List of URLs to open
    search_urls = [
        "https://www.google.com",
        "https://www.bing.com", 
        "https://www.duckduckgo.com",
        "https://www.yahoo.com"
    ]
    
    news_urls = [
        "https://www.bbc.com",
        "https://www.cnn.com",
        "https://www.reuters.com",
        "https://www.apnews.com"
    ]
    
    # Example 1: Open multiple search engines with default browser
    print("=== Opening Search Engines ===")
    open_multiple_urls(search_urls, browser_name="default", delay=2)
    
    # Example 2: Open news sites with Chrome
    print("\n=== Opening News Sites with Chrome ===")
    open_multiple_urls(news_urls, browser_name="chrome", delay=2)
    
    # Example 3: Open sites with Firefox private mode
    print("\n=== Opening Sites with Firefox Private Mode ===")
    open_multiple_urls(search_urls[:2], browser_name="firefox", incognito=True, delay=2)

if __name__ == "__main__":
    main()

path: examples/error_handling.py
content: #!/usr/bin/env python3
"""
Error handling examples for the browser opener skill.
"""

from scripts.open_browser import BrowserOpener

def demonstrate_error_handling():
    """Demonstrate various error handling scenarios."""
    opener = BrowserOpener()
    
    # Example 1: Empty URL
    print("=== Testing Empty URL ===")
    try:
        opener.open_url("")
    except ValueError as e:
        print(f"✓ Caught expected error: {e}")
    
    # Example 2: Invalid URL format
    print("\n=== Testing Invalid URL Format ===")
    try:
        opener.open_url("not-a-url")
    except ValueError as e:
        print(f"✓ Caught expected error: {e}")
    
    # Example 3: Non-existent browser
    print("\n=== Testing Non-existent Browser ===")
    try:
        opener.open_url("https://www.google.com", browser_name="nonexistent-browser")
    except (ValueError, FileNotFoundError) as e:
        print(f"✓ Caught expected error: {e}")
    
    # Example 4: Browser not available on current platform
    print("\n=== Testing Platform-specific Browser ===")
    try:
        opener.open_url("https://www.google.com", browser_name="safari")
    except (ValueError, FileNotFoundError) as e:
        print(f"✓ Caught expected error: {e}")
    
    # Example 5: Successful opening with error handling
    print("\n=== Testing Successful Opening ===")
    try:
        success = opener.open_url("https://www.google.com", browser_name="chrome")
        if success:
            print("✓ Successfully opened URL")
        else:
            print("✗ Failed to open URL")
    except Exception as e:
        print(f"✗ Unexpected error: {e}")

def safe_browser_opening(url, browser_name="default", **kwargs):
    """Safely open a browser with comprehensive error handling."""
    opener = BrowserOpener()
    
    try:
        # Validate URL
        if not url:
            raise ValueError("URL is required")
        
        if not url.startswith(('http://', 'https://')):
            url = 'https://' + url
        
        # Try to open the browser
        success = opener.open_url(url, browser_name=browser_name, **kwargs)
        
        if success:
            print(f"✓ Successfully opened {url} in {browser_name}")
            return True
        else:
            print(f"✗ Failed to open {url} in {browser_name}")
            return False
            
    except ValueError as e:
        print(f"✗ Invalid URL or browser name: {e}")
        return False
    except FileNotFoundError as e:
        print(f"✗ Browser not found: {e}")
        return False
    except PermissionError as e:
        print(f"✗ Permission denied: {e}")
        return False
    except Exception as e:
        print(f"✗ Unexpected error: {e}")
        return False

def main():
    """Demonstrate error handling and safe browser opening."""
    print("=== Browser Opener Error Handling Examples ===\n")
    
    # Demonstrate various error scenarios
    demonstrate_error_handling()
    
    print("\n=== Safe Browser Opening Example ===")
    # Use the safe wrapper function
    safe_browser_opening("https://www.google.com", browser_name="chrome")
    safe_browser_opening("https://www.bing.com", browser_name="firefox")
    safe_browser_opening("", browser_name="chrome")  # This will fail gracefully
    safe_browser_opening("invalid-url", browser_name="chrome")  # This will fail gracefully

if __name__ == "__main__":
    main()

path: README.md
content: # Browser Opener Skill

一个跨平台的浏览器打开技能，支持多种浏览器（Chrome、Firefox、Edge、Safari）和URL启动功能。

## 功能特性

- 🌐 **跨平台支持**：Windows、macOS、Linux
- 🦴 **多浏览器支持**：Chrome、Firefox、Edge、Safari
- 🔗 **URL启动**：打开指定URL
- 🚪 **新窗口**：在新窗口中打开
- 👻 **隐私模式**：无痕/隐私浏览模式
- 🤖 **无头模式**：无GUI模式（用于测试）
- 🛡️ **错误处理**：全面的错误处理机制

## 安装和使用

### 1. 安装依赖

```bash
pip install webbrowser subprocess argparse
```

### 2. 基本使用

```bash
# 使用默认浏览器打开URL
python scripts/open_browser.py --url https://www.google.com

# 使用Chrome打开URL
python scripts/open_browser.py --url https://www.google.com --browser chrome

# 使用Firefox打开URL
python scripts/open_browser.py --url https://www.google.com --browser firefox

# 使用Edge打开URL
python scripts/open_browser.py --url https://www.google.com --browser edge
```

### 3. 高级选项

```bash
# 在新窗口中打开
python scripts/open_browser.py --url https://www.google.com --new-window

# 使用隐私模式
python scripts/open_browser.py --url https://www.google.com --incognito

# 使用无头模式
python scripts/open_browser.py --url https://www.google.com --headless

# 组合使用
python scripts/open_browser.py --url https://www.google.com --browser chrome --new-window --incognito
```

## 支持的浏览器

| 浏览器 | Windows | macOS | Linux | 命令 |
|--------|---------|-------|-------|------|
| Chrome | ✅ | ✅ | ✅ | `--browser chrome` |
| Firefox | ✅ | ✅ | ✅ | `--browser firefox` |
| Edge | ✅ | ✅ | ✅ | `--browser edge` |
| Safari | ❌ | ✅ | ❌ | `--browser safari` |

## Python API

```python
from scripts.open_browser import BrowserOpener

# 创建浏览器打开器实例
opener = BrowserOpener()

# 使用默认浏览器打开URL
opener.open_url("https://www.google.com")

# 使用指定浏览器打开URL
opener.open_url("https://www.google.com", browser_name="chrome")

# 使用隐私模式打开
opener.open_url("https://www.google.com", browser_name="firefox", incognito=True)

# 在新窗口中打开
opener.open_url("https://www.google.com", browser_name="edge", new_window=True)

# 使用无头模式
opener.open_url("https://www.google.com", browser_name="chrome", headless=True)
```

## 示例代码

查看 `examples/` 目录获取更多示例：

- `basic_usage.py` - 基本使用示例
- `batch_opening.py` - 批量打开URL示例
- `error_handling.py` - 错误处理示例

## 命令行选项

| 选项 | 描述 | 必需 | 默认值 |
|------|------|------|--------|
| `--url` | 要打开的URL | 是 | 无 |
| `--browser` | 使用的浏览器 | 否 | `default` |
| `--new-window` | 在新窗口中打开 | 否 | False |
| `--incognito` | 使用隐私模式 | 否 | False |
| `--headless` | 使用无头模式 | 否 | False |

## 浏览器特定选项

### Chrome
- `--incognito`: 无痕模式
- `--headless`: 无头模式
- `--new-window`: 新窗口
- `--disable-gpu`: 禁用GPU加速

### Firefox
- `--private-window`: 私有浏览模式
- `--headless`: 无头模式
- `--new-window`: 新窗口

### Edge
- `--inprivate`: InPrivate模式
- `--headless`: 无头模式
- `--new-window`: 新窗口

### Safari
- `--new-window`: 新窗口
- 注意：Safari不支持命令行无痕或无头模式

## 错误处理

脚本包含全面的错误处理：

- **无效URL**：验证URL格式并自动添加https://前缀
- **浏览器未找到**：检查浏览器是否已安装
- **权限问题**：处理权限错误
- **平台特定问题**：处理操作系统特定错误

## 故障排除

1. **浏览器未找到**：确保浏览器已正确安装
2. **权限错误**：确保有足够的权限启动浏览器
3. **URL无法打开**：检查URL格式和网络连接
4. **平台问题**：验证浏览器在您的平台上可用

## 开发

### 项目结构

```
browser-opener-skill/
├── SKILL.md              # 技能定义
├── README.md             # 说明文档
├── scripts/              # 脚本文件
│   └── open_browser.py   # 主要脚本
├── references/           # 参考文档
│   └── browser_support.md # 浏览器支持详情
└── examples/             # 示例代码
    ├── basic_usage.py    # 基本使用示例
    ├── batch_opening.py  # 批量打开示例
    └── error_handling.py # 错误处理示例
```

### 测试

```bash
# 运行基本使用示例
python examples/basic_usage.py

# 运行批量打开示例
python examples/batch_opening.py

# 运行错误处理示例
python examples/error_handling.py
```

## 许可证

MIT License

path: references/browser_support.md
content: # Browser Support Details

This document provides detailed information about browser support across different platforms.

## Supported Browsers

### Chrome
- **Windows**: Chrome, Google Chrome
- **macOS**: Google Chrome
- **Linux**: Google Chrome, google-chrome-stable
- **Command**: `--browser chrome`
- **Installation Paths**:
  - Windows: `C:\Program Files\Google\Chrome\Application\chrome.exe`
  - macOS: `/Applications/Google Chrome.app/Contents/MacOS/Google Chrome`
  - Linux: `/usr/bin/google-chrome`, `/usr/bin/google-chrome-stable`

### Firefox
- **Windows**: Firefox, Mozilla Firefox
- **macOS**: Firefox
- **Linux**: Firefox, firefox-esr
- **Command**: `--browser firefox`
- **Installation Paths**:
  - Windows: `C:\Program Files\Mozilla Firefox\firefox.exe`
  - macOS: `/Applications/Firefox.app/Contents/MacOS/firefox`
  - Linux: `/usr/bin/firefox`, `/usr/bin/firefox-esr`

### Edge
- **Windows**: Edge, Microsoft Edge
- **macOS**: Microsoft Edge
- **Linux**: Microsoft Edge
- **Command**: `--browser edge`
- **Installation Paths**:
  - Windows: `C:\Program Files\Microsoft\Edge\Application\msedge.exe`
  - macOS: `/Applications/Microsoft Edge.app/Contents/MacOS/Microsoft Edge`

### Safari
- **macOS**: Safari, Apple Safari
- **Windows/Linux**: Not supported
- **Command**: `--browser safari`
- **Installation Paths**:
  - macOS: `/Applications/Safari.app/Contents/MacOS/Safari`

## Platform-Specific Notes

### Windows
- Uses `where` command to find browser executables
- Supports both 32-bit and 64-bit program paths
- Edge is pre-installed on Windows 10 and later

### macOS
- Uses `which` command to find browser executables
- Applications are typically in `/Applications/`
- Safari is the default browser and pre-installed

### Linux
- Uses `which` command to find browser executables
- Distribution-specific paths may vary
- Some distributions may require additional packages

## Browser Flags and Options

### Chrome
- `--incognito`: Incognito mode
- `--headless`: Headless mode (no GUI)
- `--new-window`: Open in new window
- `--disable-gpu`: Disable GPU acceleration (useful with headless)

### Firefox
- `--private-window`: Private browsing mode
- `--headless`: Headless mode
- `--new-window`: Open in new window

### Edge
- `--inprivate`: InPrivate mode
- `--headless`: Headless mode
- `--new-window`: Open in new window

### Safari
- `--new-window`: Open in new window
- Note: Safari doesn't support headless or incognito via command line

## Error Handling

The script includes comprehensive error handling for:

### Common Errors
1. **Browser Not Found**: Returns error if browser executable is not found
2. **Invalid URL**: Validates URL format and adds https:// if missing
3. **Permission Issues**: Handles permission errors when trying to launch browsers
4. **Platform-Specific Issues**: Handles OS-specific error conditions

### Troubleshooting
1. **Browser not found**: Install the browser or specify the correct path
2. **Permission denied**: Run script with appropriate permissions
3. **URL not opening**: Check URL format and network connectivity
4. **Platform issues**: Verify browser installation on your platform

## Testing

To test the browser opener:

```bash
# Test with default browser
python scripts/open_browser.py --url https://www.google.com

# Test with specific browser
python scripts/open_browser.py --url https://www.google.com --browser chrome

# Test with different options
python scripts/open_browser.py --url https://www.google.com --browser firefox --new-window --incognito
```

path: scripts/open_browser.py
content: #!/usr/bin/env python3
"""
Cross-platform browser opener script.
Supports Chrome, Firefox, Edge, Safari and default browser.
"""

import sys
import subprocess
import argparse
import webbrowser
import platform
import os
from typing import Optional, List

class BrowserOpener:
    """Cross-platform browser opener with support for multiple browsers."""
    
    def __init__(self):
        self.system = platform.system().lower()
        self.browsers = {
            'chrome': {
                'windows': ['chrome', 'google-chrome', 'google-chrome-stable'],
                'darwin': ['google-chrome', 'google-chrome-stable', 'chrome'],
                'linux': ['google-chrome', 'google-chrome-stable', 'chrome']
            },
            'firefox': {
                'windows': ['firefox', 'mozilla-firefox'],
                'darwin': ['firefox', 'mozilla-firefox'],
                'linux': ['firefox', 'mozilla-firefox']
            },
            'edge': {
                'windows': ['edge', 'microsoft-edge'],
                'darwin': ['microsoft-edge'],
                'linux': ['microsoft-edge']
            },
            'safari': {
                'windows': [],
                'darwin': ['safari', 'apple-safari'],
                'linux': []
            }
        }
    
    def find_browser_executable(self, browser_name: str) -> Optional[str]:
        """Find the executable path for a given browser."""
        if browser_name == 'default':
            return None
        
        browser_key = browser_name.lower()
        if browser_key not in self.browsers:
            raise ValueError(f"Unsupported browser: {browser_name}")
        
        possible_names = self.browsers[browser_key].get(self.system, [])
        
        for name in possible_names:
            # Check if the browser is available in PATH
            try:
                result = subprocess.run(['where' if self.system == 'windows' else 'which', name], 
                                      capture_output=True, text=True)
                if result.returncode == 0:
                    return name
            except FileNotFoundError:
                continue
        
        # Also check common installation paths
        common_paths = self._get_common_installation_paths(browser_key)
        for path in common_paths:
            if os.path.exists(path):
                return path
        
        raise FileNotFoundError(f"Browser '{browser_name}' not found on {self.system}")
    
    def _get_common_installation_paths(self, browser_key: str) -> List[str]:
        """Get common installation paths for browsers."""
        paths = []
        
        if browser_key == 'chrome':
            if self.system == 'windows':
                paths.extend([
                    r'C:\Program Files\Google\Chrome\Application\chrome.exe',
                    r'C:\Program Files (x86)\Google\Chrome\Application\chrome.exe'
                ])
            elif self.system == 'darwin':
                paths.extend([
                    '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome'
                ])
            elif self.system == 'linux':
                paths.extend([
                    '/usr/bin/google-chrome',
                    '/usr/bin/google-chrome-stable'
                ])
        
        elif browser_key == 'firefox':
            if self.system == 'windows':
                paths.extend([
                    r'C:\Program Files\Mozilla Firefox\firefox.exe',
                    r'C:\Program Files (x86)\Mozilla Firefox\firefox.exe'
                ])
            elif self.system == 'darwin':
                paths.extend([
                    '/Applications/Firefox.app/Contents/MacOS/firefox'
                ])
            elif self.system == 'linux':
                paths.extend([
                    '/usr/bin/firefox',
                    '/usr/bin/firefox-esr'
                ])
        
        elif browser_key == 'edge':
            if self.system == 'windows':
                paths.extend([
                    r'C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe',
                    r'C:\Program Files\Microsoft\Edge\Application\msedge.exe'
                ])
            elif self.system == 'darwin':
                paths.extend([
                    '/Applications/Microsoft Edge.app/Contents/MacOS/Microsoft Edge'
                ])
        
        elif browser_key == 'safari':
            if self.system == 'darwin':
                paths.extend([
                    '/Applications/Safari.app/Contents/MacOS/Safari'
                ])
        
        return paths
    
    def open_url(self, url: str, browser_name: str = 'default', 
                 new_window: bool = False, incognito: bool = False, 
                 headless: bool = False) -> bool:
        """Open a URL with the specified browser."""
        
        if not url:
            raise ValueError("URL is required")
        
        try:
            # Validate URL
            if not url.startswith(('http://', 'https://')):
                url = 'https://' + url
            
            browser_executable = None
            if browser_name != 'default':
                browser_executable = self.find_browser_executable(browser_name)
            
            # Build the command
            cmd = []
            
            if browser_executable:
                cmd.append(browser_executable)
                
                # Add browser-specific flags
                if browser_name.lower() == 'chrome':
                    if incognito:
                        cmd.append('--incognito')
                    if headless:
                        cmd.append('--headless')
                        cmd.append('--disable-gpu')
                    if new_window:
                        cmd.append('--new-window')
                
                elif browser_name.lower() == 'firefox':
                    if incognito:
                        cmd.append('--private-window')
                    if headless:
                        cmd.append('--headless')
                    if new_window:
                        cmd.append('--new-window')
                
                elif browser_name.lower() == 'edge':
                    if incognito:
                        cmd.append('--inprivate')
                    if headless:
                        cmd.append('--headless')
                    if new_window:
                        cmd.append('--new-window')
                
                elif browser_name.lower() == 'safari':
                    if new_window:
                        cmd.append('--new-window')
                    # Safari doesn't support headless or incognito via command line
            
            else:
                # Use system default browser
                if new_window:
                    # webbrowser.open_new() opens in new window/tab
                    webbrowser.open_new(url)
                    return True
                else:
                    webbrowser.open(url)
                    return True
            
            # Add URL
            cmd.append(url)
            
            # Execute command
            result = subprocess.run(cmd, capture_output=True, text=True)
            
            if result.returncode == 0:
                return True
            else:
                print(f"Error opening browser: {result.stderr}")
                return False
                
        except Exception as e:
            print(f"Error opening browser: {str(e)}")
            return False

def main():
    """Main function to handle command line arguments."""
    parser = argparse.ArgumentParser(description='Open URL in specified browser')
    parser.add_argument('--url', required=True, help='URL to open')
    parser.add_argument('--browser', default='default', 
                       help='Browser to use (chrome, firefox, edge, safari, default)')
    parser.add_argument('--new-window', action='store_true', 
                       help='Open in new window')
    parser.add_argument('--incognito', action='store_true', 
                       help='Open in incognito/private mode')
    parser.add_argument('--headless', action='store_true', 
                       help='Open in headless mode')
    
    args = parser.parse_args()
    
    opener = BrowserOpener()
    success = opener.open_url(
        url=args.url,
        browser_name=args.browser,
        new_window=args.new_window,
        incognito=args.incognito,
        headless=args.headless
    )
    
    if success:
        print(f"Successfully opened {args.url} in {args.browser}")
        sys.exit(0)
    else:
        print(f"Failed to open {args.url} in {args.browser}")
        sys.exit(1)

if __name__ == '__main__':
    main()

Security scan verdicts — ClawScan: clean | static analysis: clean | VirusTotal: clean | SkillSpector: clean (LOW)