@agenzo/merchant-cli 0.2.2 → 0.3.2

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,229 +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
- ```
27
-
28
- ## AI Agent Skill
19
+ ## 功能特性
29
20
 
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.
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` | 列出已下单的行程(分页 + 过滤) |
34
30
 
35
- ## Quick Start
31
+ > 写命令(`book` / `cancel`)受幂等键规则约束(见 [幂等键](#幂等键-idempotency-key))。
32
+ > 未实现:`ride-elife track`(pending impl,后端无位置流接口)——`get --watch` 已覆盖订单状态轮询。
36
33
 
37
- ```bash
38
- # 1. (Optional) point at a non-default host
39
- agenzo-merchant-cli config set-host https://agent.everonet.com
34
+ ## 技术栈
40
35
 
41
- # 2. Discover available services
42
- agenzo-merchant-cli services list --api-key sk_xxx
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)
43
40
 
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
41
+ ## 快速开始
49
42
 
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
43
+ ### 环境要求
58
44
 
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
45
+ - Node.js 18+
46
+ - monorepo 已 `npm install`
61
47
 
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
48
+ ### 构建
64
49
 
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
+ ### 认证
58
+
59
+ 运行面 CLI,使用 **API Key**(`--api-key`,作为 `X-Api-Key` 头逐命令携带):
70
60
 
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) |
61
+ - API Key 由 `agenzo-admin-cli keys create --scope merchant` 签发,需含 `merchant` scope。
62
+ - 缺省 `--api-key` 时交互索取(password 输入)。
63
+ - 无 Bearer Token / AuthService / keystore——与 `agenzo-token-cli` 一致。
83
64
 
84
- ### Command Reference
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
- [--child-seat-count <n>] [--infant-seat-count <n>] [--toddler-seat-count <n>] \
115
- [--arrival-flight-no <no>] [--departure-flight-no <no>] \
116
- --idempotency-key <key>
117
-
118
- # Ride flow — get status
119
- agenzo-merchant-cli ride-elife get --order-id <ride_id> --api-key sk_xxx
120
- agenzo-merchant-cli ride-elife get --order-id <ride_id> --api-key sk_xxx --watch [--watch-interval <s>] [--watch-timeout <s>]
121
-
122
- # Ride flow — cancel
123
- agenzo-merchant-cli ride-elife cancel --order-id <ride_id> --api-key sk_xxx --idempotency-key <key>
124
-
125
- # Ride flow — list orders
126
- 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)"
127
93
  ```
128
94
 
129
- ## Global Flags
95
+ ## 全局 flag
130
96
 
131
- | Flag | Description |
132
- |------|-------------|
133
- | `--format <json\|table>` | Output format. Defaults to `json`; pass `--format table` for a human-readable table. |
134
- | `--api-key <key>` | API key for runtime requests, sent as the `X-API-Key` header. |
135
- | `--idempotency-key <key>` | Caller-supplied idempotency key for write operations (`ride-elife book`, `ride-elife cancel`). |
136
- | `--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) |
137
103
 
138
- ### Output format
104
+ ## 输出与错误契约
139
105
 
140
- All commands emit JSON by default, which is ideal for scripting and AI Agents.
141
- 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>`。
142
110
 
143
- ```bash
144
- agenzo-merchant-cli ride-elife list-orders --api-key sk_xxx --format table
145
- ```
111
+ 退出码(由 cli-core `exitCodeFor` 映射):
146
112
 
147
- ### 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 |
148
121
 
149
- Ride commands make a network call, so while one is in flight the CLI shows a
150
- spinner (e.g. `⠋ Fetching quotes...`) so you can tell it is working rather than
151
- hung. This feedback is written to **stderr**, never stdout — so piping or
152
- redirecting stdout still yields a clean payload:
122
+ > api-key 鉴权映射:HTTP 401 → `KEY_INVALID`、403 → `KEY_SCOPE_DENIED`。后端返回的已知 §8 字符串码(如 `QUOTE_EXPIRED`)优先保真,否则回退 HTTP-status 映射。
153
123
 
154
- ```bash
155
- # stdout stays pure JSON; the spinner (on stderr) does not leak in
156
- agenzo-merchant-cli ride-elife quote --api-key sk_xxx ... | jq '.vehicle_classes'
157
- ```
124
+ ## 幂等键 (Idempotency-Key)
158
125
 
159
- The spinner animates only when stderr is an interactive terminal (TTY). When
160
- output is piped, redirected, or run in CI / by an agent, the animation is
161
- suppressed so no control characters end up in logs. Local commands (`config`,
162
- `services`) return instantly and show no spinner.
126
+ 写命令 `ride-elife book` / `cancel` 接受 `--idempotency-key`:
163
127
 
164
- ### Idempotency
128
+ - 格式:`[A-Za-z0-9_-]{1,128}`。
129
+ - **CLI 永不自动生成**:`--yes` 且缺键 → 硬错误 `PARAM_IDEMPOTENCY_KEY_REQUIRED`(exit 1),不发起请求;非 `--yes` 缺键 → 交互索取。
130
+ - 作为 `Idempotency-Key` HTTP **头**发送,**绝不进 body**。
131
+ - 同一逻辑请求重试用同一键;新请求用新键。
165
132
 
166
- Write operations (`ride-elife book`, `ride-elife cancel`) require a caller-supplied
167
- `--idempotency-key`. The CLI **never** auto-generates one:
133
+ ## book 的计费模型(monthly_settlement-aware)
168
134
 
169
- - Without `--yes`, the CLI prompts for the key interactively.
170
- - With `--yes`, a missing key is a hard error (`PARAM_IDEMPOTENCY_KEY_REQUIRED`).
135
+ `ride-elife book` **不接受** `--payment-method-id` 或任何卡信息——商户域不持有支付句柄。funding 由后端按 Developer 的 `billing_mode` 决定:
171
136
 
172
- The key must be 1–128 characters from `[A-Za-z0-9_-]` and is sent as the
173
- `Idempotency-Key` header — never in the request body.
137
+ - **monthly_settlement**:从月结账户扣减,无支付句柄;响应 `payment_status=ON_ACCOUNT`,含 `billing_entry_id`。
138
+ - **pay_per_call**:可选透传 `--payment-order-id`(payment-cli 已扣款的 PAID 订单号);响应回显 `payment_order_id`。
174
139
 
175
- ## Authentication
140
+ 请求 body 至多含可选 `payment_order_id`。
176
141
 
177
- Runtime commands (`services`, `ride-elife`) require `--api-key`. The value is sent on
178
- every request as the `X-API-Key` header. `config` commands are local-only and
179
- need no API key.
142
+ ## profile / host 模型
180
143
 
181
- ## Host configuration
144
+ merchant-cli **没有任何 host / config 命令**,不治理环境。它复用 `@agenzo/cli-core` 的 `ConfigManager` 默认配置(即 `agenzo-admin-cli` 统一治理的环境,默认落盘 `~/.agenzo-admin-cli/`):
182
145
 
183
- The default API host is `https://agent.everonet.com`. Override it with
184
- `config set-host` (persisted at `~/.agenzo-merchant-cli/config.json`) and revert
185
- with `config reset-host`:
146
+ - 为 `ApiClient` 提供 `baseUrl`(host + `/api/merchant/v1`)。
147
+ - 为 json 输出的 `profile` / `endpoint` 信封提供环境名 + host。
186
148
 
187
- ```bash
188
- agenzo-merchant-cli config set-host http://localhost:8000 # local dev
189
- agenzo-merchant-cli config reset-host # back to https://agent.everonet.com
190
- agenzo-merchant-cli config show
191
- ```
149
+ **环境治理(设置 host / 切换环境)归 `agenzo-admin-cli`**(`agenzo-admin-cli config set` / `set-host`)——与 `agenzo-token-cli` 一致。
192
150
 
193
- ## Error Codes (Ride)
151
+ ## 机器可读的 verb schema
194
152
 
195
- | Code | HTTP | Meaning |
196
- |------|------|---------|
197
- | 1801 | 404 | `VEHICLE_UNAVAILABLE` — No vehicles available for this trip |
198
- | 1802 | 410 | `QUOTE_EXPIRED` — Quote has expired, request a new one |
199
- | 1803 | 502 | `BOOKING_FAILED` — elife rejected the booking (details in response) |
200
- | 1804 | 409 | `CANCELLATION_NOT_ALLOWED` — Cannot cancel in current status |
201
- | 1805 | 404 | `RIDE_NOT_FOUND` — Order not found (or belongs to another org) |
202
- | 1809 | 402 | `ACCOUNT_INSUFFICIENT_BALANCE` — Not enough balance |
203
- | 1811 | 400 | `PRICE_MISMATCH` — price_amount doesn't match the quoted price |
204
- | 1812 | 400 | `VEHICLE_CLASS_MISMATCH` — vehicle_class doesn't match the quote |
153
+ 每个 `ride-elife` verb 支持 `--help --format json`,输出该 verb 的机器可读 schema(`cli` / `noun` / `verb` / `description` / `flags` / `response` / `example`,部分含 `error_recovery` / `polling`):
205
154
 
206
- When a booking fails (1803), the response `data.elife_details` contains the
207
- upstream error for debugging (e.g. missing required fields).
155
+ ```bash
156
+ agenzo-merchant-cli ride-elife quote --help --format json
157
+ agenzo-merchant-cli ride-elife book --help --format json
158
+ ```
208
159
 
209
- **Note:** `--passenger-email` is **required for scheduled/airport rides** (elife
210
- requires it for the airport partner). Omitting it for a scheduled ride results
211
- in a 1803 error with message "passenger.email: This field is required".
160
+ ## 开发
212
161
 
213
- ## Amounts
162
+ ```bash
163
+ npm run build -w @agenzo/merchant-cli # tsup 构建
164
+ npm run test -w @agenzo/merchant-cli # vitest(含 fast-check PBT)
165
+ ```
166
+
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
+ ```
214
183
 
215
- Monetary amounts are **decimals in the currency's standard unit** (e.g. `12.50`
216
- USD), not minor units / cents.
184
+ ## 文档索引
217
185
 
218
- ## 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)。
219
189
 
220
- ```bash
221
- npm install
222
- npm run build # tsup production build
223
- npm run dev # watch build
224
- npm run lint # eslint
225
- ```
190
+ ## 更新日志
226
191
 
227
- ## License
192
+ ### 2026-06
228
193
 
229
- 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`。