gsc-cli 2.2.3 → 2.2.4

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c6cfd0972501711b114e27b2a286612efcfe85bd51aaf91947bc44b8fdfd9aff
4
- data.tar.gz: 5bd6e630844f13a3115bbb4c54deda04f7f3e1585c79ac4d9037dd7c216d02a1
3
+ metadata.gz: a0154a09e436255ed97202beba5751fe2b9ed58218607b4eb1505874720e3590
4
+ data.tar.gz: e80b323d84dc95de1605efa3f87760c8ad3bb2f85f033d4f4a6625e51267fa21
5
5
  SHA512:
6
- metadata.gz: ab41e83aa4f41ca0d296218f288cb2291275c893cf60347d6cbc7083371430e06feebf00aa084d5c5978fd0bd0bd5a35f29a1beaf5839f322f2efc629bf38429
7
- data.tar.gz: 50ea5330dee9bae3b09570be862e69c3b4ec5e1aafc7126525bdd2dbe1a894c2392204749b5c7f187d32c0273530cc55f6ba66599502068b8870f1a7bdcd3f6b
6
+ metadata.gz: f1f6f6b813125ae759e18bc74309fed17bb9f5acc29a2a6f78515b5127332a7dc27b7cad9c2649a821ce5bef7bcc8ba0c3376d6a19243093918732700294a4dc
7
+ data.tar.gz: 741bd3fd7fd509ad82836c070a7c5f982f81bf114a99d35935cff4b02d022a214beadd05988043036cae536cc43cf0bd289e40d2cf845387a2c3d38c350e2f79
data/bin/gsc CHANGED
@@ -3,7 +3,7 @@
3
3
 
4
4
  # ==============================================================================
5
5
  # Google Search Console & Indexing API CLI Tool (Pure Ruby - Zero Gem Dependencies)
6
- # Standalone Single-File Distribution (Built from lib/gsc v2.2.3)
6
+ # Standalone Single-File Distribution (Built from lib/gsc v2.2.4)
7
7
  # ==============================================================================
8
8
 
9
9
  require 'net/http'
@@ -20,7 +20,7 @@ require 'stringio'
20
20
 
21
21
  # --- version.rb ---
22
22
  module GSC
23
- VERSION = '2.2.3'
23
+ VERSION = '2.2.4'
24
24
  end
25
25
 
26
26
  # --- color.rb ---
@@ -3174,6 +3174,29 @@ module GSC
3174
3174
 
3175
3175
  overall_category = data.dig('loadingExperience', 'overall_category') || data.dig('originLoadingExperience', 'overall_category')
3176
3176
 
3177
+ # Official Google Core Web Vitals Assessment evaluates ONLY the 3 Core Web Vitals:
3178
+ # LCP, INP (or legacy FID), and CLS. (FCP and TTFB are diagnostic metrics).
3179
+ # - PASSED: All present CWV metrics are 'FAST' (Good).
3180
+ # - POOR: Any CWV metric is 'SLOW' (Poor).
3181
+ # - NEEDS IMPROVEMENT: No CWV metric is 'SLOW', but at least one is 'AVERAGE'.
3182
+ cwv_keys = ['LARGEST_CONTENTFUL_PAINT_MS', 'INTERACTION_TO_NEXT_PAINT', 'CUMULATIVE_LAYOUT_SHIFT_SCORE']
3183
+ cwv_keys[1] = 'FIRST_INPUT_DELAY_MS' if !crux_metrics.key?('INTERACTION_TO_NEXT_PAINT') && crux_metrics.key?('FIRST_INPUT_DELAY_MS')
3184
+
3185
+ active_cwv = cwv_keys.map { |k| crux_metrics[k] }.compact
3186
+ cwv_assessment = if active_cwv.any?
3187
+ if active_cwv.any? { |m| m[:category] == 'SLOW' }
3188
+ 'POOR'
3189
+ elsif active_cwv.any? { |m| m[:category] == 'AVERAGE' }
3190
+ 'NEEDS IMPROVEMENT'
3191
+ elsif active_cwv.all? { |m| m[:category] == 'FAST' }
3192
+ 'PASSED'
3193
+ else
3194
+ overall_category
3195
+ end
3196
+ else
3197
+ overall_category
3198
+ end
3199
+
3177
3200
  # Opportunities
3178
3201
  opportunities = []
3179
3202
  audits.each do |k, v|
@@ -3205,6 +3228,7 @@ module GSC
3205
3228
  field_data: crux_metrics,
3206
3229
  field_source: crux_source,
3207
3230
  overall_category: overall_category,
3231
+ cwv_assessment: cwv_assessment,
3208
3232
  opportunities: opportunities.first(5)
3209
3233
  }
3210
3234
  end
@@ -22857,10 +22881,19 @@ module GSC
22857
22881
  fd = data[:field_data] || {}
22858
22882
  if fd.any?
22859
22883
  source_label = data[:field_source] == :origin ? "Domain-Wide Origin RUM" : "URL-Level RUM"
22860
- overall = data[:overall_category] || "UNKNOWN"
22861
- overall_col = overall == 'FAST' ? Color::GREEN : (overall == 'AVERAGE' ? Color::YELLOW : Color::RED)
22884
+ assessment = data[:cwv_assessment] || data[:overall_category] || "UNKNOWN"
22885
+ assessment_badge = case assessment
22886
+ when 'PASSED', 'FAST'
22887
+ Color.c("PASSED (All 3 Metrics Good)", Color::GREEN, Color::BOLD)
22888
+ when 'NEEDS IMPROVEMENT', 'AVERAGE'
22889
+ Color.c("NEEDS IMPROVEMENT", Color::YELLOW, Color::BOLD)
22890
+ when 'POOR', 'SLOW', 'FAILED'
22891
+ Color.c("FAILED (Poor Metrics Detected)", Color::RED, Color::BOLD)
22892
+ else
22893
+ Color.c(assessment, Color::YELLOW, Color::BOLD)
22894
+ end
22862
22895
  puts "\n#{Color::BOLD}🌐 CrUX FIELD DATA (28-Day Real User Monitoring - #{source_label}):#{Color::RESET}"
22863
- puts " • Core Web Vitals Status : #{Color.c(overall, overall_col, Color::BOLD)}"
22896
+ puts " • Core Web Vitals Assessment : #{assessment_badge}"
22864
22897
 
22865
22898
  if fd['LARGEST_CONTENTFUL_PAINT_MS']
22866
22899
  val = "#{(fd['LARGEST_CONTENTFUL_PAINT_MS'][:percentile].to_f / 1000).round(2)} s"
@@ -30016,10 +30049,19 @@ module GSC
30016
30049
  fd = data[:field_data] || {}
30017
30050
  if fd.any?
30018
30051
  source_label = data[:field_source] == :origin ? "Domain-Wide Origin RUM" : "URL-Level RUM"
30019
- overall = data[:overall_category] || "UNKNOWN"
30020
- overall_col = overall == 'FAST' ? Color::GREEN : (overall == 'AVERAGE' ? Color::YELLOW : Color::RED)
30052
+ assessment = data[:cwv_assessment] || data[:overall_category] || "UNKNOWN"
30053
+ assessment_badge = case assessment
30054
+ when 'PASSED', 'FAST'
30055
+ Color.c("PASSED (All 3 Metrics Good)", Color::GREEN, Color::BOLD)
30056
+ when 'NEEDS IMPROVEMENT', 'AVERAGE'
30057
+ Color.c("NEEDS IMPROVEMENT", Color::YELLOW, Color::BOLD)
30058
+ when 'POOR', 'SLOW', 'FAILED'
30059
+ Color.c("FAILED (Poor Metrics Detected)", Color::RED, Color::BOLD)
30060
+ else
30061
+ Color.c(assessment, Color::YELLOW, Color::BOLD)
30062
+ end
30021
30063
  puts "\n#{Color::BOLD}🌐 CrUX FIELD DATA (28-Day Real User Monitoring - #{source_label}):#{Color::RESET}"
30022
- puts " • Core Web Vitals Status : #{Color.c(overall, overall_col, Color::BOLD)}"
30064
+ puts " • Core Web Vitals Assessment : #{assessment_badge}"
30023
30065
 
30024
30066
  if fd['LARGEST_CONTENTFUL_PAINT_MS']
30025
30067
  val = "#{(fd['LARGEST_CONTENTFUL_PAINT_MS'][:percentile].to_f / 1000).round(2)} s"
data/dist/gsc CHANGED
@@ -3,7 +3,7 @@
3
3
 
4
4
  # ==============================================================================
5
5
  # Google Search Console & Indexing API CLI Tool (Pure Ruby - Zero Gem Dependencies)
6
- # Standalone Single-File Distribution (Built from lib/gsc v2.2.3)
6
+ # Standalone Single-File Distribution (Built from lib/gsc v2.2.4)
7
7
  # ==============================================================================
8
8
 
9
9
  require 'net/http'
@@ -20,7 +20,7 @@ require 'stringio'
20
20
 
21
21
  # --- version.rb ---
22
22
  module GSC
23
- VERSION = '2.2.3'
23
+ VERSION = '2.2.4'
24
24
  end
25
25
 
26
26
  # --- color.rb ---
@@ -3174,6 +3174,29 @@ module GSC
3174
3174
 
3175
3175
  overall_category = data.dig('loadingExperience', 'overall_category') || data.dig('originLoadingExperience', 'overall_category')
3176
3176
 
3177
+ # Official Google Core Web Vitals Assessment evaluates ONLY the 3 Core Web Vitals:
3178
+ # LCP, INP (or legacy FID), and CLS. (FCP and TTFB are diagnostic metrics).
3179
+ # - PASSED: All present CWV metrics are 'FAST' (Good).
3180
+ # - POOR: Any CWV metric is 'SLOW' (Poor).
3181
+ # - NEEDS IMPROVEMENT: No CWV metric is 'SLOW', but at least one is 'AVERAGE'.
3182
+ cwv_keys = ['LARGEST_CONTENTFUL_PAINT_MS', 'INTERACTION_TO_NEXT_PAINT', 'CUMULATIVE_LAYOUT_SHIFT_SCORE']
3183
+ cwv_keys[1] = 'FIRST_INPUT_DELAY_MS' if !crux_metrics.key?('INTERACTION_TO_NEXT_PAINT') && crux_metrics.key?('FIRST_INPUT_DELAY_MS')
3184
+
3185
+ active_cwv = cwv_keys.map { |k| crux_metrics[k] }.compact
3186
+ cwv_assessment = if active_cwv.any?
3187
+ if active_cwv.any? { |m| m[:category] == 'SLOW' }
3188
+ 'POOR'
3189
+ elsif active_cwv.any? { |m| m[:category] == 'AVERAGE' }
3190
+ 'NEEDS IMPROVEMENT'
3191
+ elsif active_cwv.all? { |m| m[:category] == 'FAST' }
3192
+ 'PASSED'
3193
+ else
3194
+ overall_category
3195
+ end
3196
+ else
3197
+ overall_category
3198
+ end
3199
+
3177
3200
  # Opportunities
3178
3201
  opportunities = []
3179
3202
  audits.each do |k, v|
@@ -3205,6 +3228,7 @@ module GSC
3205
3228
  field_data: crux_metrics,
3206
3229
  field_source: crux_source,
3207
3230
  overall_category: overall_category,
3231
+ cwv_assessment: cwv_assessment,
3208
3232
  opportunities: opportunities.first(5)
3209
3233
  }
3210
3234
  end
@@ -22857,10 +22881,19 @@ module GSC
22857
22881
  fd = data[:field_data] || {}
22858
22882
  if fd.any?
22859
22883
  source_label = data[:field_source] == :origin ? "Domain-Wide Origin RUM" : "URL-Level RUM"
22860
- overall = data[:overall_category] || "UNKNOWN"
22861
- overall_col = overall == 'FAST' ? Color::GREEN : (overall == 'AVERAGE' ? Color::YELLOW : Color::RED)
22884
+ assessment = data[:cwv_assessment] || data[:overall_category] || "UNKNOWN"
22885
+ assessment_badge = case assessment
22886
+ when 'PASSED', 'FAST'
22887
+ Color.c("PASSED (All 3 Metrics Good)", Color::GREEN, Color::BOLD)
22888
+ when 'NEEDS IMPROVEMENT', 'AVERAGE'
22889
+ Color.c("NEEDS IMPROVEMENT", Color::YELLOW, Color::BOLD)
22890
+ when 'POOR', 'SLOW', 'FAILED'
22891
+ Color.c("FAILED (Poor Metrics Detected)", Color::RED, Color::BOLD)
22892
+ else
22893
+ Color.c(assessment, Color::YELLOW, Color::BOLD)
22894
+ end
22862
22895
  puts "\n#{Color::BOLD}🌐 CrUX FIELD DATA (28-Day Real User Monitoring - #{source_label}):#{Color::RESET}"
22863
- puts " • Core Web Vitals Status : #{Color.c(overall, overall_col, Color::BOLD)}"
22896
+ puts " • Core Web Vitals Assessment : #{assessment_badge}"
22864
22897
 
22865
22898
  if fd['LARGEST_CONTENTFUL_PAINT_MS']
22866
22899
  val = "#{(fd['LARGEST_CONTENTFUL_PAINT_MS'][:percentile].to_f / 1000).round(2)} s"
@@ -30016,10 +30049,19 @@ module GSC
30016
30049
  fd = data[:field_data] || {}
30017
30050
  if fd.any?
30018
30051
  source_label = data[:field_source] == :origin ? "Domain-Wide Origin RUM" : "URL-Level RUM"
30019
- overall = data[:overall_category] || "UNKNOWN"
30020
- overall_col = overall == 'FAST' ? Color::GREEN : (overall == 'AVERAGE' ? Color::YELLOW : Color::RED)
30052
+ assessment = data[:cwv_assessment] || data[:overall_category] || "UNKNOWN"
30053
+ assessment_badge = case assessment
30054
+ when 'PASSED', 'FAST'
30055
+ Color.c("PASSED (All 3 Metrics Good)", Color::GREEN, Color::BOLD)
30056
+ when 'NEEDS IMPROVEMENT', 'AVERAGE'
30057
+ Color.c("NEEDS IMPROVEMENT", Color::YELLOW, Color::BOLD)
30058
+ when 'POOR', 'SLOW', 'FAILED'
30059
+ Color.c("FAILED (Poor Metrics Detected)", Color::RED, Color::BOLD)
30060
+ else
30061
+ Color.c(assessment, Color::YELLOW, Color::BOLD)
30062
+ end
30021
30063
  puts "\n#{Color::BOLD}🌐 CrUX FIELD DATA (28-Day Real User Monitoring - #{source_label}):#{Color::RESET}"
30022
- puts " • Core Web Vitals Status : #{Color.c(overall, overall_col, Color::BOLD)}"
30064
+ puts " • Core Web Vitals Assessment : #{assessment_badge}"
30023
30065
 
30024
30066
  if fd['LARGEST_CONTENTFUL_PAINT_MS']
30025
30067
  val = "#{(fd['LARGEST_CONTENTFUL_PAINT_MS'][:percentile].to_f / 1000).round(2)} s"
data/lib/gsc/cli/audit.rb CHANGED
@@ -170,10 +170,19 @@ module GSC
170
170
  fd = data[:field_data] || {}
171
171
  if fd.any?
172
172
  source_label = data[:field_source] == :origin ? "Domain-Wide Origin RUM" : "URL-Level RUM"
173
- overall = data[:overall_category] || "UNKNOWN"
174
- overall_col = overall == 'FAST' ? Color::GREEN : (overall == 'AVERAGE' ? Color::YELLOW : Color::RED)
173
+ assessment = data[:cwv_assessment] || data[:overall_category] || "UNKNOWN"
174
+ assessment_badge = case assessment
175
+ when 'PASSED', 'FAST'
176
+ Color.c("PASSED (All 3 Metrics Good)", Color::GREEN, Color::BOLD)
177
+ when 'NEEDS IMPROVEMENT', 'AVERAGE'
178
+ Color.c("NEEDS IMPROVEMENT", Color::YELLOW, Color::BOLD)
179
+ when 'POOR', 'SLOW', 'FAILED'
180
+ Color.c("FAILED (Poor Metrics Detected)", Color::RED, Color::BOLD)
181
+ else
182
+ Color.c(assessment, Color::YELLOW, Color::BOLD)
183
+ end
175
184
  puts "\n#{Color::BOLD}🌐 CrUX FIELD DATA (28-Day Real User Monitoring - #{source_label}):#{Color::RESET}"
176
- puts " • Core Web Vitals Status : #{Color.c(overall, overall_col, Color::BOLD)}"
185
+ puts " • Core Web Vitals Assessment : #{assessment_badge}"
177
186
 
178
187
  if fd['LARGEST_CONTENTFUL_PAINT_MS']
179
188
  val = "#{(fd['LARGEST_CONTENTFUL_PAINT_MS'][:percentile].to_f / 1000).round(2)} s"
@@ -180,10 +180,19 @@ module GSC
180
180
  fd = data[:field_data] || {}
181
181
  if fd.any?
182
182
  source_label = data[:field_source] == :origin ? "Domain-Wide Origin RUM" : "URL-Level RUM"
183
- overall = data[:overall_category] || "UNKNOWN"
184
- overall_col = overall == 'FAST' ? Color::GREEN : (overall == 'AVERAGE' ? Color::YELLOW : Color::RED)
183
+ assessment = data[:cwv_assessment] || data[:overall_category] || "UNKNOWN"
184
+ assessment_badge = case assessment
185
+ when 'PASSED', 'FAST'
186
+ Color.c("PASSED (All 3 Metrics Good)", Color::GREEN, Color::BOLD)
187
+ when 'NEEDS IMPROVEMENT', 'AVERAGE'
188
+ Color.c("NEEDS IMPROVEMENT", Color::YELLOW, Color::BOLD)
189
+ when 'POOR', 'SLOW', 'FAILED'
190
+ Color.c("FAILED (Poor Metrics Detected)", Color::RED, Color::BOLD)
191
+ else
192
+ Color.c(assessment, Color::YELLOW, Color::BOLD)
193
+ end
185
194
  puts "\n#{Color::BOLD}🌐 CrUX FIELD DATA (28-Day Real User Monitoring - #{source_label}):#{Color::RESET}"
186
- puts " • Core Web Vitals Status : #{Color.c(overall, overall_col, Color::BOLD)}"
195
+ puts " • Core Web Vitals Assessment : #{assessment_badge}"
187
196
 
188
197
  if fd['LARGEST_CONTENTFUL_PAINT_MS']
189
198
  val = "#{(fd['LARGEST_CONTENTFUL_PAINT_MS'][:percentile].to_f / 1000).round(2)} s"
@@ -86,6 +86,29 @@ module GSC
86
86
 
87
87
  overall_category = data.dig('loadingExperience', 'overall_category') || data.dig('originLoadingExperience', 'overall_category')
88
88
 
89
+ # Official Google Core Web Vitals Assessment evaluates ONLY the 3 Core Web Vitals:
90
+ # LCP, INP (or legacy FID), and CLS. (FCP and TTFB are diagnostic metrics).
91
+ # - PASSED: All present CWV metrics are 'FAST' (Good).
92
+ # - POOR: Any CWV metric is 'SLOW' (Poor).
93
+ # - NEEDS IMPROVEMENT: No CWV metric is 'SLOW', but at least one is 'AVERAGE'.
94
+ cwv_keys = ['LARGEST_CONTENTFUL_PAINT_MS', 'INTERACTION_TO_NEXT_PAINT', 'CUMULATIVE_LAYOUT_SHIFT_SCORE']
95
+ cwv_keys[1] = 'FIRST_INPUT_DELAY_MS' if !crux_metrics.key?('INTERACTION_TO_NEXT_PAINT') && crux_metrics.key?('FIRST_INPUT_DELAY_MS')
96
+
97
+ active_cwv = cwv_keys.map { |k| crux_metrics[k] }.compact
98
+ cwv_assessment = if active_cwv.any?
99
+ if active_cwv.any? { |m| m[:category] == 'SLOW' }
100
+ 'POOR'
101
+ elsif active_cwv.any? { |m| m[:category] == 'AVERAGE' }
102
+ 'NEEDS IMPROVEMENT'
103
+ elsif active_cwv.all? { |m| m[:category] == 'FAST' }
104
+ 'PASSED'
105
+ else
106
+ overall_category
107
+ end
108
+ else
109
+ overall_category
110
+ end
111
+
89
112
  # Opportunities
90
113
  opportunities = []
91
114
  audits.each do |k, v|
@@ -117,6 +140,7 @@ module GSC
117
140
  field_data: crux_metrics,
118
141
  field_source: crux_source,
119
142
  overall_category: overall_category,
143
+ cwv_assessment: cwv_assessment,
120
144
  opportunities: opportunities.first(5)
121
145
  }
122
146
  end
data/lib/gsc/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module GSC
4
- VERSION = '2.2.3'
4
+ VERSION = '2.2.4'
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gsc-cli
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.2.3
4
+ version: 2.2.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - ApollosWave LLC