Metadata-Version: 2.4
Name: ptcg-arena-cli
Version: 0.1.1
Summary: PTCG-Arena AI 对战比赛平台的命令行自动化工具（配套 Claude Code Skill）
Author: Swcmb
License-Expression: GPL-3.0-or-later
Project-URL: Homepage, https://github.com/Swcmb/ptcg-arena-cli
Project-URL: Changelog, https://github.com/Swcmb/ptcg-arena-cli/blob/main/CHANGELOG.md
Keywords: ptcg,arena,cli,kaggle,agent
Classifier: Environment :: Console
Classifier: Programming Language :: Python :: 3
Classifier: Topic :: Games/Entertainment :: Turn Based Strategy
Classifier: Topic :: Software Development :: Testing
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: COPYING
Dynamic: license-file

# ptcg-arena-cli

PTCG-Arena AI 对战比赛平台的命令行自动化工具，配套一个 Claude Code Skill。
本工具独立于本地训练项目，按环境变量 `PTCG_PROJECT_DIR` 只读引用其中的脚本与产物。

- Agent 编排说明：[`.claude/skills/ptcg-arena/SKILL.md`](.claude/skills/ptcg-arena/SKILL.md)
- 版本与发布：SemVer，`vX.Y.Z` 标签一经发布不可移动；变更历史见 [`CHANGELOG.md`](CHANGELOG.md)，
  打标签即触发 Actions 构建、GitHub Release 与 PyPI 发布
- 许可证：GPL-3.0-or-later（见 [`COPYING`](COPYING)）

## 设计边界

| 边界 | 说明 |
|:--|:--|
| 零第三方依赖 | 只用 Python 标准库（`urllib` / `tarfile` / `ast` / `csv`），不装 requests |
| 只做已验证能力 | 所有接口来自实测清单；实测 404 的 `/api/leaderboard`、`/api/status`、`/api/schedule`、`/api/competitions` 一律不实现 |
| 状态可区分 | 每条平台命令输出 `实时数据 / 缓存数据(时间) / 不可用`，网络失败绝不报成功 |
| 写操作需确认 | `agent submit` 默认 `--dry-run` 语义，真实提交要输入 `yes`；本地校验不通过直接拒绝 |
| 凭证隔离 | 密码只从环境变量或 `.secrets/credentials.json` 读取，不进命令行参数、日志、历史、Git、报告 |
| 不碰训练 | 工具永不启动训练，也不自动替换检查点；只生成供本人手动运行的命令 |

## 安装

已发布到 PyPI（包名 `ptcg-arena-cli`）：

```bash
pipx install ptcg-arena-cli      # 或 uv tool install ptcg-arena-cli
ptcg-arena --version
```

从源码安装：

```bash
cd ptcg-arena-cli
python -m venv .venv && .venv/Scripts/python -m pip install -e .
.venv/Scripts/ptcg-arena --version
```

不安装也能用：

```bash
python -m ptcg_arena --help
```

要求 Python ≥ 3.10。

## 配置凭证

任选一种，密码绝不作为命令行参数传入：

```bash
# 方式一：环境变量
export PTCG_ARENA_USERNAME='你的用户名'
export PTCG_ARENA_PASSWORD='你的密码'

# 方式二：凭证文件（该目录已被 .gitignore 排除）
mkdir -p .secrets
cat > .secrets/credentials.json <<'JSON'
{"PTCG_ARENA_USERNAME": "你的用户名", "PTCG_ARENA_PASSWORD": "你的密码"}
JSON
```

平台地址（仓库不内置）：设置 `PTCG_ARENA_BASE_URL`，或把地址写入 `.secrets/base_url.txt`
（该目录已被 `.gitignore` 排除）。填 `https` 会被拒绝——平台只有 HTTP。
其他可选环境变量：`PTCG_ARENA_CREDENTIALS`（自定义凭证文件路径）、`PTCG_ARENA_HOME`（自定义数据根目录）、
`PTCG_PROJECT_DIR`（本地训练项目目录，`export plan` 只读引用）、
`PTCG_PYTHON`（probe / 导出计划使用的解释器，默认当前 Python）。

> Windows 提醒：`.secrets` 无法用 POSIX 位收紧（实测 `stat` 返回 `0o666`，NTFS 不认 git-bash 的 `umask`）。
> 实际保护手段是「仓库外 + Git 排除」。要更强隔离请改用 DPAPI 或 Windows 凭据管理器。

## 常用命令

```bash
ptcg-arena auth login --no-input          # 登录，token 落到 .secrets/token.json
ptcg-arena auth status                    # 向平台实测校验（连不上时报「不可用」，不伪造已登录）
ptcg-arena status                         # 健康 + A/B 榜摘要
ptcg-arena competition status --board a   # 阶段、轮次区间、下一轮、调度间隔
ptcg-arena leaderboard --board a --limit 10
ptcg-arena leaderboard --board a --mine   # 只看我的队伍
ptcg-arena rounds --board a --limit 5
ptcg-arena results --mine --round 33      # 我方逐局对局（player 字段是队伍 ID）
ptcg-arena results --log-id 1             # 单局日志
ptcg-arena agent mine                     # 我的提交记录
ptcg-arena agent bots                     # 对战池 Agent
ptcg-arena cards sync                     # 拉取平台权威卡表（1267 张）并缓存
ptcg-arena agent validate <包或目录>       # 校验提交包/构建目录
ptcg-arena agent inspect <包>              # 包内清单 + sha256
ptcg-arena agent probe <构建目录>          # 真跑 agent()，验动作契约与单步耗时
ptcg-arena export plan                    # 检查导出输入 + 打印导出命令（不执行）
ptcg-arena history --limit 20             # 本地运行记录
ptcg-arena report 5                       # 取单条记录
```

机器可读输出：全局 `--json` 放在子命令**之前**：

```bash
ptcg-arena --json leaderboard --board a
```

## 正式提交

```bash
# 第一步：只看计划，零请求
ptcg-arena agent submit <包> --dry-run

# 第二步：确认后才真的上传
ptcg-arena agent submit "$PTCG_PROJECT_DIR/submission_rl_transformer2_db_migrated.tar.gz"
```

第二条命令会打印目标赛事、账号、文件名、大小、sha256、本地校验结论、已有提交数，
并要求输入 `yes`。任一环节没确认，平台侧零写入。

## 校验器覆盖的平台规则

| 编号 | 规则 | 来源 |
|:--|:--|:--|
| R1 | `deck.csv` 恰好 60 行，每行一个裸整数 | 平台规则页 |
| R2 | 每个 `cardId` 必须在平台卡表内（1–1267） | 实测 `/api/cards/csv` |
| R3 | ≥1 张真正的基础宝可梦（`cardType=0` 且 `basic=1`），化石卡不计 | 平台规则页 + 卡表实测 |
| R4 | 同名 ≤4（按 `name` 跨 `cardId` 合并），基础能量 `cardType=5` 豁免 | 平台规则页 |
| R5 | ACE SPEC（`aceSpec=1`）全牌组 ≤1，跨卡名同样合计 | 平台规则页 |
| R6 | `main.py` 必须定义同步 `agent` 函数且有显式 return | 平台规则页 |
| R7 | 必须是可解析的 `.tar.gz` / `.tgz` | 前端 `accept` + 规则页 |
| 契约 | `minCount ≤ 返回长度 ≤ maxCount`、下标 `< len(option)`、不重复 | 平台规则页 + `sdk_cg/api.py` |

**结构检查通过 ≠ 平台已接受。** 只有真实提交拿到 `status=validated/active` 才能说平台接受了。

> `agent validate` 只做静态分析（`tarfile` + `ast`），**不执行包内任何代码**。
> `agent probe` 则会 `import` 包内 `main.py` 并调用它；本项目的 `main.py` 在导入期读取 `model.pt`，
> 属于反序列化自身构建的模型。因此 `probe` 只用于**自己构建的包**，不要对来源不明的提交包运行。

## 测试

```bash
python -m pytest tests/ -q                     # 88 项，全部离线，0.8s
python scripts/check_skill_commands.py         # Skill ↔ CLI 命令一致性
```

## 退出码

| 码 | 含义 |
|:--|:--|
| 0 | 成功 |
| 2 | 凭证/配置缺失 |
| 3 | 未登录 / token 失效 |
| 4 | 网络不可达或状态无法确认（**不是成功，也不是空数据**） |
| 5 | 平台返回 4xx/5xx，或提交被平台拒绝 |
| 6 | 校验失败 / 探测未通过 |
| 7 | 写操作未获确认，已取消 |

## 已知未验证事项

平台没有公开文档，以下几项**只能靠真实提交或管理员说明**才能确认，本工具如实标注而不猜测：

1. 上传包体的大小上限（当前提交包约 71.6 MB）。
2. 包内除 `main.py` + `deck.csv` 外是否允许附带文件（当前产物带 14 个顶层项）。
3. 重复提交是覆盖旧版本还是并存，以及有无撤回手段。
4. 平台沙箱是否预装 `torch`（本包依赖它）。
5. JWT 的实际有效期。

详细依据见 `docs/platform-audit.md` §4、§9。

## License

GPL-3.0-or-later，全文见 `COPYING`。手写源文件均带
`SPDX-License-Identifier: GPL-3.0-or-later`。

```text
ptcg-arena  Copyright (C) 2026  Swcmb
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it under
certain conditions; type `show c' for details.
```
