recker 1.0.78 → 1.0.79

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.
@@ -34,6 +34,7 @@ export declare class SeoAnalyzer {
34
34
  private analyzeFeeds;
35
35
  private analyzeConversionElements;
36
36
  private calculateTextHtmlRatio;
37
+ private classifyInfoCheck;
37
38
  private convertToCheckResults;
38
39
  private buildSummary;
39
40
  private calculateMetaCompleteness;
@@ -71,7 +71,7 @@ export class SeoAnalyzer {
71
71
  const ruleResults = this.rulesEngine.evaluate(context);
72
72
  const checks = this.convertToCheckResults(ruleResults);
73
73
  const { score, grade } = this.calculateScore(ruleResults);
74
- const summary = this.buildSummary(ruleResults, checks, {
74
+ const summary = this.buildSummary(checks, {
75
75
  content,
76
76
  imageAnalysis,
77
77
  linkAnalysis,
@@ -951,6 +951,27 @@ export class SeoAnalyzer {
951
951
  }
952
952
  return undefined;
953
953
  }
954
+ classifyInfoCheck(result) {
955
+ if (result.status !== 'info')
956
+ return undefined;
957
+ const message = (result.message || '').toLowerCase();
958
+ const evidenceIssue = (result.evidence?.issue || '').toLowerCase();
959
+ const recommendation = (result.recommendation || '').toLowerCase();
960
+ const context = `${message} ${evidenceIssue} ${recommendation}`;
961
+ if (/not\s+applicable/.test(context) ||
962
+ /not\s+available/.test(context) ||
963
+ /data\s+unavailable/.test(context) ||
964
+ /context\s+unavailable/.test(context) ||
965
+ /unable\s+to\s+check/.test(context) ||
966
+ /cannot\s+verify/.test(context) ||
967
+ /cannot\s+be\s+determined/.test(context) ||
968
+ /\bunavailable\b/.test(context) ||
969
+ /not\s+set/.test(context) ||
970
+ /not\s+present/.test(context)) {
971
+ return 'not_applicable';
972
+ }
973
+ return 'suggestion';
974
+ }
954
975
  convertToCheckResults(results) {
955
976
  return results.map((r) => ({
956
977
  id: r.id,
@@ -959,26 +980,36 @@ export class SeoAnalyzer {
959
980
  severity: r.severity,
960
981
  status: r.status,
961
982
  message: r.message,
983
+ infoType: this.classifyInfoCheck(r),
962
984
  value: r.value,
963
985
  recommendation: r.recommendation,
964
986
  evidence: r.evidence,
965
987
  }));
966
988
  }
967
- buildSummary(ruleResults, checks, data) {
989
+ buildSummary(checks, data) {
968
990
  const pageType = data.pageType;
969
991
  const timings = data.timings;
970
992
  const passed = checks.filter((c) => c.status === 'pass').length;
971
993
  const warnings = checks.filter((c) => c.status === 'warn').length;
972
994
  const errors = checks.filter((c) => c.status === 'fail').length;
973
995
  const infos = checks.filter((c) => c.status === 'info').length;
996
+ const notApplicable = checks.filter((c) => c.status === 'info' && c.infoType === 'not_applicable').length;
997
+ const suggestions = checks.filter((c) => c.status === 'info' && c.infoType !== 'not_applicable').length;
974
998
  const totalChecks = checks.length;
975
999
  const scoringChecks = totalChecks - infos;
976
1000
  const passRate = scoringChecks > 0 ? Math.round((passed / scoringChecks) * 100) : 100;
977
1001
  const issuesByCategory = {};
978
- for (const result of ruleResults) {
1002
+ for (const result of checks) {
979
1003
  const cat = result.category;
980
1004
  if (!issuesByCategory[cat]) {
981
- issuesByCategory[cat] = { passed: 0, warnings: 0, errors: 0 };
1005
+ issuesByCategory[cat] = {
1006
+ passed: 0,
1007
+ warnings: 0,
1008
+ errors: 0,
1009
+ infos: 0,
1010
+ notApplicable: 0,
1011
+ suggestions: 0,
1012
+ };
982
1013
  }
983
1014
  if (result.status === 'pass')
984
1015
  issuesByCategory[cat].passed++;
@@ -986,6 +1017,15 @@ export class SeoAnalyzer {
986
1017
  issuesByCategory[cat].warnings++;
987
1018
  else if (result.status === 'fail')
988
1019
  issuesByCategory[cat].errors++;
1020
+ else if (result.status === 'info') {
1021
+ issuesByCategory[cat].infos++;
1022
+ if (result.infoType === 'not_applicable') {
1023
+ issuesByCategory[cat].notApplicable++;
1024
+ }
1025
+ else {
1026
+ issuesByCategory[cat].suggestions++;
1027
+ }
1028
+ }
989
1029
  }
990
1030
  const topIssues = checks
991
1031
  .filter((c) => c.status === 'fail' || c.status === 'warn')
@@ -1052,6 +1092,8 @@ export class SeoAnalyzer {
1052
1092
  warnings,
1053
1093
  errors,
1054
1094
  infos,
1095
+ notApplicable,
1096
+ suggestions,
1055
1097
  passRate,
1056
1098
  issuesByCategory,
1057
1099
  pageType: pageType,
@@ -29,7 +29,16 @@ export function statusIcon(status) {
29
29
  export function formatCheck(check, showEvidence = false) {
30
30
  const lines = [];
31
31
  const icon = statusIcon(check.status);
32
- lines.push(` ${icon} ${check.message}`);
32
+ let infoLabel = '';
33
+ if (check.status === 'info') {
34
+ if (check.infoType === 'not_applicable') {
35
+ infoLabel = colors.magenta(' [N/A]');
36
+ }
37
+ else if (check.infoType === 'suggestion') {
38
+ infoLabel = colors.cyan(' [SUGGESTION]');
39
+ }
40
+ }
41
+ lines.push(` ${icon} ${check.message}${infoLabel}`);
33
42
  if (check.value !== undefined) {
34
43
  lines.push(` ${colors.gray('Value:')} ${check.value}`);
35
44
  }
@@ -239,7 +248,10 @@ export function formatSeoReport(report, url, options = {}) {
239
248
  lines.push(colors.gray(' ──────────────────────────────────────────────────'));
240
249
  lines.push('');
241
250
  lines.push(` ${colors.bold('Summary')}`);
242
- lines.push(` ${colors.green('✔ Passed:')} ${s.passed} ${colors.yellow('⚠ Warnings:')} ${s.warnings} ${colors.red('✖ Errors:')} ${s.errors} ${colors.blue('ℹ Info:')} ${s.infos}`);
251
+ const infoSummary = (s.notApplicable !== undefined || s.suggestions !== undefined)
252
+ ? ` (${s.notApplicable ?? 0} not applicable, ${s.suggestions ?? 0} suggestions)`
253
+ : '';
254
+ lines.push(` ${colors.green('✔ Passed:')} ${s.passed} ${colors.yellow('⚠ Warnings:')} ${s.warnings} ${colors.red('✖ Errors:')} ${s.errors} ${colors.blue('ℹ Info:')} ${s.infos}${infoSummary}`);
243
255
  if (s.vitals) {
244
256
  lines.push(` ${colors.gray('Words:')} ${s.vitals.wordCount} | ${colors.gray('Images:')} ${s.vitals.imageCount} | ${colors.gray('Links:')} ${s.vitals.linkCount}`);
245
257
  }
@@ -381,12 +393,16 @@ function groupChecksByCategory(checks) {
381
393
  const warnings = catChecks.filter(c => c.status === 'warn').length;
382
394
  const errors = catChecks.filter(c => c.status === 'fail').length;
383
395
  const infos = catChecks.filter(c => c.status === 'info').length;
396
+ const notApplicable = catChecks.filter(c => c.status === 'info' && c.infoType === 'not_applicable').length;
397
+ const suggestions = catChecks.filter(c => c.status === 'info' && c.infoType !== 'not_applicable').length;
384
398
  const total = catChecks.length - infos;
385
399
  result[cat] = {
386
400
  passed,
387
401
  warnings,
388
402
  errors,
389
403
  infos,
404
+ notApplicable,
405
+ suggestions,
390
406
  passRate: total > 0 ? Math.round((passed / total) * 100) : 100,
391
407
  checks: catChecks,
392
408
  };
@@ -410,6 +426,8 @@ export function formatSeoReportJson(report, url, options) {
410
426
  warnings: report.checks.filter(c => c.status === 'warn').length,
411
427
  errors: report.checks.filter(c => c.status === 'fail').length,
412
428
  infos: report.checks.filter(c => c.status === 'info').length,
429
+ notApplicable: report.checks.filter(c => c.status === 'info' && c.infoType === 'not_applicable').length,
430
+ suggestions: report.checks.filter(c => c.status === 'info' && c.infoType !== 'not_applicable').length,
413
431
  passRate: report.summary.passRate,
414
432
  completeness: report.summary.completeness,
415
433
  topIssues: report.summary.topIssues,
@@ -1,6 +1,7 @@
1
1
  import { KeywordCloud } from './keywords.js';
2
2
  export type { KeywordCloud, KeywordItem } from './keywords.js';
3
3
  export type SeoStatus = 'pass' | 'warn' | 'fail' | 'info';
4
+ export type SeoInfoType = 'not_applicable' | 'suggestion';
4
5
  export type SeoPageType = 'homepage' | 'product' | 'article' | 'category' | 'search' | 'other';
5
6
  export interface SeoCheckEvidence {
6
7
  found?: string | number | string[];
@@ -18,6 +19,7 @@ export interface SeoCheckResult {
18
19
  status: SeoStatus;
19
20
  severity?: 'error' | 'warning' | 'info';
20
21
  message: string;
22
+ infoType?: SeoInfoType;
21
23
  value?: string | number;
22
24
  recommendation?: string;
23
25
  evidence?: SeoCheckEvidence;
@@ -115,11 +117,16 @@ export interface SeoSummary {
115
117
  warnings: number;
116
118
  errors: number;
117
119
  infos: number;
120
+ notApplicable: number;
121
+ suggestions: number;
118
122
  passRate: number;
119
123
  issuesByCategory: Record<string, {
120
124
  passed: number;
121
125
  warnings: number;
122
126
  errors: number;
127
+ infos: number;
128
+ notApplicable: number;
129
+ suggestions: number;
123
130
  }>;
124
131
  topIssues: Array<{
125
132
  name: string;
@@ -26,6 +26,8 @@ export interface SEORunnerResult {
26
26
  errors: number;
27
27
  warnings: number;
28
28
  infos: number;
29
+ notApplicable?: number;
30
+ suggestions?: number;
29
31
  passed: number;
30
32
  totalChecks: number;
31
33
  };
@@ -74,6 +74,8 @@ export class SEORunner extends CommandEmitter {
74
74
  errors: report.summary.errors,
75
75
  warnings: report.summary.warnings,
76
76
  infos: report.summary.infos,
77
+ notApplicable: report.summary.notApplicable,
78
+ suggestions: report.summary.suggestions,
77
79
  passed: report.summary.passed,
78
80
  totalChecks: report.summary.totalChecks,
79
81
  },
@@ -145,6 +147,8 @@ export class SEORunner extends CommandEmitter {
145
147
  errors: report.summary.errors,
146
148
  warnings: report.summary.warnings,
147
149
  passed: report.summary.passed,
150
+ notApplicable: report.summary.notApplicable,
151
+ suggestions: report.summary.suggestions,
148
152
  });
149
153
  return result;
150
154
  }
@@ -105,6 +105,8 @@ export const seoAnalyzeHandler = withHandler({ loading: true }, async (ctx, out,
105
105
  warnings: report.summary.warnings,
106
106
  errors: report.summary.errors,
107
107
  infos: report.summary.infos,
108
+ notApplicable: report.summary.notApplicable,
109
+ suggestions: report.summary.suggestions,
108
110
  vitals: report.summary.vitals,
109
111
  topIssues: report.summary.topIssues,
110
112
  quickWins: report.summary.quickWins,
@@ -131,6 +133,10 @@ export const seoAnalyzeHandler = withHandler({ loading: true }, async (ctx, out,
131
133
  { text: `Passed: ${report.summary.passed}`, checked: true },
132
134
  { text: `Warnings: ${report.summary.warnings}`, checked: report.summary.warnings === 0 },
133
135
  { text: `Errors: ${report.summary.errors}`, checked: report.summary.errors === 0 },
136
+ {
137
+ text: `Info: ${report.summary.infos} (N/A: ${report.summary.notApplicable || 0}, Sugestões: ${report.summary.suggestions || 0})`,
138
+ checked: report.summary.infos === 0,
139
+ },
134
140
  ]);
135
141
  out.blank();
136
142
  if (report.summary.topIssues?.length > 0) {
@@ -141,6 +141,8 @@ interface SeoResponseData {
141
141
  warnings?: number;
142
142
  errors?: number;
143
143
  infos?: number;
144
+ notApplicable?: number;
145
+ suggestions?: number;
144
146
  vitals?: {
145
147
  wordCount?: number;
146
148
  imageCount?: number;
@@ -343,7 +343,7 @@ function renderSeoResponse(data, width) {
343
343
  if (data.summary) {
344
344
  const s = data.summary;
345
345
  children.push(Box({ marginTop: 1 }, Text({ color: themeColor('foreground'), bold: true }, 'Summary')));
346
- children.push(Box({ flexDirection: 'row' }, Text({ color: themeColor('success') }, `✔ Passed: ${s.passed || 0} `), Text({ color: themeColor('warning') }, `⚠ Warnings: ${s.warnings || 0} `), Text({ color: themeColor('error') }, `✖ Errors: ${s.errors || 0} `), Text({ color: themeColor('accent') }, `ℹ Info: ${s.infos || 0}`)));
346
+ children.push(Box({ flexDirection: 'row' }, Text({ color: themeColor('success') }, `✔ Passed: ${s.passed || 0} `), Text({ color: themeColor('warning') }, `⚠ Warnings: ${s.warnings || 0} `), Text({ color: themeColor('error') }, `✖ Errors: ${s.errors || 0} `), Text({ color: themeColor('accent') }, `ℹ Info: ${s.infos || 0}`), Text({ color: themeColor('mutedForeground'), dim: true }, ` (N/A: ${s.notApplicable || 0}, Sugestões: ${s.suggestions || 0})`)));
347
347
  if (s.vitals) {
348
348
  children.push(Text({ color: themeColor('mutedForeground') }, `Words: ${s.vitals.wordCount || 0} | Images: ${s.vitals.imageCount || 0} | Links: ${s.vitals.linkCount || 0}${s.vitals.htmlSize ? ` | HTML: ${Math.round(s.vitals.htmlSize / 1024)}KB` : ''}`));
349
349
  }
@@ -34,6 +34,7 @@ export declare class SeoAnalyzer {
34
34
  private analyzeFeeds;
35
35
  private analyzeConversionElements;
36
36
  private calculateTextHtmlRatio;
37
+ private classifyInfoCheck;
37
38
  private convertToCheckResults;
38
39
  private buildSummary;
39
40
  private calculateMetaCompleteness;
@@ -71,7 +71,7 @@ export class SeoAnalyzer {
71
71
  const ruleResults = this.rulesEngine.evaluate(context);
72
72
  const checks = this.convertToCheckResults(ruleResults);
73
73
  const { score, grade } = this.calculateScore(ruleResults);
74
- const summary = this.buildSummary(ruleResults, checks, {
74
+ const summary = this.buildSummary(checks, {
75
75
  content,
76
76
  imageAnalysis,
77
77
  linkAnalysis,
@@ -951,6 +951,27 @@ export class SeoAnalyzer {
951
951
  }
952
952
  return undefined;
953
953
  }
954
+ classifyInfoCheck(result) {
955
+ if (result.status !== 'info')
956
+ return undefined;
957
+ const message = (result.message || '').toLowerCase();
958
+ const evidenceIssue = (result.evidence?.issue || '').toLowerCase();
959
+ const recommendation = (result.recommendation || '').toLowerCase();
960
+ const context = `${message} ${evidenceIssue} ${recommendation}`;
961
+ if (/not\s+applicable/.test(context) ||
962
+ /not\s+available/.test(context) ||
963
+ /data\s+unavailable/.test(context) ||
964
+ /context\s+unavailable/.test(context) ||
965
+ /unable\s+to\s+check/.test(context) ||
966
+ /cannot\s+verify/.test(context) ||
967
+ /cannot\s+be\s+determined/.test(context) ||
968
+ /\bunavailable\b/.test(context) ||
969
+ /not\s+set/.test(context) ||
970
+ /not\s+present/.test(context)) {
971
+ return 'not_applicable';
972
+ }
973
+ return 'suggestion';
974
+ }
954
975
  convertToCheckResults(results) {
955
976
  return results.map((r) => ({
956
977
  id: r.id,
@@ -959,26 +980,36 @@ export class SeoAnalyzer {
959
980
  severity: r.severity,
960
981
  status: r.status,
961
982
  message: r.message,
983
+ infoType: this.classifyInfoCheck(r),
962
984
  value: r.value,
963
985
  recommendation: r.recommendation,
964
986
  evidence: r.evidence,
965
987
  }));
966
988
  }
967
- buildSummary(ruleResults, checks, data) {
989
+ buildSummary(checks, data) {
968
990
  const pageType = data.pageType;
969
991
  const timings = data.timings;
970
992
  const passed = checks.filter((c) => c.status === 'pass').length;
971
993
  const warnings = checks.filter((c) => c.status === 'warn').length;
972
994
  const errors = checks.filter((c) => c.status === 'fail').length;
973
995
  const infos = checks.filter((c) => c.status === 'info').length;
996
+ const notApplicable = checks.filter((c) => c.status === 'info' && c.infoType === 'not_applicable').length;
997
+ const suggestions = checks.filter((c) => c.status === 'info' && c.infoType !== 'not_applicable').length;
974
998
  const totalChecks = checks.length;
975
999
  const scoringChecks = totalChecks - infos;
976
1000
  const passRate = scoringChecks > 0 ? Math.round((passed / scoringChecks) * 100) : 100;
977
1001
  const issuesByCategory = {};
978
- for (const result of ruleResults) {
1002
+ for (const result of checks) {
979
1003
  const cat = result.category;
980
1004
  if (!issuesByCategory[cat]) {
981
- issuesByCategory[cat] = { passed: 0, warnings: 0, errors: 0 };
1005
+ issuesByCategory[cat] = {
1006
+ passed: 0,
1007
+ warnings: 0,
1008
+ errors: 0,
1009
+ infos: 0,
1010
+ notApplicable: 0,
1011
+ suggestions: 0,
1012
+ };
982
1013
  }
983
1014
  if (result.status === 'pass')
984
1015
  issuesByCategory[cat].passed++;
@@ -986,6 +1017,15 @@ export class SeoAnalyzer {
986
1017
  issuesByCategory[cat].warnings++;
987
1018
  else if (result.status === 'fail')
988
1019
  issuesByCategory[cat].errors++;
1020
+ else if (result.status === 'info') {
1021
+ issuesByCategory[cat].infos++;
1022
+ if (result.infoType === 'not_applicable') {
1023
+ issuesByCategory[cat].notApplicable++;
1024
+ }
1025
+ else {
1026
+ issuesByCategory[cat].suggestions++;
1027
+ }
1028
+ }
989
1029
  }
990
1030
  const topIssues = checks
991
1031
  .filter((c) => c.status === 'fail' || c.status === 'warn')
@@ -1052,6 +1092,8 @@ export class SeoAnalyzer {
1052
1092
  warnings,
1053
1093
  errors,
1054
1094
  infos,
1095
+ notApplicable,
1096
+ suggestions,
1055
1097
  passRate,
1056
1098
  issuesByCategory,
1057
1099
  pageType: pageType,
@@ -29,7 +29,16 @@ export function statusIcon(status) {
29
29
  export function formatCheck(check, showEvidence = false) {
30
30
  const lines = [];
31
31
  const icon = statusIcon(check.status);
32
- lines.push(` ${icon} ${check.message}`);
32
+ let infoLabel = '';
33
+ if (check.status === 'info') {
34
+ if (check.infoType === 'not_applicable') {
35
+ infoLabel = colors.magenta(' [N/A]');
36
+ }
37
+ else if (check.infoType === 'suggestion') {
38
+ infoLabel = colors.cyan(' [SUGGESTION]');
39
+ }
40
+ }
41
+ lines.push(` ${icon} ${check.message}${infoLabel}`);
33
42
  if (check.value !== undefined) {
34
43
  lines.push(` ${colors.gray('Value:')} ${check.value}`);
35
44
  }
@@ -239,7 +248,10 @@ export function formatSeoReport(report, url, options = {}) {
239
248
  lines.push(colors.gray(' ──────────────────────────────────────────────────'));
240
249
  lines.push('');
241
250
  lines.push(` ${colors.bold('Summary')}`);
242
- lines.push(` ${colors.green('✔ Passed:')} ${s.passed} ${colors.yellow('⚠ Warnings:')} ${s.warnings} ${colors.red('✖ Errors:')} ${s.errors} ${colors.blue('ℹ Info:')} ${s.infos}`);
251
+ const infoSummary = (s.notApplicable !== undefined || s.suggestions !== undefined)
252
+ ? ` (${s.notApplicable ?? 0} not applicable, ${s.suggestions ?? 0} suggestions)`
253
+ : '';
254
+ lines.push(` ${colors.green('✔ Passed:')} ${s.passed} ${colors.yellow('⚠ Warnings:')} ${s.warnings} ${colors.red('✖ Errors:')} ${s.errors} ${colors.blue('ℹ Info:')} ${s.infos}${infoSummary}`);
243
255
  if (s.vitals) {
244
256
  lines.push(` ${colors.gray('Words:')} ${s.vitals.wordCount} | ${colors.gray('Images:')} ${s.vitals.imageCount} | ${colors.gray('Links:')} ${s.vitals.linkCount}`);
245
257
  }
@@ -381,12 +393,16 @@ function groupChecksByCategory(checks) {
381
393
  const warnings = catChecks.filter(c => c.status === 'warn').length;
382
394
  const errors = catChecks.filter(c => c.status === 'fail').length;
383
395
  const infos = catChecks.filter(c => c.status === 'info').length;
396
+ const notApplicable = catChecks.filter(c => c.status === 'info' && c.infoType === 'not_applicable').length;
397
+ const suggestions = catChecks.filter(c => c.status === 'info' && c.infoType !== 'not_applicable').length;
384
398
  const total = catChecks.length - infos;
385
399
  result[cat] = {
386
400
  passed,
387
401
  warnings,
388
402
  errors,
389
403
  infos,
404
+ notApplicable,
405
+ suggestions,
390
406
  passRate: total > 0 ? Math.round((passed / total) * 100) : 100,
391
407
  checks: catChecks,
392
408
  };
@@ -410,6 +426,8 @@ export function formatSeoReportJson(report, url, options) {
410
426
  warnings: report.checks.filter(c => c.status === 'warn').length,
411
427
  errors: report.checks.filter(c => c.status === 'fail').length,
412
428
  infos: report.checks.filter(c => c.status === 'info').length,
429
+ notApplicable: report.checks.filter(c => c.status === 'info' && c.infoType === 'not_applicable').length,
430
+ suggestions: report.checks.filter(c => c.status === 'info' && c.infoType !== 'not_applicable').length,
413
431
  passRate: report.summary.passRate,
414
432
  completeness: report.summary.completeness,
415
433
  topIssues: report.summary.topIssues,
@@ -1,6 +1,7 @@
1
1
  import { KeywordCloud } from './keywords.js';
2
2
  export type { KeywordCloud, KeywordItem } from './keywords.js';
3
3
  export type SeoStatus = 'pass' | 'warn' | 'fail' | 'info';
4
+ export type SeoInfoType = 'not_applicable' | 'suggestion';
4
5
  export type SeoPageType = 'homepage' | 'product' | 'article' | 'category' | 'search' | 'other';
5
6
  export interface SeoCheckEvidence {
6
7
  found?: string | number | string[];
@@ -18,6 +19,7 @@ export interface SeoCheckResult {
18
19
  status: SeoStatus;
19
20
  severity?: 'error' | 'warning' | 'info';
20
21
  message: string;
22
+ infoType?: SeoInfoType;
21
23
  value?: string | number;
22
24
  recommendation?: string;
23
25
  evidence?: SeoCheckEvidence;
@@ -115,11 +117,16 @@ export interface SeoSummary {
115
117
  warnings: number;
116
118
  errors: number;
117
119
  infos: number;
120
+ notApplicable: number;
121
+ suggestions: number;
118
122
  passRate: number;
119
123
  issuesByCategory: Record<string, {
120
124
  passed: number;
121
125
  warnings: number;
122
126
  errors: number;
127
+ infos: number;
128
+ notApplicable: number;
129
+ suggestions: number;
123
130
  }>;
124
131
  topIssues: Array<{
125
132
  name: string;
package/dist/version.js CHANGED
@@ -1,4 +1,4 @@
1
- const VERSION = '1.0.78';
1
+ const VERSION = '1.0.79';
2
2
  let _version = null;
3
3
  export async function getVersion() {
4
4
  if (_version)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "recker",
3
- "version": "1.0.78",
3
+ "version": "1.0.79",
4
4
  "description": "Multi-Protocol SDK for the AI Era - HTTP, WebSocket, DNS, FTP, SFTP, Telnet, HLS unified with AI providers and MCP tools",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",