{
  "markdown": "# openydt-cli\n\n广东艾科智泊 **智慧停车开放平台** 的命令行工具 —— 为人和 AI Agent 而生。\n\n把开放平台的对外接口(查费 / 缴费 / 车场 / 停车记录 / 月票 / 电子券 / 设备控制等)封装成命令行,自动处理签名鉴权(v2/v3)、多授权商 profile、多环境(test/dev/prod),并附带一套开箱即用的 AI Agent **Skills**,让智能体零额外配置即可操作平台。\n\n**元数据驱动**:接口目录 `catalog.json` 同时生成域命令与技能(`catalog.json → cmd/gen/*.go + skills/`)。改接口先改源头再重新生成,命令、参数提示、技能始终与平台对齐。\n\n## 安装\n\n需 Node ≥ 18:\n\n```bash\nnpm i -g @openydt/openydt-cli      # 全局安装\nopenydt --version\n# 免安装试用: npx @openydt/openydt-cli --help\n```\n\n安装 / 更新时会**自动把 npm 包内同版本技能同步到本机已装的各 AI agent**(Claude Code / Codex / Cursor / Gemini CLI / OpenCode 等,经 `npx skills`,用户级),避免 CLI 与 Skills 漂移,也不需要再次从 GitHub 下载技能。手动同步:`openydt skill sync`。关闭自动同步:设环境变量 `OPENYDT_NO_SKILLS_SYNC=1`。\n\n### 自动检查与一键更新\n\n```bash\nopenydt update check          # 检查 npm 最新正式版本\nopenydt update check --json   # Agent 可读结果\nopenydt update                # 更新全局 npm 包、原生二进制和同版本 Skills\n```\n\n普通命令只读取本地缓存,不会等待网络；CLI 最多每 24 小时在后台检查一次。发现新版后只提醒一次,显式运行 `openydt update` 才会修改全局安装。关闭后台检查:`OPENYDT_NO_UPDATE_CHECK=1`。\n\n### 从源码构建(开发者)\n\n```bash\nmake build          # 产出 bin/openydt\nmake catalog        # (可选)解析接口文档 Doc/*.vue → catalog/catalog.json\nmake generate       # (可选)catalog.json → cmd/gen/*.go(各域命令,同步内嵌副本)\n```\n\n> 发布见 [RELEASING.md](./RELEASING.md)。\n\n## 快速开始\n\n```bash\n# 1. 配置授权商凭据(测试环境)\nopenydt config set --profile demo --key test --secret 123456 --env test\n\n# 2. 验证凭据 / 签名链路\nopenydt auth test\n\n# 3. 查费(生成的一等命令,带类型化参数)\nopenydt trade get-park-fee --car-code 粤EJW962 --park-code 1ZS7H5PQH9 -o table\n\n# 4. 通用兜底:调用任意业务编码 cmd\nopenydt api getParkOnSiteCar --body '{\"parkCodeList\":[\"PTD2YBBZ\"],\"pageNum\":1,\"pageSize\":10}'\n```\n\n### 全量分页导出（NDJSON）\n\n带 `pageNum` / `pageSize` 的只读查询可加 `--all-pages`。CLI 会从第 1 页开始，使用接口允许的最大页尺寸顺序翻页，每页间隔 500ms；记录逐行写成 NDJSON，进度写到 stderr。\n\n```bash\nopenydt parking get-car-out-list \\\n  --park-code PTD2YBBZ \\\n  --leave-start-time 20260601000000 \\\n  --leave-end-time 20260601235959 \\\n  --all-pages \\\n  --out records.ndjson\n```\n\n`--out` 仅与 `--all-pages` 同用；不传时 NDJSON 写到 stdout。批量分析应把同一份明细只导出一次，后续指标计算复用本地文件。\n\n## 三层命令体系\n\n1. **域一等命令** `openydt <域> <命令>` —— 由 `catalog.json` 自动生成,带类型化 flag(含 `[可选: ...]` 枚举提示)、`--help`、写操作 `--yes` 守护。\n2. **通用调用** `openydt api <cmd> --body '{...}'` —— 兜底任意可调用接口(含未做成一等命令的)。\n3. **契约发现** `openydt schema [cmd]` —— 查看接口入参、枚举、领域语义和示例 body；`--json` 供 Agent 按机器规则去重、过滤和统计。\n4. **配置 / 鉴权 / 技能 / 更新** `openydt config | auth | skill | update`。\n\n### 错误输出(AI Agent 友好)\n\n失败响应不只回传原始 message,还附结构化提示:`status` / `resultCode` 的中文含义 + **可执行建议(hint)**;当 message 指明某参数时,自动从目录补出该字段的**类型 / 必填 / 说明 / 枚举可选值**;并标注是否 `retriable`。JSON 模式输出 `_error` 对象供 Agent 解析自纠,table 模式输出可读多行。\n\n### 内置命令\n\n11 个业务域,共 **149** 条一等命令(接口目录共 429 个):\n\n> 计数由 catalog 生成,运行 `make counts` 核对。\n\n| 域 | 命令 | 数量 |\n|---|---|---|\n| `trade` | 停车缴费(查费 / 缴费 / 补缴 / 预存) | 7 |\n| `park` | 车场信息 / 计费测算 | 18 |\n| `parking` | 停车记录 / 在场 / 进出 / 锁车 | 31 |\n| `device` | 设备控制(开关闸 / 显示屏 / 扫码) | 11 |\n| `ticket` | 月票 / VIP / 特殊车辆类型 | 29 |\n| `blacklist` | 黑名单 | 3 |\n| `redlist` | 白名单 | 3 |\n| `visitor` | 访客 | 2 |\n| `data` | 数据分析 | 9 |\n| `coupon` | 电子券 / 商户 | 30 |\n| `evcharge` | 电动车充电(站点 / 桩 / 订单 / 经营数据,只读) | 6 |\n\n其余模块(城市运营、第三方车场接入、积分等)及 webhook 回调接口未生成一等命令;可调用类用 `openydt api <cmd>` 调用,webhook(平台主动推送)需自建接收端,详见 `openydt-api-explorer` 技能。\n\n## 记忆 / 默认值\n\n让你和 Agent 不必每次重复车场 / 车牌等背景:\n\n- **默认值(随 profile,按环境隔离)**:`openydt config set-default --park PTD2YBBZ --car-no 桂566666`;之后命令缺 `parkCode` 时自动补全(显式值永远优先,`--verbose` 可见补全;prod 写操作仍需 `--yes`)。\n- **车场经验(AI agent 自动沉淀 / 回忆)**:存 `~/.config/openydt-cli/park-notes/{parkCode}.{env}.md`(如 `PTD2YBBZ.test.md`),一车场一环境一文件、物理隔离 test/dev/prod。Agent 操作成功后自动追加该车场的有效调用 / 陷阱 / 常用车牌,下次自动回忆;prod 不记真实车牌。清理:删对应文件。\n\n## 全局参数\n\n| flag | 说明 |\n|---|---|\n| `--profile` | 授权商 profile(默认当前) |\n| `--env` | 环境 test\\|dev\\|prod(默认 test) |\n| `-o, --output` | 输出 json\\|table |\n| `--sign` | 签名版本 v2\\|v3(默认 v2) |\n| `-y, --yes` | 确认执行写操作 |\n| `--dry-run` | 只打印将发送的签名请求,不实际发送 |\n| `-v, --verbose` | 调试信息 |\n\n环境变量可覆盖 profile:`OPENYDT_PROFILE / OPENYDT_KEY / OPENYDT_SECRET / OPENYDT_ENV / OPENYDT_SIGN`。\n\n## 签名\n\n- 请求:`POST {base}/openydt/api/v3/{cmd}?sign=...`,头 `Authorization: Base64(key:时间)`、`Content-Type: application/json;charset=utf-8`。\n- **v2**(默认):`sign = md5(key + \":\" + 时间 + \":\" + secret)`,不含 body。\n- **v3**:`sign = md5(key + \":\" + 时间 + \":\" + 紧凑body + \":\" + secret)`,含 body。\n- 时间格式 `yyyyMMddHHmmss`(本地时间),有效期 10 分钟。\n- 客户端内置自定义 `User-Agent`、重试 + 指数退避(吸收网关间歇 404 / 连接重置)、限速友好。\n\n> ⚠️ 实测:测试环境的 `test` key **仅接受 v2 签名**;`--sign v3` 会返回 `status=4 签名错误`(除非平台对该 key 开通 v3)。v3 实现遵循官方算法,生产环境如开通即可用。\n\n## AI Agent Skills\n\n`skills/` 下 13 个技能,经 `npx skills` 分发到本机各 AI agent:\n\n| Skill | 说明 |\n|---|---|\n| `openydt-shared` | 配置 / profile / 签名 / 状态码 / 限速 / 安全 / 车场经验(所有域技能先读它) |\n| `openydt-billing` | 停车缴费闭环(进车 → 查费 → 缴费 → 查单) |\n| `openydt-park` | 车场信息 / 计费测算 |\n| `openydt-record` | 停车记录 / 在场 / 锁车 |\n| `openydt-device` | 设备控制(开关闸 / 显示屏) |\n| `openydt-monthticket` | 月票 / VIP 闭环(建类型 → 开通 → 续费 / 退费) |\n| `openydt-list` | 黑名单 / 白名单 / 访客 |\n| `openydt-data` | 数据分析 |\n| `openydt-coupon` | 电子券闭环(建商家 + 模板 → 售卖 → 发放 → 回收) |\n| `openydt-evcharge` | 电动车充电(站点 / 桩 / 订单 / 经营数据查询,只读) |\n| `openydt-api-explorer` | 用 `api` 调用未封装接口 |\n| `openydt-flow-park-access` | 进出场作业流程 SOP(开闸 / 补录 / 故障自愈) |\n| `openydt-skill-maker` | 创建自定义 skill 的框架 |\n\n格式校验:`node scripts/skill-format-check/index.js`。\n\n## 测试与验证\n\n```bash\nmake test           # 单元测试(含签名锚点向量 v2/v3/Base64)\nmake smoke          # 对测试环境查费冒烟\nmake e2e            # 端到端全量验证 → TEST_REPORT.md\n```\n\n端到端验证按业务流程链(缴费 / 月票 / 黑名单访客 / 电子券)驱动每个纳入接口,产出 `TEST_REPORT.md`。\n\n## 状态码\n\n响应包络 `{data, message, resultCode, status}`。`status`:1 成功 / 2 业务失败 / 3 系统异常 / 4 签名错误 / 5 key 错误 / 6 未授权 / 7 参数不完整 / 9 接口不存在。`status=2` 时看 `resultCode`(901-912、1801)。退出码:0 成功 / 1 业务失败 / 2 参数 / 4 鉴权 / 5 网络。\n\n## 目录结构\n\n```\ncmd/            # root + api/auth/config/schema/skill + gen/(生成的各域命令)\ninternal/       # sign 签名 / client HTTP / config 配置 / output 输出 / catalog 目录 / cmdutil / skillsync\ncatalog/        # catalog.json(接口目录,由 tools/extractor 生成)\ntools/extractor # Node: 解析 Doc/*.vue → catalog.json\ninternal/gen    # Go codegen: catalog.json → cmd/gen\nskills/         # AI Agent 技能\ntests/e2e       # 端到端验证 harness\n```\n\n## 致敬\n\nopenydt-cli 的形态与设计深受 **飞书 CLI** 启发 —— Go + Cobra、接口元数据驱动、为人和 AI Agent 而生、以 `npx skills` 分发技能。在此致敬并感谢这个优秀的开源项目:\n\n- **飞书 CLI(larksuite/cli)** · <https://github.com/larksuite/cli>\n",
  "bytes": 6247,
  "sha": "828d4dc27dd0561b444565193e0744b03e01e6d2da74c302f87d30975646fd11",
  "repo_slug": "xiaowen-0725/openydt-cli",
  "fonte": "repo",
  "truncated": false,
  "api": "https://api.agentalog.com/api/listings/skl_xiaowen_0725_openydt_cli_openydt_evcharg_a1e4964b/readme"
}