Skill: wsjwoods/qianfan-usage (version 1.0.2)

# qianfan-usage 查询百度千帆 Coding Plan 用量和额度。 ## 使用方法 ``` /qianfan-usage # 自动登录并查询用量详情 /qianfan-usage --web # 打开百度千帆控制台 ``` ## 用量详情 查询 Coding Plan 的三级用量： | 周期 | 说明 | 重置时间 | |------|------|----------| | 5小时 | 短期用量 | 每5小时重置 | | 周 | 周用量 | 每周一重置 | | 月 | 月用量 | 套餐到期时重置 | ## 自动登录 脚本使用 `agent-browser` 自动登录百度账号： - 手机号：从环境变量 `QIANFAN_PHONE` 读取 - 验证码：需要手动输入（或等待短信） ## 配置 在 `~/.openclaw/workspace/.env` 中设置手机号： ``` QIANFAN_PHONE=你的手机号 ``` ## API 端点 ``` GET https://console.bce.baidu.com/api/qianfan/charge/codingPlan/quota ``` 返回格式： ```json { "success": true, "result": { "quota": { "fiveHour": { "used": 338, "limit": 1200, "resetAt": "..." }, "week": { "used": 499, "limit": 9000, "resetAt": "..." }, "month": { "used": 499, "limit": 18000, "resetAt": "..." } } } } ``` ## 依赖 - agent-browser（自动安装） - Python 3

path: .clawhub/origin.json
content: version: 1
registry: https://clawhub.ai
slug: qianfan-usage
installedVersion: 1.1.0
installedAt: 1773156000000

path: README.md
content: # Qianfan Usage

查询百度千帆 Coding Plan 用量和额度。

## 功能

- 🔍 自动检测 cookie 状态，失效时自动登录
- 📊 查询 Coding Plan 三级用量（5小时/周/月）
- 💾 保存登录状态，避免重复登录
- 🎨 彩色显示使用率和重置时间

## 安装

```bash
# 克隆仓库
git clone https://github.com/wsjwoods/qianfan-usage.git
cd qianfan-usage
```

## 使用方法

### 快速查询（推荐）

```bash
python3 qianfan_usage.py
```

自动检测 cookie 状态：
- ✅ 如果 cookie 有效，直接显示用量
- 🔑 如果 cookie 失效，自动打开登录页面，输入验证码即可

### 简化版（仅查询，需已登录）

```bash
python3 qianfan.py
```

### 完整版（带颜色和建议）

```bash
python3 check_quota_v2.py
```

## 配置

### 环境变量（可选）

设置手机号，避免每次输入：

```bash
export QIANFAN_PHONE=你的手机号
```

### Cookie 文件

登录成功后，cookie 自动保存到：
```
~/.baidu-qianfan-auth.json
```

## API 端点

```
GET https://console.bce.baidu.com/api/qianfan/charge/codingPlan/quota
```

返回格式：
```json
{
  "success": true,
  "result": {
    "quota": {
      "fiveHour": { "used": 25, "limit": 1200, "resetAt": "..." },
      "week": { "used": 2355, "limit": 9000, "resetAt": "..." },
      "month": { "used": 2355, "limit": 18000, "resetAt": "..." }
    }
  }
}
```

## 文件说明

| 文件 | 说明 |
|------|------|
| `qianfan_usage.py` | ⭐ 主程序，自动检测 cookie + 自动登录 |
| `qianfan.py` | 简化版，仅查询（需已登录） |
| `check_quota_v2.py` | 完整版，带颜色和建议 |
| `SKILL.md` | OpenClaw 技能描述 |

## 项目结构

```
qianfan-usage/
├── qianfan_usage.py      # ⭐ 主程序
├── qianfan.py            # 简化版
├── check_quota_v2.py     # 完整版
├── README.md             # 文档
├── SKILL.md              # OpenClaw 技能描述
├── LICENSE               # MIT
└── .gitignore            # 忽略敏感文件
```

## 依赖

- Python 3.8+
- curl
- [agent-browser](https://github.com/nicepkg/agent-browser)（用于自动登录）

## 输出示例

```
🔍 检查登录状态...
✓ Cookie 有效，直接查询用量

╔══════════════════════════════════════════════════════════╗
║          📊 百度千帆 · Coding Plan 用量详情              ║
╚══════════════════════════════════════════════════════════╝

⏱️  5小时周期:
   已用: 25 / 1200 (2.1%)
   剩余: 1175
   重置: 03月13日 01:50

📅 本周用量:
   已用: 2355 / 9000 (26.2%)
   剩余: 6645
   重置: 03月16日 00:00

📆 本月用量:
   已用: 2355 / 18000 (13.1%)
   剩余: 15645
   重置: 04月09日 16:39

══════════════════════════════════════════════════════════

💡 使用建议：
   • 用量正常 (2.1%)，可以继续使用
   • 月度额度剩余 86.9%
```

## License

MIT


path: _meta.json
content: {
  "name": "qianfan-usage",
  "version": "1.1.0",
  "description": "查询百度千帆 Coding Plan 用量和额度",
  "author": "xiaolong",
  "tags": [
    "qianfan",
    "baidu",
    "usage",
    "quota",
    "billing",
    "coding-plan"
  ],
  "commands": [
    {
      "name": "qianfan-usage",
      "description": "查询百度千帆 Coding Plan 用量详情",
      "script": "qianfan-usage.sh"
    }
  ],
  "env": [
    {
      "name": "QIANFAN_PHONE",
      "description": "百度账号手机号",
      "required": true
    }
  ],
  "dependencies": {
    "agent-browser": ">=1.0.0",
    "python3": ">=3.8"
  },
  "license": "MIT"
}


path: check_quota_v2.py
content: #!/usr/bin/env python3
"""
百度千帆 Coding Plan 用量查询工具
使用保存的 cookie 直接查询 API，避免重复登录
"""

import json
import subprocess
import sys
import os
from datetime import datetime

AUTH_FILE = os.path.expanduser("~/.baidu-qianfan-auth.json")
API_URL = "https://console.bce.baidu.com/api/qianfan/charge/codingPlan/quota"

# 颜色定义
CYAN = '\033[0;36m'
BLUE = '\033[0;34m'
GREEN = '\033[0;32m'
YELLOW = '\033[1;33m'
RED = '\033[0;31m'
NC = '\033[0m'

def load_cookies():
    """从状态文件加载 cookies"""
    if not os.path.exists(AUTH_FILE):
        return []
    
    try:
        with open(AUTH_FILE, 'r') as f:
            data = json.load(f)
        return data.get('cookies', [])
    except (json.JSONDecodeError, IOError) as e:
        print(f"{RED}读取 cookie 文件失败: {e}{NC}")
        return []

def build_cookie_string(cookies):
    """构建 cookie 字符串 - 只包含相关域名的 cookie"""
    cookie_parts = []
    relevant_domains = ['console.bce.baidu.com', 'bce.baidu.com', 'baidu.com']
    
    for cookie in cookies:
        name = cookie.get('name', '')
        value = cookie.get('value', '')
        domain = cookie.get('domain', '')
        
        if name and value:
            # 只包含与百度智能云相关的 cookie
            for d in relevant_domains:
                if d in domain:
                    cookie_parts.append(f"{name}={value}")
                    break
    
    return '; '.join(cookie_parts)

def query_quota():
    """查询用量"""
    cookies = load_cookies()
    
    if not cookies:
        return None, "未找到保存的 cookie，请先运行登录脚本"
    
    cookie_str = build_cookie_string(cookies)
    
    if not cookie_str:
        return None, "无法构建有效的 cookie 字符串"
    
    # 使用 curl 查询 API
    cmd = [
        'curl', '-s', '-L',
        API_URL,
        '-H', 'Accept: application/json, text/plain, */*',
        '-H', 'Accept-Language: zh-CN,zh;q=0.9,en;q=0.8',
        '-H', 'Referer: https://console.bce.baidu.com/qianfan/resource/subscribe',
        '-H', f'Cookie: {cookie_str}',
        '-H', 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
        '-H', 'X-Requested-With: XMLHttpRequest',
        '--connect-timeout', '10',
        '--max-time', '30'
    ]
    
    result = subprocess.run(cmd, capture_output=True, text=True)
    
    if result.returncode != 0:
        return None, f"请求失败: {result.stderr}"
    
    return result.stdout, None

def format_reset_time(reset_at):
    """格式化重置时间"""
    try:
        # 处理 ISO 格式时间
        dt = datetime.fromisoformat(reset_at.replace('+08:00', ''))
        return dt.strftime('%m月%d日 %H:%M')
    except:
        return reset_at

def parse_quota(data):
    """解析 API 响应"""
    try:
        if not data:
            return None, "空响应"
        
        result = json.loads(data)
        
        if not result.get('success'):
            error_msg = result.get('message', '未知错误')
            return None, f"API 返回错误: {error_msg}"
        
        quota = result.get('result', {}).get('quota', {})
        
        if not quota:
            return None, "响应中未找到 quota 数据"
        
        return quota, None
        
    except json.JSONDecodeError as e:
        return None, f"JSON 解析失败: {e}, 原始数据: {data[:200]}"

def display_quota(quota):
    """显示用量信息"""
    print(f"\n{CYAN}╔══════════════════════════════════════════════════════════╗{NC}")
    print(f"{CYAN}║          📊 百度千帆 · Coding Plan 用量详情              ║{NC}")
    print(f"{CYAN}╚══════════════════════════════════════════════════════════╝{NC}\n")
    
    # 定义周期
    periods = [
        ('⏱️  5小时周期', 'fiveHour'),
        ('📅 本周用量', 'week'),
        ('📆 本月用量', 'month')
    ]
    
    for label, key in periods:
        data = quota.get(key, {})
        used = data.get('used', 0)
        limit = data.get('limit', 0)
        reset_at = data.get('resetAt', '未知')
        
        remaining = limit - used if limit > 0 else 0
        percent = (used / limit * 100) if limit > 0 else 0
        reset_time = format_reset_time(reset_at)
        
        # 根据使用率选择颜色
        if percent < 50:
            color = GREEN
            status = "充足"
        elif percent < 80:
            color = YELLOW
            status = "注意"
        else:
            color = RED
            status = "警告"
        
        print(f"{BLUE}{label}:{NC}")
        print(f"   已用: {used} / {limit} ({color}{percent:.1f}%{NC})")
        print(f"   剩余: {remaining}")
        print(f"   重置: {reset_time}")
        print(f"   状态: {color}{status}{NC}")
        print()
    
    print(f"{CYAN}══════════════════════════════════════════════════════════{NC}")
    
    # 总体建议
    five_hour = quota.get('fiveHour', {})
    five_hour_percent = (five_hour.get('used', 0) / five_hour.get('limit', 1)) * 100
    
    print(f"\n{BLUE}💡 使用建议：{NC}")
    if five_hour_percent > 80:
        print(f"   {RED}• 5小时用量较高 ({five_hour_percent:.1f}%)，建议稍后再用{NC}")
    elif five_hour_percent > 50:
        print(f"   {YELLOW}• 5小时用量中等 ({five_hour_percent:.1f}%)，可继续使用{NC}")
    else:
        print(f"   {GREEN}• 用量正常 ({five_hour_percent:.1f}%)，可以继续使用{NC}")
    
    month = quota.get('month', {})
    month_percent = (month.get('used', 0) / month.get('limit', 1)) * 100
    print(f"   • 月度额度剩余 {(100-month_percent):.1f}%")

def main():
    print(f"{BLUE}🔍 正在查询千帆 Coding Plan 用量...{NC}")
    
    # 检查 cookie 文件
    if not os.path.exists(AUTH_FILE):
        print(f"{RED}❌ 未找到 cookie 文件: {AUTH_FILE}{NC}")
        print(f"{YELLOW}💡 请先运行登录脚本获取 cookie{NC}")
        return 1
    
    # 查询用量
    print(f"{BLUE}📊 正在请求 API...{NC}")
    result, error = query_quota()
    
    if error:
        print(f"{RED}❌ {error}{NC}")
        return 1
    
    # 解析响应
    quota, error = parse_quota(result)
    
    if error:
        print(f"{RED}❌ {error}{NC}")
        
        # 检查是否是登录过期
        if '未登录' in error or 'login' in result.lower():
            print(f"{YELLOW}💡 Cookie 可能已过期，需要重新登录{NC}")
        return 1
    
    # 显示结果
    display_quota(quota)
    
    return 0

if __name__ == '__main__':
    sys.exit(main())


path: qianfan.py
content: #!/usr/bin/env python3
"""
百度千帆 Coding Plan 用量快速查询
直接使用保存的 cookie，无需登录
"""

import json
import subprocess
import sys
import os

AUTH_FILE = os.path.expanduser("~/.baidu-qianfan-auth.json")
API_URL = "https://console.bce.baidu.com/api/qianfan/charge/codingPlan/quota"

def load_cookies():
    """加载保存的 cookies"""
    if not os.path.exists(AUTH_FILE):
        return None
    
    with open(AUTH_FILE, 'r') as f:
        data = json.load(f)
    return data.get('cookies', [])

def build_cookie_string(cookies):
    """构建 cookie 字符串"""
    parts = []
    for c in cookies:
        if 'baidu.com' in c.get('domain', ''):
            parts.append(f"{c['name']}={c['value']}")
    return '; '.join(parts)

def query():
    """查询用量"""
    cookies = load_cookies()
    if not cookies:
        return None, "未找到 cookie，请先登录"
    
    cmd = [
        'curl', '-s', '-L', API_URL,
        '-H', f'Cookie: {build_cookie_string(cookies)}',
        '-H', 'Referer: https://console.bce.baidu.com/qianfan/resource/subscribe',
        '-H', 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36'
    ]
    
    result = subprocess.run(cmd, capture_output=True, text=True)
    
    if result.returncode != 0:
        return None, result.stderr
    
    try:
        data = json.loads(result.stdout)
        if not data.get('success'):
            return None, data.get('message', '查询失败')
        return data['result']['quota'], None
    except (json.JSONDecodeError, KeyError) as e:
        return None, f"解析失败: {e}"

def format_time(t):
    """格式化时间"""
    return t.replace('T', ' ').replace('+08:00', '')[:16]

def main():
    quota, error = query()
    
    if error:
        print(f"❌ {error}")
        return 1
    
    print("=" * 50)
    print("📊 千帆 Coding Plan 用量")
    print("=" * 50)
    
    for name, key in [('5小时', 'fiveHour'), ('本周', 'week'), ('本月', 'month')]:
        q = quota.get(key, {})
        used, limit = q.get('used', 0), q.get('limit', 0)
        pct = used / limit * 100 if limit else 0
        reset = format_time(q.get('resetAt', '未知'))
        print(f"\n⏱️ {name}: {used}/{limit} ({pct:.1f}%)")
        print(f"   剩余: {limit - used} | 重置: {reset}")
    
    print("\n" + "=" * 50)
    return 0

if __name__ == '__main__':
    sys.exit(main())


path: qianfan_usage.py
content: #!/usr/bin/env python3
"""
百度千帆 Coding Plan 用量查询工具
自动检测 cookie 状态，失效时自动登录
"""

import json
import subprocess
import sys
import os
import re
import time
from datetime import datetime

AUTH_FILE = os.path.expanduser("~/.baidu-qianfan-auth.json")
API_URL = "https://console.bce.baidu.com/api/qianfan/charge/codingPlan/quota"
LOGIN_URL = "https://console.bce.baidu.com/qianfan/resource/subscribe"

# 颜色定义
CYAN = '\033[0;36m'
BLUE = '\033[0;34m'
GREEN = '\033[0;32m'
YELLOW = '\033[1;33m'
RED = '\033[0;31m'
NC = '\033[0m'

def run_browser(args):
    """运行 agent-browser 命令"""
    result = subprocess.run(
        ['agent-browser'] + args,
        capture_output=True,
        text=True
    )
    return result.stdout.strip(), result.stderr.strip(), result.returncode

def open_page(url):
    """打开页面"""
    stdout, stderr, code = run_browser(['open', url])
    return code == 0

def get_url():
    """获取当前 URL"""
    stdout, stderr, code = run_browser(['get', 'url'])
    return stdout if code == 0 else None

def get_snapshot():
    """获取页面快照"""
    stdout, stderr, code = run_browser(['snapshot', '-i'])
    return stdout if code == 0 else None

def eval_js(js_code):
    """执行 JavaScript"""
    stdout, stderr, code = run_browser(['eval', js_code])
    return stdout if code == 0 else None

def click_element(ref):
    """点击元素"""
    stdout, stderr, code = run_browser(['click', ref])
    return code == 0

def fill_input(ref, text):
    """填充输入框"""
    stdout, stderr, code = run_browser(['fill', ref, text])
    return code == 0

def close_browser():
    """关闭浏览器"""
    run_browser(['close'])

def save_auth():
    """保存登录状态"""
    stdout, stderr, code = run_browser(['state', 'save', AUTH_FILE])
    return code == 0

def parse_snapshot(snapshot):
    """解析快照，提取元素引用"""
    elements = {}
    for line in snapshot.split('\n'):
        # 匹配类似: textbox "手机号" [ref=e3]
        match = re.search(r'(\w+(?:\s+\w+)*)\s+"([^"]+)"\s+\[ref=(e\d+)\]', line)
        if match:
            elem_type, text, ref = match.groups()
            elements[text] = ref
            elements[f"{elem_type}:{text}"] = ref
        # 匹配按钮: button "登录/注册" [ref=e9]
        match = re.search(r'button\s+"([^"]+)"\s+\[ref=(e\d+)\]', line)
        if match:
            text, ref = match.groups()
            elements[text] = ref
    return elements

def build_cookie_string(cookies):
    """构建 cookie 字符串"""
    parts = []
    for c in cookies:
        if 'baidu.com' in c.get('domain', ''):
            parts.append(f"{c['name']}={c['value']}")
    return '; '.join(parts)

def query_with_curl(cookies):
    """使用 curl 查询 API"""
    cookie_str = build_cookie_string(cookies)
    
    cmd = [
        'curl', '-s', '-L', API_URL,
        '-H', f'Cookie: {cookie_str}',
        '-H', 'Referer: https://console.bce.baidu.com/qianfan/resource/subscribe',
        '-H', 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36',
        '--max-time', '10'
    ]
    
    result = subprocess.run(cmd, capture_output=True, text=True)
    return result.stdout if result.returncode == 0 else None

def check_cookie_valid():
    """检查 cookie 是否有效"""
    if not os.path.exists(AUTH_FILE):
        return False, "未找到 cookie 文件"
    
    try:
        with open(AUTH_FILE, 'r') as f:
            data = json.load(f)
        cookies = data.get('cookies', [])
        
        if not cookies:
            return False, "cookie 文件为空"
        
        # 尝试查询 API
        result = query_with_curl(cookies)
        
        if not result:
            return False, "API 请求失败"
        
        try:
            data = json.loads(result)
            if data.get('success'):
                return True, data['result']['quota']
            else:
                return False, f"API 返回错误: {data.get('message', '未知错误')}"
        except json.JSONDecodeError:
            return False, "响应解析失败，cookie 可能已过期"
            
    except (json.JSONDecodeError, IOError) as e:
        return False, f"读取 cookie 失败: {e}"

def login(phone):
    """登录百度账号"""
    print(f"{BLUE}正在打开登录页面...{NC}")
    
    # 打开订阅页面（会重定向到登录页）
    open_page(LOGIN_URL)
    time.sleep(3)
    
    # 获取登录页面元素
    snapshot = get_snapshot()
    elements = parse_snapshot(snapshot)
    
    # 检查是否已经登录
    url = get_url()
    if url and 'qianfan' in url and 'login' not in url:
        print(f"{GREEN}✓ 已经登录{NC}")
        save_auth()
        return True
    
    # 填写手机号
    if '手机号' in elements:
        fill_input(elements['手机号'], phone)
        print(f"{BLUE}已填写手机号{NC}")
    else:
        print(f"{RED}未找到手机号输入框{NC}")
        return False
    
    # 发送验证码
    if '发送验证码' in elements:
        click_element(elements['发送验证码'])
        print(f"{YELLOW}验证码已发送到 {phone}{NC}")
    else:
        print(f"{RED}未找到发送验证码按钮{NC}")
        return False
    
    # 获取验证码输入
    code = input(f"{YELLOW}请输入验证码: {NC}").strip()
    
    if not code:
        print(f"{RED}验证码不能为空{NC}")
        return False
    
    # 重新获取快照
    snapshot = get_snapshot()
    elements = parse_snapshot(snapshot)
    
    # 填写验证码
    if '短信验证码' in elements:
        fill_input(elements['短信验证码'], code)
    else:
        print(f"{RED}未找到验证码输入框{NC}")
        return False
    
    # 勾选协议
    if '我已阅读并同意' in elements:
        from subprocess import run
        run(['agent-browser', 'check', elements['我已阅读并同意']], capture_output=True)
    
    # 点击登录
    snapshot = get_snapshot()
    elements = parse_snapshot(snapshot)
    
    if '登录/注册' in elements:
        click_element(elements['登录/注册'])
        print(f"{BLUE}正在登录...{NC}")
    else:
        print(f"{RED}未找到登录按钮{NC}")
        return False
    
    # 等待登录完成
    time.sleep(5)
    
    # 检查是否需要二次验证
    url = get_url()
    if url and ('verify' in url or 'login' in url):
        print(f"{YELLOW}需要进行二次验证{NC}")
        snapshot = get_snapshot()
        elements = parse_snapshot(snapshot)
        
        if '发送验证码' in elements:
            click_element(elements['发送验证码'])
            code = input(f"{YELLOW}请输入二次验证码: {NC}").strip()
            
            snapshot = get_snapshot()
            elements = parse_snapshot(snapshot)
            
            if '验证码' in elements:
                fill_input(elements['验证码'], code)
            
            if '确定' in elements:
                click_element(elements['确定'])
            
            time.sleep(3)
    
    # 检查登录结果
    url = get_url()
    if url and 'qianfan' in url and 'login' not in url:
        print(f"{GREEN}✓ 登录成功{NC}")
        save_auth()
        return True
    else:
        print(f"{RED}登录失败{NC}")
        return False

def format_time(t):
    """格式化时间"""
    try:
        dt = datetime.fromisoformat(t.replace('+08:00', ''))
        return dt.strftime('%m月%d日 %H:%M')
    except:
        return t

def display_quota(quota):
    """显示用量"""
    print(f"\n{CYAN}╔══════════════════════════════════════════════════════════╗{NC}")
    print(f"{CYAN}║          📊 百度千帆 · Coding Plan 用量详情              ║{NC}")
    print(f"{CYAN}╚══════════════════════════════════════════════════════════╝{NC}\n")
    
    for label, key in [('⏱️  5小时周期', 'fiveHour'), ('📅 本周用量', 'week'), ('📆 本月用量', 'month')]:
        q = quota.get(key, {})
        used, limit = q.get('used', 0), q.get('limit', 0)
        remaining = limit - used if limit else 0
        pct = used / limit * 100 if limit else 0
        reset = format_time(q.get('resetAt', '未知'))
        
        if pct < 50:
            color = GREEN
        elif pct < 80:
            color = YELLOW
        else:
            color = RED
        
        print(f"{BLUE}{label}:{NC}")
        print(f"   已用: {used} / {limit} ({color}{pct:.1f}%{NC})")
        print(f"   剩余: {remaining}")
        print(f"   重置: {reset}")
        print()
    
    print(f"{CYAN}══════════════════════════════════════════════════════════{NC}")

def main():
    # 检查 cookie 是否有效
    print(f"{BLUE}🔍 检查登录状态...{NC}")
    is_valid, result = check_cookie_valid()
    
    if is_valid:
        print(f"{GREEN}✓ Cookie 有效，直接查询用量{NC}")
        display_quota(result)
        close_browser()
        return 0
    
    # Cookie 无效，需要登录
    print(f"{YELLOW}⚠ {result}{NC}")
    print(f"{YELLOW}需要重新登录{NC}\n")
    
    # 获取手机号
    phone = os.environ.get('QIANFAN_PHONE', '')
    if not phone:
        phone = input(f"{BLUE}请输入手机号: {NC}").strip()
    
    if not phone:
        print(f"{RED}手机号不能为空{NC}")
        return 1
    
    try:
        # 登录
        if login(phone):
            # 重新查询
            is_valid, result = check_cookie_valid()
            if is_valid:
                display_quota(result)
                return 0
            else:
                print(f"{RED}查询失败: {result}{NC}")
                return 1
        else:
            return 1
    finally:
        close_browser()

if __name__ == '__main__':
    sys.exit(main())


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