@nuxtseo/cli 0.5.7 → 0.5.8
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/dist/commands.js +65 -1
- package/dist/render.d.ts +5 -2
- package/dist/render.js +17 -0
- package/package.json +3 -3
- package/skills/nuxtseo-cli/SKILL.md +1 -1
- package/skills/nuxtseo-cli/references/commands.md +3 -0
- package/skills/nuxtseo-cli/references/indexing.md +16 -1
- package/skills/nuxtseo-cli/references/protocol.md +3 -0
package/dist/commands.js
CHANGED
|
@@ -9,7 +9,7 @@ import { EXIT_CODE, fail, fromSdkFailure, ok } from './failures.js';
|
|
|
9
9
|
import { awaitPairingApproval, createCliPairingClient, startPairing } from './pairing.js';
|
|
10
10
|
import { parseAbsolutePageUrl, parseChoice, parseInteger, parsePageUrlOrPath, parseRatio } from './parse.js';
|
|
11
11
|
import { PULL_PERIODS, runPull } from './pull.js';
|
|
12
|
-
import { renderAccountToken, renderAction, renderActionDismissal, renderActionResolution, renderActions, renderAnalytics, renderAnnotation, renderAnnotationDeleted, renderAnnotations, renderAuditChanges, renderBacklinkAnchors, renderBacklinksHistory, renderBacklinksSummary, renderContentDecay, renderDomainAvailability, renderDomainTraffic, renderDuplicateClusters, renderFieldVitalFindings, renderFieldVitals, renderIndexCohorts, renderIndexingDiagnostics, renderIndexingHistory, renderKeywordResearch, renderLinkOpportunities, renderLinkStructure, renderMentions, renderMonitoredPages, renderPageInspection, renderPageIssues, renderPageScan, renderPerformance, renderRankingsResearch, renderRecoverableBacklinks, renderReferringDomains, renderResearchOverview, renderScanDetail, renderScans, renderSearchAnalytics, renderSearchStatus, renderSerpResearch, renderSitemapAction, renderSitemaps, renderSitemapUrls, renderSites, renderSiteStatus, renderTimeline, renderUrlInspection, renderUrlInspectionRefresh, renderUsage, } from './render.js';
|
|
12
|
+
import { renderAccountToken, renderAction, renderActionDismissal, renderActionResolution, renderActions, renderAnalytics, renderAnnotation, renderAnnotationDeleted, renderAnnotations, renderAuditChanges, renderBacklinkAnchors, renderBacklinksHistory, renderBacklinksSummary, renderContentDecay, renderDomainAvailability, renderDomainTraffic, renderDuplicateClusters, renderFieldVitalFindings, renderFieldVitals, renderIndexCohorts, renderIndexingDiagnostics, renderIndexingHistory, renderIndexingWatches, renderKeywordResearch, renderLinkOpportunities, renderLinkStructure, renderMentions, renderMonitoredPages, renderPageInspection, renderPageIssues, renderPageScan, renderPerformance, renderRankingsResearch, renderRecoverableBacklinks, renderReferringDomains, renderResearchOverview, renderScanDetail, renderScans, renderSearchAnalytics, renderSearchStatus, renderSerpResearch, renderSitemapAction, renderSitemapEvidence, renderSitemaps, renderSitemapSubmission, renderSitemapUrls, renderSites, renderSiteStatus, renderTimeline, renderUrlInspection, renderUrlInspectionRefresh, renderUsage, } from './render.js';
|
|
13
13
|
import { writeCliResponse, writeDiagnostic, writeOutput, writeProtocolResponse } from './runtime.js';
|
|
14
14
|
import { resolveSite } from './site.js';
|
|
15
15
|
import { installSkill, SKILL_AGENTS } from './skill.js';
|
|
@@ -1010,6 +1010,54 @@ async function sitemapsList(runtime, globals) {
|
|
|
1010
1010
|
}, { signal: runtime.requestSignal }));
|
|
1011
1011
|
return present(runtime, globals, response, value => renderSitemaps(value.data));
|
|
1012
1012
|
}
|
|
1013
|
+
async function sitemapsSubmission(runtime, globals) {
|
|
1014
|
+
const resolved = await apiAndSite(runtime, globals);
|
|
1015
|
+
if (resolved._tag === 'Err')
|
|
1016
|
+
return resolved;
|
|
1017
|
+
const response = await withSpinner(runtime, 'Loading Sitemap submission', () => resolved.value.api.client.sitemaps.readSubmission({
|
|
1018
|
+
params: { siteId: resolved.value.siteId },
|
|
1019
|
+
}, { signal: runtime.requestSignal }));
|
|
1020
|
+
return present(runtime, globals, response, value => renderSitemapSubmission(value.data));
|
|
1021
|
+
}
|
|
1022
|
+
async function searchWatches(runtime, globals) {
|
|
1023
|
+
const resolved = await apiAndSite(runtime, globals);
|
|
1024
|
+
if (resolved._tag === 'Err')
|
|
1025
|
+
return resolved;
|
|
1026
|
+
const response = await withSpinner(runtime, 'Loading Watched URLs', () => resolved.value.api.client.search.listWatches({
|
|
1027
|
+
params: { siteId: resolved.value.siteId },
|
|
1028
|
+
}, { signal: runtime.requestSignal }));
|
|
1029
|
+
return present(runtime, globals, response, value => renderIndexingWatches(value.data));
|
|
1030
|
+
}
|
|
1031
|
+
async function sitemapsInspect(runtime, globals, rawUrl, engine) {
|
|
1032
|
+
const url = parseAbsolutePageUrl(rawUrl);
|
|
1033
|
+
if (url._tag === 'Err')
|
|
1034
|
+
return url;
|
|
1035
|
+
const resolved = await apiAndSite(runtime, globals);
|
|
1036
|
+
if (resolved._tag === 'Err')
|
|
1037
|
+
return resolved;
|
|
1038
|
+
const response = await withSpinner(runtime, 'Reading Sitemap evidence', () => resolved.value.api.client.sitemaps.inspect({
|
|
1039
|
+
params: { siteId: resolved.value.siteId },
|
|
1040
|
+
query: { url: url.value, searchEngine: engine },
|
|
1041
|
+
}, { signal: runtime.requestSignal }));
|
|
1042
|
+
if (response._tag === 'Err')
|
|
1043
|
+
return fromSdkFailure(response.error);
|
|
1044
|
+
if (response.value.data.state._tag === 'unavailable') {
|
|
1045
|
+
const { reason } = response.value.data.state;
|
|
1046
|
+
const exitCode = reason === 'throttled' || reason === 'provider-unavailable'
|
|
1047
|
+
? EXIT_CODE.retryable
|
|
1048
|
+
: reason === 'grant-missing' || reason === 'reauthorization-required'
|
|
1049
|
+
? EXIT_CODE.authentication
|
|
1050
|
+
: reason === 'permission-lost' || reason === 'not-enabled'
|
|
1051
|
+
? EXIT_CODE.authorization
|
|
1052
|
+
: EXIT_CODE.conflict;
|
|
1053
|
+
const incomplete = fail(exitCode, `Sitemap evidence is unavailable: ${reason}.`);
|
|
1054
|
+
if (globals.json)
|
|
1055
|
+
return { _tag: 'Err', error: { ...incomplete.error, protocolResponse: response.value } };
|
|
1056
|
+
writeOutput(runtime, renderSitemapEvidence(response.value.data));
|
|
1057
|
+
return incomplete;
|
|
1058
|
+
}
|
|
1059
|
+
return present(runtime, globals, response, value => renderSitemapEvidence(value.data));
|
|
1060
|
+
}
|
|
1013
1061
|
async function sitemapsUrls(runtime, globals, args) {
|
|
1014
1062
|
const limit = parseInteger(args.limit, { name: '--limit', minimum: 1, maximum: 1000, defaultValue: 500 });
|
|
1015
1063
|
if (limit._tag === 'Err')
|
|
@@ -2042,6 +2090,10 @@ export function createRootCommand(runtime, globals, execution) {
|
|
|
2042
2090
|
const search = defineCommand({
|
|
2043
2091
|
meta: { name: 'search', description: 'Read Search Console state' },
|
|
2044
2092
|
subCommands: {
|
|
2093
|
+
'watches': defineCommand({
|
|
2094
|
+
meta: { name: 'watches', description: 'Read Watched URLs and retained Checkpoints' },
|
|
2095
|
+
run: ({ args }) => capture(execution, () => searchWatches(runtime, globals), args._, 0)(),
|
|
2096
|
+
}),
|
|
2045
2097
|
'status': defineCommand({
|
|
2046
2098
|
meta: { name: 'status', description: 'Read the stored Search Console connection' },
|
|
2047
2099
|
run: ({ args }) => capture(execution, () => searchStatus(runtime, globals), args._, 0)(),
|
|
@@ -2149,6 +2201,18 @@ export function createRootCommand(runtime, globals, execution) {
|
|
|
2149
2201
|
const sitemaps = defineCommand({
|
|
2150
2202
|
meta: { name: 'sitemaps', description: 'Read and manage Search Console sitemaps' },
|
|
2151
2203
|
subCommands: {
|
|
2204
|
+
submission: defineCommand({
|
|
2205
|
+
meta: { name: 'submission', description: 'Read site-level Google Sitemap submission readiness' },
|
|
2206
|
+
run: ({ args }) => capture(execution, () => sitemapsSubmission(runtime, globals), args._, 0)(),
|
|
2207
|
+
}),
|
|
2208
|
+
inspect: defineCommand({
|
|
2209
|
+
meta: { name: 'inspect', description: 'Read exact Sitemap listing evidence' },
|
|
2210
|
+
args: {
|
|
2211
|
+
url: positional('sitemap-url', 'Absolute Sitemap URL'),
|
|
2212
|
+
engine: { type: 'enum', options: ['google', 'bing'], default: 'google', description: 'Google live or Bing stored evidence' },
|
|
2213
|
+
},
|
|
2214
|
+
run: ({ args }) => capture(execution, () => sitemapsInspect(runtime, globals, args.url, args.engine), args._, 1)(),
|
|
2215
|
+
}),
|
|
2152
2216
|
list: defineCommand({
|
|
2153
2217
|
meta: { name: 'list', description: 'List the sitemaps Search Console knows' },
|
|
2154
2218
|
run: ({ args }) => capture(execution, () => sitemapsList(runtime, globals), args._, 0)(),
|
package/dist/render.d.ts
CHANGED
|
@@ -4,11 +4,11 @@ import type { ActionDismiss, ActionList, ActionResolve, ActionShow } from '@nuxt
|
|
|
4
4
|
import type { AnalyticsQueryData, AnalyticsView } from '@nuxtseo/protocol/v1/analytics';
|
|
5
5
|
import type { AuditChanges, AuditContentDecay, AuditDuplicateClusters, AuditLinkOpportunities, AuditLinkStructure } from '@nuxtseo/protocol/v1/audit';
|
|
6
6
|
import type { BacklinkAnchorsData, BacklinksHistory, BacklinksSummaryData, MentionsData, RecoverableBacklinksData, ReferringDomainsData } from '@nuxtseo/protocol/v1/backlinks';
|
|
7
|
-
import type { IndexCohorts, IndexingDiagnosticsData, IndexingHistoryData, SearchAnalyticsData, SearchStatusData, UrlInspectionData, UrlInspectionRefreshData } from '@nuxtseo/protocol/v1/gsc';
|
|
7
|
+
import type { IndexCohorts, IndexingDiagnosticsData, IndexingHistoryData, IndexingWatchesData, SearchAnalyticsData, SearchStatusData, UrlInspectionData, UrlInspectionRefreshData } from '@nuxtseo/protocol/v1/gsc';
|
|
8
8
|
import type { PageInspectData, PageIssues, PageScan } from '@nuxtseo/protocol/v1/pages';
|
|
9
9
|
import type { FieldVitalFindings, FieldVitals, MonitoredPages, PerformanceScanDetail, PerformanceScans, SitePerformanceOverview } from '@nuxtseo/protocol/v1/performance';
|
|
10
10
|
import type { DomainAvailability, DomainTraffic, KeywordResearchData, RankingsResearchData, SerpResearchData, StoredResearchOverview } from '@nuxtseo/protocol/v1/research';
|
|
11
|
-
import type { SiteSitemapActionResponse, SiteSitemapsResponse, SiteSitemapUrlsResponse } from '@nuxtseo/protocol/v1/sitemaps';
|
|
11
|
+
import type { SiteSitemapActionResponse, SiteSitemapEvidenceData, SiteSitemapsResponse, SiteSitemapSubmissionData, SiteSitemapUrlsResponse } from '@nuxtseo/protocol/v1/sitemaps';
|
|
12
12
|
import type { Annotation, AnnotationDeleted, Annotations, TimelineEntries } from '@nuxtseo/protocol/v1/timeline';
|
|
13
13
|
export declare function renderSites(response: SitesListResponse, selectedSiteId?: string): string;
|
|
14
14
|
export declare function renderUsage(response: AccountUsageResponse): string;
|
|
@@ -25,6 +25,9 @@ export declare function renderUrlInspectionRefresh(data: UrlInspectionRefreshDat
|
|
|
25
25
|
export declare function renderUrlInspection(data: UrlInspectionData): string;
|
|
26
26
|
export declare function renderAuditChanges(data: AuditChanges): string;
|
|
27
27
|
export declare function renderLinkStructure(data: AuditLinkStructure): string;
|
|
28
|
+
export declare function renderSitemapSubmission(data: SiteSitemapSubmissionData): string;
|
|
29
|
+
export declare function renderSitemapEvidence(data: SiteSitemapEvidenceData): string;
|
|
30
|
+
export declare function renderIndexingWatches(data: IndexingWatchesData): string;
|
|
28
31
|
export declare function renderSitemaps(data: SiteSitemapsResponse['data']): string;
|
|
29
32
|
export declare function renderSitemapUrls(data: SiteSitemapUrlsResponse['data']): string;
|
|
30
33
|
export declare function renderSitemapAction(data: SiteSitemapActionResponse['data']): string;
|
package/dist/render.js
CHANGED
|
@@ -348,6 +348,23 @@ export function renderLinkStructure(data) {
|
|
|
348
348
|
];
|
|
349
349
|
return [header, ...slots, ...deadEnds, ...anchors].join('\n');
|
|
350
350
|
}
|
|
351
|
+
export function renderSitemapSubmission(data) {
|
|
352
|
+
return `Google Sitemap submission: ${data.state._tag}\n${JSON.stringify(data.state, null, 2)}\nCan act: ${data.callerCanAct}`;
|
|
353
|
+
}
|
|
354
|
+
export function renderSitemapEvidence(data) {
|
|
355
|
+
return [
|
|
356
|
+
`${data.searchEngine} Sitemap: ${data.sitemapUrl}`,
|
|
357
|
+
`State: ${data.state._tag}`,
|
|
358
|
+
data.capture._tag === 'captured' ? `Capture: ${data.capture.source} at ${data.capture.capturedAt}` : 'Capture: unavailable',
|
|
359
|
+
JSON.stringify(data.state, null, 2),
|
|
360
|
+
].join('\n');
|
|
361
|
+
}
|
|
362
|
+
export function renderIndexingWatches(data) {
|
|
363
|
+
return [
|
|
364
|
+
`Watched URLs: ${data.watched.length}/${data.limit}. Cadence: ${data.cadenceDays} days.`,
|
|
365
|
+
...data.watched.map(watch => `${watch.url}\n Due: ${watch.dueAt}\n Checkpoints: ${JSON.stringify(watch.checkpoints)}`),
|
|
366
|
+
].join('\n');
|
|
367
|
+
}
|
|
351
368
|
export function renderSitemaps(data) {
|
|
352
369
|
if (data.sitemaps.length === 0)
|
|
353
370
|
return `No sitemaps are known for ${data.meta.siteUrl}.`;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nuxtseo/cli",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.5.
|
|
4
|
+
"version": "0.5.8",
|
|
5
5
|
"description": "Command line interface for the Nuxt SEO public API.",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"homepage": "https://nuxtseo.com/pro",
|
|
@@ -33,8 +33,8 @@
|
|
|
33
33
|
},
|
|
34
34
|
"dependencies": {
|
|
35
35
|
"@clack/prompts": "^1.8.0",
|
|
36
|
-
"@nuxtseo/protocol": "^0.5.
|
|
37
|
-
"@nuxtseo/sdk": "^0.5.
|
|
36
|
+
"@nuxtseo/protocol": "^0.5.8",
|
|
37
|
+
"@nuxtseo/sdk": "^0.5.8",
|
|
38
38
|
"citty": "^0.2.2",
|
|
39
39
|
"pathe": "^2.0.3"
|
|
40
40
|
},
|
|
@@ -17,7 +17,7 @@ Read the matching file before you act on its subject:
|
|
|
17
17
|
| --- | --- |
|
|
18
18
|
| [references/commands.md](references/commands.md) | use a flag, range, or default. Never guess a flag |
|
|
19
19
|
| [references/protocol.md](references/protocol.md) | parse output, page through a list, or handle an exit code |
|
|
20
|
-
| [references/indexing.md](references/indexing.md) |
|
|
20
|
+
| [references/indexing.md](references/indexing.md) | interpret indexing, Sitemap evidence, or Watched URLs |
|
|
21
21
|
|
|
22
22
|
## Setup
|
|
23
23
|
|
|
@@ -198,6 +198,9 @@ The monitored Page then follows its own recurring schedule.
|
|
|
198
198
|
| `search inspect <url>` | Latest retained Google URL Inspection for one URL. Takes an absolute URL or a site-relative path. `--fresh --yes` requests Google URL Inspection through the Site connection and uses inspection quota. Errors or skipped URLs produce a nonzero exit code |
|
|
199
199
|
| `search cohorts` | Not-indexed rate per route family. Returns `analysed: false` when the not-indexed list is a sample (`reason: sampled-index-state`). `--limit 1..50` (default 12), `--min-pages 1..500` (default 5). Paused Sites exit `4` or `5`. Removed Sites return `not_found` with exit `8` |
|
|
200
200
|
| `sitemaps list` | Search Console sitemap snapshot: errors, warnings, URL counts, sync status |
|
|
201
|
+
| `sitemaps submission` | Site-level Google Sitemap submission state. Redacts account identity. Does not prove listing for an arbitrary Sitemap URL |
|
|
202
|
+
| `sitemaps inspect <sitemap-url>` | Exact Sitemap listing evidence. `--engine google\|bing` defaults to `google`. Google reads live. Bing reads dated stored data. Missing exits `0`; unavailable exits `3`, `4`, `5`, or `6` |
|
|
203
|
+
| `search watches` | Retained Watched URLs, `dueAt`, and Checkpoints. An empty Checkpoint list means no retained Checkpoint for that watch |
|
|
201
204
|
| `sitemaps urls` | Sitemap URL membership. `--generation-id`, `--feedpath`, `--cursor`, `--limit 1..1000` |
|
|
202
205
|
| `sitemaps submit <sitemap-url>` | Mutation. Submits one sitemap through the Site's stored Search Console credential. Success means Search Console accepted it, not that Google downloaded it. Read `lastDownloaded` and `isPending` in `sitemaps list` |
|
|
203
206
|
| `sitemaps delete <sitemap-url>` | Mutation. Removes one sitemap through the Site's stored Search Console credential |
|
|
@@ -65,4 +65,19 @@ Keep these reads separate:
|
|
|
65
65
|
| Which URLs appeared in the current period? | `search analytics pages` | Rows with `impressions > 0`, then each `url` |
|
|
66
66
|
| What did Google say at the last inspection? | `search inspect <url>` | The retained verdict and inspection date |
|
|
67
67
|
| What does Google say about one URL now? | `search inspect <url>` | Add `--fresh --yes`. Report fresh results, quota, and explicit errors or skipped URLs |
|
|
68
|
-
| Which URLs
|
|
68
|
+
| Which URLs belong to the Sitemap generation? | `sitemaps list`, then `sitemaps urls` | Sitemap totals and retained membership |
|
|
69
|
+
| Does a provider list this exact Sitemap URL? | `sitemaps inspect <sitemap-url>` | `state`, `capture.source`, and `capture.capturedAt` |
|
|
70
|
+
| Can the Site submit its selected Google Sitemap? | `sitemaps submission` | Site-level `state` and `callerCanAct` |
|
|
71
|
+
| What checks exist for Watched URLs? | `search watches` | Each URL's `dueAt` and retained Checkpoints |
|
|
72
|
+
|
|
73
|
+
`sitemaps inspect` uses `--engine google` by default. Use `--engine bing` for Bing's stored evidence.
|
|
74
|
+
Google reads live. Bing reports its stored capture time; it does not make a live provider request.
|
|
75
|
+
`state._tag: missing` proves absence only within that successful dated read.
|
|
76
|
+
`state._tag: unavailable` provides no listing conclusion and produces a nonzero exit.
|
|
77
|
+
Grant or reauthorization failures exit `3`. Permission loss or disabled access exits `4`.
|
|
78
|
+
Unverified or unchecked evidence exits `5`. Throttling or provider failure exits `6`.
|
|
79
|
+
The JSON response preserves the evidence with these failures.
|
|
80
|
+
|
|
81
|
+
Watched URL due times describe scheduling. They do not prove that checks can run.
|
|
82
|
+
An empty Checkpoint list means no retained Checkpoint for that watch.
|
|
83
|
+
Neither Sitemap listing nor Watched URL enrollment proves that Google indexed a Page.
|
|
@@ -135,6 +135,9 @@ command returns; never guess a chain. Verified against the response schemas.
|
|
|
135
135
|
| `search index-history` | `data.changes` | none |
|
|
136
136
|
| `search cohorts` | `data.established` and `data.ranked` | `data.rankedTotal` |
|
|
137
137
|
| `sitemaps list` | `data.sitemaps` | none |
|
|
138
|
+
| `sitemaps submission` | no list; `data.state` | none |
|
|
139
|
+
| `sitemaps inspect` | no list; `data.capture`, `data.state` | none |
|
|
140
|
+
| `search watches` | `data.watched`; each item's `checkpoints` | none |
|
|
138
141
|
| `sitemaps urls` | `data.items` | `data.page.nextCursor`, `data.page.limit` |
|
|
139
142
|
| `audit content-decay` | `data.rows` | `data.page`; `data.total`, `data.truncated` |
|
|
140
143
|
| `audit link-opportunities` | `data.rows` | `data.page`; `data.total` |
|