@nuxtseo/cli 0.1.4 → 0.2.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 +113 -31
- package/dist/api.js +7 -1
- package/dist/cli.js +62 -11
- package/dist/command-contract.js +10 -0
- package/dist/commands.d.ts +19 -0
- package/dist/commands.js +1215 -89
- package/dist/failures.d.ts +2 -1
- package/dist/failures.js +21 -1
- package/dist/parse.d.ts +9 -0
- package/dist/parse.js +21 -0
- package/dist/render.d.ts +43 -9
- package/dist/render.js +636 -5
- package/dist/skill.d.ts +22 -0
- package/dist/skill.js +56 -0
- package/package.json +9 -8
- package/skills/nuxtseo-cli/SKILL.md +236 -107
- package/skills/nuxtseo-cli/references/commands.md +162 -0
- package/skills/nuxtseo-cli/references/indexing.md +60 -0
- package/skills/nuxtseo-cli/references/protocol.md +15 -4
package/README.md
CHANGED
|
@@ -71,9 +71,14 @@ Outside an interactive terminal, `login` reads a token from stdin instead of
|
|
|
71
71
|
pairing, so CI keeps working. Tokens are never accepted as positional arguments
|
|
72
72
|
or options.
|
|
73
73
|
|
|
74
|
-
The CLI validates the token with
|
|
75
|
-
|
|
76
|
-
|
|
74
|
+
The CLI validates the token with `GET /api/v1/account/token`, which reports the
|
|
75
|
+
Team, the role, the granted scopes, and the expiry without reading a Site. It
|
|
76
|
+
then stores the token in the OS keychain through optional `@napi-rs/keyring`.
|
|
77
|
+
When keychain support is unavailable, it warns on stderr and uses
|
|
78
|
+
`~/.nuxtseo/auth.json` with mode `0600`.
|
|
79
|
+
|
|
80
|
+
`nuxtseo whoami` reads the same operation, so an agent learns about a missing
|
|
81
|
+
scope before the request that needs it.
|
|
77
82
|
|
|
78
83
|
`nuxtseo logout` removes the local credential. Revoke the token from the
|
|
79
84
|
NuxtSEO dashboard when it must stop working everywhere. An environment token
|
|
@@ -164,75 +169,151 @@ nuxtseo config
|
|
|
164
169
|
nuxtseo sites list
|
|
165
170
|
nuxtseo sites use <site-id>
|
|
166
171
|
nuxtseo usage
|
|
172
|
+
nuxtseo status
|
|
167
173
|
nuxtseo actions list
|
|
168
174
|
nuxtseo actions show <action-id>
|
|
169
175
|
nuxtseo actions resolve <action-id>
|
|
176
|
+
nuxtseo actions dismiss <action-id>
|
|
177
|
+
nuxtseo backlinks summary
|
|
178
|
+
nuxtseo backlinks referring-domains
|
|
179
|
+
nuxtseo backlinks anchors
|
|
180
|
+
nuxtseo backlinks history
|
|
170
181
|
nuxtseo backlinks recoverable
|
|
171
182
|
nuxtseo mentions list
|
|
172
183
|
nuxtseo page inspect <url>
|
|
184
|
+
nuxtseo page issues
|
|
173
185
|
nuxtseo page scan <url>
|
|
174
186
|
nuxtseo performance
|
|
187
|
+
nuxtseo vitals summary
|
|
188
|
+
nuxtseo vitals trend
|
|
189
|
+
nuxtseo vitals findings
|
|
190
|
+
nuxtseo scans list
|
|
191
|
+
nuxtseo scans show <scan-id>
|
|
192
|
+
nuxtseo scans pages
|
|
193
|
+
nuxtseo annotations list
|
|
194
|
+
nuxtseo annotations create
|
|
195
|
+
nuxtseo annotations update <annotation-id>
|
|
196
|
+
nuxtseo annotations delete <annotation-id>
|
|
197
|
+
nuxtseo analytics <view>
|
|
175
198
|
nuxtseo search status
|
|
176
|
-
nuxtseo search analytics <
|
|
199
|
+
nuxtseo search analytics <view>
|
|
177
200
|
nuxtseo search indexing <summary|urls>
|
|
201
|
+
nuxtseo search cohorts
|
|
202
|
+
nuxtseo search index-history
|
|
203
|
+
nuxtseo search inspect <url>
|
|
204
|
+
nuxtseo sitemaps list
|
|
205
|
+
nuxtseo sitemaps urls
|
|
206
|
+
nuxtseo sitemaps submit <sitemap-url>
|
|
207
|
+
nuxtseo sitemaps delete <sitemap-url>
|
|
178
208
|
nuxtseo research overview
|
|
209
|
+
nuxtseo research domain-traffic <domain>
|
|
210
|
+
nuxtseo research domain-availability <domains>
|
|
179
211
|
nuxtseo research keywords <topic>
|
|
180
212
|
nuxtseo research serp <keyword>
|
|
181
213
|
nuxtseo research rankings <domain>
|
|
214
|
+
nuxtseo audit changes
|
|
182
215
|
nuxtseo audit link-opportunities
|
|
216
|
+
nuxtseo audit link-structure
|
|
183
217
|
nuxtseo audit content-decay
|
|
184
218
|
nuxtseo audit duplicates
|
|
185
219
|
nuxtseo content briefs list
|
|
186
220
|
nuxtseo content briefs show <brief-id>
|
|
187
221
|
nuxtseo content briefs create <keyword>
|
|
222
|
+
nuxtseo timeline list
|
|
223
|
+
nuxtseo skill install
|
|
188
224
|
```
|
|
189
225
|
|
|
226
|
+
`search analytics` takes `pages`, `keywords`, `countries`, `devices`,
|
|
227
|
+
`timeseries`, `page-detail`, `keyword-detail`, or `analysis`. `page-detail`
|
|
228
|
+
needs `--page-url`, `keyword-detail` needs `--keyword`, and `analysis` needs
|
|
229
|
+
`--preset`. The `brand-only` and `non-brand` presets also need `--brand-terms`.
|
|
230
|
+
The CLI refuses a missing argument before it sends a request.
|
|
231
|
+
|
|
232
|
+
`analytics` takes `performance`, `top-pages`, `source-medium`, `key-events`,
|
|
233
|
+
`countries`, `devices`, or `dimension`. The `dimension` view needs
|
|
234
|
+
`--dimension`.
|
|
235
|
+
|
|
190
236
|
Run bare `nuxtseo` in a terminal for a task-based menu. It groups Site fixes,
|
|
191
237
|
performance, research, content, and account setup. The menu prints the direct
|
|
192
238
|
command it runs.
|
|
193
239
|
|
|
240
|
+
`performance` reads the stored Lighthouse lab overview. Real-user field data is
|
|
241
|
+
a different dataset: `vitals summary` and `vitals trend` read CrUX field p75,
|
|
242
|
+
and `vitals findings` names the DOM element behind each failing vital.
|
|
243
|
+
`status` reads the Site assessment: the verdict, the one ranked Next Action, and
|
|
244
|
+
what changed. Start there. `status`, `page issues` and `search cohorts` refuse
|
|
245
|
+
with exit `4` or `5` on an archived or paused Site.
|
|
246
|
+
The four live `backlinks` reads need the Site to have a URL. Without one they
|
|
247
|
+
exit `2`, and retrying will not help; set the Site URL first.
|
|
248
|
+
`search cohorts` returns two lists. Only `established` is proven; `ranked` is
|
|
249
|
+
ordered by raw rate with no significance test and is leads only.
|
|
250
|
+
`backlinks summary`, `backlinks referring-domains`, `backlinks anchors`,
|
|
251
|
+
`backlinks history`, `research domain-traffic` and `research domain-availability`
|
|
252
|
+
can use the Team research limit. Each response reports
|
|
253
|
+
cache use in `evidence`; a cached response spends nothing. `backlinks recoverable`
|
|
254
|
+
reads retained rows and spends nothing.
|
|
194
255
|
`search status` reads stored connection state. It never waits for Google.
|
|
195
256
|
`search indexing summary` reads retained URL Inspection coverage.
|
|
257
|
+
`search index-history` dates an indexing change against known releases.
|
|
258
|
+
`search inspect <url>` reads Google's own verdict for one URL.
|
|
259
|
+
`page inspect <url>` reads the NuxtSEO observation store for the same URL.
|
|
196
260
|
`research keywords`, `research serp`, and `research rankings` can use the Team
|
|
197
|
-
research
|
|
198
|
-
ranking responses report `cached: true`.
|
|
199
|
-
|
|
200
|
-
The CLI fetches one page per invocation. It
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
|
204
|
-
|
|
|
205
|
-
| `actions
|
|
206
|
-
| `
|
|
207
|
-
| `
|
|
208
|
-
| `backlinks
|
|
209
|
-
| `
|
|
210
|
-
| `
|
|
211
|
-
| `
|
|
212
|
-
| `
|
|
261
|
+
research limit. Keyword responses report cache use in `evidence`. SERP and
|
|
262
|
+
ranking responses report `cached: true`. A cached response spends nothing.
|
|
263
|
+
|
|
264
|
+
The CLI fetches one page per invocation by default. It never merges responses.
|
|
265
|
+
|
|
266
|
+
| Command | Paging inputs | Default | `--all` |
|
|
267
|
+
| --- | --- | --- | --- |
|
|
268
|
+
| `actions list` | `--limit 1..25`, `--offset >=0` | `--limit 10 --offset 0` | yes |
|
|
269
|
+
| `actions show` | `--group-id`, `--cursor`, `--limit 1..100` | `--limit 50` | no |
|
|
270
|
+
| `page inspect` | `--limit 1..200`, `--offset >=0` | `--limit 100 --offset 0` | yes |
|
|
271
|
+
| `backlinks recoverable` | `--limit 1..200`, `--offset >=0` | `--limit 100 --offset 0` | yes |
|
|
272
|
+
| `backlinks referring-domains` | `--limit 1..1000` | `--limit 100` | no |
|
|
273
|
+
| `backlinks anchors` | `--limit 1..1000` | `--limit 100` | no |
|
|
274
|
+
| `vitals findings` | `--limit 1..50`, `--offset >=0` | `--limit 20 --offset 0` | yes |
|
|
275
|
+
| `page issues` | `--limit 1..200`, `--offset >=0` | `--limit 100 --offset 0` | yes |
|
|
276
|
+
| `scans list` | `--limit 1..100` | `--limit 25` | no |
|
|
277
|
+
| `search cohorts` | `--limit 1..50`, `--min-pages 1..500` | `--limit 12 --min-pages 5` | no |
|
|
278
|
+
| `mentions list` | `--limit 1..200` | `--limit 100` | no |
|
|
279
|
+
| `search analytics` | `--limit 1..100`, `--page >=1` | `--limit 25 --page 1` | row views only |
|
|
280
|
+
| `search indexing` | `--limit 1..500`, `--offset >=0` | `--limit 50 --offset 0` | `urls` view only |
|
|
281
|
+
| `sitemaps urls` | `--cursor`, `--limit 1..1000` | `--limit 500` | yes |
|
|
282
|
+
| `content briefs list` | `--limit 1..100`, `--offset >=0` | `--limit 25 --offset 0` | yes |
|
|
283
|
+
| `timeline list` | `--kind`, `--feature`, `--severity`, `--since`, `--cursor`, `--limit 1..100` | `--limit 25` | no |
|
|
213
284
|
|
|
214
285
|
Keep the server order for actions. For another page, pass the next offset or
|
|
215
286
|
cursor reported by the response. A cursor is opaque; do not edit or infer it.
|
|
216
287
|
|
|
217
|
-
|
|
288
|
+
### `--all`
|
|
218
289
|
|
|
219
|
-
|
|
220
|
-
|
|
290
|
+
`--all` repeats the same operation until the server reports no more pages. It
|
|
291
|
+
writes one complete envelope per page, newline delimited. The CLI never merges,
|
|
292
|
+
unwraps, or re-ranks a page. Read the stream one JSON value per line.
|
|
221
293
|
|
|
222
|
-
|
|
294
|
+
The loop stops after 50 requests. If pages remain at that point, the CLI exits
|
|
295
|
+
`9` and stderr names the exact argument that resumes the read, for example
|
|
296
|
+
`--offset 50`. Exit `9` is a stop, never an end of data.
|
|
223
297
|
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
```
|
|
298
|
+
`--all` covers the Search Console views the server pages: `pages`, `keywords`,
|
|
299
|
+
`countries`, `devices`, and `analysis`, plus the `urls` indexing view. Every
|
|
300
|
+
other view returns one payload, so the CLI refuses `--all` there with exit `2`.
|
|
228
301
|
|
|
229
|
-
|
|
302
|
+
## Coding agents
|
|
303
|
+
|
|
304
|
+
The package ships an agent skill that teaches coding agents how to drive the
|
|
305
|
+
CLI. Install it with the CLI itself; a global install has no local
|
|
306
|
+
`node_modules` to copy from.
|
|
230
307
|
|
|
231
308
|
```sh
|
|
232
|
-
|
|
233
|
-
|
|
309
|
+
nuxtseo skill install # ~/.claude/skills/nuxtseo-cli
|
|
310
|
+
nuxtseo skill install --agent codex # ~/.codex/skills/nuxtseo-cli
|
|
311
|
+
nuxtseo skill install --target ./.claude/skills
|
|
234
312
|
```
|
|
235
313
|
|
|
314
|
+
The command reports the destination it wrote. With `--json` it emits
|
|
315
|
+
`CliSkillInstall` carrying the source and the destination.
|
|
316
|
+
|
|
236
317
|
The skill covers the JSON contract, Site selection, paging, mutation consent,
|
|
237
318
|
and what to do for each exit code.
|
|
238
319
|
|
|
@@ -248,6 +329,7 @@ and what to do for each exit code.
|
|
|
248
329
|
| `6` | Rate, quota, provider, or request timeout | Read retry metadata on stderr and retry later |
|
|
249
330
|
| `7` | Local state, network, contract, or infrastructure failure | Fix the named path or network issue; keep the request ID |
|
|
250
331
|
| `8` | Resource or accessible Site not found | Run `sites list`, then `sites use` or pass `--site` |
|
|
332
|
+
| `9` | `--all` reached its 50 request cap | Resume with the argument stderr names |
|
|
251
333
|
| `130` | Interrupted or cancelled | Confirm no mutation result before retrying |
|
|
252
334
|
|
|
253
335
|
The CLI prints the exact server error code. When available, stderr also includes
|
package/dist/api.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { createBearerTransport, createPublicV1Client } from '@nuxtseo/sdk';
|
|
2
2
|
import { EXIT_CODE, fail, ok } from './failures.js';
|
|
3
3
|
import { readConfig, resolveApiUrl, resolveCredential } from './state/index.js';
|
|
4
|
+
import { VERSION } from './version.js';
|
|
4
5
|
export function fromStateError(error) {
|
|
5
6
|
const exitCode = error._tag === 'InvalidCredential'
|
|
6
7
|
? EXIT_CODE.authentication
|
|
@@ -16,7 +17,12 @@ export function fromStateError(error) {
|
|
|
16
17
|
}
|
|
17
18
|
export function createApiClient(apiUrl, token) {
|
|
18
19
|
return createPublicV1Client({
|
|
19
|
-
transport: createBearerTransport({
|
|
20
|
+
transport: createBearerTransport({
|
|
21
|
+
baseUrl: apiUrl,
|
|
22
|
+
token,
|
|
23
|
+
// ADR-0121: agent_connected classifies the access surface by this prefix.
|
|
24
|
+
headers: { 'user-agent': `nuxtseo-cli/${VERSION}` },
|
|
25
|
+
}),
|
|
20
26
|
});
|
|
21
27
|
}
|
|
22
28
|
export async function loadApiContext(runtime, globals) {
|
package/dist/cli.js
CHANGED
|
@@ -208,7 +208,7 @@ async function interactiveBare(runtime, globals) {
|
|
|
208
208
|
message: 'Choose a task',
|
|
209
209
|
options: [
|
|
210
210
|
...(!auth.value.authenticated ? [{ value: 'login', label: 'Log in', hint: 'Team API token' }] : []),
|
|
211
|
-
{ value: 'fix', label: 'Fix my Site', hint: 'Issues, Pages, and
|
|
211
|
+
{ value: 'fix', label: 'Fix my Site', hint: 'Issues, Pages, and Scans' },
|
|
212
212
|
{ value: 'performance', label: 'Understand performance', hint: 'Performance and Search Console' },
|
|
213
213
|
{ value: 'research', label: 'Research growth', hint: 'Keywords, SERPs, and competitors' },
|
|
214
214
|
{ value: 'content', label: 'Plan content', hint: 'Briefs, decay, and duplicates' },
|
|
@@ -227,7 +227,10 @@ async function interactiveBare(runtime, globals) {
|
|
|
227
227
|
const task = await prompts.select({
|
|
228
228
|
message: 'Fix my Site',
|
|
229
229
|
options: [
|
|
230
|
+
{ value: 'status', label: 'What should I fix first?', hint: 'assessment and next action' },
|
|
230
231
|
{ value: 'actions', label: 'Issues and opportunities' },
|
|
232
|
+
{ value: 'page-issues', label: 'Raw Page Issue rows for one issue type' },
|
|
233
|
+
{ value: 'changes', label: 'What the last crawl changed' },
|
|
231
234
|
{ value: 'inspect', label: 'Inspect a Page' },
|
|
232
235
|
{ value: 'scan', label: 'Scan a Page' },
|
|
233
236
|
{ value: 'backlinks', label: 'Recover broken Backlinks' },
|
|
@@ -244,15 +247,30 @@ async function interactiveBare(runtime, globals) {
|
|
|
244
247
|
? url
|
|
245
248
|
: runInteractiveCommand(['page', task, url.value], runtime, globals);
|
|
246
249
|
}
|
|
247
|
-
|
|
250
|
+
const command = task === 'actions'
|
|
251
|
+
? ['actions', 'list']
|
|
252
|
+
: task === 'changes'
|
|
253
|
+
? ['audit', 'changes']
|
|
254
|
+
: task === 'status'
|
|
255
|
+
? ['status']
|
|
256
|
+
: task === 'page-issues'
|
|
257
|
+
? ['page', 'issues', '--source', 'crawl', '--issue', 'broken-internal-links']
|
|
258
|
+
: ['backlinks', 'recoverable'];
|
|
259
|
+
return runInteractiveCommand(command, runtime, globals);
|
|
248
260
|
}
|
|
249
261
|
if (group === 'performance') {
|
|
250
262
|
const task = await prompts.select({
|
|
251
263
|
message: 'Understand performance',
|
|
252
264
|
options: [
|
|
253
|
-
{ value: 'performance', label: 'Performance overview' },
|
|
265
|
+
{ value: 'performance', label: 'Performance overview', hint: 'stored Lighthouse lab Scans' },
|
|
266
|
+
{ value: 'vitals', label: 'Field Core Web Vitals', hint: 'CrUX real-user p75' },
|
|
267
|
+
{ value: 'findings', label: 'What to fix for Core Web Vitals', hint: 'element and fix prompt' },
|
|
268
|
+
{ value: 'scans', label: 'Lighthouse Scans', hint: 'retained lab Scans' },
|
|
269
|
+
{ value: 'cohorts', label: 'Indexing by route family', hint: 'which template Google declines' },
|
|
254
270
|
{ value: 'connection', label: 'Search Console connection' },
|
|
255
271
|
{ value: 'indexing', label: 'Search indexing coverage' },
|
|
272
|
+
{ value: 'sitemaps', label: 'Search Console sitemaps' },
|
|
273
|
+
{ value: 'traffic', label: 'Web Analytics' },
|
|
256
274
|
{ value: 'pages', label: 'Search Console Pages' },
|
|
257
275
|
{ value: 'keywords', label: 'Search Console queries' },
|
|
258
276
|
],
|
|
@@ -264,11 +282,23 @@ async function interactiveBare(runtime, globals) {
|
|
|
264
282
|
return ok(undefined);
|
|
265
283
|
const command = task === 'performance'
|
|
266
284
|
? ['performance']
|
|
267
|
-
: task === '
|
|
268
|
-
? ['
|
|
269
|
-
: task === '
|
|
270
|
-
? ['
|
|
271
|
-
:
|
|
285
|
+
: task === 'vitals'
|
|
286
|
+
? ['vitals', 'summary']
|
|
287
|
+
: task === 'findings'
|
|
288
|
+
? ['vitals', 'findings']
|
|
289
|
+
: task === 'scans'
|
|
290
|
+
? ['scans', 'list']
|
|
291
|
+
: task === 'cohorts'
|
|
292
|
+
? ['search', 'cohorts']
|
|
293
|
+
: task === 'connection'
|
|
294
|
+
? ['search', 'status']
|
|
295
|
+
: task === 'indexing'
|
|
296
|
+
? ['search', 'indexing', 'summary']
|
|
297
|
+
: task === 'sitemaps'
|
|
298
|
+
? ['sitemaps', 'list']
|
|
299
|
+
: task === 'traffic'
|
|
300
|
+
? ['analytics', 'performance']
|
|
301
|
+
: ['search', 'analytics', task];
|
|
272
302
|
return runInteractiveCommand(command, runtime, globals);
|
|
273
303
|
}
|
|
274
304
|
if (group === 'research') {
|
|
@@ -276,10 +306,13 @@ async function interactiveBare(runtime, globals) {
|
|
|
276
306
|
message: 'Research growth',
|
|
277
307
|
options: [
|
|
278
308
|
{ value: 'overview', label: 'Site and competitors', hint: 'stored data' },
|
|
279
|
-
{ value: 'keywords', label: 'Keyword ideas', hint: 'uses live research
|
|
280
|
-
{ value: 'serp', label: 'SERP analysis', hint: 'uses live research
|
|
281
|
-
{ value: 'rankings', label: 'Domain rankings', hint: 'uses live research
|
|
309
|
+
{ value: 'keywords', label: 'Keyword ideas', hint: 'uses the live research limit' },
|
|
310
|
+
{ value: 'serp', label: 'SERP analysis', hint: 'uses the live research limit' },
|
|
311
|
+
{ value: 'rankings', label: 'Domain rankings', hint: 'uses the live research limit' },
|
|
282
312
|
{ value: 'links', label: 'Link opportunities', hint: 'stored data' },
|
|
313
|
+
{ value: 'structure', label: 'Link structure', hint: 'stored data' },
|
|
314
|
+
{ value: 'backlinks', label: 'Backlink profile', hint: 'uses the live research limit' },
|
|
315
|
+
{ value: 'domain', label: 'Any domain traffic estimate', hint: 'uses the live research limit' },
|
|
283
316
|
],
|
|
284
317
|
input: runtime.input,
|
|
285
318
|
output: runtime.error,
|
|
@@ -291,6 +324,20 @@ async function interactiveBare(runtime, globals) {
|
|
|
291
324
|
return runInteractiveCommand(['research', 'overview'], runtime, globals);
|
|
292
325
|
if (task === 'links')
|
|
293
326
|
return runInteractiveCommand(['audit', 'link-opportunities'], runtime, globals);
|
|
327
|
+
if (task === 'structure')
|
|
328
|
+
return runInteractiveCommand(['audit', 'link-structure'], runtime, globals);
|
|
329
|
+
if (task === 'backlinks')
|
|
330
|
+
return runInteractiveCommand(['backlinks', 'summary'], runtime, globals);
|
|
331
|
+
if (task === 'domain') {
|
|
332
|
+
const domain = await promptTextValue(runtime, {
|
|
333
|
+
message: 'Which domain?',
|
|
334
|
+
placeholder: 'example.com',
|
|
335
|
+
label: 'Domain',
|
|
336
|
+
});
|
|
337
|
+
if (domain._tag === 'Err')
|
|
338
|
+
return domain;
|
|
339
|
+
return runInteractiveCommand(['research', 'domain-traffic', domain.value], runtime, globals);
|
|
340
|
+
}
|
|
294
341
|
const label = task === 'rankings' ? 'Domain' : 'Keyword';
|
|
295
342
|
const value = await promptTextValue(runtime, {
|
|
296
343
|
message: task === 'rankings' ? 'Which domain?' : 'Which keyword or topic?',
|
|
@@ -309,6 +356,7 @@ async function interactiveBare(runtime, globals) {
|
|
|
309
356
|
{ value: 'create', label: 'Create a Content Brief' },
|
|
310
357
|
{ value: 'decay', label: 'Content decay' },
|
|
311
358
|
{ value: 'duplicates', label: 'Duplicate clusters' },
|
|
359
|
+
{ value: 'annotations', label: 'Chart annotations', hint: 'mark what you shipped' },
|
|
312
360
|
],
|
|
313
361
|
input: runtime.input,
|
|
314
362
|
output: runtime.error,
|
|
@@ -322,6 +370,8 @@ async function interactiveBare(runtime, globals) {
|
|
|
322
370
|
return runInteractiveCommand(['audit', 'content-decay'], runtime, globals);
|
|
323
371
|
if (task === 'duplicates')
|
|
324
372
|
return runInteractiveCommand(['audit', 'duplicates'], runtime, globals);
|
|
373
|
+
if (task === 'annotations')
|
|
374
|
+
return runInteractiveCommand(['annotations', 'list'], runtime, globals);
|
|
325
375
|
const keyword = await promptTextValue(runtime, {
|
|
326
376
|
message: 'Which target keyword?',
|
|
327
377
|
placeholder: 'nuxt seo',
|
|
@@ -336,6 +386,7 @@ async function interactiveBare(runtime, globals) {
|
|
|
336
386
|
options: [
|
|
337
387
|
{ value: 'site', label: 'Switch Site', hint: config.value.siteId ?? 'none selected' },
|
|
338
388
|
{ value: 'usage', label: 'Account usage' },
|
|
389
|
+
{ value: 'whoami', label: 'Credential and scopes' },
|
|
339
390
|
{ value: 'config', label: 'Configuration' },
|
|
340
391
|
{ value: 'logout', label: 'Log out' },
|
|
341
392
|
],
|
package/dist/command-contract.js
CHANGED
|
@@ -82,7 +82,9 @@ function optionName(argument) {
|
|
|
82
82
|
export function validateCommandOptions(root, rawArgs) {
|
|
83
83
|
const resolved = resolveCommand(root, rawArgs);
|
|
84
84
|
const definitions = commandArgs(resolved.command);
|
|
85
|
+
const positionals = Object.values(definitions).filter(definition => definition.type === 'positional');
|
|
85
86
|
const aliases = new Map();
|
|
87
|
+
let positionalIndex = 0;
|
|
86
88
|
for (const definition of Object.values(definitions)) {
|
|
87
89
|
const alias = 'alias' in definition ? definition.alias : undefined;
|
|
88
90
|
const names = alias === undefined
|
|
@@ -116,7 +118,15 @@ export function validateCommandOptions(root, rawArgs) {
|
|
|
116
118
|
return fail(EXIT_CODE.invalidInput, `invalid_cli_input: Unknown option ${JSON.stringify(token)}.`);
|
|
117
119
|
if (definition.type !== 'boolean' && !resolved.remaining[index + 1]?.startsWith('-'))
|
|
118
120
|
index++;
|
|
121
|
+
continue;
|
|
122
|
+
}
|
|
123
|
+
if (positionalIndex < positionals.length) {
|
|
124
|
+
positionalIndex++;
|
|
125
|
+
continue;
|
|
119
126
|
}
|
|
127
|
+
if (Object.keys(commandChildren(resolved.command)).length > 0)
|
|
128
|
+
return fail(EXIT_CODE.invalidInput, `invalid_cli_input: Unknown command ${token}`);
|
|
129
|
+
return fail(EXIT_CODE.invalidInput, `invalid_cli_input: Unexpected argument ${JSON.stringify(token)}.`);
|
|
120
130
|
}
|
|
121
131
|
return ok(undefined);
|
|
122
132
|
}
|
package/dist/commands.d.ts
CHANGED
|
@@ -5,4 +5,23 @@ import type { CliRuntime } from './runtime.js';
|
|
|
5
5
|
export interface CommandExecution {
|
|
6
6
|
result: CliResult<void> | null;
|
|
7
7
|
}
|
|
8
|
+
/**
|
|
9
|
+
* `--all` request cap. One page per request stays the default. `--all` repeats
|
|
10
|
+
* the same operation and writes one complete envelope per page, so nothing is
|
|
11
|
+
* merged or renamed. The cap bounds an unattended loop; reaching it exits 9 and
|
|
12
|
+
* names the resume argument, so a caller never mistakes a stop for an end.
|
|
13
|
+
*/
|
|
14
|
+
export declare const ALL_PAGES_REQUEST_CAP = 50;
|
|
15
|
+
export interface PagePosition {
|
|
16
|
+
offset?: number;
|
|
17
|
+
page?: number;
|
|
18
|
+
cursor?: string;
|
|
19
|
+
}
|
|
20
|
+
export type NextPage = {
|
|
21
|
+
_tag: 'More';
|
|
22
|
+
position: PagePosition;
|
|
23
|
+
resume: string;
|
|
24
|
+
} | {
|
|
25
|
+
_tag: 'Done';
|
|
26
|
+
};
|
|
8
27
|
export declare function createRootCommand(runtime: CliRuntime, globals: GlobalOptions, execution: CommandExecution): CommandDef<any>;
|