@agenzo/merchant-cli 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,224 +1,197 @@
1
1
  # @agenzo/merchant-cli
2
2
 
3
- [![npm version](https://img.shields.io/npm/v/@agenzo/merchant-cli)](https://www.npmjs.com/package/@agenzo/merchant-cli)
4
- [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)
5
- [![Node.js](https://img.shields.io/badge/node-%3E%3D18-brightgreen)](https://nodejs.org)
3
+ > **商户履约产品线 CLI** — binary `agenzo-merchant-cli`,落地于 monorepo `agenzo-cli/apps/merchant-cli`。
4
+ > 覆盖两个 noun group:能力发现(`services`)与叫车业务闭环(`ride-elife`),共 7 条命令。
6
5
 
7
- CLI tool for AI Agents to order rides and query merchant services. Ships with a
8
- structured [SKILL.md](SKILL.md) so AI Agents can run the full ride flow with zero
9
- extra setup.
6
+ ---
10
7
 
11
- [Install](#installation) · [AI Agent Skill](#ai-agent-skill) · [Quick Start](#quick-start) · [Commands](#commands) · [Auth](#authentication)
8
+ ## 项目简介
12
9
 
13
- ## Installation
10
+ `agenzo-merchant-cli` 是 Agent 接入 Agenzo 商户履约能力的命令行入口。本期上线两个 noun group:
14
11
 
15
- ```bash
16
- npm install -g @agenzo/merchant-cli
17
- ```
12
+ - **`services`**(能力发现):让 Agent 发现可用的商户履约能力(该调哪个 noun/verb、调用流程)。本期数据源为 **CLI 内置注册表**(后端 `/services` discovery endpoint 属 pending impl)。
13
+ - **`ride-elife`**(叫车,唯一在线 provider):报价 → 下单 → 查询/轮询 → 取消 → 列单的完整闭环。
18
14
 
19
- **Requirements**: Node.js 18+
15
+ 所有通用基础设施(HTTP 客户端、输出渲染、错误体系、退出码、版本协商、配置)均复用 `@agenzo/cli-core`,app 内只保留命令处理与商户域专属逻辑(ride body 组装、NDJSON watch、verb-schema help、services 注册表、幂等键策略)。
20
16
 
21
- The package installs a single binary, `agenzo-merchant-cli`:
17
+ > 本 CLI 与 `agenzo-admin-cli` / `agenzo-token-cli` 结构、命名、构建配置保持一致(4-CLI consistency)。
22
18
 
23
- ```bash
24
- agenzo-merchant-cli --help
25
- agenzo-merchant-cli --version
26
- ```
19
+ ## 功能特性
27
20
 
28
- ## AI Agent Skill
21
+ | Noun | Verb | 类型 | HTTP | 说明 |
22
+ |---|---|---|---|---|
23
+ | `services` | `list` | Read | —(内置注册表) | 列出可用商户履约能力 |
24
+ | `services` | `get <service-id>` | Read | —(内置注册表) | 查看单个能力完整元数据(命中失败 → `SERVICE_NOT_FOUND`) |
25
+ | `ride-elife` | `quote` | Read | `POST /ride/quote` | 两点间报价(`vehicle_classes[]` + meet-and-greet) |
26
+ | `ride-elife` | `book` | Write/Y | `POST /ride/book` | 按 quote 下单(monthly_settlement-aware,见下) |
27
+ | `ride-elife` | `get` | Read | `GET /ride/<id>/status` | 查询订单状态;`--watch` 输出 NDJSON 轮询流 |
28
+ | `ride-elife` | `cancel` | Write/Y | `POST /ride/<id>/cancel` | 取消订单(无 body,可能产生费用) |
29
+ | `ride-elife` | `list-orders` | Read | `GET /ride/orders` | 列出已下单的行程(分页 + 过滤) |
29
30
 
30
- This CLI ships with a structured [SKILL.md](SKILL.md) that AI Agents can load to
31
- understand capability discovery, the `quote → book → get → [cancel]` ride flow,
32
- command parameters, and error recovery. Include `SKILL.md` in the agent's context
33
- or tool definition.
31
+ > 写命令(`book` / `cancel`)受幂等键规则约束(见 [幂等键](#幂等键-idempotency-key))。
32
+ > 未实现:`ride-elife track`(pending impl,后端无位置流接口)——`get --watch` 已覆盖订单状态轮询。
34
33
 
35
- ## Quick Start
34
+ ## 技术栈
36
35
 
37
- ```bash
38
- # 1. (Optional) point at a non-default host
39
- agenzo-merchant-cli config set-host https://agent.everonet.com
36
+ - TypeScript(ESM) + [commander@14](https://github.com/tj/commander.js) + [@inquirer/prompts](https://github.com/SBoudrias/Inquirer.js)
37
+ - 构建:[tsup](https://tsup.egoist.dev/)(esm / node18 / dts,banner `#!/usr/bin/env node`)
38
+ - 测试:[vitest](https://vitest.dev/) + [fast-check](https://fast-check.dev/)(PBT)
39
+ - 共享底包:`@agenzo/cli-core`(唯一横向依赖;**禁止** import 其它 app)
40
40
 
41
- # 2. Discover available services
42
- agenzo-merchant-cli services list --api-key sk_xxx
41
+ ## 快速开始
43
42
 
44
- # 3. Get fare quotes for a trip
45
- agenzo-merchant-cli ride-elife quote --api-key sk_xxx \
46
- --pickup-lat 1.3644 --pickup-lng 103.9915 --pickup-name "Changi Airport" \
47
- --dropoff-lat 1.2834 --dropoff-lng 103.8607 --dropoff-name "Marina Bay" \
48
- --pickup-time now
43
+ ### 环境要求
49
44
 
50
- # 4. Book against a returned quote (write op → idempotency key required)
51
- agenzo-merchant-cli --yes ride-elife book --api-key sk_xxx \
52
- --quote-id <quote_id> --vehicle-class <vehicle_class> \
53
- --price-amount <amount> --price-currency USD \
54
- --passenger-name "Ada" --passenger-phone "+6591234567" \
55
- --pickup-lat 1.3644 --pickup-lng 103.9915 --pickup-name "Changi Airport" \
56
- --dropoff-lat 1.2834 --dropoff-lng 103.8607 --dropoff-name "Marina Bay" \
57
- --pickup-time now --idempotency-key idem_001
45
+ - Node.js 18+
46
+ - monorepo 已 `npm install`
58
47
 
59
- # 5. Poll the order until a terminal status (NDJSON stream)
60
- agenzo-merchant-cli ride-elife get --order-id <ride_id> --api-key sk_xxx --watch
48
+ ### 构建
61
49
 
62
- # 6. Cancel if needed (write op → idempotency key required)
63
- agenzo-merchant-cli --yes ride-elife cancel --order-id <ride_id> --api-key sk_xxx --idempotency-key idem_002
64
-
65
- # 7. List all orders
66
- agenzo-merchant-cli ride-elife list-orders --api-key sk_xxx
50
+ ```bash
51
+ # 在 monorepo 根目录
52
+ npm run build -w @agenzo/cli-core # 必须先构建共享底包
53
+ npm run build -w @agenzo/merchant-cli # tsup 产出 dist/index.js(= bin agenzo-merchant-cli)
54
+ agenzo-merchant-cli --version
67
55
  ```
68
56
 
69
- ## Commands
57
+ ### 认证
70
58
 
71
- | Command | Description |
72
- |---------|-------------|
73
- | `config set-host <url>` | Set the API host (persisted locally) |
74
- | `config reset-host` | Reset the API host to the default |
75
- | `config show` | Show the current configuration |
76
- | `services list` | List available merchant services |
77
- | `services get <service-id>` | Retrieve a single service by id |
78
- | `ride-elife quote` | Request fare quotes between two points |
79
- | `ride-elife book` | Book a ride against a returned quote |
80
- | `ride-elife get <order-id>` | Retrieve a single ride order (add `--watch` to poll until terminal, NDJSON stream) |
81
- | `ride-elife cancel <order-id>` | Cancel a ride order (may incur a fee) |
82
- | `ride-elife list-orders` | List ride orders (paginated, optional status filter) |
59
+ 运行面 CLI,使用 **API Key**(`--api-key`,作为 `X-Api-Key` 头逐命令携带):
83
60
 
84
- ### Command Reference
61
+ - API Key 由 `agenzo-admin-cli keys create --scope merchant` 签发,需含 `merchant` scope。
62
+ - 缺省 `--api-key` 时交互索取(password 输入)。
63
+ - 无 Bearer Token / AuthService / keystore——与 `agenzo-token-cli` 一致。
64
+
65
+ ### 端到端示例
85
66
 
86
67
  ```bash
87
- # Configuration (local only, no network)
88
- agenzo-merchant-cli config set-host https://agent.everonet.com
89
- agenzo-merchant-cli config reset-host
90
- agenzo-merchant-cli config show
91
-
92
- # Services registry
93
- agenzo-merchant-cli services list --api-key sk_xxx
94
- agenzo-merchant-cli services get svc_001 --api-key sk_xxx
95
-
96
- # Ride flow — quote
97
- agenzo-merchant-cli ride-elife quote --api-key sk_xxx \
98
- --pickup-lat <lat> --pickup-lng <lng> --pickup-name <name> \
99
- --dropoff-lat <lat> --dropoff-lng <lng> --dropoff-name <name> \
100
- --pickup-time <epoch|"now"> \
101
- [--passenger-name <name>] [--passenger-phone <phone>] \
102
- [--passenger-count <n>] [--luggage-count <n>] [--children-count <n>]
103
-
104
- # Ride flow — book (price-amount/vehicle-class must match the quote response)
105
- agenzo-merchant-cli ride-elife book --api-key sk_xxx \
106
- --quote-id <id> --vehicle-class <class> \
107
- --price-amount <amount> --price-currency <USD> \
108
- --passenger-name <name> --passenger-phone <phone> \
109
- [--passenger-email <email>] \
110
- --pickup-lat <lat> --pickup-lng <lng> --pickup-name <name> \
111
- --dropoff-lat <lat> --dropoff-lng <lng> --dropoff-name <name> \
112
- --pickup-time <epoch|"now"> \
113
- [--meet-and-greet] [--welcome-sign <text>] \
114
- [--arrival-flight-no <no>] [--departure-flight-no <no>] \
115
- --idempotency-key <key>
116
-
117
- # Ride flow — get status
118
- agenzo-merchant-cli ride-elife get --order-id <ride_id> --api-key sk_xxx
119
- agenzo-merchant-cli ride-elife get --order-id <ride_id> --api-key sk_xxx --watch [--watch-interval <s>] [--watch-timeout <s>]
120
-
121
- # Ride flow — cancel
122
- agenzo-merchant-cli ride-elife cancel --order-id <ride_id> --api-key sk_xxx --idempotency-key <key>
123
-
124
- # Ride flow — list orders
125
- agenzo-merchant-cli ride-elife list-orders --api-key sk_xxx [--status <status>] [--page <n>] [--page-size <n>]
68
+ # 1. 发现能力
69
+ agenzo-merchant-cli services list
70
+ agenzo-merchant-cli services get ride-elife
71
+
72
+ # 2. 报价(产出 quote_id)
73
+ agenzo-merchant-cli ride-elife quote --api-key "$API_KEY" \
74
+ --pickup-lat 37.7937 --pickup-lng -122.3956 --pickup-name "1 Market St" \
75
+ --dropoff-lat 37.6213 --dropoff-lng -122.3790 --dropoff-name "SFO Airport" \
76
+ --pickup-time now
77
+
78
+ # 3. 下单(写操作:--yes 自动确认 + 必须提供 --idempotency-key)
79
+ agenzo-merchant-cli ride-elife book --api-key "$API_KEY" --yes \
80
+ --quote-id "$QUOTE_ID" --vehicle-class Sedan --price-amount 42.50 \
81
+ --passenger-name "Alice" --passenger-phone "+14155551234" \
82
+ --idempotency-key "book-$(date +%s)"
83
+
84
+ # 4. 查询 / 轮询(--watch 输出逐行 NDJSON)
85
+ agenzo-merchant-cli ride-elife get --api-key "$API_KEY" --order-id "$RIDE_ID"
86
+ agenzo-merchant-cli ride-elife get --api-key "$API_KEY" --order-id "$RIDE_ID" \
87
+ --watch --watch-interval 5 --watch-timeout 600
88
+
89
+ # 5. 列单 / 取消
90
+ agenzo-merchant-cli ride-elife list-orders --api-key "$API_KEY" --status Pending --page 1 --page-size 20
91
+ agenzo-merchant-cli ride-elife cancel --api-key "$API_KEY" --yes \
92
+ --order-id "$RIDE_ID" --idempotency-key "cancel-$(date +%s)"
126
93
  ```
127
94
 
128
- ## Global Flags
95
+ ## 全局 flag
129
96
 
130
- | Flag | Description |
131
- |------|-------------|
132
- | `--format <json\|table>` | Output format. Defaults to `json`; pass `--format table` for a human-readable table. |
133
- | `--api-key <key>` | API key for runtime requests, sent as the `X-API-Key` header. |
134
- | `--idempotency-key <key>` | Caller-supplied idempotency key for write operations (`ride-elife book`, `ride-elife cancel`). |
135
- | `--yes` | Skip confirmation/interactive prompts (for automation / AI Agents). |
97
+ | Flag | 默认 | 说明 |
98
+ |---|---|---|
99
+ | `--format <json\|table>` | **`json`** | 输出格式。merchant-cli 是 agent-first 入口,**默认 `json`**(刻意偏离 cli-core 的 `table` 默认,D2);亦读环境变量 `AGENZO_FORMAT` |
100
+ | `--api-key <key>` | —(交互索取) | API Key,作为 `X-Api-Key` 头逐命令携带 |
101
+ | `--yes` | `false` | 跳过交互式确认(供 CI / Agent);写命令在 `--yes` 且缺幂等键时为硬错误 |
102
+ | `--verbose` | `false` | 详细日志(写 stderr) |
136
103
 
137
- ### Output format
104
+ ## 输出与错误契约
138
105
 
139
- All commands emit JSON by default, which is ideal for scripting and AI Agents.
140
- Add `--format table` for a readable summary instead:
106
+ - **`--format json`(非 watch 命令)**:stdout 仅含**单个合法 JSON**(业务 payload + `profile`/`endpoint` 信封,endpoint 仅 host 不含 path);所有状态/进度/spinner 行写 stderr,且在 json 模式下静音。
107
+ - **`--format table`**:业务输出走 stdout,状态行/spinner 走 stderr。
108
+ - **`get --watch`**:stdout 为逐行 NDJSON 流,**不套** profile/endpoint 信封;轮询命中终态集合(`At destination` / `Cancelled` / `Rejected` / `Customer no show` / `Driver no show`,大小写敏感)或超时停止;超时末行为 `{ "watch_status": "timeout", ... }`。
109
+ - **错误信封**(cli-core §8):`json` → `{ "error": { "code", "code_num", "message", "request_id"? } }`;`table` → `✗ [<code_num>] <message>`。
141
110
 
142
- ```bash
143
- agenzo-merchant-cli ride-elife list-orders --api-key sk_xxx --format table
144
- ```
111
+ 退出码(由 cli-core `exitCodeFor` 映射):
145
112
 
146
- ### Progress feedback
113
+ | 退出码 | 含义 | 代表错误码 |
114
+ |---|---|---|
115
+ | `0` | 成功 | — |
116
+ | `1` | 业务 / 参数 | `PARAM_INVALID`(2101) · `PARAM_IDEMPOTENCY_KEY_REQUIRED`(2102) · `SERVICE_NOT_FOUND`(4101) · `VEHICLE_UNAVAILABLE`(4201) · `QUOTE_EXPIRED`(4202) · `BOOKING_FAILED`(4203) · `CANCELLATION_NOT_ALLOWED`(4204) · `BILLING_MODE_MISMATCH`(3001) · `ACCOUNT_*`(31xx) · `PAYMENT_ORDER_*`(32xx) |
117
+ | `2` | 需升级 | `UPGRADE_REQUIRED`(9008) |
118
+ | `3` | 认证 / 无效 key | `KEY_INVALID`(1101) · `KEY_SCOPE_DENIED`(1102) |
119
+ | `4` | 网络 / 5xx | `RATE_LIMITED`(5001) · `UPSTREAM_ERROR`(5101) · `INTERNAL_ERROR`(5201) |
120
+ | `5` | 用户取消 | `CLIENT_ABORTED`(9007) · SIGINT |
147
121
 
148
- Ride commands make a network call, so while one is in flight the CLI shows a
149
- spinner (e.g. `⠋ Fetching quotes...`) so you can tell it is working rather than
150
- hung. This feedback is written to **stderr**, never stdout — so piping or
151
- redirecting stdout still yields a clean payload:
122
+ > api-key 鉴权映射:HTTP 401 → `KEY_INVALID`、403 → `KEY_SCOPE_DENIED`。后端返回的已知 §8 字符串码(如 `QUOTE_EXPIRED`)优先保真,否则回退 HTTP-status 映射。
152
123
 
153
- ```bash
154
- # stdout stays pure JSON; the spinner (on stderr) does not leak in
155
- agenzo-merchant-cli ride-elife quote --api-key sk_xxx ... | jq '.vehicle_classes'
156
- ```
124
+ ## 幂等键 (Idempotency-Key)
125
+
126
+ 写命令 `ride-elife book` / `cancel` 接受 `--idempotency-key`:
127
+
128
+ - 格式:`[A-Za-z0-9_-]{1,128}`。
129
+ - **CLI 永不自动生成**:`--yes` 且缺键 → 硬错误 `PARAM_IDEMPOTENCY_KEY_REQUIRED`(exit 1),不发起请求;非 `--yes` 缺键 → 交互索取。
130
+ - 作为 `Idempotency-Key` HTTP **头**发送,**绝不进 body**。
131
+ - 同一逻辑请求重试用同一键;新请求用新键。
132
+
133
+ ## book 的计费模型(monthly_settlement-aware)
157
134
 
158
- The spinner animates only when stderr is an interactive terminal (TTY). When
159
- output is piped, redirected, or run in CI / by an agent, the animation is
160
- suppressed so no control characters end up in logs. Local commands (`config`,
161
- `services`) return instantly and show no spinner.
135
+ `ride-elife book` **不接受** `--payment-method-id` 或任何卡信息——商户域不持有支付句柄。funding 由后端按 Developer 的 `billing_mode` 决定:
162
136
 
163
- ### Idempotency
137
+ - **monthly_settlement**:从月结账户扣减,无支付句柄;响应 `payment_status=ON_ACCOUNT`,含 `billing_entry_id`。
138
+ - **pay_per_call**:可选透传 `--payment-order-id`(payment-cli 已扣款的 PAID 订单号);响应回显 `payment_order_id`。
164
139
 
165
- Write operations (`ride-elife book`, `ride-elife cancel`) require a caller-supplied
166
- `--idempotency-key`. The CLI **never** auto-generates one:
140
+ 请求 body 至多含可选 `payment_order_id`。
167
141
 
168
- - Without `--yes`, the CLI prompts for the key interactively.
169
- - With `--yes`, a missing key is a hard error (`PARAM_IDEMPOTENCY_KEY_REQUIRED`).
142
+ ## profile / host 模型
170
143
 
171
- The key must be 1–128 characters from `[A-Za-z0-9_-]` and is sent as the
172
- `Idempotency-Key` header — never in the request body.
144
+ merchant-cli **没有任何 host / config 命令**,不治理环境。它复用 `@agenzo/cli-core` 的 `ConfigManager` 默认配置(即 `agenzo-admin-cli` 统一治理的环境,默认落盘 `~/.agenzo-admin-cli/`):
173
145
 
174
- ## Authentication
146
+ - 为 `ApiClient` 提供 `baseUrl`(host + `/api/v3/agent-pay`)。
147
+ - 为 json 输出的 `profile` / `endpoint` 信封提供环境名 + host。
175
148
 
176
- Runtime commands (`services`, `ride-elife`) require `--api-key`. The value is sent on
177
- every request as the `X-API-Key` header. `config` commands are local-only and
178
- need no API key.
149
+ **环境治理(设置 host / 切换环境)归 `agenzo-admin-cli`**(`agenzo-admin-cli config set` / `set-host`)——与 `agenzo-token-cli` 一致。
179
150
 
180
- ## Host configuration
151
+ ## 机器可读的 verb schema
181
152
 
182
- The default API host is `https://agent.everonet.com`. Override it with
183
- `config set-host` (persisted at `~/.agenzo-merchant-cli/config.json`) and revert
184
- with `config reset-host`:
153
+ 每个 `ride-elife` verb 支持 `--help --format json`,输出该 verb 的机器可读 schema(`cli` / `noun` / `verb` / `description` / `flags` / `response` / `example`,部分含 `error_recovery` / `polling`):
185
154
 
186
155
  ```bash
187
- agenzo-merchant-cli config set-host http://localhost:8000 # local dev
188
- agenzo-merchant-cli config reset-host # back to https://agent.everonet.com
189
- agenzo-merchant-cli config show
156
+ agenzo-merchant-cli ride-elife quote --help --format json
157
+ agenzo-merchant-cli ride-elife book --help --format json
190
158
  ```
191
159
 
192
- ## Error Codes (Ride)
160
+ ## 开发
193
161
 
194
- | Code | HTTP | Meaning |
195
- |------|------|---------|
196
- | 1801 | 404 | `VEHICLE_UNAVAILABLE` — No vehicles available for this trip |
197
- | 1802 | 410 | `QUOTE_EXPIRED` — Quote has expired, request a new one |
198
- | 1803 | 502 | `BOOKING_FAILED` — elife rejected the booking (details in response) |
199
- | 1804 | 409 | `CANCELLATION_NOT_ALLOWED` — Cannot cancel in current status |
200
- | 1805 | 404 | `RIDE_NOT_FOUND` — Order not found (or belongs to another org) |
201
- | 1809 | 402 | `ACCOUNT_INSUFFICIENT_BALANCE` — Not enough balance |
202
- | 1811 | 400 | `PRICE_MISMATCH` — price_amount doesn't match the quoted price |
203
- | 1812 | 400 | `VEHICLE_CLASS_MISMATCH` — vehicle_class doesn't match the quote |
204
-
205
- When a booking fails (1803), the response `data.elife_details` contains the
206
- upstream error for debugging (e.g. missing required fields).
162
+ ```bash
163
+ npm run build -w @agenzo/merchant-cli # tsup 构建
164
+ npm run test -w @agenzo/merchant-cli # vitest(含 fast-check PBT)
165
+ ```
207
166
 
208
- ## Amounts
167
+ 源码结构:
168
+
169
+ ```text
170
+ apps/merchant-cli/
171
+ src/
172
+ index.ts # commander 装配 + 顶层 reportError + SIGINT
173
+ services/{list,get}.ts # 能力发现(本期:CLI 内置注册表)
174
+ services/registry.ts # 内置静态注册表(商户域)
175
+ ride-elife/{quote,book,get,cancel,list-orders}.ts
176
+ ride-elife/watch.ts # NDJSON 轮询引擎(商户域)
177
+ verb-schema.ts # --help --format json 的 verb schema(商户域)
178
+ idempotency.ts # 幂等键 resolve / normalize(商户域)
179
+ types/api.ts # ride/service 响应类型(仅 merchant 消费,不提升 cli-core)
180
+ docs/ # 测试设计文档(见下)
181
+ tests/ # vitest 单测 + PBT
182
+ ```
209
183
 
210
- Monetary amounts are **decimals in the currency's standard unit** (e.g. `12.50`
211
- USD), not minor units / cents.
184
+ ## 文档索引
212
185
 
213
- ## Development
186
+ - [测试设计文档(命令矩阵 v1)](docs/test-design-command-matrix-v1.md) — 7 条命令 × 需求/Property 覆盖矩阵、L1–L4 分层测试策略、L1 单元 / L3 命令级用例表、L4 手动可执行冒烟用例。
187
+ - 架构与规范:`architecture-upgrade/v1/`(cli-standard / cli-design §4+§8 / cli-guide)。
188
+ - monorepo 总览:[`agenzo-cli/README.md`](../../README.md)。
214
189
 
215
- ```bash
216
- npm install
217
- npm run build # tsup production build
218
- npm run dev # watch build
219
- npm run lint # eslint
220
- ```
190
+ ## 更新日志
221
191
 
222
- ## License
192
+ ### 2026-06
223
193
 
224
- MIT
194
+ - 于 monorepo `agenzo-cli/apps/merchant-cli` 落地 merchant-cli(按 cli-design §4 重写,复用 `@agenzo/cli-core`)。
195
+ - 上线 `services`(list / get)+ `ride-elife`(quote / book / get [+`--watch`] / cancel / list-orders)共 7 条命令。
196
+ - 默认输出 `json`(agent-first);API Key 鉴权(`X-Api-Key`);写命令强制 `--idempotency-key`。
197
+ - 新增测试设计文档 `docs/test-design-command-matrix-v1.md`。