@aiready/core 0.21.17 → 0.21.21

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/index.js CHANGED
@@ -57,6 +57,8 @@ __export(index_exports, {
57
57
  ParseError: () => ParseError,
58
58
  ParserFactory: () => ParserFactory,
59
59
  PythonParser: () => PythonParser,
60
+ ReadinessRating: () => ReadinessRating,
61
+ RecommendationPriority: () => RecommendationPriority,
60
62
  SEVERITY_TIME_ESTIMATES: () => SEVERITY_TIME_ESTIMATES,
61
63
  SIZE_ADJUSTED_THRESHOLDS: () => SIZE_ADJUSTED_THRESHOLDS,
62
64
  Severity: () => Severity,
@@ -124,8 +126,10 @@ __export(index_exports, {
124
126
  getSeverityColor: () => getSeverityColor,
125
127
  getSupportedLanguages: () => getSupportedLanguages,
126
128
  getToolWeight: () => getToolWeight,
129
+ getWasmPath: () => getWasmPath,
127
130
  handleCLIError: () => handleCLIError,
128
131
  handleJSONOutput: () => handleJSONOutput,
132
+ initTreeSitter: () => initTreeSitter,
129
133
  initializeParsers: () => initializeParsers,
130
134
  isFileSupported: () => isFileSupported,
131
135
  isSourceFile: () => isSourceFile,
@@ -143,6 +147,7 @@ __export(index_exports, {
143
147
  saveScoreEntry: () => saveScoreEntry,
144
148
  scanEntries: () => scanEntries,
145
149
  scanFiles: () => scanFiles,
150
+ setupParser: () => setupParser,
146
151
  validateSpokeOutput: () => validateSpokeOutput,
147
152
  validateWithSchema: () => validateWithSchema
148
153
  });
@@ -288,7 +293,12 @@ var UnifiedReportSchema = import_zod.z.object({
288
293
  totalFiles: import_zod.z.number(),
289
294
  totalIssues: import_zod.z.number(),
290
295
  criticalIssues: import_zod.z.number(),
291
- majorIssues: import_zod.z.number()
296
+ majorIssues: import_zod.z.number(),
297
+ businessImpact: import_zod.z.object({
298
+ estimatedMonthlyWaste: import_zod.z.number().optional(),
299
+ potentialSavings: import_zod.z.number().optional(),
300
+ productivityHours: import_zod.z.number().optional()
301
+ }).optional()
292
302
  }),
293
303
  results: import_zod.z.array(AnalysisResultSchema),
294
304
  scoring: import_zod.z.object({
@@ -336,15 +346,15 @@ var COMMON_FINE_TUNING_OPTIONS = [
336
346
  var GLOBAL_SCAN_OPTIONS = [...GLOBAL_INFRA_OPTIONS];
337
347
 
338
348
  // src/types/language.ts
339
- var Language = /* @__PURE__ */ ((Language6) => {
340
- Language6["TypeScript"] = "typescript";
341
- Language6["JavaScript"] = "javascript";
342
- Language6["Python"] = "python";
343
- Language6["Java"] = "java";
344
- Language6["Go"] = "go";
345
- Language6["Rust"] = "rust";
346
- Language6["CSharp"] = "csharp";
347
- return Language6;
349
+ var Language = /* @__PURE__ */ ((Language3) => {
350
+ Language3["TypeScript"] = "typescript";
351
+ Language3["JavaScript"] = "javascript";
352
+ Language3["Python"] = "python";
353
+ Language3["Java"] = "java";
354
+ Language3["Go"] = "go";
355
+ Language3["Rust"] = "rust";
356
+ Language3["CSharp"] = "csharp";
357
+ return Language3;
348
358
  })(Language || {});
349
359
  var LANGUAGE_EXTENSIONS = {
350
360
  ".ts": "typescript" /* TypeScript */,
@@ -425,51 +435,61 @@ function validateWithSchema(schema, data) {
425
435
  }
426
436
 
427
437
  // src/registry.ts
428
- var ToolRegistry = class {
429
- static getProviders() {
430
- const g = globalThis;
431
- if (!g.__AIRE_TOOL_REGISTRY__) {
432
- g.__AIRE_TOOL_REGISTRY__ = /* @__PURE__ */ new Map();
433
- }
434
- return g.__AIRE_TOOL_REGISTRY__;
438
+ var ToolRegistry = class _ToolRegistry {
439
+ /**
440
+ * Create a new ToolRegistry instance
441
+ *
442
+ * @param id Optional identifier for the registry (e.g. for debugging)
443
+ */
444
+ constructor(id = "default") {
445
+ this.providers = /* @__PURE__ */ new Map();
446
+ this.id = `registry-${id}-${Math.random().toString(36).substring(2, 9)}`;
435
447
  }
436
448
  /**
437
449
  * Register a new tool provider.
450
+ *
451
+ * @param provider The tool provider to register
438
452
  */
439
- static register(provider) {
440
- console.log(
441
- `[ToolRegistry#${this.instanceId}] Registering tool: ${provider.id} (${provider.alias.join(", ")})`
442
- );
443
- this.getProviders().set(provider.id, provider);
453
+ register(provider) {
454
+ this.providers.set(provider.id, provider);
444
455
  }
445
456
  /**
446
457
  * Get a provider by its canonical ID.
458
+ *
459
+ * @param id The tool ID
460
+ * @returns The provider if found
447
461
  */
448
- static get(id) {
449
- return this.getProviders().get(id);
462
+ get(id) {
463
+ return this.providers.get(id);
450
464
  }
451
465
  /**
452
466
  * Get a provider by name or alias.
467
+ *
468
+ * @param nameOrAlias The tool name or alias string
469
+ * @returns The provider if found
453
470
  */
454
- static find(nameOrAlias) {
455
- const providers = this.getProviders();
456
- const exact = providers.get(nameOrAlias);
471
+ find(nameOrAlias) {
472
+ const exact = this.providers.get(nameOrAlias);
457
473
  if (exact) return exact;
458
- for (const p of providers.values()) {
474
+ for (const p of this.providers.values()) {
459
475
  if (p.alias.includes(nameOrAlias)) return p;
460
476
  }
461
477
  return void 0;
462
478
  }
463
479
  /**
464
480
  * Get all registered tool providers.
481
+ *
482
+ * @returns Array of all registered tool providers
465
483
  */
466
- static getAll() {
467
- return Array.from(this.getProviders().values());
484
+ getAll() {
485
+ return Array.from(this.providers.values());
468
486
  }
469
487
  /**
470
488
  * Get all available tool IDs from the ToolName enum.
489
+ *
490
+ * @returns Array of valid ToolName identifiers
471
491
  */
472
- static getAvailableIds() {
492
+ getAvailableIds() {
473
493
  return Object.values(ToolName).filter(
474
494
  (v) => typeof v === "string"
475
495
  );
@@ -477,11 +497,54 @@ var ToolRegistry = class {
477
497
  /**
478
498
  * Clear the registry (primarily for testing).
479
499
  */
500
+ clear() {
501
+ this.providers.clear();
502
+ }
503
+ // --- Static Compatibility Layer ---
504
+ static getGlobalRegistry() {
505
+ const g = globalThis;
506
+ if (!g.__AIRE_TOOL_REGISTRY_INSTANCE__) {
507
+ g.__AIRE_TOOL_REGISTRY_INSTANCE__ = new _ToolRegistry("global");
508
+ }
509
+ return g.__AIRE_TOOL_REGISTRY_INSTANCE__;
510
+ }
511
+ /**
512
+ * Static register (Singleton compatibility)
513
+ */
514
+ static register(provider) {
515
+ this.getGlobalRegistry().register(provider);
516
+ }
517
+ /**
518
+ * Static get (Singleton compatibility)
519
+ */
520
+ static get(id) {
521
+ return this.getGlobalRegistry().get(id);
522
+ }
523
+ /**
524
+ * Static find (Singleton compatibility)
525
+ */
526
+ static find(nameOrAlias) {
527
+ return this.getGlobalRegistry().find(nameOrAlias);
528
+ }
529
+ /**
530
+ * Static getAll (Singleton compatibility)
531
+ */
532
+ static getAll() {
533
+ return this.getGlobalRegistry().getAll();
534
+ }
535
+ /**
536
+ * Static getAvailableIds (Singleton compatibility)
537
+ */
538
+ static getAvailableIds() {
539
+ return this.getGlobalRegistry().getAvailableIds();
540
+ }
541
+ /**
542
+ * Static clear (Singleton compatibility)
543
+ */
480
544
  static clear() {
481
- this.getProviders().clear();
545
+ this.getGlobalRegistry().clear();
482
546
  }
483
547
  };
484
- ToolRegistry.instanceId = globalThis.Math.random();
485
548
 
486
549
  // src/utils/file-scanner.ts
487
550
  var import_glob = require("glob");
@@ -593,7 +656,8 @@ async function scanFiles(options) {
593
656
  });
594
657
  const gitignoreFiles = await (0, import_glob.glob)("**/.gitignore", {
595
658
  cwd: rootDir,
596
- ignore: finalExclude,
659
+ ignore: (exclude || []).concat(["**/node_modules/**", "**/.git/**"]),
660
+ // Minimal ignore for gitignore discovery
597
661
  absolute: true
598
662
  });
599
663
  if (gitignoreFiles.length > 0) {
@@ -660,7 +724,7 @@ async function scanEntries(options) {
660
724
  });
661
725
  const gitignoreFiles = await (0, import_glob.glob)("**/.gitignore", {
662
726
  cwd: rootDir,
663
- ignore: finalExclude,
727
+ ignore: (exclude || []).concat(["**/node_modules/**", "**/.git/**"]),
664
728
  absolute: true
665
729
  });
666
730
  if (gitignoreFiles.length > 0) {
@@ -684,8 +748,9 @@ async function scanEntries(options) {
684
748
  }
685
749
  }
686
750
  const filteredDirs = dirs.filter((d) => {
687
- const rel = (0, import_path.relative)(rootDir || ".", d).replace(/\\/g, "/").replace(/\/$/, "");
751
+ let rel = (0, import_path.relative)(rootDir || ".", d).replace(/\\/g, "/");
688
752
  if (rel === "") return true;
753
+ if (!rel.endsWith("/")) rel += "/";
689
754
  return !ig.ignores(rel);
690
755
  });
691
756
  return { files, dirs: filteredDirs };
@@ -750,7 +815,8 @@ function getElapsedTime(startTime) {
750
815
  return ((Date.now() - startTime) / 1e3).toFixed(2);
751
816
  }
752
817
  function getScoreBar(val) {
753
- return "\u2588".repeat(Math.round(val / 10)).padEnd(10, "\u2591");
818
+ const clamped = Math.max(0, Math.min(100, val));
819
+ return "\u2588".repeat(Math.round(clamped / 10)).padEnd(10, "\u2591");
754
820
  }
755
821
  function getSafetyIcon(rating) {
756
822
  switch (rating) {
@@ -1011,7 +1077,7 @@ var TypeScriptParser = class {
1011
1077
  extractFromDeclaration(declaration, importedNames, code, parentNode) {
1012
1078
  const exports2 = [];
1013
1079
  const metadata = this.analyzeMetadata(parentNode || declaration, code);
1014
- if (declaration.type === "FunctionDeclaration" && declaration.id) {
1080
+ if ((declaration.type === "FunctionDeclaration" || declaration.type === "TSDeclareFunction") && declaration.id) {
1015
1081
  exports2.push({
1016
1082
  name: declaration.id.name,
1017
1083
  type: "function",
@@ -1039,11 +1105,21 @@ var TypeScriptParser = class {
1039
1105
  const body = declaration.body.body;
1040
1106
  const methods = body.filter((m) => m.type === "MethodDefinition");
1041
1107
  const properties = body.filter((m) => m.type === "PropertyDefinition");
1108
+ const constructor = methods.find(
1109
+ (m) => m.kind === "constructor"
1110
+ );
1111
+ const parameters = constructor ? constructor.value.params.map((p) => {
1112
+ if (p.type === "Identifier") return p.name;
1113
+ if (p.type === "TSParameterProperty" && p.parameter.type === "Identifier")
1114
+ return p.parameter.name;
1115
+ return "unknown";
1116
+ }) : [];
1042
1117
  exports2.push({
1043
1118
  name: declaration.id.name,
1044
1119
  type: "class",
1045
1120
  methodCount: methods.length,
1046
1121
  propertyCount: properties.length,
1122
+ parameters,
1047
1123
  loc: declaration.loc ? {
1048
1124
  start: {
1049
1125
  line: declaration.loc.start.line,
@@ -1119,10 +1195,95 @@ var TypeScriptParser = class {
1119
1195
  }
1120
1196
  };
1121
1197
 
1122
- // src/parsers/python-parser.ts
1198
+ // src/parsers/tree-sitter-utils.ts
1123
1199
  var Parser = __toESM(require("web-tree-sitter"));
1124
1200
  var path = __toESM(require("path"));
1125
1201
  var fs = __toESM(require("fs"));
1202
+ var isTreeSitterInitialized = false;
1203
+ async function initTreeSitter() {
1204
+ if (isTreeSitterInitialized) return;
1205
+ try {
1206
+ const wasmPath = getWasmPath("web-tree-sitter");
1207
+ await Parser.Parser.init({
1208
+ locateFile() {
1209
+ return wasmPath || "web-tree-sitter.wasm";
1210
+ }
1211
+ });
1212
+ isTreeSitterInitialized = true;
1213
+ } catch (error) {
1214
+ console.error("Failed to initialize web-tree-sitter:", error);
1215
+ isTreeSitterInitialized = true;
1216
+ }
1217
+ }
1218
+ function findInPnpmStore(startDir, fileName, depth = 0) {
1219
+ if (depth > 8) return null;
1220
+ const pnpmDir = path.join(startDir, "node_modules", ".pnpm");
1221
+ if (fs.existsSync(pnpmDir)) {
1222
+ return findFileRecursively(pnpmDir, fileName, 0);
1223
+ }
1224
+ const parent = path.dirname(startDir);
1225
+ if (parent === startDir) return null;
1226
+ return findInPnpmStore(parent, fileName, depth + 1);
1227
+ }
1228
+ function findFileRecursively(dir, fileName, depth) {
1229
+ if (depth > 6) return null;
1230
+ try {
1231
+ const entries = fs.readdirSync(dir, { withFileTypes: true });
1232
+ for (const entry of entries) {
1233
+ if (entry.isFile() && entry.name === fileName) {
1234
+ return path.join(dir, entry.name);
1235
+ }
1236
+ }
1237
+ for (const entry of entries) {
1238
+ if (entry.isDirectory()) {
1239
+ const found = findFileRecursively(
1240
+ path.join(dir, entry.name),
1241
+ fileName,
1242
+ depth + 1
1243
+ );
1244
+ if (found) return found;
1245
+ }
1246
+ }
1247
+ } catch (err) {
1248
+ }
1249
+ return null;
1250
+ }
1251
+ function getWasmPath(language) {
1252
+ const wasmFileName = language === "web-tree-sitter" ? "web-tree-sitter.wasm" : `tree-sitter-${language}.wasm`;
1253
+ const immediatePaths = [
1254
+ path.join(process.cwd(), wasmFileName),
1255
+ path.join(__dirname, wasmFileName),
1256
+ path.join(__dirname, "assets", wasmFileName)
1257
+ ];
1258
+ for (const p of immediatePaths) {
1259
+ if (fs.existsSync(p)) return p;
1260
+ }
1261
+ const pnpmPath = findInPnpmStore(__dirname, wasmFileName);
1262
+ if (pnpmPath) return pnpmPath;
1263
+ const pnpmPathCwd = findInPnpmStore(process.cwd(), wasmFileName);
1264
+ if (pnpmPathCwd) return pnpmPathCwd;
1265
+ console.warn(
1266
+ `[Parser] WASM file for ${language} not found. CWD: ${process.cwd()}, DIR: ${__dirname}`
1267
+ );
1268
+ return null;
1269
+ }
1270
+ async function setupParser(language) {
1271
+ await initTreeSitter();
1272
+ const wasmPath = getWasmPath(language);
1273
+ if (!wasmPath) {
1274
+ return null;
1275
+ }
1276
+ try {
1277
+ const parser = new Parser.Parser();
1278
+ const Lang = await Parser.Language.load(wasmPath);
1279
+ parser.setLanguage(Lang);
1280
+ return parser;
1281
+ } catch (error) {
1282
+ return null;
1283
+ }
1284
+ }
1285
+
1286
+ // src/parsers/python-parser.ts
1126
1287
  var PythonParser = class {
1127
1288
  constructor() {
1128
1289
  this.language = "python" /* Python */;
@@ -1135,47 +1296,8 @@ var PythonParser = class {
1135
1296
  */
1136
1297
  async initialize() {
1137
1298
  if (this.initialized) return;
1138
- try {
1139
- await Parser.Parser.init();
1140
- this.parser = new Parser.Parser();
1141
- const possiblePaths = [
1142
- path.join(
1143
- process.cwd(),
1144
- "node_modules/@unit-mesh/treesitter-artifacts/wasm/tree-sitter-python.wasm"
1145
- ),
1146
- path.join(
1147
- __dirname,
1148
- "../../node_modules/@unit-mesh/treesitter-artifacts/wasm/tree-sitter-python.wasm"
1149
- ),
1150
- path.join(
1151
- __dirname,
1152
- "../../../node_modules/@unit-mesh/treesitter-artifacts/wasm/tree-sitter-python.wasm"
1153
- ),
1154
- path.join(
1155
- __dirname,
1156
- "../../../../node_modules/@unit-mesh/treesitter-artifacts/wasm/tree-sitter-python.wasm"
1157
- ),
1158
- path.join(
1159
- process.cwd(),
1160
- "node_modules/tree-sitter-wasms/out/tree-sitter-python.wasm"
1161
- ),
1162
- path.join(__dirname, "../assets/tree-sitter-python.wasm")
1163
- ];
1164
- let wasmPath = "";
1165
- for (const p of possiblePaths) {
1166
- if (fs.existsSync(p)) {
1167
- wasmPath = p;
1168
- break;
1169
- }
1170
- }
1171
- if (!wasmPath) {
1172
- return;
1173
- }
1174
- const Python = await Parser.Language.load(wasmPath);
1175
- this.parser.setLanguage(Python);
1176
- this.initialized = true;
1177
- } catch (error) {
1178
- }
1299
+ this.parser = await setupParser("python");
1300
+ this.initialized = true;
1179
1301
  }
1180
1302
  async getAST(code, filePath) {
1181
1303
  if (!this.initialized) await this.initialize();
@@ -1564,9 +1686,6 @@ var PythonParser = class {
1564
1686
  };
1565
1687
 
1566
1688
  // src/parsers/java-parser.ts
1567
- var Parser3 = __toESM(require("web-tree-sitter"));
1568
- var path2 = __toESM(require("path"));
1569
- var fs2 = __toESM(require("fs"));
1570
1689
  var JavaParser = class {
1571
1690
  constructor() {
1572
1691
  this.language = "java" /* Java */;
@@ -1579,55 +1698,8 @@ var JavaParser = class {
1579
1698
  */
1580
1699
  async initialize() {
1581
1700
  if (this.initialized) return;
1582
- try {
1583
- if (typeof Parser3.Parser.init === "function") {
1584
- await Parser3.Parser.init();
1585
- }
1586
- this.parser = new Parser3.Parser();
1587
- const possiblePaths = [
1588
- path2.join(
1589
- process.cwd(),
1590
- "node_modules/@unit-mesh/treesitter-artifacts/wasm/tree-sitter-java.wasm"
1591
- ),
1592
- path2.join(
1593
- __dirname,
1594
- "../../node_modules/@unit-mesh/treesitter-artifacts/wasm/tree-sitter-java.wasm"
1595
- ),
1596
- path2.join(
1597
- __dirname,
1598
- "../../../node_modules/@unit-mesh/treesitter-artifacts/wasm/tree-sitter-java.wasm"
1599
- ),
1600
- path2.join(
1601
- __dirname,
1602
- "../../../../node_modules/@unit-mesh/treesitter-artifacts/wasm/tree-sitter-java.wasm"
1603
- ),
1604
- path2.join(
1605
- process.cwd(),
1606
- "node_modules/tree-sitter-wasms/out/tree-sitter-java.wasm"
1607
- )
1608
- ];
1609
- let wasmPath = "";
1610
- for (const p of possiblePaths) {
1611
- if (fs2.existsSync(p)) {
1612
- wasmPath = p;
1613
- break;
1614
- }
1615
- }
1616
- if (!wasmPath) {
1617
- console.warn(
1618
- `Java WASM not found. Tried paths: ${possiblePaths.join(", ")}`
1619
- );
1620
- return;
1621
- }
1622
- const Java = await Parser3.Language.load(wasmPath);
1623
- this.parser.setLanguage(Java);
1624
- this.initialized = true;
1625
- } catch (error) {
1626
- console.error("Failed to initialize tree-sitter-java:", error);
1627
- if (error instanceof Error && error.stack) {
1628
- console.error(error.stack);
1629
- }
1630
- }
1701
+ this.parser = await setupParser("java");
1702
+ this.initialized = true;
1631
1703
  }
1632
1704
  async getAST(code, filePath) {
1633
1705
  if (!this.initialized) await this.initialize();
@@ -1897,9 +1969,6 @@ var JavaParser = class {
1897
1969
  };
1898
1970
 
1899
1971
  // src/parsers/csharp-parser.ts
1900
- var Parser5 = __toESM(require("web-tree-sitter"));
1901
- var path3 = __toESM(require("path"));
1902
- var fs3 = __toESM(require("fs"));
1903
1972
  var CSharpParser = class {
1904
1973
  constructor() {
1905
1974
  this.language = "csharp" /* CSharp */;
@@ -1912,48 +1981,8 @@ var CSharpParser = class {
1912
1981
  */
1913
1982
  async initialize() {
1914
1983
  if (this.initialized) return;
1915
- try {
1916
- if (typeof Parser5.Parser.init === "function") {
1917
- await Parser5.Parser.init();
1918
- }
1919
- this.parser = new Parser5.Parser();
1920
- const possiblePaths = [
1921
- path3.join(
1922
- process.cwd(),
1923
- "node_modules/@unit-mesh/treesitter-artifacts/wasm/tree-sitter-c_sharp.wasm"
1924
- ),
1925
- path3.join(
1926
- __dirname,
1927
- "../../node_modules/@unit-mesh/treesitter-artifacts/wasm/tree-sitter-c_sharp.wasm"
1928
- ),
1929
- path3.join(
1930
- __dirname,
1931
- "../../../node_modules/@unit-mesh/treesitter-artifacts/wasm/tree-sitter-c_sharp.wasm"
1932
- ),
1933
- path3.join(
1934
- __dirname,
1935
- "../../../../node_modules/@unit-mesh/treesitter-artifacts/wasm/tree-sitter-c_sharp.wasm"
1936
- )
1937
- ];
1938
- let wasmPath = "";
1939
- for (const p of possiblePaths) {
1940
- if (fs3.existsSync(p)) {
1941
- wasmPath = p;
1942
- break;
1943
- }
1944
- }
1945
- if (!wasmPath) {
1946
- console.warn(
1947
- `C# WASM not found. Tried paths: ${possiblePaths.join(", ")}`
1948
- );
1949
- return;
1950
- }
1951
- const CSharp = await Parser5.Language.load(wasmPath);
1952
- this.parser.setLanguage(CSharp);
1953
- this.initialized = true;
1954
- } catch (error) {
1955
- console.error("Failed to initialize tree-sitter-c-sharp:", error);
1956
- }
1984
+ this.parser = await setupParser("c_sharp");
1985
+ this.initialized = true;
1957
1986
  }
1958
1987
  async getAST(code, filePath) {
1959
1988
  if (!this.initialized) await this.initialize();
@@ -2234,9 +2263,6 @@ var CSharpParser = class {
2234
2263
  };
2235
2264
 
2236
2265
  // src/parsers/go-parser.ts
2237
- var Parser7 = __toESM(require("web-tree-sitter"));
2238
- var path4 = __toESM(require("path"));
2239
- var fs4 = __toESM(require("fs"));
2240
2266
  var GoParser = class {
2241
2267
  constructor() {
2242
2268
  this.language = "go" /* Go */;
@@ -2249,48 +2275,8 @@ var GoParser = class {
2249
2275
  */
2250
2276
  async initialize() {
2251
2277
  if (this.initialized) return;
2252
- try {
2253
- if (typeof Parser7.Parser.init === "function") {
2254
- await Parser7.Parser.init();
2255
- }
2256
- this.parser = new Parser7.Parser();
2257
- const possiblePaths = [
2258
- path4.join(
2259
- process.cwd(),
2260
- "node_modules/@unit-mesh/treesitter-artifacts/wasm/tree-sitter-go.wasm"
2261
- ),
2262
- path4.join(
2263
- __dirname,
2264
- "../../node_modules/@unit-mesh/treesitter-artifacts/wasm/tree-sitter-go.wasm"
2265
- ),
2266
- path4.join(
2267
- __dirname,
2268
- "../../../node_modules/@unit-mesh/treesitter-artifacts/wasm/tree-sitter-go.wasm"
2269
- ),
2270
- path4.join(
2271
- __dirname,
2272
- "../../../../node_modules/@unit-mesh/treesitter-artifacts/wasm/tree-sitter-go.wasm"
2273
- )
2274
- ];
2275
- let wasmPath = "";
2276
- for (const p of possiblePaths) {
2277
- if (fs4.existsSync(p)) {
2278
- wasmPath = p;
2279
- break;
2280
- }
2281
- }
2282
- if (!wasmPath) {
2283
- console.warn(
2284
- `Go WASM not found. Tried paths: ${possiblePaths.join(", ")}`
2285
- );
2286
- return;
2287
- }
2288
- const Go = await Parser7.Language.load(wasmPath);
2289
- this.parser.setLanguage(Go);
2290
- this.initialized = true;
2291
- } catch (error) {
2292
- console.error("Failed to initialize tree-sitter-go:", error);
2293
- }
2278
+ this.parser = await setupParser("go");
2279
+ this.initialized = true;
2294
2280
  }
2295
2281
  async getAST(code, filePath) {
2296
2282
  if (!this.initialized) await this.initialize();
@@ -2580,6 +2566,9 @@ var GoParser = class {
2580
2566
 
2581
2567
  // src/parsers/parser-factory.ts
2582
2568
  var ParserFactory = class _ParserFactory {
2569
+ /**
2570
+ * Create a new ParserFactory instance
2571
+ */
2583
2572
  constructor() {
2584
2573
  this.parsers = /* @__PURE__ */ new Map();
2585
2574
  this.extensionMap = new Map(
@@ -2592,7 +2581,9 @@ var ParserFactory = class _ParserFactory {
2592
2581
  this.registerParser(new GoParser());
2593
2582
  }
2594
2583
  /**
2595
- * Get singleton instance
2584
+ * Get the global singleton instance
2585
+ *
2586
+ * @returns The singleton ParserFactory instance
2596
2587
  */
2597
2588
  static getInstance() {
2598
2589
  if (!_ParserFactory.instance) {
@@ -3139,6 +3130,20 @@ function generateHTML(graph) {
3139
3130
  }
3140
3131
 
3141
3132
  // src/scoring.ts
3133
+ var RecommendationPriority = /* @__PURE__ */ ((RecommendationPriority2) => {
3134
+ RecommendationPriority2["High"] = "high";
3135
+ RecommendationPriority2["Medium"] = "medium";
3136
+ RecommendationPriority2["Low"] = "low";
3137
+ return RecommendationPriority2;
3138
+ })(RecommendationPriority || {});
3139
+ var ReadinessRating = /* @__PURE__ */ ((ReadinessRating2) => {
3140
+ ReadinessRating2["Excellent"] = "Excellent";
3141
+ ReadinessRating2["Good"] = "Good";
3142
+ ReadinessRating2["Fair"] = "Fair";
3143
+ ReadinessRating2["NeedsWork"] = "Needs Work";
3144
+ ReadinessRating2["Critical"] = "Critical";
3145
+ return ReadinessRating2;
3146
+ })(ReadinessRating || {});
3142
3147
  var DEFAULT_TOOL_WEIGHTS = {
3143
3148
  ["pattern-detect" /* PatternDetect */]: 22,
3144
3149
  ["context-analyzer" /* ContextAnalyzer */]: 19,
@@ -3213,10 +3218,10 @@ function parseWeightString(weightStr) {
3213
3218
  if (!weightStr) return weights;
3214
3219
  const pairs = weightStr.split(",");
3215
3220
  for (const pair of pairs) {
3216
- const [toolShortName, weightStr2] = pair.split(":");
3217
- if (toolShortName && weightStr2) {
3221
+ const [toolShortName, weightValueStr] = pair.split(":");
3222
+ if (toolShortName && weightValueStr) {
3218
3223
  const toolName = normalizeToolName(toolShortName.trim());
3219
- const weight = parseInt(weightStr2.trim(), 10);
3224
+ const weight = parseInt(weightValueStr.trim(), 10);
3220
3225
  if (!isNaN(weight) && weight > 0) {
3221
3226
  weights.set(toolName, weight);
3222
3227
  }
@@ -3271,11 +3276,11 @@ function calculateOverallScore(toolOutputs, config, cliWeights) {
3271
3276
  };
3272
3277
  }
3273
3278
  function getRating(score) {
3274
- if (score >= 90) return "Excellent";
3275
- if (score >= 75) return "Good";
3276
- if (score >= 60) return "Fair";
3277
- if (score >= 40) return "Needs Work";
3278
- return "Critical";
3279
+ if (score >= 90) return "Excellent" /* Excellent */;
3280
+ if (score >= 75) return "Good" /* Good */;
3281
+ if (score >= 60) return "Fair" /* Fair */;
3282
+ if (score >= 40) return "Needs Work" /* NeedsWork */;
3283
+ return "Critical" /* Critical */;
3279
3284
  }
3280
3285
  function getRatingWithContext(score, fileCount, modelTier = "standard") {
3281
3286
  const threshold = getRecommendedThreshold(fileCount, modelTier);
@@ -3284,16 +3289,18 @@ function getRatingWithContext(score, fileCount, modelTier = "standard") {
3284
3289
  }
3285
3290
  function getRatingDisplay(rating) {
3286
3291
  switch (rating) {
3287
- case "Excellent":
3292
+ case "Excellent" /* Excellent */:
3288
3293
  return { emoji: "\u2705", color: "green" };
3289
- case "Good":
3294
+ case "Good" /* Good */:
3290
3295
  return { emoji: "\u{1F44D}", color: "blue" };
3291
- case "Fair":
3296
+ case "Fair" /* Fair */:
3292
3297
  return { emoji: "\u26A0\uFE0F", color: "yellow" };
3293
- case "Needs Work":
3298
+ case "Needs Work" /* NeedsWork */:
3294
3299
  return { emoji: "\u{1F528}", color: "orange" };
3295
- case "Critical":
3300
+ case "Critical" /* Critical */:
3296
3301
  return { emoji: "\u274C", color: "red" };
3302
+ default:
3303
+ return { emoji: "\u2753", color: "gray" };
3297
3304
  }
3298
3305
  }
3299
3306
  function formatScore(result) {
@@ -3318,7 +3325,12 @@ function formatToolScore(output) {
3318
3325
  result += ` Recommendations:
3319
3326
  `;
3320
3327
  output.recommendations.forEach((rec, i) => {
3321
- const priorityIcon = rec.priority === "high" ? "\u{1F534}" : rec.priority === "medium" ? "\u{1F7E1}" : "\u{1F535}";
3328
+ let priorityIcon = "\u{1F535}";
3329
+ const prio = rec.priority;
3330
+ if (prio === "high" /* High */ || prio === "high")
3331
+ priorityIcon = "\u{1F534}";
3332
+ else if (prio === "medium" /* Medium */ || prio === "medium")
3333
+ priorityIcon = "\u{1F7E1}";
3322
3334
  result += ` ${i + 1}. ${priorityIcon} ${rec.action}
3323
3335
  `;
3324
3336
  result += ` Impact: +${rec.estimatedImpact} points
@@ -3400,15 +3412,17 @@ var DEFAULT_COST_CONFIG = {
3400
3412
  daysPerMonth: 30
3401
3413
  };
3402
3414
  function calculateMonthlyCost(tokenWaste, config = {}) {
3415
+ const multiplier = tokenWaste > 5e4 ? 5 : tokenWaste > 1e4 ? 3.5 : 2.5;
3403
3416
  const budget = calculateTokenBudget({
3404
- totalContextTokens: tokenWaste * 2.5,
3417
+ totalContextTokens: tokenWaste * multiplier,
3405
3418
  wastedTokens: {
3406
3419
  duplication: tokenWaste * 0.7,
3407
3420
  fragmentation: tokenWaste * 0.3,
3408
- chattiness: 0
3421
+ chattiness: 0.1 * tokenWaste
3422
+ // Added baseline chattiness
3409
3423
  }
3410
3424
  });
3411
- const preset = getModelPreset("claude-4.6");
3425
+ const preset = getModelPreset("claude-3.5-sonnet");
3412
3426
  return estimateCostFromBudget(budget, preset, config);
3413
3427
  }
3414
3428
  function calculateTokenBudget(params) {
@@ -3890,7 +3904,7 @@ function calculatePatternEntropy(files) {
3890
3904
  }
3891
3905
  const dirGroups = /* @__PURE__ */ new Map();
3892
3906
  for (const file of files) {
3893
- const parts = file.path.split("/").slice(0, 4).join("/") || "root";
3907
+ const parts = file.path.split("/").slice(0, -1).join("/") || "root";
3894
3908
  dirGroups.set(parts, (dirGroups.get(parts) || 0) + 1);
3895
3909
  }
3896
3910
  const counts = Array.from(dirGroups.values());
@@ -4746,6 +4760,8 @@ function getRepoMetadata(directory) {
4746
4760
  ParseError,
4747
4761
  ParserFactory,
4748
4762
  PythonParser,
4763
+ ReadinessRating,
4764
+ RecommendationPriority,
4749
4765
  SEVERITY_TIME_ESTIMATES,
4750
4766
  SIZE_ADJUSTED_THRESHOLDS,
4751
4767
  Severity,
@@ -4813,8 +4829,10 @@ function getRepoMetadata(directory) {
4813
4829
  getSeverityColor,
4814
4830
  getSupportedLanguages,
4815
4831
  getToolWeight,
4832
+ getWasmPath,
4816
4833
  handleCLIError,
4817
4834
  handleJSONOutput,
4835
+ initTreeSitter,
4818
4836
  initializeParsers,
4819
4837
  isFileSupported,
4820
4838
  isSourceFile,
@@ -4832,6 +4850,7 @@ function getRepoMetadata(directory) {
4832
4850
  saveScoreEntry,
4833
4851
  scanEntries,
4834
4852
  scanFiles,
4853
+ setupParser,
4835
4854
  validateSpokeOutput,
4836
4855
  validateWithSchema
4837
4856
  });