@aiready/core 0.24.23 → 0.24.25

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 (59) hide show
  1. package/dist/chunk-3GCIM6XG.mjs +904 -0
  2. package/dist/chunk-3S5WU6KX.mjs +552 -0
  3. package/dist/chunk-4OMXBYX7.mjs +167 -0
  4. package/dist/chunk-6YWGFKZG.mjs +250 -0
  5. package/dist/chunk-A3BIROBZ.mjs +902 -0
  6. package/dist/chunk-BYMQDORS.mjs +256 -0
  7. package/dist/chunk-CBZNRNEF.mjs +309 -0
  8. package/dist/chunk-ET2WRQSM.mjs +262 -0
  9. package/dist/chunk-F4FTHFHK.mjs +552 -0
  10. package/dist/chunk-G737F72Q.mjs +256 -0
  11. package/dist/chunk-GVFUAIWU.mjs +864 -0
  12. package/dist/chunk-KSEA5XDH.mjs +894 -0
  13. package/dist/chunk-LMIZRJFV.mjs +256 -0
  14. package/dist/chunk-LRPBPWBM.mjs +170 -0
  15. package/dist/chunk-MOTBXU6W.mjs +902 -0
  16. package/dist/chunk-OAH6FVVF.mjs +919 -0
  17. package/dist/chunk-OCM6HLBM.mjs +262 -0
  18. package/dist/chunk-OFBRNGKT.mjs +893 -0
  19. package/dist/chunk-P3KYGPO4.mjs +262 -0
  20. package/dist/chunk-PNWSO6XQ.mjs +250 -0
  21. package/dist/chunk-SO6UKAPR.mjs +164 -0
  22. package/dist/chunk-T2FW6AAF.mjs +552 -0
  23. package/dist/chunk-TQX77RIC.mjs +250 -0
  24. package/dist/chunk-X64EJ3ZO.mjs +314 -0
  25. package/dist/client/index.d.mts +1 -1
  26. package/dist/client/index.d.ts +1 -1
  27. package/dist/client/index.js +32 -5
  28. package/dist/client/index.mjs +1 -1
  29. package/dist/csharp-parser-3CGM6FKB.mjs +9 -0
  30. package/dist/csharp-parser-UWRUYHUH.mjs +9 -0
  31. package/dist/csharp-parser-WIAIE3DD.mjs +9 -0
  32. package/dist/go-parser-AH5QNS4O.mjs +9 -0
  33. package/dist/go-parser-CSAB23BL.mjs +9 -0
  34. package/dist/go-parser-Q3HI32B7.mjs +9 -0
  35. package/dist/index-CL_0jxiJ.d.mts +1315 -0
  36. package/dist/index-CL_0jxiJ.d.ts +1315 -0
  37. package/dist/index-ClwnZa_Y.d.mts +1333 -0
  38. package/dist/index-ClwnZa_Y.d.ts +1333 -0
  39. package/dist/index-DC0cdf0g.d.mts +1321 -0
  40. package/dist/index-DC0cdf0g.d.ts +1321 -0
  41. package/dist/index-DKqKGhcJ.d.mts +1309 -0
  42. package/dist/index-DKqKGhcJ.d.ts +1309 -0
  43. package/dist/index-DNnlhdk0.d.mts +1318 -0
  44. package/dist/index-DNnlhdk0.d.ts +1318 -0
  45. package/dist/index-De2xy_k5.d.mts +1326 -0
  46. package/dist/index-De2xy_k5.d.ts +1326 -0
  47. package/dist/index.d.mts +104 -20
  48. package/dist/index.d.ts +104 -20
  49. package/dist/index.js +581 -147
  50. package/dist/index.mjs +507 -134
  51. package/dist/java-parser-GUKWCEYS.mjs +9 -0
  52. package/dist/java-parser-XTWT5Y5I.mjs +9 -0
  53. package/dist/java-parser-YP5XWLQK.mjs +9 -0
  54. package/dist/python-parser-AOPXUEIV.mjs +8 -0
  55. package/dist/python-parser-FB55P6UA.mjs +8 -0
  56. package/dist/python-parser-WIJPSRKC.mjs +8 -0
  57. package/dist/typescript-parser-5ZWLLMWJ.mjs +7 -0
  58. package/dist/typescript-parser-TWPRLYK6.mjs +7 -0
  59. package/package.json +5 -1
package/dist/index.js CHANGED
@@ -96,7 +96,10 @@ var init_typescript_parser = __esm({
96
96
  range: true,
97
97
  tokens: true,
98
98
  comment: true,
99
- jsx: filePath.endsWith("x")
99
+ jsx: filePath.endsWith("x"),
100
+ ecmaVersion: "latest"
101
+ // Support for latest TypeScript features like Decorators and Explicit Resource Management
102
+ // are enabled by default in latest typescript-estree when ecmaVersion is 'latest'.
100
103
  });
101
104
  } catch (error) {
102
105
  const err = error;
@@ -114,7 +117,10 @@ var init_typescript_parser = __esm({
114
117
  range: true,
115
118
  tokens: true,
116
119
  comment: true,
117
- jsx: filePath.endsWith("x")
120
+ jsx: filePath.endsWith("x"),
121
+ ecmaVersion: "latest"
122
+ // Support for latest TypeScript features like Decorators and Explicit Resource Management
123
+ // are enabled by default in latest typescript-estree when ecmaVersion is 'latest'.
118
124
  });
119
125
  const imports = this.extractImports(ast);
120
126
  const exports2 = this.extractExports(ast, code, filePath);
@@ -266,7 +272,7 @@ var init_typescript_parser = __esm({
266
272
  let isPrimitive = false;
267
273
  let isTyped = false;
268
274
  if (initializer) {
269
- if (initializer.type === "Literal" || initializer.type === "TemplateLiteral" && initializer.expressions.length === 0) {
275
+ if (initializer.type === "Literal" || initializer.type === "BigIntLiteral" || initializer.type === "TemplateLiteral" && initializer.expressions.length === 0) {
270
276
  isPrimitive = true;
271
277
  }
272
278
  }
@@ -365,7 +371,8 @@ var init_typescript_parser = __esm({
365
371
  body,
366
372
  (_, v) => typeof v === "bigint" ? v.toString() : v
367
373
  );
368
- if (bodyContent.includes('"name":"console"') || bodyContent.includes('"name":"process"') || bodyContent.includes('"name":"fs"') || bodyContent.includes('"name":"global"') || bodyContent.includes('"name":"window"') || bodyContent.includes('"name":"fetch"') || bodyContent.includes('"name":"axios"')) {
374
+ if (bodyContent.includes('"name":"console"') || bodyContent.includes('"name":"process"') || bodyContent.includes('"name":"fs"') || bodyContent.includes('"name":"global"') || bodyContent.includes('"name":"window"') || bodyContent.includes('"name":"fetch"') || bodyContent.includes('"name":"axios"') || bodyContent.includes('"type":"UsingDeclaration"') || // Explicit Resource Management
375
+ bodyContent.includes('"type":"AwaitExpression"')) {
369
376
  return false;
370
377
  }
371
378
  return true;
@@ -501,6 +508,25 @@ var init_metadata_utils = __esm({
501
508
  }
502
509
  });
503
510
 
511
+ // src/utils/path-utils.ts
512
+ function getDirname(importMetaUrl) {
513
+ if (importMetaUrl) {
514
+ return (0, import_path4.dirname)((0, import_url.fileURLToPath)(importMetaUrl));
515
+ }
516
+ if (typeof __dirname !== "undefined") {
517
+ return __dirname;
518
+ }
519
+ throw new Error("getDirname: importMetaUrl is required in ESM environments");
520
+ }
521
+ var import_path4, import_url;
522
+ var init_path_utils = __esm({
523
+ "src/utils/path-utils.ts"() {
524
+ "use strict";
525
+ import_path4 = require("path");
526
+ import_url = require("url");
527
+ }
528
+ });
529
+
504
530
  // src/parsers/tree-sitter-utils.ts
505
531
  async function initTreeSitter() {
506
532
  if (isTreeSitterInitialized) return;
@@ -554,18 +580,18 @@ function getWasmPath(language) {
554
580
  const wasmFileName = language === "web-tree-sitter" ? "web-tree-sitter.wasm" : `tree-sitter-${language}.wasm`;
555
581
  const immediatePaths = [
556
582
  path.join(process.cwd(), wasmFileName),
557
- path.join(__dirname, wasmFileName),
558
- path.join(__dirname, "assets", wasmFileName)
583
+ path.join(__dirname2, wasmFileName),
584
+ path.join(__dirname2, "assets", wasmFileName)
559
585
  ];
560
586
  for (const p of immediatePaths) {
561
587
  if (fs.existsSync(p)) return p;
562
588
  }
563
- const pnpmPath = findInPnpmStore(__dirname, wasmFileName);
589
+ const pnpmPath = findInPnpmStore(__dirname2, wasmFileName);
564
590
  if (pnpmPath) return pnpmPath;
565
591
  const pnpmPathCwd = findInPnpmStore(process.cwd(), wasmFileName);
566
592
  if (pnpmPathCwd) return pnpmPathCwd;
567
593
  console.warn(
568
- `[Parser] WASM file for ${language} not found. CWD: ${process.cwd()}, DIR: ${__dirname}`
594
+ `[Parser] WASM file for ${language} not found. CWD: ${process.cwd()}, DIR: ${__dirname2}`
569
595
  );
570
596
  return null;
571
597
  }
@@ -584,24 +610,23 @@ async function setupParser(language) {
584
610
  return null;
585
611
  }
586
612
  }
587
- var Parser, path, fs, import_url, import_meta, getDirname, __dirname, isTreeSitterInitialized;
613
+ var Parser, path, fs, import_meta, getDirname2, __dirname2, isTreeSitterInitialized;
588
614
  var init_tree_sitter_utils = __esm({
589
615
  "src/parsers/tree-sitter-utils.ts"() {
590
616
  "use strict";
591
617
  Parser = __toESM(require("web-tree-sitter"));
592
618
  path = __toESM(require("path"));
593
619
  fs = __toESM(require("fs"));
594
- import_url = require("url");
620
+ init_path_utils();
595
621
  import_meta = {};
596
- getDirname = () => {
622
+ getDirname2 = () => {
597
623
  try {
598
- if (typeof __dirname !== "undefined") return __dirname;
599
- return path.dirname((0, import_url.fileURLToPath)(import_meta.url));
624
+ return getDirname(import_meta.url);
600
625
  } catch {
601
626
  return process.cwd();
602
627
  }
603
628
  };
604
- __dirname = getDirname();
629
+ __dirname2 = getDirname2();
605
630
  isTreeSitterInitialized = false;
606
631
  }
607
632
  });
@@ -2034,6 +2059,7 @@ __export(index_exports, {
2034
2059
  COMMON_FINE_TUNING_OPTIONS: () => COMMON_FINE_TUNING_OPTIONS,
2035
2060
  CONTEXT_TIER_THRESHOLDS: () => CONTEXT_TIER_THRESHOLDS,
2036
2061
  CSharpParser: () => CSharpParser,
2062
+ DEFAULT_AUTO_EXCLUDE_PATTERNS: () => DEFAULT_AUTO_EXCLUDE_PATTERNS,
2037
2063
  DEFAULT_COST_CONFIG: () => DEFAULT_COST_CONFIG,
2038
2064
  DEFAULT_EXCLUDE: () => DEFAULT_EXCLUDE,
2039
2065
  DEFAULT_TOOL_WEIGHTS: () => DEFAULT_TOOL_WEIGHTS,
@@ -2042,6 +2068,8 @@ __export(index_exports, {
2042
2068
  FRIENDLY_TOOL_NAMES: () => FRIENDLY_TOOL_NAMES,
2043
2069
  GLOBAL_INFRA_OPTIONS: () => GLOBAL_INFRA_OPTIONS,
2044
2070
  GLOBAL_SCAN_OPTIONS: () => GLOBAL_SCAN_OPTIONS,
2071
+ GitHubIssueResolverAgent: () => GitHubIssueResolverAgent,
2072
+ GitHubService: () => GitHubService,
2045
2073
  GoParser: () => GoParser,
2046
2074
  IssueSchema: () => IssueSchema,
2047
2075
  IssueType: () => IssueType,
@@ -2146,6 +2174,8 @@ __export(index_exports, {
2146
2174
  generateStatCards: () => generateStatCards,
2147
2175
  generateTable: () => generateTable,
2148
2176
  generateValueChain: () => generateValueChain,
2177
+ getChangedFiles: () => getChangedFiles,
2178
+ getDirname: () => getDirname,
2149
2179
  getElapsedTime: () => getElapsedTime,
2150
2180
  getErrorMessage: () => getErrorMessage,
2151
2181
  getFileCommitTimestamps: () => getFileCommitTimestamps,
@@ -2214,12 +2244,14 @@ __export(index_exports, {
2214
2244
  resolveOutputPath: () => resolveOutputPath,
2215
2245
  runBatchAnalysis: () => runBatchAnalysis,
2216
2246
  runStandardCliAction: () => runStandardCliAction,
2247
+ safeJsonStringify: () => safeJsonStringify,
2217
2248
  saveScoreEntry: () => saveScoreEntry,
2218
2249
  scanEntries: () => scanEntries,
2219
2250
  scanFiles: () => scanFiles,
2220
2251
  setupParser: () => setupParser,
2221
2252
  severityToAnnotationLevel: () => severityToAnnotationLevel,
2222
2253
  toErrorMessage: () => toErrorMessage,
2254
+ validateConfig: () => validateConfig,
2223
2255
  validateSpokeOutput: () => validateSpokeOutput,
2224
2256
  validateWithSchema: () => validateWithSchema,
2225
2257
  withErrorHandling: () => withErrorHandling,
@@ -2325,6 +2357,7 @@ var import_zod3 = require("zod");
2325
2357
  var IssueSchema = import_zod3.z.object({
2326
2358
  type: IssueTypeSchema,
2327
2359
  severity: SeveritySchema,
2360
+ category: import_zod3.z.string().optional(),
2328
2361
  message: import_zod3.z.string(),
2329
2362
  location: LocationSchema,
2330
2363
  suggestion: import_zod3.z.string().optional()
@@ -2365,6 +2398,7 @@ var SpokeSummarySchema = import_zod5.z.object({
2365
2398
  totalIssues: import_zod5.z.number().optional(),
2366
2399
  criticalIssues: import_zod5.z.number().optional(),
2367
2400
  majorIssues: import_zod5.z.number().optional(),
2401
+ minorIssues: import_zod5.z.number().optional(),
2368
2402
  score: import_zod5.z.number().optional()
2369
2403
  }).catchall(import_zod5.z.any());
2370
2404
  var SpokeOutputSchema = import_zod5.z.object({
@@ -2383,6 +2417,7 @@ var UnifiedReportSchema = import_zod5.z.object({
2383
2417
  totalIssues: import_zod5.z.number(),
2384
2418
  criticalIssues: import_zod5.z.number(),
2385
2419
  majorIssues: import_zod5.z.number(),
2420
+ minorIssues: import_zod5.z.number(),
2386
2421
  businessImpact: import_zod5.z.object({
2387
2422
  estimatedMonthlyWaste: import_zod5.z.number().optional(),
2388
2423
  potentialSavings: import_zod5.z.number().optional(),
@@ -2405,9 +2440,24 @@ var UnifiedReportSchema = import_zod5.z.object({
2405
2440
 
2406
2441
  // src/types/schemas/config.ts
2407
2442
  var import_zod6 = require("zod");
2443
+ var AutoExcludeSchema = import_zod6.z.object({
2444
+ /** Enable automatic detection of test files */
2445
+ tests: import_zod6.z.boolean().optional(),
2446
+ /** Enable automatic detection of mock files */
2447
+ mocks: import_zod6.z.boolean().optional(),
2448
+ /** Enable automatic detection of barrel/re-export files */
2449
+ barrels: import_zod6.z.boolean().optional(),
2450
+ /** Enable automatic detection of generated files */
2451
+ generated: import_zod6.z.boolean().optional()
2452
+ }).optional();
2453
+ var TieredExcludeSchema = import_zod6.z.record(import_zod6.z.string(), import_zod6.z.array(import_zod6.z.string()));
2408
2454
  var AIReadyConfigSchema = import_zod6.z.object({
2409
- /** Files or directories to exclude from scan */
2410
- exclude: import_zod6.z.array(import_zod6.z.string()).optional(),
2455
+ /** Extend from another config file (relative path) */
2456
+ extends: import_zod6.z.string().optional(),
2457
+ /** Files or directories to exclude from scan (flat array or tiered) */
2458
+ exclude: import_zod6.z.union([import_zod6.z.array(import_zod6.z.string()), TieredExcludeSchema]).optional(),
2459
+ /** Auto-exclusion settings for common patterns */
2460
+ autoExclude: AutoExcludeSchema,
2411
2461
  /** Fail CI/CD if score below threshold (0-100) */
2412
2462
  threshold: import_zod6.z.number().optional(),
2413
2463
  /** Fail on issues: critical, major, any */
@@ -2434,7 +2484,15 @@ var AIReadyConfigSchema = import_zod6.z.object({
2434
2484
  compareBaseline: import_zod6.z.string().optional()
2435
2485
  }).optional(),
2436
2486
  /** Tool-specific configuration overrides (Strictly ToolName -> Config) */
2437
- tools: import_zod6.z.record(import_zod6.z.string(), import_zod6.z.any()).optional(),
2487
+ tools: import_zod6.z.record(
2488
+ import_zod6.z.string(),
2489
+ import_zod6.z.object({
2490
+ /** Whether to enable this tool */
2491
+ enabled: import_zod6.z.boolean().optional(),
2492
+ /** Severity overrides for specific categories */
2493
+ severityOverrides: import_zod6.z.record(import_zod6.z.string(), SeveritySchema).optional()
2494
+ }).catchall(import_zod6.z.any())
2495
+ ).optional(),
2438
2496
  /** Scoring profile and weights */
2439
2497
  scoring: import_zod6.z.object({
2440
2498
  /** Name of the scoring profile (e.g. "strict", "balanced") */
@@ -2516,7 +2574,8 @@ var GLOBAL_INFRA_OPTIONS = [
2516
2574
  "include",
2517
2575
  "exclude",
2518
2576
  "tools",
2519
- "scoring"
2577
+ "scoring",
2578
+ "changedFilesOnly"
2520
2579
  ];
2521
2580
  var GLOBAL_SCAN_OPTIONS = [
2522
2581
  "rootDir",
@@ -2527,7 +2586,7 @@ var GLOBAL_SCAN_OPTIONS = [
2527
2586
  "output",
2528
2587
  "format",
2529
2588
  "parallel",
2530
- "showBreakdown"
2589
+ "changedFilesOnly"
2531
2590
  ];
2532
2591
  var COMMON_FINE_TUNING_OPTIONS = [
2533
2592
  "maxDepth",
@@ -2795,6 +2854,106 @@ var import_promises = require("fs/promises");
2795
2854
  var import_fs = require("fs");
2796
2855
  var import_path = require("path");
2797
2856
  var import_ignore = __toESM(require("ignore"));
2857
+
2858
+ // src/utils/history-git.ts
2859
+ var import_child_process = require("child_process");
2860
+ function getFileCommitTimestamps(file) {
2861
+ const lineStamps = {};
2862
+ try {
2863
+ const output = (0, import_child_process.execSync)(`git blame -t "${file}"`, {
2864
+ encoding: "utf-8",
2865
+ stdio: ["ignore", "pipe", "ignore"]
2866
+ });
2867
+ const lines = output.split("\n");
2868
+ for (const line of lines) {
2869
+ if (!line) continue;
2870
+ const match = line.match(/^\S+\s+\(.*?(\d{10,})\s+[-+]\d+\s+(\d+)\)/);
2871
+ if (match) {
2872
+ const ts = parseInt(match[1], 10);
2873
+ const ln = parseInt(match[2], 10);
2874
+ lineStamps[ln] = ts;
2875
+ }
2876
+ }
2877
+ } catch {
2878
+ }
2879
+ return lineStamps;
2880
+ }
2881
+ function getLineRangeLastModifiedCached(lineStamps, startLine, endLine) {
2882
+ let latest = 0;
2883
+ for (let i = startLine; i <= endLine; i++) {
2884
+ if (lineStamps[i] && lineStamps[i] > latest) {
2885
+ latest = lineStamps[i];
2886
+ }
2887
+ }
2888
+ return latest;
2889
+ }
2890
+ function getRepoMetadata(directory) {
2891
+ const metadata = {};
2892
+ try {
2893
+ try {
2894
+ metadata.url = (0, import_child_process.execSync)("git config --get remote.origin.url", {
2895
+ cwd: directory,
2896
+ encoding: "utf-8",
2897
+ stdio: ["ignore", "pipe", "ignore"]
2898
+ }).trim();
2899
+ } catch {
2900
+ }
2901
+ try {
2902
+ metadata.branch = (0, import_child_process.execSync)("git rev-parse --abbrev-ref HEAD", {
2903
+ cwd: directory,
2904
+ encoding: "utf-8",
2905
+ stdio: ["ignore", "pipe", "ignore"]
2906
+ }).trim();
2907
+ } catch {
2908
+ }
2909
+ try {
2910
+ metadata.commit = (0, import_child_process.execSync)("git rev-parse HEAD", {
2911
+ cwd: directory,
2912
+ encoding: "utf-8",
2913
+ stdio: ["ignore", "pipe", "ignore"]
2914
+ }).trim();
2915
+ } catch {
2916
+ }
2917
+ try {
2918
+ metadata.author = (0, import_child_process.execSync)("git log -1 --format=%ae", {
2919
+ cwd: directory,
2920
+ encoding: "utf-8",
2921
+ stdio: ["ignore", "pipe", "ignore"]
2922
+ }).trim();
2923
+ } catch {
2924
+ }
2925
+ } catch {
2926
+ }
2927
+ return metadata;
2928
+ }
2929
+ function getChangedFiles(directory) {
2930
+ const changedFiles = /* @__PURE__ */ new Set();
2931
+ try {
2932
+ const trackedOutput = (0, import_child_process.execSync)("git diff HEAD --name-only", {
2933
+ cwd: directory,
2934
+ encoding: "utf-8",
2935
+ stdio: ["ignore", "pipe", "ignore"]
2936
+ }).trim();
2937
+ if (trackedOutput) {
2938
+ trackedOutput.split("\n").forEach((f) => changedFiles.add(f));
2939
+ }
2940
+ const untrackedOutput = (0, import_child_process.execSync)(
2941
+ "git ls-files --others --exclude-standard",
2942
+ {
2943
+ cwd: directory,
2944
+ encoding: "utf-8",
2945
+ stdio: ["ignore", "pipe", "ignore"]
2946
+ }
2947
+ ).trim();
2948
+ if (untrackedOutput) {
2949
+ untrackedOutput.split("\n").forEach((f) => changedFiles.add(f));
2950
+ }
2951
+ } catch {
2952
+ }
2953
+ return Array.from(changedFiles);
2954
+ }
2955
+
2956
+ // src/utils/file-scanner.ts
2798
2957
  var DEFAULT_EXCLUDE = [
2799
2958
  // Dependencies
2800
2959
  "**/node_modules/**",
@@ -2866,12 +3025,12 @@ var VAGUE_FILE_NAMES = /* @__PURE__ */ new Set([
2866
3025
  ]);
2867
3026
  async function scanFiles(options) {
2868
3027
  const {
2869
- rootDir,
3028
+ rootDir = ".",
2870
3029
  include = ["**/*.{ts,tsx,js,jsx,py,java,go,rs,cs}"],
2871
3030
  // Multi-language support
2872
3031
  exclude
2873
3032
  } = options;
2874
- const ignoreFilePath = (0, import_path.join)(rootDir || ".", ".aireadyignore");
3033
+ const ignoreFilePath = (0, import_path.join)(rootDir, ".aireadyignore");
2875
3034
  let ignoreFromFile = [];
2876
3035
  if ((0, import_fs.existsSync)(ignoreFilePath)) {
2877
3036
  try {
@@ -2904,13 +3063,14 @@ async function scanFiles(options) {
2904
3063
  // Minimal ignore for gitignore discovery
2905
3064
  absolute: true
2906
3065
  });
3066
+ let filtered = files;
2907
3067
  if (gitignoreFiles.length > 0) {
2908
3068
  try {
2909
3069
  const ig = (0, import_ignore.default)();
2910
3070
  for (const gitignorePath of gitignoreFiles) {
2911
3071
  const gitTxt = await (0, import_promises.readFile)(gitignorePath, "utf-8");
2912
3072
  const gitignoreDir = (0, import_path.dirname)(gitignorePath);
2913
- const relativePrefix = (0, import_path.relative)(rootDir || ".", gitignoreDir).replace(
3073
+ const relativePrefix = (0, import_path.relative)(rootDir, gitignoreDir).replace(
2914
3074
  /\\/g,
2915
3075
  "/"
2916
3076
  );
@@ -2925,22 +3085,26 @@ async function scanFiles(options) {
2925
3085
  );
2926
3086
  }
2927
3087
  }
2928
- const filtered = files.filter((f) => {
2929
- let rel = (0, import_path.relative)(rootDir || ".", f).replace(/\\/g, "/");
3088
+ filtered = files.filter((f) => {
3089
+ let rel = (0, import_path.relative)(rootDir, f).replace(/\\/g, "/");
2930
3090
  if (rel === "") rel = f;
2931
3091
  return !ig.ignores(rel);
2932
3092
  });
2933
- return filtered;
2934
3093
  } catch {
2935
- return files;
2936
3094
  }
2937
3095
  }
2938
- return files;
3096
+ if (options.changedFilesOnly) {
3097
+ const changedFiles = getChangedFiles(rootDir).map(
3098
+ (f) => (0, import_path.resolve)(rootDir, f)
3099
+ );
3100
+ return filtered.filter((f) => changedFiles.includes(f));
3101
+ }
3102
+ return filtered;
2939
3103
  }
2940
3104
  async function scanEntries(options) {
2941
3105
  const files = await scanFiles(options);
2942
- const { rootDir, exclude, includeTests } = options;
2943
- const ignoreFilePath = (0, import_path.join)(rootDir || ".", ".aireadyignore");
3106
+ const { rootDir = ".", exclude, includeTests } = options;
3107
+ const ignoreFilePath = (0, import_path.join)(rootDir, ".aireadyignore");
2944
3108
  let ignoreFromFile = [];
2945
3109
  if ((0, import_fs.existsSync)(ignoreFilePath)) {
2946
3110
  try {
@@ -2976,7 +3140,7 @@ async function scanEntries(options) {
2976
3140
  for (const gitignorePath of gitignoreFiles) {
2977
3141
  const gitTxt = await (0, import_promises.readFile)(gitignorePath, "utf-8");
2978
3142
  const gitignoreDir = (0, import_path.dirname)(gitignorePath);
2979
- const relativePrefix = (0, import_path.relative)(rootDir || ".", gitignoreDir).replace(
3143
+ const relativePrefix = (0, import_path.relative)(rootDir, gitignoreDir).replace(
2980
3144
  /\\/g,
2981
3145
  "/"
2982
3146
  );
@@ -2992,7 +3156,7 @@ async function scanEntries(options) {
2992
3156
  }
2993
3157
  }
2994
3158
  const filteredDirs = dirs.filter((d) => {
2995
- let rel = (0, import_path.relative)(rootDir || ".", d).replace(/\\/g, "/");
3159
+ let rel = (0, import_path.relative)(rootDir, d).replace(/\\/g, "/");
2996
3160
  if (rel === "") return true;
2997
3161
  if (!rel.endsWith("/")) rel += "/";
2998
3162
  return !ig.ignores(rel);
@@ -3048,13 +3212,20 @@ function resolveOutputPath(userPath, defaultFilename, workingDir = process.cwd()
3048
3212
  ensureDir(outputPath);
3049
3213
  return outputPath;
3050
3214
  }
3215
+ function safeJsonStringify(obj, indent = 2) {
3216
+ return JSON.stringify(
3217
+ obj,
3218
+ (_, v) => typeof v === "bigint" ? v.toString() : v,
3219
+ indent
3220
+ );
3221
+ }
3051
3222
  function handleJSONOutput(data, outputFile, successMessage) {
3052
3223
  if (outputFile) {
3053
3224
  ensureDir(outputFile);
3054
- (0, import_fs2.writeFileSync)(outputFile, JSON.stringify(data, null, 2));
3225
+ (0, import_fs2.writeFileSync)(outputFile, safeJsonStringify(data, 2));
3055
3226
  console.log(successMessage || `\u2705 Results saved to ${outputFile}`);
3056
3227
  } else {
3057
- console.log(JSON.stringify(data, null, 2));
3228
+ console.log(safeJsonStringify(data, 2));
3058
3229
  }
3059
3230
  }
3060
3231
  function findLatestReport(dirPath) {
@@ -3245,7 +3416,7 @@ function handleCLIError(error, commandName) {
3245
3416
 
3246
3417
  // src/utils/cli-helpers.ts
3247
3418
  async function loadMergedConfig(directory, defaults, cliOptions) {
3248
- const config = await loadConfig(directory);
3419
+ const { config } = await loadConfig(directory);
3249
3420
  const mergedConfig = mergeConfigWithDefaults(config, defaults);
3250
3421
  const result = {
3251
3422
  ...mergedConfig,
@@ -3780,8 +3951,7 @@ function estimateTokens(text) {
3780
3951
 
3781
3952
  // src/utils/config.ts
3782
3953
  var import_fs3 = require("fs");
3783
- var import_path4 = require("path");
3784
- var import_url2 = require("url");
3954
+ var import_path5 = require("path");
3785
3955
  var CONFIG_FILES = [
3786
3956
  "aiready.json",
3787
3957
  "aiready.config.json",
@@ -3790,12 +3960,164 @@ var CONFIG_FILES = [
3790
3960
  "aiready.config.js",
3791
3961
  ".aireadyrc.js"
3792
3962
  ];
3793
- async function loadConfig(rootDir) {
3794
- let currentDir = (0, import_path4.resolve)(rootDir);
3963
+ var DEFAULT_AUTO_EXCLUDE_PATTERNS = {
3964
+ tests: [
3965
+ "**/*.test.ts",
3966
+ "**/*.test.tsx",
3967
+ "**/*.test.js",
3968
+ "**/*.test.jsx",
3969
+ "**/*.spec.ts",
3970
+ "**/*.spec.tsx",
3971
+ "**/*.spec.js",
3972
+ "**/*.spec.jsx",
3973
+ "**/__tests__/**",
3974
+ "**/tests/**"
3975
+ ],
3976
+ mocks: [
3977
+ "**/__mocks__/**",
3978
+ "**/*.mock.ts",
3979
+ "**/*.mock.tsx",
3980
+ "**/*.mock.js",
3981
+ "**/*.mock.jsx"
3982
+ ],
3983
+ barrels: ["**/index.ts", "**/index.js"],
3984
+ generated: [
3985
+ "**/.next/**",
3986
+ "**/.sst/**",
3987
+ "**/.cache/**",
3988
+ "**/dist/**",
3989
+ "**/build/**"
3990
+ ]
3991
+ };
3992
+ function deepMerge(base, override) {
3993
+ const result = { ...base };
3994
+ for (const key of Object.keys(override)) {
3995
+ const baseVal = base[key];
3996
+ const overrideVal = override[key];
3997
+ if (baseVal && overrideVal && typeof baseVal === "object" && typeof overrideVal === "object" && !Array.isArray(baseVal) && !Array.isArray(overrideVal)) {
3998
+ result[key] = deepMerge(baseVal, overrideVal);
3999
+ } else if (overrideVal !== void 0) {
4000
+ result[key] = overrideVal;
4001
+ }
4002
+ }
4003
+ return result;
4004
+ }
4005
+ function checkPatternWarnings(config, configPath) {
4006
+ const warnings = [];
4007
+ const excludeArray = Array.isArray(config.exclude) ? config.exclude : config.exclude ? Object.values(config.exclude).flat() : [];
4008
+ const seen = /* @__PURE__ */ new Set();
4009
+ for (const pattern of excludeArray) {
4010
+ if (seen.has(pattern)) {
4011
+ warnings.push({
4012
+ rule: "duplicate-exclude",
4013
+ message: `Duplicate pattern '${pattern}' in exclude array`
4014
+ });
4015
+ }
4016
+ seen.add(pattern);
4017
+ if (pattern.match(/^\*\*\/[^/]+\.[^/]+$/)) {
4018
+ warnings.push({
4019
+ rule: "single-file-glob",
4020
+ message: `Single-file glob '${pattern}' - use without ** prefix`,
4021
+ suggestion: pattern.replace(/^\*\*\//, "")
4022
+ });
4023
+ }
4024
+ const normalized = pattern.replace(/^\*\*\//, "").replace(/^\*\//, "");
4025
+ for (const other of seen) {
4026
+ if (other === pattern) continue;
4027
+ const otherNormalized = other.replace(/^\*\*\//, "").replace(/^\*\//, "");
4028
+ if (normalized === otherNormalized) {
4029
+ warnings.push({
4030
+ rule: "overlapping-pattern",
4031
+ message: `Patterns '${pattern}' and '${other}' likely match the same files`
4032
+ });
4033
+ }
4034
+ }
4035
+ }
4036
+ if (config.extends) {
4037
+ warnings.push({
4038
+ rule: "config-inheritance",
4039
+ message: `Config extends '${config.extends}' - ensure base config exists`
4040
+ });
4041
+ }
4042
+ return warnings;
4043
+ }
4044
+ function resolveConfigPath(extendsPath, baseConfigPath) {
4045
+ const baseDir = (0, import_path5.dirname)(baseConfigPath);
4046
+ return (0, import_path5.resolve)(baseDir, extendsPath);
4047
+ }
4048
+ async function loadConfigWithInheritance(configPath, alreadyLoaded = /* @__PURE__ */ new Set()) {
4049
+ const resolvedPath = (0, import_path5.resolve)(configPath);
4050
+ if (alreadyLoaded.has(resolvedPath)) {
4051
+ throw new Error(
4052
+ `Circular config inheritance detected: ${Array.from(alreadyLoaded).join(" -> ")} -> ${resolvedPath}`
4053
+ );
4054
+ }
4055
+ alreadyLoaded.add(resolvedPath);
4056
+ const content = (0, import_fs3.readFileSync)(resolvedPath, "utf-8");
4057
+ let rawConfig = JSON.parse(content);
4058
+ const warnings = [];
4059
+ const legacyKeys = ["toolConfigs", "scanConfig", "aiReady"];
4060
+ const foundLegacy = legacyKeys.filter((key) => key in rawConfig);
4061
+ if (foundLegacy.length > 0) {
4062
+ console.warn(
4063
+ `\u26A0\uFE0F Legacy configuration keys found: ${foundLegacy.join(", ")}. Please migrate to the new schema.`
4064
+ );
4065
+ }
4066
+ if (rawConfig.extends) {
4067
+ const baseConfigPath = resolveConfigPath(rawConfig.extends, resolvedPath);
4068
+ if (!(0, import_fs3.existsSync)(baseConfigPath)) {
4069
+ throw new Error(
4070
+ `Base config not found: ${rawConfig.extends} (resolved to ${baseConfigPath})`
4071
+ );
4072
+ }
4073
+ const baseResult = await loadConfigWithInheritance(
4074
+ baseConfigPath,
4075
+ alreadyLoaded
4076
+ );
4077
+ rawConfig = deepMerge(baseResult.config, rawConfig);
4078
+ warnings.push(...baseResult.warnings);
4079
+ }
4080
+ warnings.push(...checkPatternWarnings(rawConfig, resolvedPath));
4081
+ const config = AIReadyConfigSchema.parse(rawConfig);
4082
+ return { config, warnings };
4083
+ }
4084
+ function applyAutoExclusions(config, projectRoot) {
4085
+ const autoExclude = config.autoExclude ?? {
4086
+ tests: true,
4087
+ mocks: true,
4088
+ barrels: false,
4089
+ generated: true
4090
+ };
4091
+ if (!autoExclude.tests && !autoExclude.mocks && !autoExclude.barrels && !autoExclude.generated) {
4092
+ return config;
4093
+ }
4094
+ const patterns = [];
4095
+ if (autoExclude.tests) {
4096
+ patterns.push(...DEFAULT_AUTO_EXCLUDE_PATTERNS.tests);
4097
+ }
4098
+ if (autoExclude.mocks) {
4099
+ patterns.push(...DEFAULT_AUTO_EXCLUDE_PATTERNS.mocks);
4100
+ }
4101
+ if (autoExclude.barrels) {
4102
+ patterns.push(...DEFAULT_AUTO_EXCLUDE_PATTERNS.barrels);
4103
+ }
4104
+ if (autoExclude.generated) {
4105
+ patterns.push(...DEFAULT_AUTO_EXCLUDE_PATTERNS.generated);
4106
+ }
4107
+ const existingExclude = config.exclude ?? [];
4108
+ const existingArray = Array.isArray(existingExclude) ? existingExclude : existingExclude?.global ?? [];
4109
+ return {
4110
+ ...config,
4111
+ exclude: [...existingArray, ...patterns]
4112
+ };
4113
+ }
4114
+ async function loadConfig(rootDir, options) {
4115
+ const warnings = [];
4116
+ let currentDir = (0, import_path5.resolve)(rootDir);
3795
4117
  while (true) {
3796
4118
  const foundConfigs = [];
3797
4119
  for (const configFile of CONFIG_FILES) {
3798
- if ((0, import_fs3.existsSync)((0, import_path4.join)(currentDir, configFile))) {
4120
+ if ((0, import_fs3.existsSync)((0, import_path5.join)(currentDir, configFile))) {
3799
4121
  foundConfigs.push(configFile);
3800
4122
  }
3801
4123
  }
@@ -3806,39 +4128,17 @@ async function loadConfig(rootDir) {
3806
4128
  ", "
3807
4129
  )}. Using ${foundConfigs[0]}.`
3808
4130
  );
3809
- } else {
3810
4131
  }
3811
4132
  const configFile = foundConfigs[0];
3812
- const configPath = (0, import_path4.join)(currentDir, configFile);
4133
+ const configPath = (0, import_path5.join)(currentDir, configFile);
3813
4134
  try {
3814
- let config;
3815
- if (configFile.endsWith(".js")) {
3816
- const fileUrl = (0, import_url2.pathToFileURL)(configPath).href;
3817
- const module2 = await import(`${fileUrl}?t=${Date.now()}`);
3818
- config = module2.default || module2;
3819
- } else {
3820
- const content = (0, import_fs3.readFileSync)(configPath, "utf-8");
3821
- config = JSON.parse(content);
4135
+ const result = await loadConfigWithInheritance(configPath);
4136
+ warnings.push(...result.warnings);
4137
+ let config = result.config;
4138
+ if (options?.applyAutoExclude !== false) {
4139
+ config = applyAutoExclusions(config, currentDir);
3822
4140
  }
3823
- const legacyKeys = ["toolConfigs"];
3824
- const rootLevelTools = [
3825
- "pattern-detect",
3826
- "context-analyzer",
3827
- "naming-consistency",
3828
- "ai-signal-clarity"
3829
- ];
3830
- const allKeys = Object.keys(config);
3831
- const foundLegacy = allKeys.filter(
3832
- (k) => legacyKeys.includes(k) || rootLevelTools.includes(k)
3833
- );
3834
- if (foundLegacy.length > 0) {
3835
- console.warn(
3836
- `\u26A0\uFE0F Legacy configuration keys found: ${foundLegacy.join(
3837
- ", "
3838
- )}. These are deprecated and should be moved under the "tools" key.`
3839
- );
3840
- }
3841
- return AIReadyConfigSchema.parse(config);
4141
+ return { config, warnings };
3842
4142
  } catch (error) {
3843
4143
  const errorMessage = error instanceof Error ? error.message : String(error);
3844
4144
  const configError = new Error(
@@ -3851,13 +4151,27 @@ async function loadConfig(rootDir) {
3851
4151
  throw configError;
3852
4152
  }
3853
4153
  }
3854
- const parent = (0, import_path4.dirname)(currentDir);
4154
+ const parent = (0, import_path5.dirname)(currentDir);
3855
4155
  if (parent === currentDir) {
3856
4156
  break;
3857
4157
  }
3858
4158
  currentDir = parent;
3859
4159
  }
3860
- return null;
4160
+ return { config: null, warnings };
4161
+ }
4162
+ function validateConfig(configPath) {
4163
+ try {
4164
+ const content = (0, import_fs3.readFileSync)(configPath, "utf-8");
4165
+ const config = JSON.parse(content);
4166
+ return checkPatternWarnings(config, configPath);
4167
+ } catch (error) {
4168
+ return [
4169
+ {
4170
+ rule: "parse-error",
4171
+ message: `Failed to parse config: ${error instanceof Error ? error.message : String(error)}`
4172
+ }
4173
+ ];
4174
+ }
3861
4175
  }
3862
4176
  function mergeConfigWithDefaults(userConfig, defaults) {
3863
4177
  if (!userConfig) return defaults;
@@ -5003,6 +5317,9 @@ function extractBlocksPython(file, content) {
5003
5317
  return blocks;
5004
5318
  }
5005
5319
 
5320
+ // src/index.ts
5321
+ init_path_utils();
5322
+
5006
5323
  // src/business/pricing-models.ts
5007
5324
  var MODEL_PRICING_PRESETS = {
5008
5325
  "gpt-5.4-mini": {
@@ -6565,9 +6882,9 @@ function calculateChangeAmplification(params) {
6565
6882
 
6566
6883
  // src/utils/history.ts
6567
6884
  var import_fs4 = require("fs");
6568
- var import_path5 = require("path");
6885
+ var import_path6 = require("path");
6569
6886
  function getHistoryPath(rootDir) {
6570
- return (0, import_path5.join)(rootDir, ".aiready", "history.json");
6887
+ return (0, import_path6.join)(rootDir, ".aiready", "history.json");
6571
6888
  }
6572
6889
  function loadScoreHistory(rootDir) {
6573
6890
  const historyPath = getHistoryPath(rootDir);
@@ -6584,7 +6901,7 @@ function loadScoreHistory(rootDir) {
6584
6901
  }
6585
6902
  function saveScoreEntry(rootDir, entry) {
6586
6903
  const historyPath = getHistoryPath(rootDir);
6587
- const historyDir = (0, import_path5.dirname)(historyPath);
6904
+ const historyDir = (0, import_path6.dirname)(historyPath);
6588
6905
  if (!(0, import_fs4.existsSync)(historyDir)) {
6589
6906
  (0, import_fs4.mkdirSync)(historyDir, { recursive: true });
6590
6907
  }
@@ -6637,78 +6954,6 @@ function clearHistory(rootDir) {
6637
6954
  }
6638
6955
  }
6639
6956
 
6640
- // src/utils/history-git.ts
6641
- var import_child_process = require("child_process");
6642
- function getFileCommitTimestamps(file) {
6643
- const lineStamps = {};
6644
- try {
6645
- const output = (0, import_child_process.execSync)(`git blame -t "${file}"`, {
6646
- encoding: "utf-8",
6647
- stdio: ["ignore", "pipe", "ignore"]
6648
- });
6649
- const lines = output.split("\n");
6650
- for (const line of lines) {
6651
- if (!line) continue;
6652
- const match = line.match(/^\S+\s+\(.*?(\d{10,})\s+[-+]\d+\s+(\d+)\)/);
6653
- if (match) {
6654
- const ts = parseInt(match[1], 10);
6655
- const ln = parseInt(match[2], 10);
6656
- lineStamps[ln] = ts;
6657
- }
6658
- }
6659
- } catch {
6660
- }
6661
- return lineStamps;
6662
- }
6663
- function getLineRangeLastModifiedCached(lineStamps, startLine, endLine) {
6664
- let latest = 0;
6665
- for (let i = startLine; i <= endLine; i++) {
6666
- if (lineStamps[i] && lineStamps[i] > latest) {
6667
- latest = lineStamps[i];
6668
- }
6669
- }
6670
- return latest;
6671
- }
6672
- function getRepoMetadata(directory) {
6673
- const metadata = {};
6674
- try {
6675
- try {
6676
- metadata.url = (0, import_child_process.execSync)("git config --get remote.origin.url", {
6677
- cwd: directory,
6678
- encoding: "utf-8",
6679
- stdio: ["ignore", "pipe", "ignore"]
6680
- }).trim();
6681
- } catch {
6682
- }
6683
- try {
6684
- metadata.branch = (0, import_child_process.execSync)("git rev-parse --abbrev-ref HEAD", {
6685
- cwd: directory,
6686
- encoding: "utf-8",
6687
- stdio: ["ignore", "pipe", "ignore"]
6688
- }).trim();
6689
- } catch {
6690
- }
6691
- try {
6692
- metadata.commit = (0, import_child_process.execSync)("git rev-parse HEAD", {
6693
- cwd: directory,
6694
- encoding: "utf-8",
6695
- stdio: ["ignore", "pipe", "ignore"]
6696
- }).trim();
6697
- } catch {
6698
- }
6699
- try {
6700
- metadata.author = (0, import_child_process.execSync)("git log -1 --format=%ae", {
6701
- cwd: directory,
6702
- encoding: "utf-8",
6703
- stdio: ["ignore", "pipe", "ignore"]
6704
- }).trim();
6705
- } catch {
6706
- }
6707
- } catch {
6708
- }
6709
- return metadata;
6710
- }
6711
-
6712
6957
  // src/utils/github-utils.ts
6713
6958
  function emitAnnotation(params) {
6714
6959
  const { level, file, line, col, title, message } = params;
@@ -6797,7 +7042,7 @@ Found ${issues.length} issues.`));
6797
7042
 
6798
7043
  // src/utils/test-utils.ts
6799
7044
  var import_fs5 = require("fs");
6800
- var import_path6 = require("path");
7045
+ var import_path7 = require("path");
6801
7046
  var TEST_PATTERNS = [
6802
7047
  // TypeScript/JavaScript test files
6803
7048
  /\.(test|spec)\.(ts|tsx|js|jsx)$/,
@@ -6862,7 +7107,7 @@ function detectTestFramework(rootDir) {
6862
7107
  // go testing is built-in
6863
7108
  ];
6864
7109
  for (const m of manifests) {
6865
- const p = (0, import_path6.join)(rootDir, m.file);
7110
+ const p = (0, import_path7.join)(rootDir, m.file);
6866
7111
  if ((0, import_fs5.existsSync)(p)) {
6867
7112
  if (m.file === "go.mod") return true;
6868
7113
  try {
@@ -6920,6 +7165,188 @@ async function withErrorHandling(operation, context) {
6920
7165
  return { success: false, error: `${contextPrefix}${message}` };
6921
7166
  }
6922
7167
  }
7168
+
7169
+ // src/growth/agents.ts
7170
+ var import_child_process2 = require("child_process");
7171
+ var GitHubIssueResolverAgent = class {
7172
+ constructor(options) {
7173
+ this.generate = options.generate;
7174
+ if (!options.trustedAuthors || options.trustedAuthors.length === 0) {
7175
+ throw new Error(
7176
+ "[GitHubIssueResolverAgent] Security Error: trustedAuthors must be explicitly configured."
7177
+ );
7178
+ }
7179
+ this.trustedAuthors = options.trustedAuthors;
7180
+ }
7181
+ async resolve(issue, workingDir) {
7182
+ console.log(
7183
+ `[GitHubIssueResolverAgent] Resolving issue #${issue.number}: ${issue.title}`
7184
+ );
7185
+ const strategy = await this.identifyStrategy(issue);
7186
+ console.log(`[GitHubIssueResolverAgent] Selected Strategy: ${strategy}`);
7187
+ try {
7188
+ switch (strategy) {
7189
+ case "CORE_EVOLUTION_SYNC":
7190
+ if (issue.author && !this.trustedAuthors.includes(issue.author)) {
7191
+ console.warn(
7192
+ `[GitHubIssueResolverAgent] Unauthorized evolution attempt by ${issue.author}. Blocking.`
7193
+ );
7194
+ return {
7195
+ success: false,
7196
+ message: `Unauthorized actor: ${issue.author} is not in trustedAuthors list.`
7197
+ };
7198
+ }
7199
+ return await this.executeSubtreeSync(issue, workingDir);
7200
+ case "EVOLUTION_CONTRIBUTION":
7201
+ return await this.applyContributionPattern(issue, workingDir);
7202
+ case "BUG_FIX":
7203
+ return await this.applyAgenticPatch(issue, workingDir);
7204
+ default:
7205
+ return { success: false, message: `Unknown strategy: ${strategy}` };
7206
+ }
7207
+ } catch (error) {
7208
+ console.error(
7209
+ `[GitHubIssueResolverAgent] Resolution failed for issue #${issue.number}:`,
7210
+ error.message
7211
+ );
7212
+ return {
7213
+ success: false,
7214
+ message: `Resolution failed: ${error.message}`
7215
+ };
7216
+ }
7217
+ }
7218
+ async identifyStrategy(issue) {
7219
+ if (issue.labels.includes("evolution-sync")) return "CORE_EVOLUTION_SYNC";
7220
+ if (issue.labels.includes("evolution-contribution"))
7221
+ return "EVOLUTION_CONTRIBUTION";
7222
+ if (issue.labels.includes("bug")) return "BUG_FIX";
7223
+ const prompt = `
7224
+ Analyze the GitHub Issue:
7225
+ Title: ${issue.title}
7226
+ Labels: ${issue.labels.join(", ")}
7227
+
7228
+ Categorize into: CORE_EVOLUTION_SYNC, EVOLUTION_CONTRIBUTION, BUG_FIX, or UNKNOWN.
7229
+ Only return the category name.
7230
+ `;
7231
+ return (await this.generate(prompt)).trim();
7232
+ }
7233
+ async executeSubtreeSync(issue, workingDir) {
7234
+ const hubVersion = this.extractVersion(issue.body);
7235
+ const prefix = "core/";
7236
+ const hubUrl = "https://github.com/serverlessclaw/serverlessclaw.git";
7237
+ console.log(
7238
+ `[GitHubIssueResolverAgent] Performing Subtree Pull (Hub v${hubVersion}) into ${workingDir}...`
7239
+ );
7240
+ try {
7241
+ try {
7242
+ (0, import_child_process2.execSync)(`git remote add hub ${hubUrl}`, {
7243
+ cwd: workingDir,
7244
+ stdio: "ignore"
7245
+ });
7246
+ } catch (e) {
7247
+ if (!e.message.includes("already exists")) {
7248
+ console.warn(
7249
+ `[GitHubIssueResolverAgent] Remote add warning: ${e.message}`
7250
+ );
7251
+ }
7252
+ }
7253
+ (0, import_child_process2.execSync)(`git fetch hub`, { cwd: workingDir, stdio: "pipe" });
7254
+ console.log(
7255
+ `[GitHubIssueResolverAgent] Executing subtree pull for v${hubVersion}...`
7256
+ );
7257
+ (0, import_child_process2.execSync)(
7258
+ `git subtree pull --prefix=${prefix} hub ${hubVersion} --squash -m "chore(sync): evolution upgrade to ${hubVersion}"`,
7259
+ {
7260
+ cwd: workingDir,
7261
+ env: { ...process.env, GIT_MERGE_AUTOEDIT: "no" }
7262
+ }
7263
+ );
7264
+ return {
7265
+ success: true,
7266
+ message: `Successfully sync'd Hub ${hubVersion} via subtree merge`
7267
+ };
7268
+ } catch (error) {
7269
+ console.error(
7270
+ `[GitHubIssueResolverAgent] Subtree sync failed: ${error.message}`
7271
+ );
7272
+ throw new Error(`Subtree sync failed: ${error.message}`, {
7273
+ cause: error
7274
+ });
7275
+ }
7276
+ }
7277
+ async applyContributionPattern(issue, workingDir) {
7278
+ console.log(
7279
+ `[GitHubIssueResolverAgent] Pattern absorption requested: ${issue.title}`
7280
+ );
7281
+ return {
7282
+ success: true,
7283
+ message: `Contribution strategy identified. Pattern "${issue.title}" is ready for human screening and promotion.`
7284
+ };
7285
+ }
7286
+ async applyAgenticPatch(issue, workingDir) {
7287
+ console.log(`[GitHubIssueResolverAgent] Bug fix requested: ${issue.title}`);
7288
+ return {
7289
+ success: true,
7290
+ message: `Patch strategy identified. Agentic fix for "${issue.title}" is being drafted.`
7291
+ };
7292
+ }
7293
+ extractVersion(body) {
7294
+ const match = body.match(/v\d+\.\d+\.\d+/);
7295
+ if (match) return match[0];
7296
+ const branchMatch = body.match(/branch:?\s*([a-zA-Z0-9.\-_/]+)/i);
7297
+ if (branchMatch) return branchMatch[1];
7298
+ return "main";
7299
+ }
7300
+ };
7301
+
7302
+ // src/services/github-service.ts
7303
+ var import_rest = require("@octokit/rest");
7304
+ var GitHubService = class {
7305
+ constructor(token) {
7306
+ this.octokit = new import_rest.Octokit({ auth: token });
7307
+ }
7308
+ /**
7309
+ * Creates an issue in a repository.
7310
+ */
7311
+ async createHubIssue(owner, repo, issue) {
7312
+ const { data } = await this.octokit.issues.create({
7313
+ owner,
7314
+ repo,
7315
+ title: issue.title,
7316
+ body: issue.body,
7317
+ labels: issue.labels || ["innovation-harvest"]
7318
+ });
7319
+ return data.number;
7320
+ }
7321
+ /**
7322
+ * Creates a Pull Request in a repository.
7323
+ */
7324
+ async createPullRequest(owner, repo, pr) {
7325
+ const { data } = await this.octokit.pulls.create({
7326
+ owner,
7327
+ repo,
7328
+ title: pr.title,
7329
+ body: pr.body,
7330
+ head: pr.head,
7331
+ base: pr.base
7332
+ });
7333
+ return data.number;
7334
+ }
7335
+ /**
7336
+ * Scans a repository content.
7337
+ */
7338
+ async listRecentChangesInRepo(owner, repo, path2 = "") {
7339
+ const { data } = await this.octokit.repos.getContent({
7340
+ owner,
7341
+ repo,
7342
+ path: path2
7343
+ });
7344
+ if (Array.isArray(data)) {
7345
+ return data.map((file) => file.path);
7346
+ }
7347
+ return [];
7348
+ }
7349
+ };
6923
7350
  // Annotate the CommonJS export names for ESM import in node:
6924
7351
  0 && (module.exports = {
6925
7352
  AIReadyConfigSchema,
@@ -6930,6 +7357,7 @@ async function withErrorHandling(operation, context) {
6930
7357
  COMMON_FINE_TUNING_OPTIONS,
6931
7358
  CONTEXT_TIER_THRESHOLDS,
6932
7359
  CSharpParser,
7360
+ DEFAULT_AUTO_EXCLUDE_PATTERNS,
6933
7361
  DEFAULT_COST_CONFIG,
6934
7362
  DEFAULT_EXCLUDE,
6935
7363
  DEFAULT_TOOL_WEIGHTS,
@@ -6938,6 +7366,8 @@ async function withErrorHandling(operation, context) {
6938
7366
  FRIENDLY_TOOL_NAMES,
6939
7367
  GLOBAL_INFRA_OPTIONS,
6940
7368
  GLOBAL_SCAN_OPTIONS,
7369
+ GitHubIssueResolverAgent,
7370
+ GitHubService,
6941
7371
  GoParser,
6942
7372
  IssueSchema,
6943
7373
  IssueType,
@@ -7042,6 +7472,8 @@ async function withErrorHandling(operation, context) {
7042
7472
  generateStatCards,
7043
7473
  generateTable,
7044
7474
  generateValueChain,
7475
+ getChangedFiles,
7476
+ getDirname,
7045
7477
  getElapsedTime,
7046
7478
  getErrorMessage,
7047
7479
  getFileCommitTimestamps,
@@ -7110,12 +7542,14 @@ async function withErrorHandling(operation, context) {
7110
7542
  resolveOutputPath,
7111
7543
  runBatchAnalysis,
7112
7544
  runStandardCliAction,
7545
+ safeJsonStringify,
7113
7546
  saveScoreEntry,
7114
7547
  scanEntries,
7115
7548
  scanFiles,
7116
7549
  setupParser,
7117
7550
  severityToAnnotationLevel,
7118
7551
  toErrorMessage,
7552
+ validateConfig,
7119
7553
  validateSpokeOutput,
7120
7554
  validateWithSchema,
7121
7555
  withErrorHandling,