@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.mjs CHANGED
@@ -18,6 +18,8 @@ import {
18
18
  ModelTier,
19
19
  ModelTierSchema,
20
20
  ParseError,
21
+ ReadinessRating,
22
+ RecommendationPriority,
21
23
  SIZE_ADJUSTED_THRESHOLDS,
22
24
  Severity,
23
25
  SeveritySchema,
@@ -39,7 +41,7 @@ import {
39
41
  getToolWeight,
40
42
  normalizeToolName,
41
43
  parseWeightString
42
- } from "./chunk-COHIBX3Q.mjs";
44
+ } from "./chunk-SWTDBVYJ.mjs";
43
45
 
44
46
  // src/types/contract.ts
45
47
  function validateSpokeOutput(toolName, output) {
@@ -100,51 +102,61 @@ function validateWithSchema(schema, data) {
100
102
  }
101
103
 
102
104
  // src/registry.ts
103
- var ToolRegistry = class {
104
- static getProviders() {
105
- const g = globalThis;
106
- if (!g.__AIRE_TOOL_REGISTRY__) {
107
- g.__AIRE_TOOL_REGISTRY__ = /* @__PURE__ */ new Map();
108
- }
109
- return g.__AIRE_TOOL_REGISTRY__;
105
+ var ToolRegistry = class _ToolRegistry {
106
+ /**
107
+ * Create a new ToolRegistry instance
108
+ *
109
+ * @param id Optional identifier for the registry (e.g. for debugging)
110
+ */
111
+ constructor(id = "default") {
112
+ this.providers = /* @__PURE__ */ new Map();
113
+ this.id = `registry-${id}-${Math.random().toString(36).substring(2, 9)}`;
110
114
  }
111
115
  /**
112
116
  * Register a new tool provider.
117
+ *
118
+ * @param provider The tool provider to register
113
119
  */
114
- static register(provider) {
115
- console.log(
116
- `[ToolRegistry#${this.instanceId}] Registering tool: ${provider.id} (${provider.alias.join(", ")})`
117
- );
118
- this.getProviders().set(provider.id, provider);
120
+ register(provider) {
121
+ this.providers.set(provider.id, provider);
119
122
  }
120
123
  /**
121
124
  * Get a provider by its canonical ID.
125
+ *
126
+ * @param id The tool ID
127
+ * @returns The provider if found
122
128
  */
123
- static get(id) {
124
- return this.getProviders().get(id);
129
+ get(id) {
130
+ return this.providers.get(id);
125
131
  }
126
132
  /**
127
133
  * Get a provider by name or alias.
134
+ *
135
+ * @param nameOrAlias The tool name or alias string
136
+ * @returns The provider if found
128
137
  */
129
- static find(nameOrAlias) {
130
- const providers = this.getProviders();
131
- const exact = providers.get(nameOrAlias);
138
+ find(nameOrAlias) {
139
+ const exact = this.providers.get(nameOrAlias);
132
140
  if (exact) return exact;
133
- for (const p of providers.values()) {
141
+ for (const p of this.providers.values()) {
134
142
  if (p.alias.includes(nameOrAlias)) return p;
135
143
  }
136
144
  return void 0;
137
145
  }
138
146
  /**
139
147
  * Get all registered tool providers.
148
+ *
149
+ * @returns Array of all registered tool providers
140
150
  */
141
- static getAll() {
142
- return Array.from(this.getProviders().values());
151
+ getAll() {
152
+ return Array.from(this.providers.values());
143
153
  }
144
154
  /**
145
155
  * Get all available tool IDs from the ToolName enum.
156
+ *
157
+ * @returns Array of valid ToolName identifiers
146
158
  */
147
- static getAvailableIds() {
159
+ getAvailableIds() {
148
160
  return Object.values(ToolName).filter(
149
161
  (v) => typeof v === "string"
150
162
  );
@@ -152,11 +164,54 @@ var ToolRegistry = class {
152
164
  /**
153
165
  * Clear the registry (primarily for testing).
154
166
  */
167
+ clear() {
168
+ this.providers.clear();
169
+ }
170
+ // --- Static Compatibility Layer ---
171
+ static getGlobalRegistry() {
172
+ const g = globalThis;
173
+ if (!g.__AIRE_TOOL_REGISTRY_INSTANCE__) {
174
+ g.__AIRE_TOOL_REGISTRY_INSTANCE__ = new _ToolRegistry("global");
175
+ }
176
+ return g.__AIRE_TOOL_REGISTRY_INSTANCE__;
177
+ }
178
+ /**
179
+ * Static register (Singleton compatibility)
180
+ */
181
+ static register(provider) {
182
+ this.getGlobalRegistry().register(provider);
183
+ }
184
+ /**
185
+ * Static get (Singleton compatibility)
186
+ */
187
+ static get(id) {
188
+ return this.getGlobalRegistry().get(id);
189
+ }
190
+ /**
191
+ * Static find (Singleton compatibility)
192
+ */
193
+ static find(nameOrAlias) {
194
+ return this.getGlobalRegistry().find(nameOrAlias);
195
+ }
196
+ /**
197
+ * Static getAll (Singleton compatibility)
198
+ */
199
+ static getAll() {
200
+ return this.getGlobalRegistry().getAll();
201
+ }
202
+ /**
203
+ * Static getAvailableIds (Singleton compatibility)
204
+ */
205
+ static getAvailableIds() {
206
+ return this.getGlobalRegistry().getAvailableIds();
207
+ }
208
+ /**
209
+ * Static clear (Singleton compatibility)
210
+ */
155
211
  static clear() {
156
- this.getProviders().clear();
212
+ this.getGlobalRegistry().clear();
157
213
  }
158
214
  };
159
- ToolRegistry.instanceId = globalThis.Math.random();
160
215
 
161
216
  // src/utils/file-scanner.ts
162
217
  import { glob } from "glob";
@@ -268,7 +323,8 @@ async function scanFiles(options) {
268
323
  });
269
324
  const gitignoreFiles = await glob("**/.gitignore", {
270
325
  cwd: rootDir,
271
- ignore: finalExclude,
326
+ ignore: (exclude || []).concat(["**/node_modules/**", "**/.git/**"]),
327
+ // Minimal ignore for gitignore discovery
272
328
  absolute: true
273
329
  });
274
330
  if (gitignoreFiles.length > 0) {
@@ -335,7 +391,7 @@ async function scanEntries(options) {
335
391
  });
336
392
  const gitignoreFiles = await glob("**/.gitignore", {
337
393
  cwd: rootDir,
338
- ignore: finalExclude,
394
+ ignore: (exclude || []).concat(["**/node_modules/**", "**/.git/**"]),
339
395
  absolute: true
340
396
  });
341
397
  if (gitignoreFiles.length > 0) {
@@ -359,8 +415,9 @@ async function scanEntries(options) {
359
415
  }
360
416
  }
361
417
  const filteredDirs = dirs.filter((d) => {
362
- const rel = relative(rootDir || ".", d).replace(/\\/g, "/").replace(/\/$/, "");
418
+ let rel = relative(rootDir || ".", d).replace(/\\/g, "/");
363
419
  if (rel === "") return true;
420
+ if (!rel.endsWith("/")) rel += "/";
364
421
  return !ig.ignores(rel);
365
422
  });
366
423
  return { files, dirs: filteredDirs };
@@ -425,7 +482,8 @@ function getElapsedTime(startTime) {
425
482
  return ((Date.now() - startTime) / 1e3).toFixed(2);
426
483
  }
427
484
  function getScoreBar(val) {
428
- return "\u2588".repeat(Math.round(val / 10)).padEnd(10, "\u2591");
485
+ const clamped = Math.max(0, Math.min(100, val));
486
+ return "\u2588".repeat(Math.round(clamped / 10)).padEnd(10, "\u2591");
429
487
  }
430
488
  function getSafetyIcon(rating) {
431
489
  switch (rating) {
@@ -686,7 +744,7 @@ var TypeScriptParser = class {
686
744
  extractFromDeclaration(declaration, importedNames, code, parentNode) {
687
745
  const exports = [];
688
746
  const metadata = this.analyzeMetadata(parentNode || declaration, code);
689
- if (declaration.type === "FunctionDeclaration" && declaration.id) {
747
+ if ((declaration.type === "FunctionDeclaration" || declaration.type === "TSDeclareFunction") && declaration.id) {
690
748
  exports.push({
691
749
  name: declaration.id.name,
692
750
  type: "function",
@@ -714,11 +772,21 @@ var TypeScriptParser = class {
714
772
  const body = declaration.body.body;
715
773
  const methods = body.filter((m) => m.type === "MethodDefinition");
716
774
  const properties = body.filter((m) => m.type === "PropertyDefinition");
775
+ const constructor = methods.find(
776
+ (m) => m.kind === "constructor"
777
+ );
778
+ const parameters = constructor ? constructor.value.params.map((p) => {
779
+ if (p.type === "Identifier") return p.name;
780
+ if (p.type === "TSParameterProperty" && p.parameter.type === "Identifier")
781
+ return p.parameter.name;
782
+ return "unknown";
783
+ }) : [];
717
784
  exports.push({
718
785
  name: declaration.id.name,
719
786
  type: "class",
720
787
  methodCount: methods.length,
721
788
  propertyCount: properties.length,
789
+ parameters,
722
790
  loc: declaration.loc ? {
723
791
  start: {
724
792
  line: declaration.loc.start.line,
@@ -794,10 +862,95 @@ var TypeScriptParser = class {
794
862
  }
795
863
  };
796
864
 
797
- // src/parsers/python-parser.ts
865
+ // src/parsers/tree-sitter-utils.ts
798
866
  import * as Parser from "web-tree-sitter";
799
867
  import * as path from "path";
800
868
  import * as fs from "fs";
869
+ var isTreeSitterInitialized = false;
870
+ async function initTreeSitter() {
871
+ if (isTreeSitterInitialized) return;
872
+ try {
873
+ const wasmPath = getWasmPath("web-tree-sitter");
874
+ await Parser.Parser.init({
875
+ locateFile() {
876
+ return wasmPath || "web-tree-sitter.wasm";
877
+ }
878
+ });
879
+ isTreeSitterInitialized = true;
880
+ } catch (error) {
881
+ console.error("Failed to initialize web-tree-sitter:", error);
882
+ isTreeSitterInitialized = true;
883
+ }
884
+ }
885
+ function findInPnpmStore(startDir, fileName, depth = 0) {
886
+ if (depth > 8) return null;
887
+ const pnpmDir = path.join(startDir, "node_modules", ".pnpm");
888
+ if (fs.existsSync(pnpmDir)) {
889
+ return findFileRecursively(pnpmDir, fileName, 0);
890
+ }
891
+ const parent = path.dirname(startDir);
892
+ if (parent === startDir) return null;
893
+ return findInPnpmStore(parent, fileName, depth + 1);
894
+ }
895
+ function findFileRecursively(dir, fileName, depth) {
896
+ if (depth > 6) return null;
897
+ try {
898
+ const entries = fs.readdirSync(dir, { withFileTypes: true });
899
+ for (const entry of entries) {
900
+ if (entry.isFile() && entry.name === fileName) {
901
+ return path.join(dir, entry.name);
902
+ }
903
+ }
904
+ for (const entry of entries) {
905
+ if (entry.isDirectory()) {
906
+ const found = findFileRecursively(
907
+ path.join(dir, entry.name),
908
+ fileName,
909
+ depth + 1
910
+ );
911
+ if (found) return found;
912
+ }
913
+ }
914
+ } catch (err) {
915
+ }
916
+ return null;
917
+ }
918
+ function getWasmPath(language) {
919
+ const wasmFileName = language === "web-tree-sitter" ? "web-tree-sitter.wasm" : `tree-sitter-${language}.wasm`;
920
+ const immediatePaths = [
921
+ path.join(process.cwd(), wasmFileName),
922
+ path.join(__dirname, wasmFileName),
923
+ path.join(__dirname, "assets", wasmFileName)
924
+ ];
925
+ for (const p of immediatePaths) {
926
+ if (fs.existsSync(p)) return p;
927
+ }
928
+ const pnpmPath = findInPnpmStore(__dirname, wasmFileName);
929
+ if (pnpmPath) return pnpmPath;
930
+ const pnpmPathCwd = findInPnpmStore(process.cwd(), wasmFileName);
931
+ if (pnpmPathCwd) return pnpmPathCwd;
932
+ console.warn(
933
+ `[Parser] WASM file for ${language} not found. CWD: ${process.cwd()}, DIR: ${__dirname}`
934
+ );
935
+ return null;
936
+ }
937
+ async function setupParser(language) {
938
+ await initTreeSitter();
939
+ const wasmPath = getWasmPath(language);
940
+ if (!wasmPath) {
941
+ return null;
942
+ }
943
+ try {
944
+ const parser = new Parser.Parser();
945
+ const Lang = await Parser.Language.load(wasmPath);
946
+ parser.setLanguage(Lang);
947
+ return parser;
948
+ } catch (error) {
949
+ return null;
950
+ }
951
+ }
952
+
953
+ // src/parsers/python-parser.ts
801
954
  var PythonParser = class {
802
955
  constructor() {
803
956
  this.language = "python" /* Python */;
@@ -810,47 +963,8 @@ var PythonParser = class {
810
963
  */
811
964
  async initialize() {
812
965
  if (this.initialized) return;
813
- try {
814
- await Parser.Parser.init();
815
- this.parser = new Parser.Parser();
816
- const possiblePaths = [
817
- path.join(
818
- process.cwd(),
819
- "node_modules/@unit-mesh/treesitter-artifacts/wasm/tree-sitter-python.wasm"
820
- ),
821
- path.join(
822
- __dirname,
823
- "../../node_modules/@unit-mesh/treesitter-artifacts/wasm/tree-sitter-python.wasm"
824
- ),
825
- path.join(
826
- __dirname,
827
- "../../../node_modules/@unit-mesh/treesitter-artifacts/wasm/tree-sitter-python.wasm"
828
- ),
829
- path.join(
830
- __dirname,
831
- "../../../../node_modules/@unit-mesh/treesitter-artifacts/wasm/tree-sitter-python.wasm"
832
- ),
833
- path.join(
834
- process.cwd(),
835
- "node_modules/tree-sitter-wasms/out/tree-sitter-python.wasm"
836
- ),
837
- path.join(__dirname, "../assets/tree-sitter-python.wasm")
838
- ];
839
- let wasmPath = "";
840
- for (const p of possiblePaths) {
841
- if (fs.existsSync(p)) {
842
- wasmPath = p;
843
- break;
844
- }
845
- }
846
- if (!wasmPath) {
847
- return;
848
- }
849
- const Python = await Parser.Language.load(wasmPath);
850
- this.parser.setLanguage(Python);
851
- this.initialized = true;
852
- } catch (error) {
853
- }
966
+ this.parser = await setupParser("python");
967
+ this.initialized = true;
854
968
  }
855
969
  async getAST(code, filePath) {
856
970
  if (!this.initialized) await this.initialize();
@@ -1239,9 +1353,6 @@ var PythonParser = class {
1239
1353
  };
1240
1354
 
1241
1355
  // src/parsers/java-parser.ts
1242
- import * as Parser3 from "web-tree-sitter";
1243
- import * as path2 from "path";
1244
- import * as fs2 from "fs";
1245
1356
  var JavaParser = class {
1246
1357
  constructor() {
1247
1358
  this.language = "java" /* Java */;
@@ -1254,55 +1365,8 @@ var JavaParser = class {
1254
1365
  */
1255
1366
  async initialize() {
1256
1367
  if (this.initialized) return;
1257
- try {
1258
- if (typeof Parser3.Parser.init === "function") {
1259
- await Parser3.Parser.init();
1260
- }
1261
- this.parser = new Parser3.Parser();
1262
- const possiblePaths = [
1263
- path2.join(
1264
- process.cwd(),
1265
- "node_modules/@unit-mesh/treesitter-artifacts/wasm/tree-sitter-java.wasm"
1266
- ),
1267
- path2.join(
1268
- __dirname,
1269
- "../../node_modules/@unit-mesh/treesitter-artifacts/wasm/tree-sitter-java.wasm"
1270
- ),
1271
- path2.join(
1272
- __dirname,
1273
- "../../../node_modules/@unit-mesh/treesitter-artifacts/wasm/tree-sitter-java.wasm"
1274
- ),
1275
- path2.join(
1276
- __dirname,
1277
- "../../../../node_modules/@unit-mesh/treesitter-artifacts/wasm/tree-sitter-java.wasm"
1278
- ),
1279
- path2.join(
1280
- process.cwd(),
1281
- "node_modules/tree-sitter-wasms/out/tree-sitter-java.wasm"
1282
- )
1283
- ];
1284
- let wasmPath = "";
1285
- for (const p of possiblePaths) {
1286
- if (fs2.existsSync(p)) {
1287
- wasmPath = p;
1288
- break;
1289
- }
1290
- }
1291
- if (!wasmPath) {
1292
- console.warn(
1293
- `Java WASM not found. Tried paths: ${possiblePaths.join(", ")}`
1294
- );
1295
- return;
1296
- }
1297
- const Java = await Parser3.Language.load(wasmPath);
1298
- this.parser.setLanguage(Java);
1299
- this.initialized = true;
1300
- } catch (error) {
1301
- console.error("Failed to initialize tree-sitter-java:", error);
1302
- if (error instanceof Error && error.stack) {
1303
- console.error(error.stack);
1304
- }
1305
- }
1368
+ this.parser = await setupParser("java");
1369
+ this.initialized = true;
1306
1370
  }
1307
1371
  async getAST(code, filePath) {
1308
1372
  if (!this.initialized) await this.initialize();
@@ -1572,9 +1636,6 @@ var JavaParser = class {
1572
1636
  };
1573
1637
 
1574
1638
  // src/parsers/csharp-parser.ts
1575
- import * as Parser5 from "web-tree-sitter";
1576
- import * as path3 from "path";
1577
- import * as fs3 from "fs";
1578
1639
  var CSharpParser = class {
1579
1640
  constructor() {
1580
1641
  this.language = "csharp" /* CSharp */;
@@ -1587,48 +1648,8 @@ var CSharpParser = class {
1587
1648
  */
1588
1649
  async initialize() {
1589
1650
  if (this.initialized) return;
1590
- try {
1591
- if (typeof Parser5.Parser.init === "function") {
1592
- await Parser5.Parser.init();
1593
- }
1594
- this.parser = new Parser5.Parser();
1595
- const possiblePaths = [
1596
- path3.join(
1597
- process.cwd(),
1598
- "node_modules/@unit-mesh/treesitter-artifacts/wasm/tree-sitter-c_sharp.wasm"
1599
- ),
1600
- path3.join(
1601
- __dirname,
1602
- "../../node_modules/@unit-mesh/treesitter-artifacts/wasm/tree-sitter-c_sharp.wasm"
1603
- ),
1604
- path3.join(
1605
- __dirname,
1606
- "../../../node_modules/@unit-mesh/treesitter-artifacts/wasm/tree-sitter-c_sharp.wasm"
1607
- ),
1608
- path3.join(
1609
- __dirname,
1610
- "../../../../node_modules/@unit-mesh/treesitter-artifacts/wasm/tree-sitter-c_sharp.wasm"
1611
- )
1612
- ];
1613
- let wasmPath = "";
1614
- for (const p of possiblePaths) {
1615
- if (fs3.existsSync(p)) {
1616
- wasmPath = p;
1617
- break;
1618
- }
1619
- }
1620
- if (!wasmPath) {
1621
- console.warn(
1622
- `C# WASM not found. Tried paths: ${possiblePaths.join(", ")}`
1623
- );
1624
- return;
1625
- }
1626
- const CSharp = await Parser5.Language.load(wasmPath);
1627
- this.parser.setLanguage(CSharp);
1628
- this.initialized = true;
1629
- } catch (error) {
1630
- console.error("Failed to initialize tree-sitter-c-sharp:", error);
1631
- }
1651
+ this.parser = await setupParser("c_sharp");
1652
+ this.initialized = true;
1632
1653
  }
1633
1654
  async getAST(code, filePath) {
1634
1655
  if (!this.initialized) await this.initialize();
@@ -1909,9 +1930,6 @@ var CSharpParser = class {
1909
1930
  };
1910
1931
 
1911
1932
  // src/parsers/go-parser.ts
1912
- import * as Parser7 from "web-tree-sitter";
1913
- import * as path4 from "path";
1914
- import * as fs4 from "fs";
1915
1933
  var GoParser = class {
1916
1934
  constructor() {
1917
1935
  this.language = "go" /* Go */;
@@ -1924,48 +1942,8 @@ var GoParser = class {
1924
1942
  */
1925
1943
  async initialize() {
1926
1944
  if (this.initialized) return;
1927
- try {
1928
- if (typeof Parser7.Parser.init === "function") {
1929
- await Parser7.Parser.init();
1930
- }
1931
- this.parser = new Parser7.Parser();
1932
- const possiblePaths = [
1933
- path4.join(
1934
- process.cwd(),
1935
- "node_modules/@unit-mesh/treesitter-artifacts/wasm/tree-sitter-go.wasm"
1936
- ),
1937
- path4.join(
1938
- __dirname,
1939
- "../../node_modules/@unit-mesh/treesitter-artifacts/wasm/tree-sitter-go.wasm"
1940
- ),
1941
- path4.join(
1942
- __dirname,
1943
- "../../../node_modules/@unit-mesh/treesitter-artifacts/wasm/tree-sitter-go.wasm"
1944
- ),
1945
- path4.join(
1946
- __dirname,
1947
- "../../../../node_modules/@unit-mesh/treesitter-artifacts/wasm/tree-sitter-go.wasm"
1948
- )
1949
- ];
1950
- let wasmPath = "";
1951
- for (const p of possiblePaths) {
1952
- if (fs4.existsSync(p)) {
1953
- wasmPath = p;
1954
- break;
1955
- }
1956
- }
1957
- if (!wasmPath) {
1958
- console.warn(
1959
- `Go WASM not found. Tried paths: ${possiblePaths.join(", ")}`
1960
- );
1961
- return;
1962
- }
1963
- const Go = await Parser7.Language.load(wasmPath);
1964
- this.parser.setLanguage(Go);
1965
- this.initialized = true;
1966
- } catch (error) {
1967
- console.error("Failed to initialize tree-sitter-go:", error);
1968
- }
1945
+ this.parser = await setupParser("go");
1946
+ this.initialized = true;
1969
1947
  }
1970
1948
  async getAST(code, filePath) {
1971
1949
  if (!this.initialized) await this.initialize();
@@ -2255,6 +2233,9 @@ var GoParser = class {
2255
2233
 
2256
2234
  // src/parsers/parser-factory.ts
2257
2235
  var ParserFactory = class _ParserFactory {
2236
+ /**
2237
+ * Create a new ParserFactory instance
2238
+ */
2258
2239
  constructor() {
2259
2240
  this.parsers = /* @__PURE__ */ new Map();
2260
2241
  this.extensionMap = new Map(
@@ -2267,7 +2248,9 @@ var ParserFactory = class _ParserFactory {
2267
2248
  this.registerParser(new GoParser());
2268
2249
  }
2269
2250
  /**
2270
- * Get singleton instance
2251
+ * Get the global singleton instance
2252
+ *
2253
+ * @returns The singleton ParserFactory instance
2271
2254
  */
2272
2255
  static getInstance() {
2273
2256
  if (!_ParserFactory.instance) {
@@ -2569,8 +2552,8 @@ function estimateTokens(text) {
2569
2552
  }
2570
2553
 
2571
2554
  // src/utils/config.ts
2572
- import { readFileSync, existsSync as existsSync7 } from "fs";
2573
- import { join as join7, resolve, dirname as dirname3 } from "path";
2555
+ import { readFileSync, existsSync as existsSync4 } from "fs";
2556
+ import { join as join4, resolve, dirname as dirname4 } from "path";
2574
2557
  import { pathToFileURL } from "url";
2575
2558
  var CONFIG_FILES = [
2576
2559
  "aiready.json",
@@ -2584,8 +2567,8 @@ async function loadConfig(rootDir) {
2584
2567
  let currentDir = resolve(rootDir);
2585
2568
  while (true) {
2586
2569
  for (const configFile of CONFIG_FILES) {
2587
- const configPath = join7(currentDir, configFile);
2588
- if (existsSync7(configPath)) {
2570
+ const configPath = join4(currentDir, configFile);
2571
+ if (existsSync4(configPath)) {
2589
2572
  try {
2590
2573
  let config;
2591
2574
  if (configFile.endsWith(".js")) {
@@ -2613,7 +2596,7 @@ async function loadConfig(rootDir) {
2613
2596
  }
2614
2597
  }
2615
2598
  }
2616
- const parent = dirname3(currentDir);
2599
+ const parent = dirname4(currentDir);
2617
2600
  if (parent === currentDir) {
2618
2601
  break;
2619
2602
  }
@@ -2718,15 +2701,17 @@ var DEFAULT_COST_CONFIG = {
2718
2701
  daysPerMonth: 30
2719
2702
  };
2720
2703
  function calculateMonthlyCost(tokenWaste, config = {}) {
2704
+ const multiplier = tokenWaste > 5e4 ? 5 : tokenWaste > 1e4 ? 3.5 : 2.5;
2721
2705
  const budget = calculateTokenBudget({
2722
- totalContextTokens: tokenWaste * 2.5,
2706
+ totalContextTokens: tokenWaste * multiplier,
2723
2707
  wastedTokens: {
2724
2708
  duplication: tokenWaste * 0.7,
2725
2709
  fragmentation: tokenWaste * 0.3,
2726
- chattiness: 0
2710
+ chattiness: 0.1 * tokenWaste
2711
+ // Added baseline chattiness
2727
2712
  }
2728
2713
  });
2729
- const preset = getModelPreset("claude-4.6");
2714
+ const preset = getModelPreset("claude-3.5-sonnet");
2730
2715
  return estimateCostFromBudget(budget, preset, config);
2731
2716
  }
2732
2717
  function calculateTokenBudget(params) {
@@ -3208,7 +3193,7 @@ function calculatePatternEntropy(files) {
3208
3193
  }
3209
3194
  const dirGroups = /* @__PURE__ */ new Map();
3210
3195
  for (const file of files) {
3211
- const parts = file.path.split("/").slice(0, 4).join("/") || "root";
3196
+ const parts = file.path.split("/").slice(0, -1).join("/") || "root";
3212
3197
  dirGroups.set(parts, (dirGroups.get(parts) || 0) + 1);
3213
3198
  }
3214
3199
  const counts = Array.from(dirGroups.values());
@@ -3891,14 +3876,14 @@ function calculateExtendedFutureProofScore(params) {
3891
3876
  }
3892
3877
 
3893
3878
  // src/utils/history.ts
3894
- import { readFileSync as readFileSync2, writeFileSync as writeFileSync2, existsSync as existsSync8, mkdirSync as mkdirSync2 } from "fs";
3895
- import { join as join8, dirname as dirname4 } from "path";
3879
+ import { readFileSync as readFileSync2, writeFileSync as writeFileSync2, existsSync as existsSync5, mkdirSync as mkdirSync2 } from "fs";
3880
+ import { join as join5, dirname as dirname5 } from "path";
3896
3881
  function getHistoryPath(rootDir) {
3897
- return join8(rootDir, ".aiready", "history.json");
3882
+ return join5(rootDir, ".aiready", "history.json");
3898
3883
  }
3899
3884
  function loadScoreHistory(rootDir) {
3900
3885
  const historyPath = getHistoryPath(rootDir);
3901
- if (!existsSync8(historyPath)) {
3886
+ if (!existsSync5(historyPath)) {
3902
3887
  return [];
3903
3888
  }
3904
3889
  try {
@@ -3911,8 +3896,8 @@ function loadScoreHistory(rootDir) {
3911
3896
  }
3912
3897
  function saveScoreEntry(rootDir, entry) {
3913
3898
  const historyPath = getHistoryPath(rootDir);
3914
- const historyDir = dirname4(historyPath);
3915
- if (!existsSync8(historyDir)) {
3899
+ const historyDir = dirname5(historyPath);
3900
+ if (!existsSync5(historyDir)) {
3916
3901
  mkdirSync2(historyDir, { recursive: true });
3917
3902
  }
3918
3903
  const history = loadScoreHistory(rootDir);
@@ -3959,7 +3944,7 @@ function exportHistory(rootDir, format = "json") {
3959
3944
  }
3960
3945
  function clearHistory(rootDir) {
3961
3946
  const historyPath = getHistoryPath(rootDir);
3962
- if (existsSync8(historyPath)) {
3947
+ if (existsSync5(historyPath)) {
3963
3948
  writeFileSync2(historyPath, JSON.stringify([]));
3964
3949
  }
3965
3950
  }
@@ -4063,6 +4048,8 @@ export {
4063
4048
  ParseError,
4064
4049
  ParserFactory,
4065
4050
  PythonParser,
4051
+ ReadinessRating,
4052
+ RecommendationPriority,
4066
4053
  SEVERITY_TIME_ESTIMATES,
4067
4054
  SIZE_ADJUSTED_THRESHOLDS,
4068
4055
  Severity,
@@ -4130,8 +4117,10 @@ export {
4130
4117
  getSeverityColor,
4131
4118
  getSupportedLanguages,
4132
4119
  getToolWeight,
4120
+ getWasmPath,
4133
4121
  handleCLIError,
4134
4122
  handleJSONOutput,
4123
+ initTreeSitter,
4135
4124
  initializeParsers,
4136
4125
  isFileSupported,
4137
4126
  isSourceFile,
@@ -4149,6 +4138,7 @@ export {
4149
4138
  saveScoreEntry,
4150
4139
  scanEntries,
4151
4140
  scanFiles,
4141
+ setupParser,
4152
4142
  validateSpokeOutput,
4153
4143
  validateWithSchema
4154
4144
  };