Metadata-Version: 2.4
Name: dailo-devtools
Version: 0.2.2
Summary: 通过代劳 DevTools 调试单台 Android 设备的 Python API 与 CLI
License-Expression: MIT
Project-URL: Script SDK, https://pypi.org/project/dailo-sdk/
Keywords: android,automation,dailo,devtools,cli
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Framework :: AsyncIO
Classifier: Typing :: Typed
Requires-Python: >=3.11
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: dailo-sdk==0.2.2
Requires-Dist: playwright<2,>=1.58
Requires-Dist: aiohttp<4,>=3.14
Dynamic: license-file

# Dailo DevTools

在电脑上运行和调试代劳 Android 与 Windows 自动化脚本。提供 `dailo-dev` 命令行工具与 Python 客户端，可执行脚本、读取文字与控件、保存截图和查看日志。

- 命令行执行 Python 文件或短代码。
- Python API 支持连接设备、截图、观察和停止运行。
- 自动携带脚本目录中的 Python 模块与 `assets/`。
- 关键图文日志保存到电脑，可离线查看；开发日志留在执行设备，按需读取。

## 安装

需要 Python 3.11 或更新版本，以及已安装代劳 App、开启 DevTools 的 Android 设备。

```sh
python -m pip install dailo-devtools
dailo-dev install
```

`dailo-dev install` 安装后台连接所需的 Chromium 运行时，只需执行一次。

## 连接设备

从代劳 App 的 DevTools 入口复制连接链接，保存为 `connection.json`：

```json
{
  "url": "<从代劳 App 复制的 DevTools 链接>"
}
```

启动连接服务：

```sh
dailo-dev serve --connection connection.json
```

保持服务运行，在另一个终端执行后续命令。连接文件包含访问设备的凭据，请保存在本机；链接过期或重新连接时，从 App 获取新链接。

## Windows 本机调试

Windows 使用代劳安装目录中的 `runtime/windows-x64`，复用产品的 Rust 宿主和脚本执行通路，无需安装 Python 系统或视觉库。`--hwnd` 或 `--executable` 选择目标；省略时观察当前显示桌面。执行默认隐藏目标窗口，可用设置 `automation_mode: "normal"` 显式选择普通模式。

```sh
dailo-dev windows --runtime "C:\Apps\代劳\runtime\windows-x64" applications
dailo-dev windows --runtime "C:\Apps\代劳\runtime\windows-x64" desktops
dailo-dev windows --runtime "C:\Apps\代劳\runtime\windows-x64" --hwnd 123456 inspect
dailo-dev windows --runtime "C:\Apps\代劳\runtime\windows-x64" --hwnd 123456 screenshot screen.png
dailo-dev windows --runtime "C:\Apps\代劳\runtime\windows-x64" --hwnd 123456 exec --file main.py --timeout 300
```

Python 客户端提供同一能力；`cancel()` 可由调用方其他线程停止正在执行的脚本：

```python
from dailo_devtools import Windows

device = Windows(r"C:\Apps\代劳\runtime\windows-x64", hwnd=123456)
print(device.inspect())
device.run_file("main.py", config={"rounds": 5})
```

开发日志通过Android的`await device.developer_logs(execution_id)`或Windows的`device.developer_logs(execution_id)`读取。返回`items`和`nextCursor`；游标非空时继续传入`cursor`。读取日志不会执行脚本或采图。关键日志由脚本`key_log`自动同步。

## 运行脚本

执行一段代码：

```sh
dailo-dev exec --code "from dailo import text; print(text())"
```

执行 Python 文件并传入任务设置：

```sh
dailo-dev exec --file main.py --config settings.json
```

脚本可使用 [dailo-sdk](https://pypi.org/project/dailo-sdk/) 的文字、控件和图片定位 API。文件模式会自动上传脚本目录中的 Python 模块和 `assets/`；`--timeout` 设置执行时限，单位为秒，默认 300。

只携带本次所需资源时，使用 `--assets` 指定相对脚本目录的文件或目录；设备上保留相同相对路径。省略此参数时携带整个 `assets/`，单独使用 `--assets` 时不携带资源。Python 模块始终自动携带。

```sh
dailo-dev exec --file main.py --assets assets/battle.png assets/maps
dailo-dev exec --code "from dailo import text; print(text())" --assets
```

## 常用命令

| 命令 | 用途 |
| --- | --- |
| `dailo-dev status` | 查看连接和运行状态 |
| `dailo-dev inspect` | 读取设备画面的文字与控件 |
| `dailo-dev screenshot screen.png` | 保存设备截图 |
| `dailo-dev cancel` | 停止当前脚本 |
| `dailo-dev reconnect` | 使用持久连接配置重新连接设备 |
| `dailo-dev logs <日志目录>` | 离线查看图文日志 |

运行 `dailo-dev --help` 或 `dailo-dev exec --help` 查看完整选项。

## Python API

```python
import asyncio
import json
from pathlib import Path

from dailo_devtools import Device, read_logs


async def main():
    connection = json.loads(Path("connection.json").read_text(encoding="utf-8"))

    async with Device(connection) as device:
        result = await device.execute("from dailo import text; print(text())")
        await device.screenshot("screen.png")
        print(result)
        print(read_logs(result["logDirectory"]))


asyncio.run(main())
```

`Device` 还提供 `run_file(path, config=...)`、`inspect()` 和 `cancel()`。使用 Python 客户端时无需启动 `dailo-dev serve`；异步上下文管理器负责建立和关闭连接。

Android执行超时后请求停止；收到终态时直接返回原结果并标记`transportDeadlineExceeded`，可核`errorCode`和日志。停止后仍未收到结果或连接中断时才抛异常，保留未确认记录，不自动重放。

`run_file()` 和 `execute()` 的 `assets=None` 默认携带 `assets/`。传入显式列表会只携带选定资源，`assets=[]` 不携带资源，例如：

```python
await device.run_file("main.py", assets=["assets/battle.png", "assets/maps"])
await device.execute("from dailo import text; print(text())", assets=[])
```

Windows 的 `run_file()`、`execute()` 每次生成独立 `devtools:windows:…` 执行 ID，脚本通过 `execution()` 读取。明确续接某次失败时传入 `retry_of_execution_id=原执行ID`；新调用默认不关联旧父。调试 ID 不代表产品任务记录。

Android 的同名参数沿用Host提供的本父真实执行ID，只设置本次重试来源，退出后恢复原上下文。续接连续延期时，传入上一父脚本中`dailo.execution().execution_id`的完整原值；不要传请求短ID、sessionId或自行拼接ID。CLI使用`--retry-of-execution-id`，持久服务的`execute`／`run_file`请求使用`retry_of_execution_id`。省略参数表示新调用，不沿用旧延期链；该参数不修改原延期时间，也不绕过最早执行时间。

## 许可

MIT。
