a
This commit is contained in:
@@ -0,0 +1,140 @@
|
||||
# OpenCLI Integration - 通用CLI集成技能
|
||||
|
||||
集成 [OpenCLI](https://github.com/jackwener/opencli) 能力,将任何网站、Electron应用转换为命令行接口。
|
||||
|
||||
## 🎯 项目定位
|
||||
|
||||
这是**预备技能**,当前保持 **xhs-cli + lightpanda** 方案(稳定),但为未来扩展保留OpenCLI能力。
|
||||
|
||||
```
|
||||
当前方案(稳定) 未来扩展(预留)
|
||||
├─ xhs-cli ├─ OpenCLI ← 本技能
|
||||
├─ lightpanda └─ 更多网站CLI化
|
||||
└─ 现有爬虫
|
||||
```
|
||||
|
||||
## 🚀 快速开始
|
||||
|
||||
### 安装OpenCLI
|
||||
|
||||
```bash
|
||||
# 1. 安装Node.js >= 20.0.0
|
||||
curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
|
||||
sudo apt-get install -y nodejs
|
||||
|
||||
# 2. 安装OpenCLI
|
||||
npm install -g @jackwener/opencli
|
||||
|
||||
# 3. 验证安装
|
||||
opencli --version
|
||||
```
|
||||
|
||||
### 基础使用
|
||||
|
||||
```bash
|
||||
# 检查状态
|
||||
python3 opencli_adapter.py status
|
||||
|
||||
# 诊断环境
|
||||
python3 opencli_adapter.py doctor
|
||||
|
||||
# 探索网站API
|
||||
python3 opencli_adapter.py explore https://www.xiaohongshu.com
|
||||
|
||||
# 生成适配器
|
||||
python3 opencli_adapter.py synthesize xiaohongshu
|
||||
|
||||
# 执行命令
|
||||
python3 opencli_adapter.py exec xiaohongshu search --args query=关键词
|
||||
```
|
||||
|
||||
## 📚 API文档
|
||||
|
||||
### 初始化
|
||||
|
||||
```python
|
||||
from opencli_adapter import OpenCLIAdapter
|
||||
|
||||
adapter = OpenCLIAdapter()
|
||||
```
|
||||
|
||||
### 核心方法
|
||||
|
||||
| 方法 | 说明 | 示例 |
|
||||
|------|------|------|
|
||||
| `setup()` | 初始化环境 | `adapter.setup()` |
|
||||
| `doctor()` | 诊断状态 | `adapter.doctor()` |
|
||||
| `list()` | 列出适配器 | `adapter.list()` |
|
||||
| `explore(url)` | 探索API | `adapter.explore("https://...")` |
|
||||
| `synthesize(name)` | 生成适配器 | `adapter.synthesize("mysite")` |
|
||||
| `execute(cli, action)` | 执行命令 | `adapter.execute("xhs", "search", query="...")` |
|
||||
|
||||
### 便捷方法
|
||||
|
||||
```python
|
||||
# 搜索
|
||||
adapter.search("xiaohongshu", "关键词")
|
||||
|
||||
# 获取详情
|
||||
adapter.get("xiaohongshu", "note_id")
|
||||
|
||||
# 控制Electron应用
|
||||
adapter.control_electron("antigravity", "open_file", path="/path/to/file")
|
||||
```
|
||||
|
||||
## 🔧 适配器配置示例
|
||||
|
||||
### YAML声明式适配器
|
||||
|
||||
```python
|
||||
config = {
|
||||
"name": "mysite",
|
||||
"base_url": "https://example.com",
|
||||
"selectors": {
|
||||
"search_box": "input[name='q']",
|
||||
"search_button": "button[type='submit']",
|
||||
"result_item": ".result-item"
|
||||
},
|
||||
"commands": {
|
||||
"search": {
|
||||
"description": "搜索内容",
|
||||
"params": ["query"]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
path = adapter.create_yaml_adapter("mysite", config)
|
||||
```
|
||||
|
||||
## 📋 与现有方案对比
|
||||
|
||||
| 特性 | xhs-cli | OpenCLI | 适用场景 |
|
||||
|------|---------|---------|---------|
|
||||
| 稳定性 | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ | 生产环境用xhs-cli |
|
||||
| 通用性 | ⭐⭐ | ⭐⭐⭐⭐⭐ | 新网站用OpenCLI探索 |
|
||||
| 易用性 | ⭐⭐⭐⭐ | ⭐⭐⭐ | xhs-cli更直接 |
|
||||
| 扩展性 | ⭐⭐ | ⭐⭐⭐⭐⭐ | OpenCLI可扩展任意网站 |
|
||||
| 资源占用 | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ | xhs-cli更轻量 |
|
||||
|
||||
## ⚠️ 使用建议
|
||||
|
||||
### 当前阶段(保持现状)
|
||||
- ✅ 继续使用 `xhs-cli` 处理小红书
|
||||
- ✅ 继续使用 `lightpanda` 进行网页抓取
|
||||
- ✅ 本技能作为**技术储备**
|
||||
|
||||
### 未来可能的使用场景
|
||||
1. **新网站接入** - 快速探索并生成CLI
|
||||
2. **Electron应用** - 控制Antigravity等工具
|
||||
3. **复杂交互** - 需要浏览器自动化的场景
|
||||
4. **AI自发现** - 让AI自动学习和使用新工具
|
||||
|
||||
## 🔗 参考链接
|
||||
|
||||
- OpenCLI GitHub: https://github.com/jackwener/opencli
|
||||
- npm包: https://www.npmjs.com/package/@jackwener/opencli
|
||||
- 中文文档: https://github.com/jackwener/opencli/blob/main/README.zh-CN.md
|
||||
|
||||
## 📝 License
|
||||
|
||||
MIT
|
||||
@@ -0,0 +1,105 @@
|
||||
# OpenCLI Integration - 通用CLI集成技能
|
||||
|
||||
集成 OpenCLI 能力,将任何网站、Electron应用转换为命令行接口,供AI Agent调用。
|
||||
|
||||
## 🎯 功能特性
|
||||
|
||||
- ✅ **网站CLI化** - 将任意网站转换为CLI工具
|
||||
- ✅ **Electron应用控制** - 控制Antigravity等Electron应用
|
||||
- ✅ **AI自动发现** - 自动探索网站API并生成适配器
|
||||
- ✅ **浏览器复用** - 复用Chrome登录态,零风控
|
||||
- ✅ **动态适配器** - 支持.yaml声明式和.ts编程式适配器
|
||||
|
||||
## 🚀 使用方法
|
||||
|
||||
### 前置要求
|
||||
|
||||
```bash
|
||||
# 1. 安装Node.js >= 20.0.0
|
||||
curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
|
||||
sudo apt-get install -y nodejs
|
||||
|
||||
# 2. 安装OpenCLI
|
||||
npm install -g @jackwener/opencli
|
||||
|
||||
# 3. 确保Chrome正在运行且已登录目标网站
|
||||
```
|
||||
|
||||
### 命令行使用
|
||||
|
||||
```bash
|
||||
# 探索网站API
|
||||
python3 /home/ubuntu/.nanobot/workspace/skills/opencli-integration/opencli_adapter.py explore https://www.xiaohongshu.com
|
||||
|
||||
# 生成适配器
|
||||
python3 /home/ubuntu/.nanobot/workspace/skills/opencli-integration/opencli_adapter.py synthesize xiaohongshu
|
||||
|
||||
# 执行CLI命令
|
||||
python3 /home/ubuntu/.nanobot/workspace/skills/opencli-integration/opencli_adapter.py exec xiaohongshu search "关键词"
|
||||
|
||||
# 诊断状态
|
||||
python3 /home/ubuntu/.nanobot/workspace/skills/opencli-integration/opencli_adapter.py doctor
|
||||
```
|
||||
|
||||
### Python API
|
||||
|
||||
```python
|
||||
from opencli_adapter import OpenCLIAdapter
|
||||
|
||||
adapter = OpenCLIAdapter()
|
||||
|
||||
# 探索网站
|
||||
result = adapter.explore("https://www.xiaohongshu.com")
|
||||
|
||||
# 生成适配器
|
||||
adapter.synthesize("xiaohongshu")
|
||||
|
||||
# 执行命令
|
||||
result = adapter.execute("xiaohongshu", "search", query="关键词")
|
||||
```
|
||||
|
||||
## 📋 内置支持
|
||||
|
||||
OpenCLI官方支持的网站/应用:
|
||||
- B站 (bilibili)
|
||||
- 知乎 (zhihu)
|
||||
- 小红书 (xiaohongshu)
|
||||
- Twitter/X
|
||||
- Reddit
|
||||
- YouTube
|
||||
- Antigravity (Electron)
|
||||
|
||||
## 🔧 高级用法
|
||||
|
||||
### 自定义适配器
|
||||
|
||||
```python
|
||||
# 创建自定义适配器
|
||||
adapter.create_custom_adapter(
|
||||
name="mysite",
|
||||
base_url="https://example.com",
|
||||
selectors={
|
||||
"search_box": "input[name='q']",
|
||||
"search_button": "button[type='submit']"
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
### Electron应用控制
|
||||
|
||||
```python
|
||||
# 控制Electron应用
|
||||
adapter.control_electron("antigravity", "open_file", path="/path/to/file")
|
||||
```
|
||||
|
||||
## ⚠️ 注意事项
|
||||
|
||||
- 需要Chrome浏览器正在运行
|
||||
- 需要Node.js >= 20.0.0
|
||||
- 新网站可能需要手动登录
|
||||
- AI发现API的准确性需要验证
|
||||
|
||||
## 📚 参考
|
||||
|
||||
- OpenCLI GitHub: https://github.com/jackwener/opencli
|
||||
- npm包: https://www.npmjs.com/package/@jackwener/opencli
|
||||
@@ -0,0 +1,427 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
OpenCLI Integration Adapter
|
||||
将OpenCLI能力封装为Python接口
|
||||
"""
|
||||
|
||||
import subprocess
|
||||
import json
|
||||
import os
|
||||
import shutil
|
||||
from pathlib import Path
|
||||
from typing import Dict, List, Optional, Any
|
||||
|
||||
|
||||
class OpenCLIAdapter:
|
||||
"""OpenCLI适配器"""
|
||||
|
||||
def __init__(self, clis_dir: Optional[str] = None):
|
||||
"""
|
||||
初始化OpenCLI适配器
|
||||
|
||||
Args:
|
||||
clis_dir: 适配器存储目录,默认 ~/.opencli/clis
|
||||
"""
|
||||
self.clis_dir = clis_dir or os.path.expanduser("~/.opencli/clis")
|
||||
self._check_opencli()
|
||||
|
||||
def _check_opencli(self) -> bool:
|
||||
"""检查OpenCLI是否已安装"""
|
||||
if not shutil.which("opencli"):
|
||||
raise RuntimeError(
|
||||
"OpenCLI未安装。请先运行: npm install -g @jackwener/opencli"
|
||||
)
|
||||
return True
|
||||
|
||||
def _run_command(self, cmd: List[str], capture_output: bool = True) -> Dict[str, Any]:
|
||||
"""
|
||||
运行OpenCLI命令
|
||||
|
||||
Args:
|
||||
cmd: 命令列表
|
||||
capture_output: 是否捕获输出
|
||||
|
||||
Returns:
|
||||
{"success": bool, "stdout": str, "stderr": str, "returncode": int}
|
||||
"""
|
||||
try:
|
||||
result = subprocess.run(
|
||||
["opencli"] + cmd,
|
||||
capture_output=capture_output,
|
||||
text=True,
|
||||
timeout=120
|
||||
)
|
||||
|
||||
return {
|
||||
"success": result.returncode == 0,
|
||||
"stdout": result.stdout,
|
||||
"stderr": result.stderr,
|
||||
"returncode": result.returncode
|
||||
}
|
||||
except subprocess.TimeoutExpired:
|
||||
return {
|
||||
"success": False,
|
||||
"stdout": "",
|
||||
"stderr": "Command timeout",
|
||||
"returncode": -1
|
||||
}
|
||||
except Exception as e:
|
||||
return {
|
||||
"success": False,
|
||||
"stdout": "",
|
||||
"stderr": str(e),
|
||||
"returncode": -1
|
||||
}
|
||||
|
||||
# ==================== 核心功能 ====================
|
||||
|
||||
def setup(self) -> Dict[str, Any]:
|
||||
"""
|
||||
初始化OpenCLI环境
|
||||
检查Browser Bridge连通性
|
||||
"""
|
||||
return self._run_command(["setup"])
|
||||
|
||||
def doctor(self) -> Dict[str, Any]:
|
||||
"""
|
||||
诊断OpenCLI状态
|
||||
检查daemon、扩展和浏览器连接
|
||||
"""
|
||||
return self._run_command(["doctor"])
|
||||
|
||||
def list(self) -> List[Dict[str, Any]]:
|
||||
"""
|
||||
列出所有可用的CLI适配器
|
||||
|
||||
Returns:
|
||||
适配器列表
|
||||
"""
|
||||
result = self._run_command(["list", "--json"])
|
||||
|
||||
if result["success"]:
|
||||
try:
|
||||
return json.loads(result["stdout"])
|
||||
except json.JSONDecodeError:
|
||||
return []
|
||||
return []
|
||||
|
||||
def explore(self, url: str, output_dir: Optional[str] = None) -> Dict[str, Any]:
|
||||
"""
|
||||
探索网站API
|
||||
AI自动发现网站接口
|
||||
|
||||
Args:
|
||||
url: 目标网站URL
|
||||
output_dir: 输出目录
|
||||
|
||||
Returns:
|
||||
探索结果
|
||||
"""
|
||||
cmd = ["explore", url]
|
||||
if output_dir:
|
||||
cmd.extend(["--output", output_dir])
|
||||
|
||||
return self._run_command(cmd)
|
||||
|
||||
def synthesize(self, name: str, url: Optional[str] = None) -> Dict[str, Any]:
|
||||
"""
|
||||
生成适配器
|
||||
基于探索结果生成CLI适配器
|
||||
|
||||
Args:
|
||||
name: 适配器名称
|
||||
url: 网站URL(如已explore可省略)
|
||||
|
||||
Returns:
|
||||
生成结果
|
||||
"""
|
||||
cmd = ["synthesize", name]
|
||||
if url:
|
||||
cmd.extend(["--url", url])
|
||||
|
||||
return self._run_command(cmd)
|
||||
|
||||
def register(self, name: str, adapter_path: Optional[str] = None) -> Dict[str, Any]:
|
||||
"""
|
||||
注册适配器
|
||||
|
||||
Args:
|
||||
name: 适配器名称
|
||||
adapter_path: 适配器文件路径
|
||||
|
||||
Returns:
|
||||
注册结果
|
||||
"""
|
||||
cmd = ["register", name]
|
||||
if adapter_path:
|
||||
cmd.append(adapter_path)
|
||||
|
||||
return self._run_command(cmd)
|
||||
|
||||
def execute(self, cli_name: str, command: str, **kwargs) -> Dict[str, Any]:
|
||||
"""
|
||||
执行CLI命令
|
||||
|
||||
Args:
|
||||
cli_name: CLI名称
|
||||
command: 命令名称
|
||||
**kwargs: 命令参数
|
||||
|
||||
Returns:
|
||||
执行结果
|
||||
"""
|
||||
cmd = [cli_name, command]
|
||||
|
||||
# 添加参数
|
||||
for key, value in kwargs.items():
|
||||
if isinstance(value, bool) and value:
|
||||
cmd.append(f"--{key}")
|
||||
else:
|
||||
cmd.extend([f"--{key}", str(value)])
|
||||
|
||||
return self._run_command(cmd)
|
||||
|
||||
# ==================== 便捷方法 ====================
|
||||
|
||||
def search(self, cli_name: str, query: str, **kwargs) -> Dict[str, Any]:
|
||||
"""
|
||||
便捷搜索方法
|
||||
|
||||
Args:
|
||||
cli_name: CLI名称
|
||||
query: 搜索关键词
|
||||
**kwargs: 其他参数
|
||||
|
||||
Returns:
|
||||
搜索结果
|
||||
"""
|
||||
return self.execute(cli_name, "search", query=query, **kwargs)
|
||||
|
||||
def get(self, cli_name: str, id: str, **kwargs) -> Dict[str, Any]:
|
||||
"""
|
||||
便捷获取方法
|
||||
|
||||
Args:
|
||||
cli_name: CLI名称
|
||||
id: 资源ID
|
||||
**kwargs: 其他参数
|
||||
|
||||
Returns:
|
||||
获取结果
|
||||
"""
|
||||
return self.execute(cli_name, "get", id=id, **kwargs)
|
||||
|
||||
# ==================== Electron应用控制 ====================
|
||||
|
||||
def control_electron(self, app_name: str, action: str, **kwargs) -> Dict[str, Any]:
|
||||
"""
|
||||
控制Electron应用
|
||||
|
||||
Args:
|
||||
app_name: 应用名称
|
||||
action: 动作名称
|
||||
**kwargs: 动作参数
|
||||
|
||||
Returns:
|
||||
执行结果
|
||||
"""
|
||||
return self.execute(f"electron:{app_name}", action, **kwargs)
|
||||
|
||||
# ==================== 适配器管理 ====================
|
||||
|
||||
def create_yaml_adapter(self, name: str, config: Dict[str, Any]) -> str:
|
||||
"""
|
||||
创建YAML声明式适配器
|
||||
|
||||
Args:
|
||||
name: 适配器名称
|
||||
config: 适配器配置
|
||||
|
||||
Returns:
|
||||
适配器文件路径
|
||||
"""
|
||||
import yaml
|
||||
|
||||
adapter_path = os.path.join(self.clis_dir, f"{name}.yaml")
|
||||
os.makedirs(self.clis_dir, exist_ok=True)
|
||||
|
||||
with open(adapter_path, 'w', encoding='utf-8') as f:
|
||||
yaml.dump(config, f, allow_unicode=True)
|
||||
|
||||
return adapter_path
|
||||
|
||||
def get_adapter_info(self, name: str) -> Optional[Dict[str, Any]]:
|
||||
"""
|
||||
获取适配器信息
|
||||
|
||||
Args:
|
||||
name: 适配器名称
|
||||
|
||||
Returns:
|
||||
适配器信息
|
||||
"""
|
||||
# 检查YAML适配器
|
||||
yaml_path = os.path.join(self.clis_dir, f"{name}.yaml")
|
||||
if os.path.exists(yaml_path):
|
||||
import yaml
|
||||
with open(yaml_path, 'r', encoding='utf-8') as f:
|
||||
return yaml.safe_load(f)
|
||||
|
||||
# 检查TypeScript适配器
|
||||
ts_path = os.path.join(self.clis_dir, f"{name}.ts")
|
||||
if os.path.exists(ts_path):
|
||||
return {"type": "typescript", "path": ts_path}
|
||||
|
||||
return None
|
||||
|
||||
def remove_adapter(self, name: str) -> bool:
|
||||
"""
|
||||
删除适配器
|
||||
|
||||
Args:
|
||||
name: 适配器名称
|
||||
|
||||
Returns:
|
||||
是否成功
|
||||
"""
|
||||
removed = False
|
||||
|
||||
yaml_path = os.path.join(self.clis_dir, f"{name}.yaml")
|
||||
if os.path.exists(yaml_path):
|
||||
os.remove(yaml_path)
|
||||
removed = True
|
||||
|
||||
ts_path = os.path.join(self.clis_dir, f"{name}.ts")
|
||||
if os.path.exists(ts_path):
|
||||
os.remove(ts_path)
|
||||
removed = True
|
||||
|
||||
return removed
|
||||
|
||||
# ==================== 状态检查 ====================
|
||||
|
||||
def is_ready(self) -> Dict[str, Any]:
|
||||
"""
|
||||
检查OpenCLI是否就绪
|
||||
|
||||
Returns:
|
||||
状态信息
|
||||
"""
|
||||
checks = {
|
||||
"opencli_installed": shutil.which("opencli") is not None,
|
||||
"node_version": None,
|
||||
"chrome_running": False,
|
||||
"clis_dir_exists": os.path.exists(self.clis_dir),
|
||||
}
|
||||
|
||||
# 检查Node版本
|
||||
try:
|
||||
result = subprocess.run(
|
||||
["node", "--version"],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
timeout=5
|
||||
)
|
||||
if result.returncode == 0:
|
||||
checks["node_version"] = result.stdout.strip()
|
||||
except:
|
||||
pass
|
||||
|
||||
# 检查Chrome是否运行(简单检查)
|
||||
try:
|
||||
result = subprocess.run(
|
||||
["pgrep", "-x", "chrome"],
|
||||
capture_output=True,
|
||||
timeout=2
|
||||
)
|
||||
checks["chrome_running"] = result.returncode == 0
|
||||
except:
|
||||
pass
|
||||
|
||||
checks["ready"] = (
|
||||
checks["opencli_installed"] and
|
||||
checks["node_version"] and
|
||||
checks["clis_dir_exists"]
|
||||
)
|
||||
|
||||
return checks
|
||||
|
||||
|
||||
# ==================== 命令行接口 ====================
|
||||
|
||||
def main():
|
||||
"""命令行入口"""
|
||||
import argparse
|
||||
|
||||
parser = argparse.ArgumentParser(description='OpenCLI Adapter')
|
||||
subparsers = parser.add_subparsers(dest='command', help='可用命令')
|
||||
|
||||
# setup
|
||||
subparsers.add_parser('setup', help='初始化OpenCLI')
|
||||
|
||||
# doctor
|
||||
subparsers.add_parser('doctor', help='诊断OpenCLI状态')
|
||||
|
||||
# list
|
||||
subparsers.add_parser('list', help='列出可用适配器')
|
||||
|
||||
# explore
|
||||
explore_parser = subparsers.add_parser('explore', help='探索网站API')
|
||||
explore_parser.add_argument('url', help='目标网站URL')
|
||||
|
||||
# synthesize
|
||||
synth_parser = subparsers.add_parser('synthesize', help='生成适配器')
|
||||
synth_parser.add_argument('name', help='适配器名称')
|
||||
synth_parser.add_argument('--url', help='网站URL')
|
||||
|
||||
# exec
|
||||
exec_parser = subparsers.add_parser('exec', help='执行CLI命令')
|
||||
exec_parser.add_argument('cli', help='CLI名称')
|
||||
exec_parser.add_argument('action', help='动作名称')
|
||||
exec_parser.add_argument('--args', nargs='*', help='额外参数')
|
||||
|
||||
# status
|
||||
subparsers.add_parser('status', help='检查状态')
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
if not args.command:
|
||||
parser.print_help()
|
||||
return
|
||||
|
||||
adapter = OpenCLIAdapter()
|
||||
|
||||
if args.command == 'setup':
|
||||
result = adapter.setup()
|
||||
print(result["stdout"] if result["success"] else result["stderr"])
|
||||
|
||||
elif args.command == 'doctor':
|
||||
result = adapter.doctor()
|
||||
print(result["stdout"] if result["success"] else result["stderr"])
|
||||
|
||||
elif args.command == 'list':
|
||||
adapters = adapter.list()
|
||||
print(json.dumps(adapters, indent=2, ensure_ascii=False))
|
||||
|
||||
elif args.command == 'explore':
|
||||
print(f"正在探索: {args.url}")
|
||||
result = adapter.explore(args.url)
|
||||
print(result["stdout"] if result["success"] else result["stderr"])
|
||||
|
||||
elif args.command == 'synthesize':
|
||||
print(f"正在生成适配器: {args.name}")
|
||||
result = adapter.synthesize(args.name, args.url)
|
||||
print(result["stdout"] if result["success"] else result["stderr"])
|
||||
|
||||
elif args.command == 'exec':
|
||||
print(f"执行: {args.cli} {args.action}")
|
||||
result = adapter.execute(args.cli, args.action)
|
||||
print(result["stdout"] if result["success"] else result["stderr"])
|
||||
|
||||
elif args.command == 'status':
|
||||
status = adapter.is_ready()
|
||||
print(json.dumps(status, indent=2, ensure_ascii=False))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
@@ -0,0 +1,145 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
OpenCLI Integration 测试脚本
|
||||
"""
|
||||
|
||||
import sys
|
||||
sys.path.insert(0, '/home/ubuntu/.nanobot/workspace/skills/opencli-integration')
|
||||
|
||||
from opencli_adapter import OpenCLIAdapter
|
||||
|
||||
|
||||
def test_status():
|
||||
"""测试状态检查"""
|
||||
print("=" * 60)
|
||||
print("测试1: 状态检查")
|
||||
print("=" * 60)
|
||||
|
||||
try:
|
||||
adapter = OpenCLIAdapter()
|
||||
status = adapter.is_ready()
|
||||
|
||||
print(f"OpenCLI安装: {'✅' if status['opencli_installed'] else '❌'}")
|
||||
print(f"Node版本: {status['node_version'] or '❌ 未安装'}")
|
||||
print(f"Chrome运行: {'✅' if status['chrome_running'] else '❌'}")
|
||||
print(f"CLIs目录: {'✅' if status['clis_dir_exists'] else '❌'}")
|
||||
print(f"整体就绪: {'✅' if status['ready'] else '❌'}")
|
||||
|
||||
except RuntimeError as e:
|
||||
print(f"⚠️ {e}")
|
||||
|
||||
print()
|
||||
|
||||
|
||||
def test_adapter_info():
|
||||
"""测试适配器信息"""
|
||||
print("=" * 60)
|
||||
print("测试2: 适配器管理")
|
||||
print("=" * 60)
|
||||
|
||||
try:
|
||||
adapter = OpenCLIAdapter()
|
||||
|
||||
# 检查clis目录
|
||||
import os
|
||||
clis_dir = os.path.expanduser("~/.opencli/clis")
|
||||
if os.path.exists(clis_dir):
|
||||
adapters = os.listdir(clis_dir)
|
||||
print(f"已安装适配器: {len(adapters)}个")
|
||||
for a in adapters[:5]: # 只显示前5个
|
||||
print(f" - {a}")
|
||||
else:
|
||||
print("适配器目录不存在")
|
||||
|
||||
except Exception as e:
|
||||
print(f"⚠️ {e}")
|
||||
|
||||
print()
|
||||
|
||||
|
||||
def test_yaml_adapter():
|
||||
"""测试创建YAML适配器"""
|
||||
print("=" * 60)
|
||||
print("测试3: YAML适配器创建")
|
||||
print("=" * 60)
|
||||
|
||||
try:
|
||||
adapter = OpenCLIAdapter()
|
||||
|
||||
config = {
|
||||
"name": "test_site",
|
||||
"base_url": "https://example.com",
|
||||
"description": "测试适配器",
|
||||
"commands": {
|
||||
"search": {
|
||||
"description": "搜索",
|
||||
"params": ["query"]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
path = adapter.create_yaml_adapter("test_site", config)
|
||||
print(f"✅ 适配器创建成功: {path}")
|
||||
|
||||
# 读取验证
|
||||
info = adapter.get_adapter_info("test_site")
|
||||
if info:
|
||||
print(f"✅ 适配器信息读取成功")
|
||||
print(f" 名称: {info.get('name')}")
|
||||
print(f" URL: {info.get('base_url')}")
|
||||
|
||||
# 清理
|
||||
adapter.remove_adapter("test_site")
|
||||
print("✅ 测试适配器已清理")
|
||||
|
||||
except Exception as e:
|
||||
print(f"⚠️ {e}")
|
||||
|
||||
print()
|
||||
|
||||
|
||||
def test_list_adapters():
|
||||
"""测试列出适配器"""
|
||||
print("=" * 60)
|
||||
print("测试4: 列出适配器")
|
||||
print("=" * 60)
|
||||
|
||||
try:
|
||||
adapter = OpenCLIAdapter()
|
||||
adapters = adapter.list()
|
||||
|
||||
if adapters:
|
||||
print(f"发现 {len(adapters)} 个适配器:")
|
||||
for a in adapters[:5]:
|
||||
print(f" - {a.get('name', 'unknown')}")
|
||||
else:
|
||||
print("暂无适配器或未安装OpenCLI")
|
||||
|
||||
except Exception as e:
|
||||
print(f"⚠️ {e}")
|
||||
|
||||
print()
|
||||
|
||||
|
||||
def main():
|
||||
"""运行所有测试"""
|
||||
print("\n")
|
||||
print("╔" + "=" * 58 + "╗")
|
||||
print("║" + " " * 12 + "OpenCLI Integration 测试" + " " * 22 + "║")
|
||||
print("╚" + "=" * 58 + "╝")
|
||||
print("\n")
|
||||
|
||||
test_status()
|
||||
test_adapter_info()
|
||||
test_yaml_adapter()
|
||||
test_list_adapters()
|
||||
|
||||
print("=" * 60)
|
||||
print("所有测试完成!")
|
||||
print("=" * 60)
|
||||
print("\n注意: 完整功能测试需要安装OpenCLI和Chrome浏览器")
|
||||
print("安装命令: npm install -g @jackwener/opencli")
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
Reference in New Issue
Block a user