viatris-exam-cli 0.0.0-stage → 1.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,3 +1,212 @@
1
- # Temporary Holding Version
1
+ # Viatris Exam CLI
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ 面向 Agent 的 Viatris 考试 OpenAPI 命令行客户端。运行时零第三方依赖,要求 Node.js 18 或更高版本。
4
+
5
+ ## 安装
6
+
7
+ ```bash
8
+ npm link
9
+ export VIATRIS_API_KEY="replace-with-real-key"
10
+ ```
11
+
12
+ 默认连接线上环境:
13
+
14
+ ```text
15
+ https://apaaspsc.doubaoapps.com/app/app_17gbe211qq5/openapi/
16
+ ```
17
+
18
+ 切换到开发环境:
19
+
20
+ ```bash
21
+ export VIATRIS_API_ENV="development"
22
+ ```
23
+
24
+ 开发环境地址:
25
+
26
+ ```text
27
+ https://apaaspsc-app_17gbe211qq5-1879207268486311.aiforce.run/app/app_17gbe211qq5/openapi/
28
+ ```
29
+
30
+ `VIATRIS_API_ENV` 支持 `production`、`development`,以及别名 `prod`、`dev`。如需临时连接其他部署,可设置 `VIATRIS_API_BASE_URL`;该变量的优先级高于环境预设。
31
+
32
+ CLI 不接受 `--api-key` 参数,避免密钥进入 shell history、进程列表或 Agent 日志。默认使用:
33
+
34
+ ```text
35
+ X-API-Key: <VIATRIS_API_KEY>
36
+ ```
37
+
38
+ 若服务端使用 Bearer Token:
39
+
40
+ ```bash
41
+ export VIATRIS_API_KEY_HEADER="Authorization"
42
+ export VIATRIS_API_KEY_PREFIX="Bearer "
43
+ ```
44
+
45
+ ## Agent 接口约定
46
+
47
+ - API 成功响应以 JSON 写入 `stdout`。
48
+ - 错误以单行结构化 JSON 写入 `stderr`。
49
+ - POST/PUT 请求从文件、`stdin` 或 `--json` 读取 JSON 对象。
50
+ - API Key 只从 `VIATRIS_API_KEY` 环境变量读取。
51
+ - 默认使用线上环境,可通过 `VIATRIS_API_ENV=development` 切换到开发环境。
52
+ - `VIATRIS_API_BASE_URL` 可覆盖当前环境地址。
53
+ - GET 请求遇到网络错误、HTTP 429 或 5xx 时自动重试,POST/PUT 不自动重试。
54
+ - `describe` 返回机器可读的命令、参数、认证和退出码清单。
55
+ - ID 路径参数自动进行 URL 编码。
56
+ - HTTP 401/403 使用专用退出码,方便 Agent 判断需要刷新认证。
57
+
58
+ ```bash
59
+ viatris-exam describe --compact
60
+ ```
61
+
62
+ 退出码:
63
+
64
+ | 退出码 | 含义 |
65
+ | --- | --- |
66
+ | `0` | 成功 |
67
+ | `1` | API 返回错误 |
68
+ | `2` | 命令、参数、校验或输入错误 |
69
+ | `3` | 环境配置错误 |
70
+ | `4` | 网络或超时错误 |
71
+ | `5` | 认证或授权错误 |
72
+
73
+ ## 命令
74
+
75
+ ### 产品知识树
76
+
77
+ ```bash
78
+ viatris-exam products get "$PRODUCT_ID"
79
+ viatris-exam products update-knowledge-tree "$PRODUCT_ID" \
80
+ --input knowledge-tree.json
81
+ ```
82
+
83
+ 知识树回写是完整替换操作,必须一次提交全部 10-500 个 L3/L4 动态节点。先查询产品以获取固定 L2 维度的 `clientRef`。
84
+
85
+ ### 出题任务
86
+
87
+ ```bash
88
+ viatris-exam gen-tasks list --status generating --limit 20
89
+ viatris-exam gen-tasks get "$TASK_ID"
90
+ viatris-exam gen-tasks submit "$TASK_ID" --input examples/generated-questions.json
91
+ ```
92
+
93
+ `externalRef` 是题目回写的幂等键。Agent 重试 POST 前应复用原值。
94
+
95
+ ### 考试记录
96
+
97
+ ```bash
98
+ viatris-exam exam-records get "$RECORD_ID"
99
+ viatris-exam exam-records scoring-rules "$RECORD_ID"
100
+ ```
101
+
102
+ 第二个命令返回答卷绑定版本的完整评分规则及用于回写的 `taskId`。
103
+
104
+ ### 评分任务
105
+
106
+ ```bash
107
+ viatris-exam scoring get "$TASK_ID"
108
+ viatris-exam scoring submit "$TASK_ID" --input examples/scoring-results.json
109
+ ```
110
+
111
+ 评分规则 V2 使用稳定的评分点 ID、扣分规则 ID 和题目级封顶规则,由服务端计算最终得分。V1 `pointResults` 结构继续兼容。
112
+
113
+ ### 考试与题库
114
+
115
+ ```bash
116
+ viatris-exam exams create --input exam.json
117
+ viatris-exam questions create < questions.json
118
+ viatris-exam questions version "$QUESTION_ID" --input version.json
119
+ ```
120
+
121
+ ### 医疗知识检索
122
+
123
+ 简单查询可直接使用参数:
124
+
125
+ ```bash
126
+ viatris-exam medical-search search "阿托伐他汀 适应症" \
127
+ --file-type drug \
128
+ --limit 4 \
129
+ --max-length 1200
130
+ ```
131
+
132
+ 也可提交完整 JSON:
133
+
134
+ ```bash
135
+ printf '%s' '{"query":"阿托伐他汀 适应症","limit":4}' |
136
+ viatris-exam medical-search search
137
+ ```
138
+
139
+ ## 错误格式
140
+
141
+ ```json
142
+ {
143
+ "error": {
144
+ "type": "http_error",
145
+ "message": "API request failed with HTTP 422.",
146
+ "details": {
147
+ "status": 422,
148
+ "method": "POST",
149
+ "path": "/openapi/questions",
150
+ "requestId": "request-id",
151
+ "response": {
152
+ "message": "validation failed"
153
+ }
154
+ }
155
+ }
156
+ }
157
+ ```
158
+
159
+ ## 全局参数
160
+
161
+ ```text
162
+ --base-url <url> 覆盖当前环境地址
163
+ --key-header <name> 覆盖 VIATRIS_API_KEY_HEADER
164
+ --key-prefix <value> 覆盖 VIATRIS_API_KEY_PREFIX
165
+ --timeout <ms> 超时时间,默认 30000
166
+ --retries <n> GET 重试次数,默认 2
167
+ --compact 输出单行紧凑 JSON
168
+ ```
169
+
170
+ 地址选择优先级为 `--base-url`、`VIATRIS_API_BASE_URL`、`VIATRIS_API_ENV` 对应的预设地址。认证 Key 仍必须通过 `VIATRIS_API_KEY` 提供。
171
+
172
+ ## 项目结构
173
+
174
+ ```text
175
+ src/
176
+ ├── cli.js # 入口与异常收口
177
+ ├── app.js # 应用编排
178
+ ├── commands.js # 领域命令路由
179
+ ├── command-handlers/
180
+ │ └── *.js # 各领域到 OpenAPI 请求的映射
181
+ ├── args.js # 参数解析与校验
182
+ ├── input.js # JSON 文件、stdin 与内联输入
183
+ ├── config.js # 环境、地址与认证配置
184
+ ├── http.js # HTTP、重试与响应处理
185
+ ├── metadata.js # 版本、命令和环境元数据
186
+ ├── help.js # 帮助文本
187
+ ├── output.js # 标准 JSON 输出
188
+ └── errors.js # 错误类型
189
+ skills/
190
+ └── viatris-exam-cli/
191
+ ├── SKILL.md
192
+ └── references/cli-reference.md
193
+ ```
194
+
195
+ 可分发的 Agent Skill 位于 `skills/viatris-exam-cli/`,与 `src/` 同级并包含在 npm 发布包中。`skills/viatris-exam-cli.zip` 是同步生成的独立分发包。`.trae/skills/viatris-exam-cli` 是指向规范目录的相对符号链接,仅用于本地自动发现。
196
+
197
+ ## 变更规则
198
+
199
+ 任何代码、命令、接口结构、环境地址或文档变化都必须:
200
+
201
+ 1. 更新 `skills/viatris-exam-cli/SKILL.md` 及受影响的参考文件。
202
+ 2. 同步递增 `package.json`、`src/metadata.js` 和 Skill frontmatter 中的版本。
203
+ 3. 保持 `src/cli.js` 为薄入口,将能力放在职责单一的模块中。
204
+ 4. 重新生成 Skill ZIP 并执行验证:
205
+
206
+ ```bash
207
+ npm run pack:skill
208
+ npm test
209
+ npm run check
210
+ npm run check:versions
211
+ npm run check:skill
212
+ ```
package/package.json CHANGED
@@ -1,6 +1,24 @@
1
1
  {
2
2
  "name": "viatris-exam-cli",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "version": "1.3.0",
4
+ "description": "Agent-friendly CLI for the Viatris exam OpenAPI",
5
+ "type": "module",
6
+ "bin": {
7
+ "viatris-exam": "./src/cli.js"
8
+ },
9
+ "files": [
10
+ "src/",
11
+ "skills/"
12
+ ],
13
+ "scripts": {
14
+ "test": "node --test",
15
+ "check": "node --check src/*.js && node --check src/command-handlers/*.js",
16
+ "check:versions": "node scripts/check-versions.js",
17
+ "check:skill": "node scripts/check-skill.js",
18
+ "pack:skill": "cd skills && /bin/rm -f viatris-exam-cli.zip && /usr/bin/zip -qr viatris-exam-cli.zip viatris-exam-cli -x '*.DS_Store'"
19
+ },
20
+ "engines": {
21
+ "node": ">=18"
22
+ },
23
+ "license": "UNLICENSED"
24
+ }
@@ -0,0 +1,44 @@
1
+ ---
2
+ name: viatris-exam-cli
3
+ description: Operate the Viatris exam OpenAPI through its agent-friendly CLI. Use for products, knowledge trees, generation tasks, exam records, scoring, exams, questions, or medical search.
4
+ version: 1.3.0
5
+ ---
6
+
7
+ # Viatris Exam CLI
8
+
9
+ Use the repository-local CLI for every supported API operation. Do not call the HTTP endpoints directly when the CLI covers the task.
10
+
11
+ ## Start
12
+
13
+ 1. Run commands from the repository root.
14
+ 2. Require `VIATRIS_API_KEY` in the environment. Never place the key in arguments, files, output, or logs.
15
+ 3. Use production by default. Set `VIATRIS_API_ENV=development` only when the user requests development or testing.
16
+ 4. Run `node src/cli.js describe --compact` when capability discovery or exact machine-readable metadata is needed.
17
+ 5. Read [references/cli-reference.md](references/cli-reference.md) before constructing a write payload or handling a nonzero exit code.
18
+
19
+ ## Execute
20
+
21
+ - Invoke the CLI as `node src/cli.js ...`. Do not require `npm link`.
22
+ - Prefer `--input <file>` for existing payloads and stdin for generated payloads.
23
+ - Parse successful `stdout` as JSON.
24
+ - Parse failed `stderr` as JSON and branch on both exit code and `error.type`.
25
+ - Preserve `externalRef` when retrying question submission. It is the idempotency key.
26
+ - Prefer scoring rule V2 for generated questions and scoring results. Use stable point and deduction-rule IDs.
27
+ - Do not automatically retry POST or PUT commands. Inspect the returned error and determine whether the server accepted the request.
28
+ - Keep temporary payloads outside the repository unless they are requested deliverables.
29
+
30
+ ## Maintain
31
+
32
+ Treat every repository behavior, command, schema, URL, documentation, or implementation change as a versioned Skill change.
33
+
34
+ For every change:
35
+
36
+ 1. Update `skills/viatris-exam-cli/` and its affected references.
37
+ 2. Increment the semantic version in `package.json`, `src/metadata.js`, and this frontmatter `version`.
38
+ 3. Keep all three versions identical.
39
+ 4. Keep `src/cli.js` as a thin entrypoint. Put capabilities in focused modules under `src/`.
40
+ 5. Keep `.trae/skills/viatris-exam-cli` as a relative symlink to the distributable Skill directory.
41
+ 6. Run `npm run pack:skill` so `skills/viatris-exam-cli.zip` matches the canonical directory.
42
+ 7. Run `npm test`, `npm run check`, `npm run check:versions`, and `npm run check:skill`.
43
+
44
+ Do not finish a code change while the Skill or any version is stale.
@@ -0,0 +1,319 @@
1
+ # CLI Reference
2
+
3
+ ## Authentication And Environment
4
+
5
+ Required:
6
+
7
+ ```bash
8
+ export VIATRIS_API_KEY="..."
9
+ ```
10
+
11
+ Environment selection:
12
+
13
+ | Value | Target |
14
+ | --- | --- |
15
+ | unset, `production`, `prod` | Production |
16
+ | `development`, `dev` | Development |
17
+
18
+ `VIATRIS_API_BASE_URL` overrides the selected environment. Use it only for an explicitly supplied custom deployment or local mock.
19
+
20
+ Default authentication header:
21
+
22
+ ```text
23
+ X-API-Key: <VIATRIS_API_KEY>
24
+ ```
25
+
26
+ For Bearer authentication:
27
+
28
+ ```bash
29
+ export VIATRIS_API_KEY_HEADER="Authorization"
30
+ export VIATRIS_API_KEY_PREFIX="Bearer "
31
+ ```
32
+
33
+ ## Capability Discovery
34
+
35
+ ```bash
36
+ node src/cli.js describe --compact
37
+ node src/cli.js --help
38
+ node src/cli.js --version
39
+ ```
40
+
41
+ `describe` does not require credentials. It returns commands, paths, environment metadata, authentication metadata, and exit codes as JSON.
42
+
43
+ ## Commands
44
+
45
+ Get a product and its fixed L2 dimensions:
46
+
47
+ ```bash
48
+ node src/cli.js products get "$PRODUCT_ID" --compact
49
+ ```
50
+
51
+ Use each returned `fixedDimensions[].clientRef` as the parent reference for an L3 node.
52
+
53
+ Replace a product knowledge tree:
54
+
55
+ ```bash
56
+ node src/cli.js products update-knowledge-tree "$PRODUCT_ID" \
57
+ --input knowledge-tree.json \
58
+ --compact
59
+ ```
60
+
61
+ Payload shape:
62
+
63
+ ```json
64
+ {
65
+ "nodes": [
66
+ {
67
+ "clientRef": "disease.hypertension",
68
+ "parentClientRef": "dimension:disease",
69
+ "level": 3,
70
+ "dimensionCode": "disease",
71
+ "name": "高血压",
72
+ "sortOrder": 1
73
+ },
74
+ {
75
+ "clientRef": "disease.hypertension.definition",
76
+ "parentClientRef": "disease.hypertension",
77
+ "level": 4,
78
+ "dimensionCode": "disease",
79
+ "name": "定义与诊断",
80
+ "sortOrder": 1,
81
+ "documents": [
82
+ {
83
+ "title": "药品说明书",
84
+ "url": "https://example.com/source",
85
+ "summary": "与该知识点直接对应的证据摘录"
86
+ }
87
+ ]
88
+ }
89
+ ]
90
+ }
91
+ ```
92
+
93
+ Submit the complete L3/L4 node set, between 10 and 500 nodes. Every `clientRef` must be unique within the payload. L3 nodes use `dimension:<code>` as `parentClientRef`; L4 nodes use an L3 `clientRef`. Every L4 node needs at least one document. A successful PUT replaces the previous dynamic nodes, so do not send a partial tree.
94
+
95
+ List generation tasks:
96
+
97
+ ```bash
98
+ node src/cli.js gen-tasks list \
99
+ --status generating \
100
+ --limit 20 \
101
+ --compact
102
+ ```
103
+
104
+ `--status` accepts `generating`, `partial_failed`, or `failed`. `--limit` accepts 1 through 50.
105
+
106
+ Get one generation task:
107
+
108
+ ```bash
109
+ node src/cli.js gen-tasks get "$TASK_ID" --compact
110
+ ```
111
+
112
+ Submit generated questions:
113
+
114
+ ```bash
115
+ node src/cli.js gen-tasks submit "$TASK_ID" --input payload.json --compact
116
+ ```
117
+
118
+ Payload shape:
119
+
120
+ ```json
121
+ {
122
+ "items": [
123
+ {
124
+ "externalRef": "agent-q-0001",
125
+ "failureId": "optional-failure-id",
126
+ "content": {
127
+ "stem": "Question stem",
128
+ "referenceAnswer": "Reference answer",
129
+ "scoringPoints": [
130
+ {
131
+ "id": "dose-selection",
132
+ "point": "Scoring point",
133
+ "maxScore": 4,
134
+ "criteria": "Choose one deduction level",
135
+ "deductionRules": [
136
+ {
137
+ "id": "dose-selection-full",
138
+ "level": "full",
139
+ "deductScore": 0,
140
+ "criteria": "Complete answer"
141
+ },
142
+ {
143
+ "id": "dose-selection-zero",
144
+ "level": "zero",
145
+ "deductScore": 4,
146
+ "criteria": "Wrong or missing answer"
147
+ }
148
+ ]
149
+ }
150
+ ],
151
+ "scoringRuleVersion": 2,
152
+ "scoreCapRules": [
153
+ {
154
+ "id": "critical-error-1",
155
+ "description": "Critical contradictory conclusion",
156
+ "maxTotalScore": 2
157
+ }
158
+ ],
159
+ "evidence": [
160
+ {
161
+ "source": "Source",
162
+ "citation": "Citation",
163
+ "relevance": "Relevance"
164
+ }
165
+ ]
166
+ },
167
+ "qcResult": {
168
+ "outOfScope": false,
169
+ "insufficientEvidence": false,
170
+ "answerConflict": false,
171
+ "duplicateRisk": false,
172
+ "summary": "No obvious issue"
173
+ }
174
+ }
175
+ ],
176
+ "finished": true
177
+ }
178
+ ```
179
+
180
+ Get a submitted exam record and its frozen answers:
181
+
182
+ ```bash
183
+ node src/cli.js exam-records get "$RECORD_ID" --compact
184
+ ```
185
+
186
+ Get the complete scoring rules bound to the record:
187
+
188
+ ```bash
189
+ node src/cli.js exam-records scoring-rules "$RECORD_ID" --compact
190
+ ```
191
+
192
+ The response includes the scoring `taskId`, `schemaVersion`, frozen question versions, evidence, V2 deduction rules, score caps, and item IDs. Use its `taskId` for scoring submission.
193
+
194
+ Get a scoring task:
195
+
196
+ ```bash
197
+ node src/cli.js scoring get "$TASK_ID" --compact
198
+ ```
199
+
200
+ Submit scoring results:
201
+
202
+ ```bash
203
+ node src/cli.js scoring submit "$TASK_ID" --input results.json --compact
204
+ ```
205
+
206
+ Payload shape:
207
+
208
+ ```json
209
+ {
210
+ "items": [
211
+ {
212
+ "itemId": "item-id",
213
+ "ok": true,
214
+ "pointJudgements": [
215
+ {
216
+ "pointId": "dose-selection",
217
+ "appliedDeductionRuleId": "dose-selection-full",
218
+ "reason": "Reason for selecting this deduction level",
219
+ "quote": "Supporting answer quote"
220
+ }
221
+ ],
222
+ "triggeredScoreCaps": [],
223
+ "flags": [],
224
+ "needReview": false
225
+ }
226
+ ]
227
+ }
228
+ ```
229
+
230
+ For V2, submit exactly one `pointJudgement` per scoring point. IDs must match the fetched rule set. Add triggered cap rule IDs to `triggeredScoreCaps`; the server calculates the score, so `total` is optional and must match if supplied. V1 remains compatible through `pointResults` and required `total`. For a failed item, set `ok` to `false` and provide `failureReason`.
231
+
232
+ Create an exam:
233
+
234
+ ```bash
235
+ node src/cli.js exams create --input exam.json --compact
236
+ ```
237
+
238
+ Required top-level fields are `name`, `product`, `questionCount`, `startAt`, `endAt`, `resultPolicy`, and `assigneeIds`. `questionCount` is 1 through 150. Use either `questions` or legacy `questionIds`, never both. Each question score must be a positive integer and the complete exam must total exactly 100.
239
+
240
+ Create questions directly:
241
+
242
+ ```bash
243
+ node src/cli.js questions create --input questions.json --compact
244
+ ```
245
+
246
+ Payload shape is `{ "items": [...] }`. Each item requires `product`, `dimension`, and `content`; provide `externalRef` for idempotency. Prefer `scoringRuleVersion: 2`, stable IDs on scoring points and deduction rules, and explicit `scoreCapRules`.
247
+
248
+ The API has partial-success semantics: inspect `accepted`, `duplicates`, and every entry in `rejected` even when the HTTP response is successful.
249
+
250
+ Add a question version:
251
+
252
+ ```bash
253
+ node src/cli.js questions version "$QUESTION_ID" --input version.json --compact
254
+ ```
255
+
256
+ Required fields are `stem`, `referenceAnswer`, nonempty `scoringPoints`, `evidence`, and `editReason`. V2 versions may also include `scoringRuleVersion: 2`, deduction rules, and `scoreCapRules`.
257
+
258
+ Search medical evidence:
259
+
260
+ ```bash
261
+ node src/cli.js medical-search search "阿托伐他汀 适应症" \
262
+ --file-type drug \
263
+ --limit 4 \
264
+ --max-length 1200 \
265
+ --compact
266
+ ```
267
+
268
+ Or use JSON:
269
+
270
+ ```bash
271
+ printf '%s' '{"query":"阿托伐他汀 适应症","limit":4}' |
272
+ node src/cli.js medical-search search --compact
273
+ ```
274
+
275
+ Do not combine query flags with JSON input.
276
+
277
+ ## Input Rules
278
+
279
+ Choose exactly one input form:
280
+
281
+ ```bash
282
+ node src/cli.js questions create --input payload.json
283
+ node src/cli.js questions create --input - < payload.json
284
+ node src/cli.js questions create --json '{"items":[]}'
285
+ printf '%s' '{"items":[]}' | node src/cli.js questions create
286
+ ```
287
+
288
+ The top-level JSON value must be an object.
289
+
290
+ ## Output And Errors
291
+
292
+ Success writes API JSON to `stdout`. Errors write one JSON object to `stderr`:
293
+
294
+ ```json
295
+ {
296
+ "error": {
297
+ "type": "http_error",
298
+ "message": "API request failed with HTTP 422.",
299
+ "details": {
300
+ "status": 422,
301
+ "method": "POST",
302
+ "path": "/openapi/questions",
303
+ "requestId": "optional-request-id",
304
+ "response": {}
305
+ }
306
+ }
307
+ }
308
+ ```
309
+
310
+ | Exit | Meaning | Agent action |
311
+ | --- | --- | --- |
312
+ | `0` | Success | Parse stdout JSON |
313
+ | `1` | API error | Inspect status and response |
314
+ | `2` | Usage, validation, or input error | Correct command or payload |
315
+ | `3` | Configuration error | Check environment configuration |
316
+ | `4` | Network or timeout error | GET may be retried; inspect POST/PUT state first |
317
+ | `5` | Authentication or authorization error | Refresh or correct credentials |
318
+
319
+ GET automatically retries network errors, HTTP 429, and HTTP 5xx. POST and PUT never retry automatically.
Binary file
package/src/app.js ADDED
@@ -0,0 +1,36 @@
1
+ import { assertNoExtraPositionals, parseArgs } from "./args.js";
2
+ import { resolveCommand } from "./commands.js";
3
+ import { configFrom } from "./config.js";
4
+ import { helpText } from "./help.js";
5
+ import { request } from "./http.js";
6
+ import { describeCli, VERSION } from "./metadata.js";
7
+ import { writeJson } from "./output.js";
8
+
9
+ export async function run(
10
+ argv,
11
+ {
12
+ stdout = process.stdout,
13
+ environmentVariables = process.env,
14
+ } = {},
15
+ ) {
16
+ const { positionals, options } = parseArgs(argv);
17
+
18
+ if (options.version) {
19
+ stdout.write(`${VERSION}\n`);
20
+ return;
21
+ }
22
+ if (options.help || positionals.length === 0) {
23
+ stdout.write(helpText());
24
+ return;
25
+ }
26
+ if (positionals[0] === "describe") {
27
+ assertNoExtraPositionals(positionals, 1);
28
+ writeJson(stdout, describeCli(), options.compact);
29
+ return;
30
+ }
31
+
32
+ const command = await resolveCommand(positionals, options);
33
+ const config = configFrom(options, environmentVariables);
34
+ const response = await request(command, config);
35
+ writeJson(stdout, response, options.compact);
36
+ }