cliany-site 文档
cliany-site 基于 LLM 和 Chrome CDP 协议,将任意网页操作自动化为可重复调用的 CLI 命令。核心流程:explore(探索)→ generate(生成适配器)→ run(执行)。
v0.16.365 提供维护中的 ASF Confluence 只读关键词搜索包。公开资产已按固定 SHA-256 在隔离环境完成安装、严格校验与只读查询验收,案例现为 active;已有 adapter 不会自动覆盖。安装命令见 README。
v0.16.368 将 ASF Jenkins 只读 job 列表案例晋级 active。维护版 v0.16.367 公开包已通过固定哈希安装、严格校验和 5/106 条在线查询,首次 demo 路径也完成验收;历史 v0.14.1 包仍不适用。已有 adapter 不会自动覆盖。安装命令见 README。
Chrome 的 browser navigate 会检查导航后的语义树:若看到站点验证页,返回 E_PAGE_NOT_READY,不会把已接受 URL 误作可用页面。npm 搜索在当前网络仍受 Cloudflare 验证页阻挡。
严格发布预检会校验包版本、官网和两份路线图使用同一基线;路线图版本滞后会在创建 tag 前阻断发布。这是发布上下文的一致性检查,不代表 Chrome、LLM 或第三方工作流已就绪。
严格 publication audit 会有限重试短暂的远端 Git 或 GitHub/PyPI JSON 传输失败;持续失败和 HTTP 响应仍是阻断证据,不会被当作已发布。
官网不再在运行时请求 Google Fonts,而是使用显式系统字体栈;第三方字体网络错误不会阻塞页面或制造控制台错误。
GET /adapters?detail= 与 GET /doctor?llm_live= 共用严格布尔解析:各只能出现一次,true/false、1/0 与 yes/no 保持兼容;无效或重复值返回 BAD_REQUEST / HTTP 400,不会静默退回简略 adapter 列表。
安装
PyPI 安装(推荐)
pip install cliany-site
源码安装
git clone https://github.com/pearjelly/cliany.site.git
cd cliany.site
pip install -e .
依赖 Python ≥ 3.11 和 Chrome/Chromium 浏览器(工具会自动检测并启动)。
配置 LLM
支持 Anthropic(Claude)和 OpenAI(GPT-4o)两种 provider,二选一:
# Anthropic Claude(推荐)
export CLIANY_LLM_PROVIDER=anthropic
export CLIANY_ANTHROPIC_API_KEY="sk-ant-..."
# OpenAI GPT-4o
export CLIANY_LLM_PROVIDER=openai
export CLIANY_OPENAI_API_KEY="sk-..."
也可以写入 .env 文件,查找顺序:~/.config/cliany-site/.env → 所选运行目录的 .env(默认 ~/.cliany-site/.env)→ 项目目录 .env → 系统环境变量。
explore --json 遇到 LLM 网关、限流或服务暂不可用时会返回 E_LLM_UNAVAILABLE,并在 details.retryable、details.status_code 和 details.phase 中给出可重试上下文;错误消息会清洗原始 HTML 网关页。
OpenAI 兼容客户端使用 120 秒网络操作超时,并关闭 SDK 内部重试。探索保留可见的外层尝试与退避;doctor 只做一次显式预检。这不是整个流程的总时限,响应分块和重试可延长耗时,重试也可能产生额外模型费用。
模型失败与重试诊断
从 v0.16.381 起,实测 HTTP 状态优先于正文中的网关关键词,被拒绝的请求不会重复调用。CLI/live doctor 的 401/403 保留 E_LLM_AUTH_FAILED,其他 HTTP 拒绝返回 retryable=false。重试警告及可选 explore_llm_attempt_error 事件仅提供固定类别、状态和 retryability,不回显上游正文或私密地址;其他旧进度事件仍可能含 workflow URL。既有网络超时与结果质量门禁不变,不据此宣称提速或 provider 持续可用。见失败与重试诊断边界。
10 分钟成功路径
先检查本机,再运行一个无需登录的公开只读案例。demo 只在本地没有同名 adapter 时按固定 SHA-256 安装,始终先运行 verify --strict,通过后才查询,并要求至少一条结果。失败会非零退出,不覆盖已有 adapter,不执行 candidate 或需要登录的案例。不需要先配置 LLM key 或 Chrome/CDP;Jira、Confluence 和 Jenkins 案例仍依赖 GitHub 发布资产和第三方站点可达。准备生成自己的命令时,再进入 配置 LLM 和 explore。
# 1. 查看 human 摘要和下一步
cliany-site doctor
# 2. 拿到真实 issue 结果;检查 ok=true 和 data.row_count >= 1
cliany-site demo --case-id apache-jira-issues --json
# 3. 或搜索公开 Wiki 页面
cliany-site demo --case-id apache-confluence-search --json
# 4. 或读取公开 Jenkins job 列表
cliany-site demo --case-id apache-jenkins-jobs --json
# 5. 查看其他维护中的案例
cliany-site cases --status active
2026-10-02 使用已发布 PyPI v0.16.368 CLI 在全新 HOME 运行 Jira demo:固定哈希安装、cliany-site verify issues.apache.org --strict --json 校验和只读查询返回 5 条 Spark issue,第二次运行复用 adapter。查看完整审计;它只证明捕获时点的结果,不代表 live LLM 或第三方服务持续可用。
维护者还可用 scripts/capture_active_demo_evidence.py 在当前环境生成日期化的只读查询快照;静态校验必须先通过。
普通 doctor 只检查本地配置,不会真实调用 LLM provider。自动化读取 JSON 时,data.summary.ready_for_explore 与 generate_adapters.local_ready 只表示本地配置可用,local_blockers 只解释本地前提;只有 data.summary.ready_for_live_explore=true(或等价 capability 字段)才能放行真实 explore。provider 预检失败时,本地前提仍可保持 local_ready=true,同时整体 ready=false、live_blockers=["llm_live"];按 next_step 重跑严格命令:
cliany-site doctor --llm-live --require-capability generate_adapters --json
发布者也可以提供直接 HTTPS adapter 包;远程安装必须固定完成归档的 64 个字符小写十六进制 SHA-256,并会复用同一套包校验:
cliany-site market publish github.com --version 1.0.0 --json
发布成功 JSON 中的 data.package_sha256 是完成归档的 64 个字符小写十六进制 SHA-256 摘要;将该值填入发布者提供的通用 HTTPS 安装命令:
cliany-site market install https://publisher.example/releases/adapter.cliany-adapter.tar.gz --sha256 <64-hex-sha256> --dry-run --json
--dry-run 成功只说明分发包可用,不会安装 adapter;已安装同名 adapter 时,预检会返回 installed_version 与 incoming version,并以 requires_force=true 的只读计划表示仍需显式覆盖。若 installed_version=null,仍以 would_replace 判断 adapter 是否存在。运行 verify <domain> 前,请移除该选项完成安装。
维护中的公开 demo 已在案例目录中提供 release 固定 URL 和 SHA-256。先查看案例,再复制首条安装命令:
cliany-site cases --case-id suitecrm-accounts
doctor — 环境检查
检查 Chrome CDP 连通性、LLM Key 有效性、目录结构。
cliany-site doctor [--json] [--llm-live]
准备运行 explore 时,使用 cliany-site doctor --llm-live --require-capability generate_adapters --json 做一次真实 provider 预检;只有它成功,才继续生成新 adapter。没有 key 会返回 E_LLM_DISABLED,上游连接失败会返回 E_LLM_UNAVAILABLE,两者都保留 error.details。
能力门禁失败时,JSON 会在 error.details 保留完整 checks / summary;缺少 Chrome/CDP 返回 E_CDP_UNAVAILABLE,没有 LLM key 返回 E_LLM_DISABLED,provider 上游不可用则保留 E_LLM_UNAVAILABLE,方便自动化修复正确依赖或稍后重试。普通 doctor --json 在硬检查失败时也返回同一套稳定错误码,不会退回通用 E_UNKNOWN。普通 doctor --llm-live 也会把缺少 key 指向配置修复,把上游错误指向重试。
实时模型检查若因 TLS、DNS、拒绝连接或超时失败,error.details.summary.llm_live_preflight.transport_reason 会给出安全的分类,action 会给出对应排查方向;TLS 握手失败并不能证明密钥无效。
只配置另一家 provider 的密钥不会让当前探索 provider 就绪。上游返回 HTTP 401/403 时,预检返回不可重试的 E_LLM_AUTH_FAILED,仅保留状态码和安全修复建议,不回显上游响应正文。
返回示例:
{"success": true, "data": {"cdp": true, "llm": true, "adapters_dir": true}}
login — 保存登录状态
打开目标 URL,等待用户在浏览器中完成登录,然后加密保存适用于目标主机的 Cookie。加密不可用时保存失败,不会回退写入明文;显式指定的 Session 缺失或无法读取时,导航会在打开页面前报错。当前不支持恢复 LocalStorage;依赖它的站点需重新登录。
cliany-site login "https://your-site.com" [--json]
explore — 探索工作流
核心命令。指定 URL 和任务描述,LLM 自动分析页面 AXTree,规划并执行操作路径,将结果生成为 Python/Click CLI 适配器。
cliany-site [ROOT OPTIONS] explore <url> <workflow> [OPTIONS]
Options:
--force 覆盖已有 adapter(无需确认)
--json JSON 输出
-i, --interactive 交互式探索,每步手动确认
--extend <domain> 增量扩展已有适配器
--record / --no-record 是否记录探索过程
--headless 和 --cdp-url 是根选项,必须放在 explore 前。前者让 cliany-site 启动无头 Chrome;后者连接已经运行的远程 CDP 浏览器。
Jev 意图定位(实验性)
不确定控件名称时,可用自然语言在当前页面中只读查找。此命令不会点击、输入或自动生成 adapter;必须配置 TYPESAFE_API_KEY,并显式允许外发意图与页面元素名称、角色。不要在禁止外发敏感信息的页面使用;模型准确率和延迟尚未经过真实服务评测。
cliany-site browser find --by intent --value "输入订单号的搜索框" --allow-remote --min-confidence 0.8 --json
返回的 ref 只适用于当前页面状态。完整的数据边界与拒绝策略见 Jev 意图定位文档。
示例:
# 基础探索
cliany-site explore "https://github.com" "搜索仓库并查看 README" --json
# 交互式(每步确认)
cliany-site explore "https://github.com" "管理 Issues" --interactive
# 增量扩展(不覆盖已有命令)
cliany-site explore "https://github.com" "创建 PR" --extend github.com
list — 查看适配器
cliany-site list [--json]
列出 ~/.cliany-site/adapters/ 目录下所有已生成的域名适配器及其命令。
执行适配器命令
生成适配器后,通过 cliany-site <domain> <command> 执行:
# 查看 github.com 适配器的所有命令
cliany-site github.com --help
# 执行搜索命令
cliany-site github.com search --query "browser automation" --json
# 从断点恢复
cliany-site github.com search --query "browser automation" --resume --json
数据命令的提取质量语义
生成的 list-、search-、read- 和 extract- 命令,以及包含 extract action 的任何命令,默认使用 expects_nonempty=true。零条数据、关键字段缺失和 partial 结果都会返回 E_EMPTY_RESULT,而不是只完成点击后报告成功。只有某个工作流的零匹配本来就是合法结果时,命令才可声明 expects_nonempty=false:零匹配仍返回 ok=true,同时继续提供 data.quality 作为行数和数据质量信号。失败的结构化对象行会额外在 data.quality.field_blank_rows 中按字段给出缺失或空白值的 1 起始结果行号,帮助定位字段映射或页面内容;成功结果不会增加该字段。重新 explore 某个命令会应用这条规则到新生成的代码,但不会静默改写已安装的旧 adapter;即使允许零匹配,关键字段缺失或 partial 结果仍然失败。
语义提取目标
从 v0.16.380 起,新生成的提取保存实测 AX 语义目标,读取前在当前页面重新定位并检查唯一 DOM 区域。缺失或无法消除歧义的目标返回 E_SELECTOR_NOT_FOUND,不能冒充合法零匹配;已存在区域且声明 expects_nonempty=false 时仍可返回零条结果。生成的原子调用通过 browser extract --target-json 传递实测记录,而不是猜测 CSS。原生列表/表格支持和 100 行上限仍保留;已有 adapter 不会自动迁移,新语义 adapter 需要 v0.16.380 或更新的支持运行时。见 语义提取目标与兼容性。
命令计时元数据
从 v0.16.378 起,CLI 信封的 meta.duration_measured=true 才表示 duration_ms 是实测值。有效的亚毫秒调用可向下取整为 0;false 表示未测量,此时 0 仅是兼容占位。旧版或手工构造的元数据没有该标记时,也不能据其数值判断延迟。
从 v0.16.379 起,首次探索只在发现 commands.py 或 metadata.json 核心文件时沿用合并路径。仅有提取/快照辅助文件不会再丢失新生成命令的实测起始 URL 或模型;已有 adapter 不会自动重写。
计时从根 CLI 入口、参数解析之前开始,到构造该元数据的时点为止,不包括之前的模块导入和之后的输出、清理,也不是 CPU 或纯 LLM 耗时。嵌套原子调用独立计时,父调用包含子调用执行。旧生成文件不自动改写;SDK/HTTP 顶层仍保留各自的旧信封格式,doctor 的单项检查耗时不变。这不代表工作流变快或浏览器支持并发。
Python SDK
从 v0.16.383 起,SDK/HTTP 会在浏览器工作前拒绝生成命令未声明的参数名,包括 dry_run=True。例如 query 拼成 qurey 时,不再静默改用录制默认值:返回 E_INVALID_PARAM,详情只列出 unknown_params 与 allowed_params 名称,不回显参数值;HTTP 使用 JSON 400。正确参数、默认值与既有包文件不变;旧 command_defs 的行为、参数值转换和数据质量门禁保持原样。这不是全部旧 adapter 的参数校验承诺。
从 v0.16.382 起,SDK/HTTP 首次生成按核心文件而非辅助目录判断已有 adapter,保留起始 URL 路径和模型记录。结构化模型服务异常保留 E_LLM_AUTH_FAILED 或 E_LLM_UNAVAILABLE、retryable、status_code 与 phase=llm_invoke,不回显上游异常正文。HTTP 仍使用 SDK JSON 信封,对上游依赖返回 503;这不是调用者登录失败,retryable=false 时先修复服务配置,不盲目重试。其他旧异常路径不在此隐私承诺内,既有 adapter、信封格式和请求时限不变。
from cliany_site.sdk import ClanySite
import asyncio
async def main():
async with ClanySite() as cs:
result = await cs.verify("github.com")
if not result["success"]:
error = result["error"] or {}
raise RuntimeError(f"{error.get('code')}: {error.get('message')}")
print(result["data"]["results"][0])
asyncio.run(main())
直接 SDK 的控制参数也遵循严格契约:explore(force=...)、execute(..., params=..., dry_run=..., sandbox=...) 与 list_adapters(detail=...) 只接受声明的参数类型;畸形值会在 adapter 查找或浏览器工作前返回 E_INVALID_PARAM。save_session(domain) 只接受可带合法端口的主机名,并会在打开 Chrome 前拒绝凭据、路径、空白和无效端口。同步 execute() 支持 sandbox=True 并转发同一条本地预检。
SDK 方法统一返回 {success, data, error} 信封。doctor() 现在复用 CLI 的结构化 checks 与 summary 契约,并保留稳定硬阻塞错误码和 error.details 诊断;默认不会调用 provider,只有自动化在 explore 前确实需要 live preflight 时才传入 doctor(llm_live=True, require_capability="generate_adapters")。llm_live 必须是实际 Python 布尔值;字符串、数字和 None 会在 CDP 或 provider 检查前返回 E_INVALID_PARAM,不会让 truthy 字符串意外启动 live preflight。verify(domain) 与 cliany-site verify <domain> --strict 使用相同的静态检查:安全目录名、metadata、生成模块安全、manifest 完整性,以及 commands.py 是否真正导出可加载的 Click group;它不会连接 Chrome 或 LLM。adapter 目录、metadata.json、commands.py、manifest 或 manifest 声明文件若为符号链接,会在读取内容或导入模块前以 security_issue 拒绝。根 CLI 直接执行 adapter 命令也会在导入 commands.py 前运行生成模块源码扫描:禁用模式和非 UTF-8 模块返回 E_VERIFY_STATIC / security_issue。存在 manifest 时,它还会校验每个声明文件的哈希;失配返回 E_VERIFY_STATIC / manifest_error。未安装 adapter 返回 ADAPTER_NOT_FOUND,静态校验失败返回带 results 诊断的 E_VERIFY_STATIC。execute 在启动浏览器前使用同一套本地静态契约。调用 explore 前仍需先通过严格的 live provider 预检;仅有配置过的凭据不代表 adapter 生成当前可用。
同步 save_session(domain, cdp_url=..., headless=...) 与 await ClanySite(...).save_session(domain) 使用相同的主机校验和浏览器配置路径,不会绕过 Chrome 或 session 安全检查。
HTTP API
启动本地 REST API 服务:
# 默认 Chrome 连接
cliany-site serve --port 8080
# 让 cliany-site 为服务启动无头 Chrome
cliany-site --headless serve --port 8080
# 复用已运行的远程 CDP 浏览器
cliany-site --cdp-url "ws://chrome:9222" serve --port 8080
--headless 和 --cdp-url 都是根选项,必须写在 serve 之前。每次只选一条浏览器路径:前者为当前服务启动 Chrome,后者连接已有远程 Chrome。
| 端点 | 方法 | 说明 |
|---|---|---|
GET /health | GET | 确认服务可访问并返回已安装版本 |
GET /doctor | GET | 与 CLI 对齐的结构化环境诊断;可显式执行 live preflight |
GET /adapters?detail=true | GET | 列出适配器;可显式包含元数据 |
GET /verify?domain=<domain> | GET | 严格静态验证已安装 adapter,不连接 Chrome |
POST /explore | POST | 探索工作流 |
POST /execute | POST | 执行适配器命令 |
POST /login | POST | 捕获 Session |
curl -i http://localhost:8080/health
# {"status":"ok","service":"cliany-site","version":"<installed-version>"}
curl -i http://localhost:8080/doctor
curl -i "http://localhost:8080/doctor?llm_live=true&require_capability=generate_adapters"
curl -i "http://localhost:8080/adapters?detail=true"
curl -i "http://localhost:8080/verify?domain=github.com"
curl -X POST http://localhost:8080/explore \
-H "Content-Type: application/json" \
-d '{"url": "https://github.com", "workflow": "搜索仓库"}'
GET /health 是 liveness probe:它确认 HTTP 服务可访问,并返回服务名和已安装版本;它不代表 Chrome/CDP 或 LLM provider 已就绪,请使用 GET /doctor 查看这些诊断。GET /adapters?detail=true 可显式请求 adapter 元数据。llm_live、detail、require_capability 与 domain 各只能出现一次;llm_live 与 detail 只接受 true/false、1/0 或 yes/no。非法布尔值或重复键返回 BAD_REQUEST / 400,不会静默改变响应形状、所选能力或 adapter domain。该端点返回与 CLI 一致的 checks、summary、稳定硬阻塞错误码和修复建议;默认不会调用 provider,只有显式 llm_live=true 才会执行 live preflight,require_capability=generate_adapters 必须同时使用它。Chrome、LLM 或指定能力暂不可用时返回 503。GET /verify 必须提供且只能提供一个安全的 domain 查询参数,只运行静态 adapter 检查,不会连接 Chrome 或 LLM;重复 domain 返回 BAD_REQUEST / 400,无效目录名返回 E_INVALID_PARAM / 400,已安装但不可安全加载或核心文件为符号链接的 adapter 返回 E_VERIFY_STATIC / 422。POST /execute 在启动浏览器前使用同一套本地静态契约:它会在读取或导入前拒绝符号链接目录、metadata、命令模块或 manifest;若 manifest 存在,其声明文件必须是普通文件且哈希匹配,不会先启动浏览器。其他响应保留 SDK 信封:404 表示 adapter 或命令不存在,503 表示 Chrome 或 LLM 依赖暂不可用,500 表示意外服务端失败。写操作端点只接受 JSON 对象;params 必须是对象,force / dry_run 必须是布尔值。
POST /execute 的可选布尔字段 sandbox 会在 Chrome 启动前预检完成参数替换的动作。新生成 adapter 的根 --sandbox 使用相同策略;跨域导航、危险 URL scheme、JavaScript 执行或下载返回 E_SANDBOX_VIOLATION / 422。这条本地策略结果不表示 Chrome、LLM 或第三方工作流已成功。
写操作端点只接受已声明字段,未知字段会在进入 SDK 前返回 BAD_REQUEST / 400:POST /explore 接受 url、workflow、兼容旧调用的 workflow_description 与 force;POST /execute 接受 domain、command、params、dry_run 与 sandbox;POST /login 接受 url。必填 url、workflow、domain 与 command 必须是非空字符串。对 POST /explore 与 POST /login,url 还必须是不含空白、带 host 的 http 或 https URL;不支持的 scheme、缺失 host 或畸形 URL 同样返回 BAD_REQUEST / 400,不会让无效浏览器目标进入 SDK,也不会让畸形 JSON 变成意外服务端错误。直接调用 ClanySite.explore() 或 ClanySite.login() 时也复用同一规则;无效 URL 在构造 explorer 或浏览器 session 前返回 INVALID_URL。
YAML 工作流编排
# workflow.yaml
name: GitHub 搜索并查看详情
steps:
- name: 搜索仓库
adapter: github.com
command: search
params:
query: "cliany-site"
- name: 查看第一个结果
adapter: github.com
command: view
params:
repo: "$prev.data.results[0].name"
cliany-site workflow run workflow.yaml --json
cliany-site workflow validate workflow.yaml --json
批量执行
从 CSV/JSON 文件批量驱动适配器命令:
cliany-site workflow batch github.com search data.csv --concurrency 3 --json
环境变量参考
| 变量 | 默认值 | 说明 |
|---|---|---|
CLIANY_RUNTIME_HOME | ~/.cliany-site | 独立运行文件目录;demo 子进程继承,不改变 Chrome 的 OS HOME |
CLIANY_LLM_PROVIDER | — | anthropic 或 openai |
CLIANY_ANTHROPIC_API_KEY | — | Anthropic API Key |
CLIANY_OPENAI_API_KEY | — | OpenAI API Key |
CLIANY_OPENAI_BASE_URL | — | 自定义 OpenAI 兼容端点 |
CLIANY_CROSS_ORIGIN_IFRAMES | true | 是否递归采集跨域 iframe |
常见问题
Chrome 无法连接怎么办?
运行 cliany-site doctor --json 检查 CDP 状态。默认检查不会真实调用 LLM provider;在耗时较长的 explore 前,可以运行 cliany-site doctor --llm-live --require-capability generate_adapters --json 做一次严格 provider 门禁。若上游网关、限流、provider 连接或服务不可用,命令会以非零结果返回 E_LLM_UNAVAILABLE,完整检查数据保留在 error.details。Candidate 晋级时,如果 generate_adapters.ready=false,或 llm_live 返回 warning/error(例如 E_LLM_UNAVAILABLE provider connection failure),请停止本轮真实 explore,把 doctor JSON / 错误摘要作为 blocker 证据。工具会自动尝试启动 Chrome;如果失败,可手动启动:
/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome \
--remote-debugging-port=9222 \
--user-data-dir=/tmp/chrome-debug
页面改版后命令失效?
小幅页面变化由 AXTree 模糊匹配和自愈机制自动处理。大幅改版时,用 --extend 增量重新探索即可:
cliany-site explore "https://your-site.com" "原有任务" --extend your-site.com
如何创建 candidate promotion issue?
推进 PyPI candidate 前,先按 Candidate Promotion Runbook(docs/candidate-promotion-runbook.md)跑 cliany-site doctor --llm-live --require-capability generate_adapters --json、adapter package、metadata validation 和 online smoke。PyPI 搜索案例的目标包名应保持 pypi.org-<version>.cliany-adapter.tar.gz,online smoke 使用 cliany-site pypi.org search-packages --query cliany-site --json。
先运行 cliany-site cases --status candidate --promotion-plan --json 读取 primary_issue_template_command 和 issue_template_json_command,再运行 cliany-site cases --case-id <id> --issue-template 生成带 Primary Runbook、Command SHA-256、Promotion Command Plan Summary、Promotion Command Plan command_sha256 子行、source / missing 子行、Doctor Preflight Evidence Fields 和 Doctor Preflight Evidence Template 的 issue body。随后先保留基础 cliany-site cases --case-id <id> --evidence-bundle --json 输出,再运行 cliany-site doctor --llm-live --require-capability generate_adapters --json > /tmp/cliany-doctor-preflight.json 和 cliany-site cases --case-id <id> --evidence-bundle --doctor-json /tmp/cliany-doctor-preflight.json --json,在 issue 摘要中引用 primary_next_task_runbook、llm_live_preflight_required、llm_live_preflight_command_sha256、promotion_command_plan[*].command_sha256、doctor_preflight_evidence_fields、doctor_preflight_evidence_values、doctor_preflight_evidence_ok、doctor_preflight_evidence_missing_count、doctor_preflight_state、doctor_preflight_state_fields、doctor_preflight_state_statuses 和 expected_adapter_package,确保贡献者先做 live LLM preflight、再执行当前 evidence task,并上传正确的 adapter release asset。doctor_preflight_state_fields 固定为 preflight_state.status、preflight_state.ready_for_adapter_package、preflight_state.primary_reason、preflight_state.reason_codes、preflight_state.next_action;doctor_preflight_state_statuses 只允许 ready、blocked、missing_fields。普通 cliany-site cases --status candidate 输出也会展示 preflight_required、preflight_blocker 和 runbook_first,方便非 JSON 交接。若 preflight 未通过,贴回 doctor JSON 中的 summary.llm_live_preflight 与 CDP blocker 字段作为证据;若 --doctor-json 已生成 evidence,则读取 doctor_preflight_state.status,只在 ready 且 preflight_state.ready_for_adapter_package=true 时继续 explore,blocked 或 missing_fields 时先贴证据。若使用 python scripts/plan_next_iteration.py --issues-dir /tmp/cliany-candidate-issues 生成 artifacts,先对比 candidate_promotions[*].issue_template_command、candidate_promotions[*].issue_template_json_command、issue-metadata.json、case_promotion_evidence_primary_llm_live_preflight_required、case_promotion_evidence_primary_llm_live_preflight_command_sha256、case_promotion_evidence_primary_llm_live_preflight_blocker_comment、case_promotion_evidence_primary_doctor_preflight_blocker_comment、case_promotion_evidence_primary_doctor_preflight_evidence_template_sha256、case_promotion_doctor_preflight_evidence_template_sha256、doctor_preflight_state_fields、doctor_preflight_state_statuses、required_labels、required_label_count、required_labels_sha256 与 case_promotion_evidence_primary_runbook_steps / hash 是否漂移,再创建 GitHub issue。
Doctor evidence 现在包含 summary.capabilities.generate_adapters.local_ready 和 summary.capabilities.generate_adapters.local_blockers,可在 live provider 被阻塞时单独说明本地前提是否健康;它们不能替代 candidate explore 所需的 summary.llm_live_preflight.ready=true。
普通 cliany-site cases --status candidate 会把未来的 adapter 命令标为“当前不可运行”;必须先完成包发布、安装并通过 verify --strict,它才会成为可执行命令,不能当作 active demo 快速命令。
如果已经保存 doctor JSON,可运行 python scripts/plan_next_iteration.py --doctor-json /tmp/cliany-doctor-preflight.json --issues-dir /tmp/cliany-candidate-issues。本地 issue-metadata.json 保留 source path 供追溯;candidate issue body 则只带当前 doctor_preflight_state、extracted values 的 SHA-256、抽取字段,以及包含 --doctor-json 的 issue/evidence bundle commands,适合在 live LLM blocked 时生成 blocker-ready issue 草稿而不公开维护机路径。Planner body 会把已附加的 doctor preflight 与仍未附加的 adapter package evidence 分开显示;provider blocked 时只给出恢复后重跑 strict preflight 的 handoff,不会放行 candidate explore。
如果维护工具只读取 promotion queue,可直接比对 promotion_plan.primary_doctor_preflight_evidence_template_field_count、promotion_plan.primary_doctor_preflight_evidence_template_sha256、promotion_plan.primary_llm_live_preflight_command_sha256、candidate primary_doctor_preflight_evidence_template_sha256 和 task_queue[*].doctor_preflight_evidence_template_sha256 / task_queue[*].llm_live_preflight_command_sha256,无需展开完整 evidence bundle 也能发现 doctor 证据模板与 preflight 命令漂移。
如果维护工具只读取 case validation,可从 scripts/validate_cases.py --json 的 promotion_evidence_summary.primary_next_task.doctor_preflight_evidence_template_sha256、doctor_preflight_state_fields、doctor_preflight_state_statuses,scripts/validate_cases.py --report 的 primary_doctor_preflight_evidence_template_sha256,或纯文本 scripts/validate_cases.py --strict stdout 的 promotion_evidence_primary_doctor_preflight_evidence_template_sha256 / promotion_evidence_primary_llm_live_preflight_command_sha256 比对同一 doctor 模板、state contract 与 preflight 命令漂移。
公开 candidate issue 也应保持与当前 template 一致。先运行 python scripts/audit_candidate_issues.py --repo pearjelly/cliany.site --json 只读检查开放 case-proposal issue 的 title、body 与 SHA-256;不属于当前 manifest 的 title 会报告为 unexpected。保存过 doctor JSON 时,追加 --doctor-json /tmp/cliany-doctor-preflight.json,让审计按同一份 extracted gate evidence 渲染期望正文,并在本地 JSON 报告记录 source path、values SHA-256、state status 和 package runnable 状态;公开 body 只保留 values SHA-256、gate state 与抽取字段。预检证据已附加时,Primary Evidence Task 会将 package evidence 与 doctor evidence 分开显示,并在 provider 暂不可用时指向恢复后重跑严格 preflight,仍不会放行 candidate explore。旧的占位模板不会被误报为当前 blocker handoff,也不会泄露维护机路径。不带 --json 的人工报告会直接显示 unexpected issue 的实际 title 和 URL,方便先定位 blocker。只有审阅 stale 并先解决 missing、duplicate、unexpected 后才运行 python scripts/audit_candidate_issues.py --repo pearjelly/cliany.site --doctor-json /tmp/cliany-doctor-preflight.json --apply --confirm-rewrite --json。工具不会创建、关闭 issue 或将 candidate 提前标记为 active。
如果 stale candidate issue 正文已经包含 Doctor Preflight Evidence 和 64 位 values_sha256,不带 --doctor-json 的显式 --apply 会以 doctor_json_required_before_rewrite 拒绝改写;只有审阅 stale 并先解决 missing、duplicate、unexpected 后,才运行带当前 doctor JSON 的 --apply --confirm-rewrite。
如何在服务器/Docker 中使用?
选择一个浏览器管理路径;--headless 和 --cdp-url 都必须位于 explore 前,且远程 CDP 已存在时不需要 --headless。
# 让 cliany-site 启动无头 Chrome
cliany-site --headless explore "https://github.com" "搜索仓库" --json
# 连接已运行的远程 CDP 浏览器
cliany-site --cdp-url "ws://localhost:9222" explore "https://github.com" "搜索仓库" --json