@aiready/core 0.19.3 → 0.21.0

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
@@ -4,6 +4,7 @@ import {
4
4
  AnalysisStatusSchema,
5
5
  CONTEXT_TIER_THRESHOLDS,
6
6
  DEFAULT_TOOL_WEIGHTS,
7
+ FRIENDLY_TOOL_NAMES,
7
8
  IssueSchema,
8
9
  IssueType,
9
10
  IssueTypeSchema,
@@ -18,7 +19,10 @@ import {
18
19
  Severity,
19
20
  SeveritySchema,
20
21
  SpokeOutputSchema,
22
+ SpokeSummarySchema,
21
23
  TOOL_NAME_MAP,
24
+ ToolName,
25
+ ToolNameSchema,
22
26
  UnifiedReportSchema,
23
27
  calculateOverallScore,
24
28
  formatScore,
@@ -32,7 +36,7 @@ import {
32
36
  getToolWeight,
33
37
  normalizeToolName,
34
38
  parseWeightString
35
- } from "./chunk-D3D3NCRR.mjs";
39
+ } from "./chunk-YCA4FTEK.mjs";
36
40
 
37
41
  // src/types/contract.ts
38
42
  function validateSpokeOutput(toolName, output) {
@@ -92,6 +96,65 @@ function validateWithSchema(schema, data) {
92
96
  };
93
97
  }
94
98
 
99
+ // src/registry.ts
100
+ var ToolRegistry = class {
101
+ static getProviders() {
102
+ const g = globalThis;
103
+ if (!g.__AIRE_TOOL_REGISTRY__) {
104
+ g.__AIRE_TOOL_REGISTRY__ = /* @__PURE__ */ new Map();
105
+ }
106
+ return g.__AIRE_TOOL_REGISTRY__;
107
+ }
108
+ /**
109
+ * Register a new tool provider.
110
+ */
111
+ static register(provider) {
112
+ console.log(
113
+ `[ToolRegistry#${this.instanceId}] Registering tool: ${provider.id} (${provider.alias.join(", ")})`
114
+ );
115
+ this.getProviders().set(provider.id, provider);
116
+ }
117
+ /**
118
+ * Get a provider by its canonical ID.
119
+ */
120
+ static get(id) {
121
+ return this.getProviders().get(id);
122
+ }
123
+ /**
124
+ * Get a provider by name or alias.
125
+ */
126
+ static find(nameOrAlias) {
127
+ const providers = this.getProviders();
128
+ const exact = providers.get(nameOrAlias);
129
+ if (exact) return exact;
130
+ for (const p of providers.values()) {
131
+ if (p.alias.includes(nameOrAlias)) return p;
132
+ }
133
+ return void 0;
134
+ }
135
+ /**
136
+ * Get all registered tool providers.
137
+ */
138
+ static getAll() {
139
+ return Array.from(this.getProviders().values());
140
+ }
141
+ /**
142
+ * Get all available tool IDs from the ToolName enum.
143
+ */
144
+ static getAvailableIds() {
145
+ return Object.values(ToolName).filter(
146
+ (v) => typeof v === "string"
147
+ );
148
+ }
149
+ /**
150
+ * Clear the registry (primarily for testing).
151
+ */
152
+ static clear() {
153
+ this.getProviders().clear();
154
+ }
155
+ };
156
+ ToolRegistry.instanceId = globalThis.Math.random();
157
+
95
158
  // src/utils/file-scanner.ts
96
159
  import { glob } from "glob";
97
160
  import { readFile } from "fs/promises";
@@ -184,7 +247,13 @@ async function scanFiles(options) {
184
247
  ignoreFromFile = [];
185
248
  }
186
249
  }
187
- const TEST_PATTERNS = ["**/*.test.*", "**/*.spec.*", "**/__tests__/**", "**/test/**", "**/tests/**"];
250
+ const TEST_PATTERNS = [
251
+ "**/*.test.*",
252
+ "**/*.spec.*",
253
+ "**/__tests__/**",
254
+ "**/test/**",
255
+ "**/tests/**"
256
+ ];
188
257
  const baseExclude = options.includeTests ? DEFAULT_EXCLUDE.filter((p) => !TEST_PATTERNS.includes(p)) : DEFAULT_EXCLUDE;
189
258
  const finalExclude = [
190
259
  .../* @__PURE__ */ new Set([...exclude || [], ...ignoreFromFile, ...baseExclude])
@@ -205,12 +274,19 @@ async function scanFiles(options) {
205
274
  for (const gitignorePath of gitignoreFiles) {
206
275
  const gitTxt = await readFile(gitignorePath, "utf-8");
207
276
  const gitignoreDir = dirname(gitignorePath);
208
- const relativePrefix = relative(rootDir || ".", gitignoreDir).replace(/\\/g, "/");
277
+ const relativePrefix = relative(rootDir || ".", gitignoreDir).replace(
278
+ /\\/g,
279
+ "/"
280
+ );
209
281
  const patterns = gitTxt.split(/\r?\n/).map((s) => s.trim()).filter(Boolean).filter((l) => !l.startsWith("#"));
210
282
  if (relativePrefix === "." || relativePrefix === "") {
211
283
  ig.add(patterns);
212
284
  } else {
213
- ig.add(patterns.map((p) => p.startsWith("/") ? `${relativePrefix}${p}` : `${relativePrefix}/**/${p}`));
285
+ ig.add(
286
+ patterns.map(
287
+ (p) => p.startsWith("/") ? `${relativePrefix}${p}` : `${relativePrefix}/**/${p}`
288
+ )
289
+ );
214
290
  }
215
291
  }
216
292
  const filtered = files.filter((f) => {
@@ -238,9 +314,17 @@ async function scanEntries(options) {
238
314
  ignoreFromFile = [];
239
315
  }
240
316
  }
241
- const TEST_PATTERNS = ["**/*.test.*", "**/*.spec.*", "**/__tests__/**", "**/test/**", "**/tests/**"];
317
+ const TEST_PATTERNS = [
318
+ "**/*.test.*",
319
+ "**/*.spec.*",
320
+ "**/__tests__/**",
321
+ "**/test/**",
322
+ "**/tests/**"
323
+ ];
242
324
  const baseExclude = includeTests ? DEFAULT_EXCLUDE.filter((p) => !TEST_PATTERNS.includes(p)) : DEFAULT_EXCLUDE;
243
- const finalExclude = [.../* @__PURE__ */ new Set([...exclude || [], ...ignoreFromFile, ...baseExclude])];
325
+ const finalExclude = [
326
+ .../* @__PURE__ */ new Set([...exclude || [], ...ignoreFromFile, ...baseExclude])
327
+ ];
244
328
  const dirs = await glob("**/", {
245
329
  cwd: rootDir,
246
330
  ignore: finalExclude,
@@ -256,16 +340,23 @@ async function scanEntries(options) {
256
340
  for (const gitignorePath of gitignoreFiles) {
257
341
  const gitTxt = await readFile(gitignorePath, "utf-8");
258
342
  const gitignoreDir = dirname(gitignorePath);
259
- const relativePrefix = relative(rootDir || ".", gitignoreDir).replace(/\\/g, "/");
343
+ const relativePrefix = relative(rootDir || ".", gitignoreDir).replace(
344
+ /\\/g,
345
+ "/"
346
+ );
260
347
  const patterns = gitTxt.split(/\r?\n/).map((s) => s.trim()).filter(Boolean).filter((l) => !l.startsWith("#"));
261
348
  if (relativePrefix === "." || relativePrefix === "") {
262
349
  ig.add(patterns);
263
350
  } else {
264
- ig.add(patterns.map((p) => p.startsWith("/") ? `${relativePrefix}${p}` : `${relativePrefix}/**/${p}`));
351
+ ig.add(
352
+ patterns.map(
353
+ (p) => p.startsWith("/") ? `${relativePrefix}${p}` : `${relativePrefix}/**/${p}`
354
+ )
355
+ );
265
356
  }
266
357
  }
267
358
  const filteredDirs = dirs.filter((d) => {
268
- let rel = relative(rootDir || ".", d).replace(/\\/g, "/").replace(/\/$/, "");
359
+ const rel = relative(rootDir || ".", d).replace(/\\/g, "/").replace(/\/$/, "");
269
360
  if (rel === "") return true;
270
361
  return !ig.ignores(rel);
271
362
  });
@@ -2204,7 +2295,7 @@ function calculateChangeAmplification(params) {
2204
2295
  const hotspots = files.map((f) => ({ ...f, amplificationFactor: f.fanOut + f.fanIn * 0.5 })).sort((a, b) => b.amplificationFactor - a.amplificationFactor);
2205
2296
  const maxAmplification = hotspots[0].amplificationFactor;
2206
2297
  const avgAmplification = hotspots.reduce((sum, h) => sum + h.amplificationFactor, 0) / hotspots.length;
2207
- let score = Math.max(
2298
+ const score = Math.max(
2208
2299
  0,
2209
2300
  Math.min(
2210
2301
  100,
@@ -2530,6 +2621,7 @@ export {
2530
2621
  DEFAULT_COST_CONFIG,
2531
2622
  DEFAULT_EXCLUDE,
2532
2623
  DEFAULT_TOOL_WEIGHTS,
2624
+ FRIENDLY_TOOL_NAMES,
2533
2625
  IssueSchema,
2534
2626
  IssueType,
2535
2627
  IssueTypeSchema,
@@ -2548,7 +2640,11 @@ export {
2548
2640
  Severity,
2549
2641
  SeveritySchema,
2550
2642
  SpokeOutputSchema,
2643
+ SpokeSummarySchema,
2551
2644
  TOOL_NAME_MAP,
2645
+ ToolName,
2646
+ ToolNameSchema,
2647
+ ToolRegistry,
2552
2648
  TypeScriptParser,
2553
2649
  UnifiedReportSchema,
2554
2650
  VAGUE_FILE_NAMES,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aiready/core",
3
- "version": "0.19.3",
3
+ "version": "0.21.0",
4
4
  "description": "Shared utilities for AIReady analysis tools",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",