@nuxtseo/cli 0.5.1 → 0.5.3

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/pull.js CHANGED
@@ -304,6 +304,7 @@ export async function runPull(runtime, globals, args, resolve, catalogue = PULL_
304
304
  const skipped = [];
305
305
  let stopped = false;
306
306
  let completed = 0;
307
+ let explainedAnalyticsConnection = false;
307
308
  await forEachBounded(operations, concurrency.value, async (candidate) => {
308
309
  if (stopped) {
309
310
  skipped.push(candidate.name);
@@ -318,6 +319,15 @@ export async function runPull(runtime, globals, args, resolve, catalogue = PULL_
318
319
  });
319
320
  const outcome = pullLine(candidate.name, result);
320
321
  writeProtocolResponse(runtime, outcome.line);
322
+ if (!explainedAnalyticsConnection
323
+ && candidate.name.startsWith('analytics ')
324
+ && result._tag === 'Err'
325
+ && result.error._tag === 'ApiFailure'
326
+ && result.error.code === 'conflict'
327
+ && result.error.details?.action === 'connect_web_analytics') {
328
+ explainedAnalyticsConnection = true;
329
+ writeDiagnostic(runtime, 'Web Analytics is not connected. Connect a property to read these views. For a full SEO pull, use --exclude analytics.');
330
+ }
321
331
  exitCodes.push(outcome.exitCode);
322
332
  completed++;
323
333
  // An expired or rejected credential fails every later read the same way.
package/dist/render.js CHANGED
@@ -893,10 +893,26 @@ export function renderScanDetail(data) {
893
893
  ];
894
894
  if (data.lcpElement)
895
895
  blocks.push(`LCP element ${data.lcpElement.selector ?? data.lcpElement.nodeLabel ?? 'unknown'}`);
896
- if (data.performanceIssues.length) {
896
+ if (data.observedTrace?._tag === 'available') {
897
+ const trace = data.observedTrace;
897
898
  blocks.push([
898
- `Wasteful assets (${data.performanceIssues.length})`,
899
- ...data.performanceIssues.map(issue => ` ${issue.wastedMs ?? 0}ms ${issue.wastedBytes ?? 0}b ${issue.subtype ?? issue.type} ${issue.url ?? ''}`.trimEnd()),
899
+ `Observed trace LCP ${trace.observedLcpMs}ms throttling ${trace.throttlingMethod}`,
900
+ ...trace.phases.map(phase => ` ${phase.id} ${phase.durationMs}ms`),
901
+ 'Trace phases describe observed LCP. Reported LCP can be simulated.',
902
+ ].join('\n'));
903
+ }
904
+ else {
905
+ blocks.push(`Observed trace unavailable ${data.observedTrace?.reason ?? 'legacy-response'}`);
906
+ }
907
+ if (data.javascript) {
908
+ const bytes = (amount) => amount === null ? 'unknown' : `${amount}b`;
909
+ blocks.push(`JavaScript ${bytes(data.javascript.transferBytes)} transferred ${bytes(data.javascript.decodedBytes)} decoded ${data.javascript.scriptCount ?? 'unknown'} resources`);
910
+ }
911
+ const waste = data.performanceIssues.filter(issue => issue.subtype !== 'js-transfer-weight');
912
+ if (waste.length) {
913
+ blocks.push([
914
+ `Wasteful assets (${waste.length})`,
915
+ ...waste.map(issue => ` ${issue.wastedMs ?? 0}ms ${issue.wastedBytes ?? 0}b ${issue.subtype ?? issue.type} ${issue.url ?? ''}`.trimEnd()),
900
916
  ].join('\n'));
901
917
  }
902
918
  if (data.thirdParties.length) {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@nuxtseo/cli",
3
3
  "type": "module",
4
- "version": "0.5.1",
4
+ "version": "0.5.3",
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.1",
37
- "@nuxtseo/sdk": "^0.5.1",
36
+ "@nuxtseo/protocol": "^0.5.3",
37
+ "@nuxtseo/sdk": "^0.5.3",
38
38
  "citty": "^0.2.2",
39
39
  "pathe": "^2.0.3"
40
40
  },
@@ -138,9 +138,35 @@ lines.
138
138
  | `scans show <scan-id>` | One Scan, and the evidence behind its scores: wasteful assets, repeat-visit cache policy, third-party scripts, the LCP element, and every failing accessibility and best-practices check with its CSS selectors and DOM snippets. Read `coverage` before quoting a total |
139
139
  | `scans pages` | The Pages this Site scans on a schedule. Add one with `page scan <url>` |
140
140
 
141
+ `scans show` can include `observedTrace` from the retained Lighthouse projection.
142
+ If its tag is `available`, its phases describe `observedLcpMs` from the browser trace.
143
+ `throttlingMethod` names how Lighthouse computed the reported metrics.
144
+ With `simulate`, reported `lcp` is modeled. Observed trace phases do not partition that modeled value.
145
+ With `devtools` or `provided`, Lighthouse uses observed metrics.
146
+ Neither value is real-user field data.
147
+ An `unavailable` tag names missing, invalid, or legacy evidence.
148
+ Older servers can omit the field. Omission also means unavailable.
149
+ This command never reads raw reports or starts a projection backfill.
150
+
141
151
  `page inspect` and `page scan` take an absolute URL, for example
142
152
  `https://example.com/about`.
143
153
 
154
+ ### JavaScript byte measurements
155
+
156
+ `scans show` returns `data.javascript` with stored `transferBytes`, `decodedBytes`, and `scriptCount`.
157
+ Each measurement is nullable. `javascript: null` means no stored JavaScript measurement.
158
+ An older server may omit the field.
159
+
160
+ The extractor counts JavaScript by resource type, MIME type, or `.js` / `.mjs` URL.
161
+ It includes downloaded JavaScript labelled `Other`, which can include prefetch requests.
162
+ The stored totals do not separate prefetch from executed JavaScript.
163
+ They do not measure parse, compile, or execution work.
164
+
165
+ For a `js-transfer-weight` diagnostic, `wastedBytes` holds total decoded JavaScript bytes.
166
+ It is not removable code or Lighthouse unused-byte savings.
167
+ Use `data.javascript` for byte comparisons, and `unused` findings for unused-byte evidence.
168
+ Do not infer a reduction in executed JavaScript from download totals alone.
169
+
144
170
  `page scan` enables recurring monitoring.
145
171
  Read `scans pages` before scanning many new URLs. The server refuses a new
146
172
  Page when five monitored Pages are already enabled. That limit comes from