@aiready/core 0.23.2 → 0.23.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.
Files changed (79) hide show
  1. package/dist/__tests__/parser-factory.test.d.ts +1 -1
  2. package/dist/__tests__/parser-factory.test.js +62 -50
  3. package/dist/__tests__/python-parser.test.d.ts +1 -1
  4. package/dist/__tests__/python-parser.test.js +111 -109
  5. package/dist/__tests__/scoring.test.d.ts +1 -1
  6. package/dist/__tests__/scoring.test.js +193 -176
  7. package/dist/chunk-3YI4IS3D.mjs +191 -173
  8. package/dist/chunk-5HIXDC3X.mjs +273 -251
  9. package/dist/chunk-5V3L53AE.mjs +805 -0
  10. package/dist/chunk-CKVKHN3G.mjs +228 -211
  11. package/dist/chunk-COHIBX3Q.mjs +213 -195
  12. package/dist/chunk-CWRCDSKZ.mjs +91 -82
  13. package/dist/chunk-D3D3NCRR.mjs +147 -129
  14. package/dist/chunk-HCFYP7UD.mjs +805 -0
  15. package/dist/chunk-HFLFBA6F.mjs +79 -72
  16. package/dist/chunk-HKSARRCD.mjs +66 -58
  17. package/dist/chunk-JJ5JL5FX.mjs +91 -82
  18. package/dist/chunk-KDSTXVLQ.mjs +724 -0
  19. package/dist/chunk-KI7XORTN.mjs +91 -82
  20. package/dist/chunk-LTMHFNFK.mjs +690 -0
  21. package/dist/chunk-LTNXTXRI.mjs +228 -211
  22. package/dist/chunk-M22BXHBR.mjs +805 -0
  23. package/dist/chunk-MH3A3LX6.mjs +200 -182
  24. package/dist/chunk-NGHT7JOG.mjs +697 -0
  25. package/dist/chunk-OQ6IGDXG.mjs +147 -129
  26. package/dist/chunk-QAFB3HXQ.mjs +181 -165
  27. package/dist/chunk-QQBKXHLU.mjs +678 -0
  28. package/dist/chunk-RDHYGES7.mjs +678 -0
  29. package/dist/chunk-SWTDBVYJ.mjs +228 -213
  30. package/dist/chunk-UIWL5JQB.mjs +79 -72
  31. package/dist/chunk-UQGI67WR.mjs +79 -72
  32. package/dist/chunk-UTZOO4XO.mjs +147 -131
  33. package/dist/chunk-X4F46I5L.mjs +213 -195
  34. package/dist/chunk-XKK7YHPX.mjs +204 -186
  35. package/dist/chunk-YCA4FTEK.mjs +190 -172
  36. package/dist/chunk-ZSZRRTJM.mjs +719 -0
  37. package/dist/client-BgmiMoil.d.mts +1344 -0
  38. package/dist/client-BgmiMoil.d.ts +1344 -0
  39. package/dist/client-BxGrPuuN.d.mts +1191 -0
  40. package/dist/client-BxGrPuuN.d.ts +1191 -0
  41. package/dist/client-D-cn9ydj.d.mts +1136 -0
  42. package/dist/client-D-cn9ydj.d.ts +1136 -0
  43. package/dist/client-D9seCH4K.d.mts +1334 -0
  44. package/dist/client-D9seCH4K.d.ts +1334 -0
  45. package/dist/client-DIXIh7rw.d.mts +1193 -0
  46. package/dist/client-DIXIh7rw.d.ts +1193 -0
  47. package/dist/client-DVHXWOHw.d.mts +1245 -0
  48. package/dist/client-DVHXWOHw.d.ts +1245 -0
  49. package/dist/client.d.mts +2 -1098
  50. package/dist/client.d.ts +2 -1098
  51. package/dist/client.js +23 -43
  52. package/dist/client.mjs +3 -25
  53. package/dist/index.d.mts +325 -103
  54. package/dist/index.d.ts +325 -103
  55. package/dist/index.js +307 -324
  56. package/dist/index.mjs +283 -306
  57. package/dist/parsers/parser-factory.d.ts +45 -45
  58. package/dist/parsers/parser-factory.js +86 -84
  59. package/dist/parsers/python-parser.d.ts +33 -28
  60. package/dist/parsers/python-parser.js +224 -222
  61. package/dist/parsers/typescript-parser.d.ts +15 -10
  62. package/dist/parsers/typescript-parser.js +223 -197
  63. package/dist/scoring.d.ts +59 -49
  64. package/dist/scoring.js +129 -127
  65. package/dist/types/language.d.ts +104 -93
  66. package/dist/types/language.js +23 -23
  67. package/dist/types.d.ts +105 -87
  68. package/dist/types.js +1 -1
  69. package/dist/utils/ast-parser.d.ts +42 -33
  70. package/dist/utils/ast-parser.js +159 -162
  71. package/dist/utils/cli-helpers.d.ts +27 -10
  72. package/dist/utils/cli-helpers.js +45 -43
  73. package/dist/utils/config.d.ts +8 -3
  74. package/dist/utils/config.js +67 -69
  75. package/dist/utils/file-scanner.d.ts +1 -1
  76. package/dist/utils/file-scanner.js +80 -76
  77. package/dist/utils/metrics.d.ts +1 -1
  78. package/dist/utils/metrics.js +2 -2
  79. package/package.json +1 -1
@@ -1,47 +1,47 @@
1
1
  // src/types/schema.ts
2
- import { z } from "zod";
2
+ import { z } from 'zod';
3
3
  var Severity = /* @__PURE__ */ ((Severity2) => {
4
- Severity2["Critical"] = "critical";
5
- Severity2["Major"] = "major";
6
- Severity2["Minor"] = "minor";
7
- Severity2["Info"] = "info";
4
+ Severity2['Critical'] = 'critical';
5
+ Severity2['Major'] = 'major';
6
+ Severity2['Minor'] = 'minor';
7
+ Severity2['Info'] = 'info';
8
8
  return Severity2;
9
9
  })(Severity || {});
10
10
  var SeveritySchema = z.nativeEnum(Severity);
11
11
  var IssueType = /* @__PURE__ */ ((IssueType2) => {
12
- IssueType2["DuplicatePattern"] = "duplicate-pattern";
13
- IssueType2["PatternInconsistency"] = "pattern-inconsistency";
14
- IssueType2["ContextFragmentation"] = "context-fragmentation";
15
- IssueType2["DependencyHealth"] = "dependency-health";
16
- IssueType2["CircularDependency"] = "circular-dependency";
17
- IssueType2["DocDrift"] = "doc-drift";
18
- IssueType2["NamingInconsistency"] = "naming-inconsistency";
19
- IssueType2["NamingQuality"] = "naming-quality";
20
- IssueType2["ArchitectureInconsistency"] = "architecture-inconsistency";
21
- IssueType2["DeadCode"] = "dead-code";
22
- IssueType2["MissingTypes"] = "missing-types";
23
- IssueType2["MagicLiteral"] = "magic-literal";
24
- IssueType2["BooleanTrap"] = "boolean-trap";
25
- IssueType2["AiSignalClarity"] = "ai-signal-clarity";
26
- IssueType2["LowTestability"] = "low-testability";
27
- IssueType2["AgentNavigationFailure"] = "agent-navigation-failure";
28
- IssueType2["AmbiguousApi"] = "ambiguous-api";
29
- IssueType2["ChangeAmplification"] = "change-amplification";
12
+ IssueType2['DuplicatePattern'] = 'duplicate-pattern';
13
+ IssueType2['PatternInconsistency'] = 'pattern-inconsistency';
14
+ IssueType2['ContextFragmentation'] = 'context-fragmentation';
15
+ IssueType2['DependencyHealth'] = 'dependency-health';
16
+ IssueType2['CircularDependency'] = 'circular-dependency';
17
+ IssueType2['DocDrift'] = 'doc-drift';
18
+ IssueType2['NamingInconsistency'] = 'naming-inconsistency';
19
+ IssueType2['NamingQuality'] = 'naming-quality';
20
+ IssueType2['ArchitectureInconsistency'] = 'architecture-inconsistency';
21
+ IssueType2['DeadCode'] = 'dead-code';
22
+ IssueType2['MissingTypes'] = 'missing-types';
23
+ IssueType2['MagicLiteral'] = 'magic-literal';
24
+ IssueType2['BooleanTrap'] = 'boolean-trap';
25
+ IssueType2['AiSignalClarity'] = 'ai-signal-clarity';
26
+ IssueType2['LowTestability'] = 'low-testability';
27
+ IssueType2['AgentNavigationFailure'] = 'agent-navigation-failure';
28
+ IssueType2['AmbiguousApi'] = 'ambiguous-api';
29
+ IssueType2['ChangeAmplification'] = 'change-amplification';
30
30
  return IssueType2;
31
31
  })(IssueType || {});
32
32
  var IssueTypeSchema = z.nativeEnum(IssueType);
33
33
  var AnalysisStatus = /* @__PURE__ */ ((AnalysisStatus2) => {
34
- AnalysisStatus2["Processing"] = "processing";
35
- AnalysisStatus2["Completed"] = "completed";
36
- AnalysisStatus2["Failed"] = "failed";
34
+ AnalysisStatus2['Processing'] = 'processing';
35
+ AnalysisStatus2['Completed'] = 'completed';
36
+ AnalysisStatus2['Failed'] = 'failed';
37
37
  return AnalysisStatus2;
38
38
  })(AnalysisStatus || {});
39
39
  var AnalysisStatusSchema = z.nativeEnum(AnalysisStatus);
40
40
  var ModelTier = /* @__PURE__ */ ((ModelTier2) => {
41
- ModelTier2["Compact"] = "compact";
42
- ModelTier2["Standard"] = "standard";
43
- ModelTier2["Extended"] = "extended";
44
- ModelTier2["Frontier"] = "frontier";
41
+ ModelTier2['Compact'] = 'compact';
42
+ ModelTier2['Standard'] = 'standard';
43
+ ModelTier2['Extended'] = 'extended';
44
+ ModelTier2['Frontier'] = 'frontier';
45
45
  return ModelTier2;
46
46
  })(ModelTier || {});
47
47
  var ModelTierSchema = z.nativeEnum(ModelTier);
@@ -50,14 +50,14 @@ var LocationSchema = z.object({
50
50
  line: z.number(),
51
51
  column: z.number().optional(),
52
52
  endLine: z.number().optional(),
53
- endColumn: z.number().optional()
53
+ endColumn: z.number().optional(),
54
54
  });
55
55
  var IssueSchema = z.object({
56
56
  type: IssueTypeSchema,
57
57
  severity: SeveritySchema,
58
58
  message: z.string(),
59
59
  location: LocationSchema,
60
- suggestion: z.string().optional()
60
+ suggestion: z.string().optional(),
61
61
  });
62
62
  var MetricsSchema = z.object({
63
63
  tokenCost: z.number().optional(),
@@ -77,102 +77,113 @@ var MetricsSchema = z.object({
77
77
  comprehensionDifficultyIndex: z.number().optional(),
78
78
  // Extended metrics for specific spokes
79
79
  totalSymbols: z.number().optional(),
80
- totalExports: z.number().optional()
80
+ totalExports: z.number().optional(),
81
81
  });
82
82
  var AnalysisResultSchema = z.object({
83
83
  fileName: z.string(),
84
84
  issues: z.array(IssueSchema),
85
- metrics: MetricsSchema
85
+ metrics: MetricsSchema,
86
86
  });
87
87
  var SpokeOutputSchema = z.object({
88
88
  results: z.array(AnalysisResultSchema),
89
89
  summary: z.any(),
90
- metadata: z.object({
91
- toolName: z.string(),
92
- version: z.string(),
93
- timestamp: z.string()
94
- }).catchall(z.any()).optional()
95
- });
96
- var UnifiedReportSchema = z.object({
97
- summary: z.object({
98
- totalFiles: z.number(),
99
- totalIssues: z.number(),
100
- criticalIssues: z.number(),
101
- majorIssues: z.number()
102
- }),
103
- results: z.array(AnalysisResultSchema),
104
- scoring: z.object({
105
- overall: z.number(),
106
- rating: z.string(),
107
- timestamp: z.string(),
108
- breakdown: z.array(z.object({
90
+ metadata: z
91
+ .object({
109
92
  toolName: z.string(),
110
- score: z.number()
111
- }).catchall(z.any()))
112
- }).optional()
113
- }).catchall(z.any());
93
+ version: z.string(),
94
+ timestamp: z.string(),
95
+ })
96
+ .catchall(z.any())
97
+ .optional(),
98
+ });
99
+ var UnifiedReportSchema = z
100
+ .object({
101
+ summary: z.object({
102
+ totalFiles: z.number(),
103
+ totalIssues: z.number(),
104
+ criticalIssues: z.number(),
105
+ majorIssues: z.number(),
106
+ }),
107
+ results: z.array(AnalysisResultSchema),
108
+ scoring: z
109
+ .object({
110
+ overall: z.number(),
111
+ rating: z.string(),
112
+ timestamp: z.string(),
113
+ breakdown: z.array(
114
+ z
115
+ .object({
116
+ toolName: z.string(),
117
+ score: z.number(),
118
+ })
119
+ .catchall(z.any())
120
+ ),
121
+ })
122
+ .optional(),
123
+ })
124
+ .catchall(z.any());
114
125
 
115
126
  // src/types/language.ts
116
127
  var Language = /* @__PURE__ */ ((Language2) => {
117
- Language2["TypeScript"] = "typescript";
118
- Language2["JavaScript"] = "javascript";
119
- Language2["Python"] = "python";
120
- Language2["Java"] = "java";
121
- Language2["Go"] = "go";
122
- Language2["Rust"] = "rust";
123
- Language2["CSharp"] = "csharp";
128
+ Language2['TypeScript'] = 'typescript';
129
+ Language2['JavaScript'] = 'javascript';
130
+ Language2['Python'] = 'python';
131
+ Language2['Java'] = 'java';
132
+ Language2['Go'] = 'go';
133
+ Language2['Rust'] = 'rust';
134
+ Language2['CSharp'] = 'csharp';
124
135
  return Language2;
125
136
  })(Language || {});
126
137
  var LANGUAGE_EXTENSIONS = {
127
- ".ts": "typescript" /* TypeScript */,
128
- ".tsx": "typescript" /* TypeScript */,
129
- ".js": "javascript" /* JavaScript */,
130
- ".jsx": "javascript" /* JavaScript */,
131
- ".py": "python" /* Python */,
132
- ".java": "java" /* Java */,
133
- ".go": "go" /* Go */,
134
- ".rs": "rust" /* Rust */,
135
- ".cs": "csharp" /* CSharp */
138
+ '.ts': 'typescript' /* TypeScript */,
139
+ '.tsx': 'typescript' /* TypeScript */,
140
+ '.js': 'javascript' /* JavaScript */,
141
+ '.jsx': 'javascript' /* JavaScript */,
142
+ '.py': 'python' /* Python */,
143
+ '.java': 'java' /* Java */,
144
+ '.go': 'go' /* Go */,
145
+ '.rs': 'rust' /* Rust */,
146
+ '.cs': 'csharp' /* CSharp */,
136
147
  };
137
148
  var ParseError = class extends Error {
138
149
  constructor(message, filePath, loc) {
139
150
  super(message);
140
151
  this.filePath = filePath;
141
152
  this.loc = loc;
142
- this.name = "ParseError";
153
+ this.name = 'ParseError';
143
154
  }
144
155
  };
145
156
 
146
157
  // src/scoring.ts
147
158
  var DEFAULT_TOOL_WEIGHTS = {
148
- "pattern-detect": 22,
149
- "context-analyzer": 19,
159
+ 'pattern-detect': 22,
160
+ 'context-analyzer': 19,
150
161
  consistency: 14,
151
- "ai-signal-clarity": 11,
152
- "agent-grounding": 10,
162
+ 'ai-signal-clarity': 11,
163
+ 'agent-grounding': 10,
153
164
  testability: 10,
154
- "doc-drift": 8,
155
- deps: 6
165
+ 'doc-drift': 8,
166
+ deps: 6,
156
167
  };
157
168
  var TOOL_NAME_MAP = {
158
- patterns: "pattern-detect",
159
- context: "context-analyzer",
160
- consistency: "consistency",
161
- "AI signal clarity": "ai-signal-clarity",
162
- "ai-signal-clarity": "ai-signal-clarity",
163
- grounding: "agent-grounding",
164
- "agent-grounding": "agent-grounding",
165
- testability: "testability",
166
- tests: "testability",
167
- "doc-drift": "doc-drift",
168
- docs: "doc-drift",
169
- deps: "deps"
169
+ patterns: 'pattern-detect',
170
+ context: 'context-analyzer',
171
+ consistency: 'consistency',
172
+ 'AI signal clarity': 'ai-signal-clarity',
173
+ 'ai-signal-clarity': 'ai-signal-clarity',
174
+ grounding: 'agent-grounding',
175
+ 'agent-grounding': 'agent-grounding',
176
+ testability: 'testability',
177
+ tests: 'testability',
178
+ 'doc-drift': 'doc-drift',
179
+ docs: 'doc-drift',
180
+ deps: 'deps',
170
181
  };
171
182
  var CONTEXT_TIER_THRESHOLDS = {
172
183
  compact: { idealTokens: 3e3, criticalTokens: 1e4, idealDepth: 4 },
173
184
  standard: { idealTokens: 5e3, criticalTokens: 15e3, idealDepth: 5 },
174
185
  extended: { idealTokens: 15e3, criticalTokens: 5e4, idealDepth: 7 },
175
- frontier: { idealTokens: 5e4, criticalTokens: 15e4, idealDepth: 10 }
186
+ frontier: { idealTokens: 5e4, criticalTokens: 15e4, idealDepth: 10 },
176
187
  };
177
188
  var SIZE_ADJUSTED_THRESHOLDS = {
178
189
  xs: 80,
@@ -183,20 +194,21 @@ var SIZE_ADJUSTED_THRESHOLDS = {
183
194
  // 200-500 files
184
195
  large: 65,
185
196
  // 500-2000 files
186
- enterprise: 58
197
+ enterprise: 58,
187
198
  // 2000+ files
188
199
  };
189
200
  function getProjectSizeTier(fileCount) {
190
- if (fileCount < 50) return "xs";
191
- if (fileCount < 200) return "small";
192
- if (fileCount < 500) return "medium";
193
- if (fileCount < 2e3) return "large";
194
- return "enterprise";
201
+ if (fileCount < 50) return 'xs';
202
+ if (fileCount < 200) return 'small';
203
+ if (fileCount < 500) return 'medium';
204
+ if (fileCount < 2e3) return 'large';
205
+ return 'enterprise';
195
206
  }
196
- function getRecommendedThreshold(fileCount, modelTier = "standard") {
207
+ function getRecommendedThreshold(fileCount, modelTier = 'standard') {
197
208
  const sizeTier = getProjectSizeTier(fileCount);
198
209
  const base = SIZE_ADJUSTED_THRESHOLDS[sizeTier];
199
- const modelBonus = modelTier === "frontier" ? -3 : modelTier === "extended" ? -2 : 0;
210
+ const modelBonus =
211
+ modelTier === 'frontier' ? -3 : modelTier === 'extended' ? -2 : 0;
200
212
  return base + modelBonus;
201
213
  }
202
214
  function normalizeToolName(shortName) {
@@ -216,9 +228,9 @@ function parseWeightString(weightStr) {
216
228
  if (!weightStr) {
217
229
  return weights;
218
230
  }
219
- const pairs = weightStr.split(",");
231
+ const pairs = weightStr.split(',');
220
232
  for (const pair of pairs) {
221
- const [toolShortName, weightStr2] = pair.split(":");
233
+ const [toolShortName, weightStr2] = pair.split(':');
222
234
  if (toolShortName && weightStr2) {
223
235
  const toolName = normalizeToolName(toolShortName.trim());
224
236
  const weight = parseInt(weightStr2.trim(), 10);
@@ -231,13 +243,14 @@ function parseWeightString(weightStr) {
231
243
  }
232
244
  function calculateOverallScore(toolOutputs, config, cliWeights) {
233
245
  if (toolOutputs.size === 0) {
234
- throw new Error("No tool outputs provided for scoring");
246
+ throw new Error('No tool outputs provided for scoring');
235
247
  }
236
248
  const weights = /* @__PURE__ */ new Map();
237
249
  for (const [toolName] of toolOutputs.entries()) {
238
250
  const cliWeight = cliWeights?.get(toolName);
239
251
  const configWeight = config?.tools?.[toolName]?.scoreWeight;
240
- const weight = cliWeight ?? configWeight ?? DEFAULT_TOOL_WEIGHTS[toolName] ?? 5;
252
+ const weight =
253
+ cliWeight ?? configWeight ?? DEFAULT_TOOL_WEIGHTS[toolName] ?? 5;
241
254
  weights.set(toolName, weight);
242
255
  }
243
256
  let weightedSum = 0;
@@ -262,44 +275,44 @@ function calculateOverallScore(toolOutputs, config, cliWeights) {
262
275
  return `(${output.score} \xD7 ${w})`;
263
276
  }
264
277
  );
265
- const formulaStr = `[${formulaParts.join(" + ")}] / ${totalWeight} = ${overall}`;
278
+ const formulaStr = `[${formulaParts.join(' + ')}] / ${totalWeight} = ${overall}`;
266
279
  return {
267
280
  overall,
268
281
  rating,
269
- timestamp: (/* @__PURE__ */ new Date()).toISOString(),
282
+ timestamp: /* @__PURE__ */ new Date().toISOString(),
270
283
  toolsUsed,
271
284
  breakdown,
272
285
  calculation: {
273
286
  formula: formulaStr,
274
287
  weights: calculationWeights,
275
- normalized: formulaStr
276
- }
288
+ normalized: formulaStr,
289
+ },
277
290
  };
278
291
  }
279
292
  function getRating(score) {
280
- if (score >= 90) return "Excellent";
281
- if (score >= 75) return "Good";
282
- if (score >= 60) return "Fair";
283
- if (score >= 40) return "Needs Work";
284
- return "Critical";
293
+ if (score >= 90) return 'Excellent';
294
+ if (score >= 75) return 'Good';
295
+ if (score >= 60) return 'Fair';
296
+ if (score >= 40) return 'Needs Work';
297
+ return 'Critical';
285
298
  }
286
- function getRatingWithContext(score, fileCount, modelTier = "standard") {
299
+ function getRatingWithContext(score, fileCount, modelTier = 'standard') {
287
300
  const threshold = getRecommendedThreshold(fileCount, modelTier);
288
301
  const normalized = score - threshold + 70;
289
302
  return getRating(normalized);
290
303
  }
291
304
  function getRatingDisplay(rating) {
292
305
  switch (rating) {
293
- case "Excellent":
294
- return { emoji: "\u2705", color: "green" };
295
- case "Good":
296
- return { emoji: "\u{1F44D}", color: "blue" };
297
- case "Fair":
298
- return { emoji: "\u26A0\uFE0F", color: "yellow" };
299
- case "Needs Work":
300
- return { emoji: "\u{1F528}", color: "orange" };
301
- case "Critical":
302
- return { emoji: "\u274C", color: "red" };
306
+ case 'Excellent':
307
+ return { emoji: '\u2705', color: 'green' };
308
+ case 'Good':
309
+ return { emoji: '\u{1F44D}', color: 'blue' };
310
+ case 'Fair':
311
+ return { emoji: '\u26A0\uFE0F', color: 'yellow' };
312
+ case 'Needs Work':
313
+ return { emoji: '\u{1F528}', color: 'orange' };
314
+ case 'Critical':
315
+ return { emoji: '\u274C', color: 'red' };
303
316
  }
304
317
  }
305
318
  function formatScore(result) {
@@ -314,17 +327,22 @@ function formatToolScore(output) {
314
327
  result += ` Factors:
315
328
  `;
316
329
  output.factors.forEach((factor) => {
317
- const impactSign = factor.impact > 0 ? "+" : "";
330
+ const impactSign = factor.impact > 0 ? '+' : '';
318
331
  result += ` \u2022 ${factor.name}: ${impactSign}${factor.impact} - ${factor.description}
319
332
  `;
320
333
  });
321
- result += "\n";
334
+ result += '\n';
322
335
  }
323
336
  if (output.recommendations && output.recommendations.length > 0) {
324
337
  result += ` Recommendations:
325
338
  `;
326
339
  output.recommendations.forEach((rec, i) => {
327
- const priorityIcon = rec.priority === "high" ? "\u{1F534}" : rec.priority === "medium" ? "\u{1F7E1}" : "\u{1F535}";
340
+ const priorityIcon =
341
+ rec.priority === 'high'
342
+ ? '\u{1F534}'
343
+ : rec.priority === 'medium'
344
+ ? '\u{1F7E1}'
345
+ : '\u{1F535}';
328
346
  result += ` ${i + 1}. ${priorityIcon} ${rec.action}
329
347
  `;
330
348
  result += ` Impact: +${rec.estimatedImpact} points
@@ -534,5 +552,5 @@ export {
534
552
  getRatingDisplay,
535
553
  formatScore,
536
554
  formatToolScore,
537
- generateHTML
555
+ generateHTML,
538
556
  };