@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.
- package/dist/chunk-3GCIM6XG.mjs +904 -0
- package/dist/chunk-3S5WU6KX.mjs +552 -0
- package/dist/chunk-4OMXBYX7.mjs +167 -0
- package/dist/chunk-6YWGFKZG.mjs +250 -0
- package/dist/chunk-A3BIROBZ.mjs +902 -0
- package/dist/chunk-BYMQDORS.mjs +256 -0
- package/dist/chunk-CBZNRNEF.mjs +309 -0
- package/dist/chunk-ET2WRQSM.mjs +262 -0
- package/dist/chunk-F4FTHFHK.mjs +552 -0
- package/dist/chunk-G737F72Q.mjs +256 -0
- package/dist/chunk-GVFUAIWU.mjs +864 -0
- package/dist/chunk-KSEA5XDH.mjs +894 -0
- package/dist/chunk-LMIZRJFV.mjs +256 -0
- package/dist/chunk-LRPBPWBM.mjs +170 -0
- package/dist/chunk-MOTBXU6W.mjs +902 -0
- package/dist/chunk-OAH6FVVF.mjs +919 -0
- package/dist/chunk-OCM6HLBM.mjs +262 -0
- package/dist/chunk-OFBRNGKT.mjs +893 -0
- package/dist/chunk-P3KYGPO4.mjs +262 -0
- package/dist/chunk-PNWSO6XQ.mjs +250 -0
- package/dist/chunk-SO6UKAPR.mjs +164 -0
- package/dist/chunk-T2FW6AAF.mjs +552 -0
- package/dist/chunk-TQX77RIC.mjs +250 -0
- package/dist/chunk-X64EJ3ZO.mjs +314 -0
- package/dist/client/index.d.mts +1 -1
- package/dist/client/index.d.ts +1 -1
- package/dist/client/index.js +32 -5
- package/dist/client/index.mjs +1 -1
- package/dist/csharp-parser-3CGM6FKB.mjs +9 -0
- package/dist/csharp-parser-UWRUYHUH.mjs +9 -0
- package/dist/csharp-parser-WIAIE3DD.mjs +9 -0
- package/dist/go-parser-AH5QNS4O.mjs +9 -0
- package/dist/go-parser-CSAB23BL.mjs +9 -0
- package/dist/go-parser-Q3HI32B7.mjs +9 -0
- package/dist/index-CL_0jxiJ.d.mts +1315 -0
- package/dist/index-CL_0jxiJ.d.ts +1315 -0
- package/dist/index-ClwnZa_Y.d.mts +1333 -0
- package/dist/index-ClwnZa_Y.d.ts +1333 -0
- package/dist/index-DC0cdf0g.d.mts +1321 -0
- package/dist/index-DC0cdf0g.d.ts +1321 -0
- package/dist/index-DKqKGhcJ.d.mts +1309 -0
- package/dist/index-DKqKGhcJ.d.ts +1309 -0
- package/dist/index-DNnlhdk0.d.mts +1318 -0
- package/dist/index-DNnlhdk0.d.ts +1318 -0
- package/dist/index-De2xy_k5.d.mts +1326 -0
- package/dist/index-De2xy_k5.d.ts +1326 -0
- package/dist/index.d.mts +104 -20
- package/dist/index.d.ts +104 -20
- package/dist/index.js +581 -147
- package/dist/index.mjs +507 -134
- package/dist/java-parser-GUKWCEYS.mjs +9 -0
- package/dist/java-parser-XTWT5Y5I.mjs +9 -0
- package/dist/java-parser-YP5XWLQK.mjs +9 -0
- package/dist/python-parser-AOPXUEIV.mjs +8 -0
- package/dist/python-parser-FB55P6UA.mjs +8 -0
- package/dist/python-parser-WIJPSRKC.mjs +8 -0
- package/dist/typescript-parser-5ZWLLMWJ.mjs +7 -0
- package/dist/typescript-parser-TWPRLYK6.mjs +7 -0
- package/package.json +5 -1
package/dist/index.mjs
CHANGED
|
@@ -52,28 +52,29 @@ import {
|
|
|
52
52
|
getToolWeight,
|
|
53
53
|
normalizeToolName,
|
|
54
54
|
parseWeightString
|
|
55
|
-
} from "./chunk-
|
|
55
|
+
} from "./chunk-OAH6FVVF.mjs";
|
|
56
56
|
import {
|
|
57
57
|
TypeScriptParser
|
|
58
|
-
} from "./chunk-
|
|
58
|
+
} from "./chunk-X64EJ3ZO.mjs";
|
|
59
59
|
import {
|
|
60
60
|
PythonParser
|
|
61
|
-
} from "./chunk-
|
|
61
|
+
} from "./chunk-T2FW6AAF.mjs";
|
|
62
62
|
import {
|
|
63
63
|
JavaParser
|
|
64
|
-
} from "./chunk-
|
|
64
|
+
} from "./chunk-TQX77RIC.mjs";
|
|
65
65
|
import {
|
|
66
66
|
CSharpParser
|
|
67
|
-
} from "./chunk-
|
|
67
|
+
} from "./chunk-G737F72Q.mjs";
|
|
68
68
|
import {
|
|
69
69
|
GoParser
|
|
70
|
-
} from "./chunk-
|
|
70
|
+
} from "./chunk-OCM6HLBM.mjs";
|
|
71
71
|
import "./chunk-3D3I5K5W.mjs";
|
|
72
72
|
import {
|
|
73
|
+
getDirname,
|
|
73
74
|
getWasmPath,
|
|
74
75
|
initTreeSitter,
|
|
75
76
|
setupParser
|
|
76
|
-
} from "./chunk-
|
|
77
|
+
} from "./chunk-LRPBPWBM.mjs";
|
|
77
78
|
import {
|
|
78
79
|
LANGUAGE_EXTENSIONS,
|
|
79
80
|
Language,
|
|
@@ -334,8 +335,108 @@ var ToolRegistry = class _ToolRegistry {
|
|
|
334
335
|
import { glob } from "glob";
|
|
335
336
|
import { readFile } from "fs/promises";
|
|
336
337
|
import { existsSync } from "fs";
|
|
337
|
-
import { join, relative, dirname } from "path";
|
|
338
|
+
import { join, relative, dirname, resolve } from "path";
|
|
338
339
|
import ignorePkg from "ignore";
|
|
340
|
+
|
|
341
|
+
// src/utils/history-git.ts
|
|
342
|
+
import { execSync } from "child_process";
|
|
343
|
+
function getFileCommitTimestamps(file) {
|
|
344
|
+
const lineStamps = {};
|
|
345
|
+
try {
|
|
346
|
+
const output = execSync(`git blame -t "${file}"`, {
|
|
347
|
+
encoding: "utf-8",
|
|
348
|
+
stdio: ["ignore", "pipe", "ignore"]
|
|
349
|
+
});
|
|
350
|
+
const lines = output.split("\n");
|
|
351
|
+
for (const line of lines) {
|
|
352
|
+
if (!line) continue;
|
|
353
|
+
const match = line.match(/^\S+\s+\(.*?(\d{10,})\s+[-+]\d+\s+(\d+)\)/);
|
|
354
|
+
if (match) {
|
|
355
|
+
const ts = parseInt(match[1], 10);
|
|
356
|
+
const ln = parseInt(match[2], 10);
|
|
357
|
+
lineStamps[ln] = ts;
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
} catch {
|
|
361
|
+
}
|
|
362
|
+
return lineStamps;
|
|
363
|
+
}
|
|
364
|
+
function getLineRangeLastModifiedCached(lineStamps, startLine, endLine) {
|
|
365
|
+
let latest = 0;
|
|
366
|
+
for (let i = startLine; i <= endLine; i++) {
|
|
367
|
+
if (lineStamps[i] && lineStamps[i] > latest) {
|
|
368
|
+
latest = lineStamps[i];
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
return latest;
|
|
372
|
+
}
|
|
373
|
+
function getRepoMetadata(directory) {
|
|
374
|
+
const metadata = {};
|
|
375
|
+
try {
|
|
376
|
+
try {
|
|
377
|
+
metadata.url = execSync("git config --get remote.origin.url", {
|
|
378
|
+
cwd: directory,
|
|
379
|
+
encoding: "utf-8",
|
|
380
|
+
stdio: ["ignore", "pipe", "ignore"]
|
|
381
|
+
}).trim();
|
|
382
|
+
} catch {
|
|
383
|
+
}
|
|
384
|
+
try {
|
|
385
|
+
metadata.branch = execSync("git rev-parse --abbrev-ref HEAD", {
|
|
386
|
+
cwd: directory,
|
|
387
|
+
encoding: "utf-8",
|
|
388
|
+
stdio: ["ignore", "pipe", "ignore"]
|
|
389
|
+
}).trim();
|
|
390
|
+
} catch {
|
|
391
|
+
}
|
|
392
|
+
try {
|
|
393
|
+
metadata.commit = execSync("git rev-parse HEAD", {
|
|
394
|
+
cwd: directory,
|
|
395
|
+
encoding: "utf-8",
|
|
396
|
+
stdio: ["ignore", "pipe", "ignore"]
|
|
397
|
+
}).trim();
|
|
398
|
+
} catch {
|
|
399
|
+
}
|
|
400
|
+
try {
|
|
401
|
+
metadata.author = execSync("git log -1 --format=%ae", {
|
|
402
|
+
cwd: directory,
|
|
403
|
+
encoding: "utf-8",
|
|
404
|
+
stdio: ["ignore", "pipe", "ignore"]
|
|
405
|
+
}).trim();
|
|
406
|
+
} catch {
|
|
407
|
+
}
|
|
408
|
+
} catch {
|
|
409
|
+
}
|
|
410
|
+
return metadata;
|
|
411
|
+
}
|
|
412
|
+
function getChangedFiles(directory) {
|
|
413
|
+
const changedFiles = /* @__PURE__ */ new Set();
|
|
414
|
+
try {
|
|
415
|
+
const trackedOutput = execSync("git diff HEAD --name-only", {
|
|
416
|
+
cwd: directory,
|
|
417
|
+
encoding: "utf-8",
|
|
418
|
+
stdio: ["ignore", "pipe", "ignore"]
|
|
419
|
+
}).trim();
|
|
420
|
+
if (trackedOutput) {
|
|
421
|
+
trackedOutput.split("\n").forEach((f) => changedFiles.add(f));
|
|
422
|
+
}
|
|
423
|
+
const untrackedOutput = execSync(
|
|
424
|
+
"git ls-files --others --exclude-standard",
|
|
425
|
+
{
|
|
426
|
+
cwd: directory,
|
|
427
|
+
encoding: "utf-8",
|
|
428
|
+
stdio: ["ignore", "pipe", "ignore"]
|
|
429
|
+
}
|
|
430
|
+
).trim();
|
|
431
|
+
if (untrackedOutput) {
|
|
432
|
+
untrackedOutput.split("\n").forEach((f) => changedFiles.add(f));
|
|
433
|
+
}
|
|
434
|
+
} catch {
|
|
435
|
+
}
|
|
436
|
+
return Array.from(changedFiles);
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
// src/utils/file-scanner.ts
|
|
339
440
|
var DEFAULT_EXCLUDE = [
|
|
340
441
|
// Dependencies
|
|
341
442
|
"**/node_modules/**",
|
|
@@ -407,12 +508,12 @@ var VAGUE_FILE_NAMES = /* @__PURE__ */ new Set([
|
|
|
407
508
|
]);
|
|
408
509
|
async function scanFiles(options) {
|
|
409
510
|
const {
|
|
410
|
-
rootDir,
|
|
511
|
+
rootDir = ".",
|
|
411
512
|
include = ["**/*.{ts,tsx,js,jsx,py,java,go,rs,cs}"],
|
|
412
513
|
// Multi-language support
|
|
413
514
|
exclude
|
|
414
515
|
} = options;
|
|
415
|
-
const ignoreFilePath = join(rootDir
|
|
516
|
+
const ignoreFilePath = join(rootDir, ".aireadyignore");
|
|
416
517
|
let ignoreFromFile = [];
|
|
417
518
|
if (existsSync(ignoreFilePath)) {
|
|
418
519
|
try {
|
|
@@ -445,13 +546,14 @@ async function scanFiles(options) {
|
|
|
445
546
|
// Minimal ignore for gitignore discovery
|
|
446
547
|
absolute: true
|
|
447
548
|
});
|
|
549
|
+
let filtered = files;
|
|
448
550
|
if (gitignoreFiles.length > 0) {
|
|
449
551
|
try {
|
|
450
552
|
const ig = ignorePkg();
|
|
451
553
|
for (const gitignorePath of gitignoreFiles) {
|
|
452
554
|
const gitTxt = await readFile(gitignorePath, "utf-8");
|
|
453
555
|
const gitignoreDir = dirname(gitignorePath);
|
|
454
|
-
const relativePrefix = relative(rootDir
|
|
556
|
+
const relativePrefix = relative(rootDir, gitignoreDir).replace(
|
|
455
557
|
/\\/g,
|
|
456
558
|
"/"
|
|
457
559
|
);
|
|
@@ -466,22 +568,26 @@ async function scanFiles(options) {
|
|
|
466
568
|
);
|
|
467
569
|
}
|
|
468
570
|
}
|
|
469
|
-
|
|
470
|
-
let rel = relative(rootDir
|
|
571
|
+
filtered = files.filter((f) => {
|
|
572
|
+
let rel = relative(rootDir, f).replace(/\\/g, "/");
|
|
471
573
|
if (rel === "") rel = f;
|
|
472
574
|
return !ig.ignores(rel);
|
|
473
575
|
});
|
|
474
|
-
return filtered;
|
|
475
576
|
} catch {
|
|
476
|
-
return files;
|
|
477
577
|
}
|
|
478
578
|
}
|
|
479
|
-
|
|
579
|
+
if (options.changedFilesOnly) {
|
|
580
|
+
const changedFiles = getChangedFiles(rootDir).map(
|
|
581
|
+
(f) => resolve(rootDir, f)
|
|
582
|
+
);
|
|
583
|
+
return filtered.filter((f) => changedFiles.includes(f));
|
|
584
|
+
}
|
|
585
|
+
return filtered;
|
|
480
586
|
}
|
|
481
587
|
async function scanEntries(options) {
|
|
482
588
|
const files = await scanFiles(options);
|
|
483
|
-
const { rootDir, exclude, includeTests } = options;
|
|
484
|
-
const ignoreFilePath = join(rootDir
|
|
589
|
+
const { rootDir = ".", exclude, includeTests } = options;
|
|
590
|
+
const ignoreFilePath = join(rootDir, ".aireadyignore");
|
|
485
591
|
let ignoreFromFile = [];
|
|
486
592
|
if (existsSync(ignoreFilePath)) {
|
|
487
593
|
try {
|
|
@@ -517,7 +623,7 @@ async function scanEntries(options) {
|
|
|
517
623
|
for (const gitignorePath of gitignoreFiles) {
|
|
518
624
|
const gitTxt = await readFile(gitignorePath, "utf-8");
|
|
519
625
|
const gitignoreDir = dirname(gitignorePath);
|
|
520
|
-
const relativePrefix = relative(rootDir
|
|
626
|
+
const relativePrefix = relative(rootDir, gitignoreDir).replace(
|
|
521
627
|
/\\/g,
|
|
522
628
|
"/"
|
|
523
629
|
);
|
|
@@ -533,7 +639,7 @@ async function scanEntries(options) {
|
|
|
533
639
|
}
|
|
534
640
|
}
|
|
535
641
|
const filteredDirs = dirs.filter((d) => {
|
|
536
|
-
let rel = relative(rootDir
|
|
642
|
+
let rel = relative(rootDir, d).replace(/\\/g, "/");
|
|
537
643
|
if (rel === "") return true;
|
|
538
644
|
if (!rel.endsWith("/")) rel += "/";
|
|
539
645
|
return !ig.ignores(rel);
|
|
@@ -595,13 +701,20 @@ function resolveOutputPath(userPath, defaultFilename, workingDir = process.cwd()
|
|
|
595
701
|
ensureDir(outputPath);
|
|
596
702
|
return outputPath;
|
|
597
703
|
}
|
|
704
|
+
function safeJsonStringify(obj, indent = 2) {
|
|
705
|
+
return JSON.stringify(
|
|
706
|
+
obj,
|
|
707
|
+
(_, v) => typeof v === "bigint" ? v.toString() : v,
|
|
708
|
+
indent
|
|
709
|
+
);
|
|
710
|
+
}
|
|
598
711
|
function handleJSONOutput(data, outputFile, successMessage) {
|
|
599
712
|
if (outputFile) {
|
|
600
713
|
ensureDir(outputFile);
|
|
601
|
-
writeFileSync(outputFile,
|
|
714
|
+
writeFileSync(outputFile, safeJsonStringify(data, 2));
|
|
602
715
|
console.log(successMessage || `\u2705 Results saved to ${outputFile}`);
|
|
603
716
|
} else {
|
|
604
|
-
console.log(
|
|
717
|
+
console.log(safeJsonStringify(data, 2));
|
|
605
718
|
}
|
|
606
719
|
}
|
|
607
720
|
function findLatestReport(dirPath) {
|
|
@@ -792,7 +905,7 @@ function handleCLIError(error, commandName) {
|
|
|
792
905
|
|
|
793
906
|
// src/utils/cli-helpers.ts
|
|
794
907
|
async function loadMergedConfig(directory, defaults, cliOptions) {
|
|
795
|
-
const config = await loadConfig(directory);
|
|
908
|
+
const { config } = await loadConfig(directory);
|
|
796
909
|
const mergedConfig = mergeConfigWithDefaults(config, defaults);
|
|
797
910
|
const result = {
|
|
798
911
|
...mergedConfig,
|
|
@@ -954,27 +1067,27 @@ var ParserFactory = class _ParserFactory {
|
|
|
954
1067
|
Object.entries(LANGUAGE_EXTENSIONS).map(([ext, lang]) => [ext, lang])
|
|
955
1068
|
);
|
|
956
1069
|
this.registerLazyParser("typescript" /* TypeScript */, async () => {
|
|
957
|
-
const { TypeScriptParser: TypeScriptParser2 } = await import("./typescript-parser-
|
|
1070
|
+
const { TypeScriptParser: TypeScriptParser2 } = await import("./typescript-parser-5ZWLLMWJ.mjs");
|
|
958
1071
|
return new TypeScriptParser2();
|
|
959
1072
|
});
|
|
960
1073
|
this.registerLazyParser("javascript" /* JavaScript */, async () => {
|
|
961
|
-
const { TypeScriptParser: TypeScriptParser2 } = await import("./typescript-parser-
|
|
1074
|
+
const { TypeScriptParser: TypeScriptParser2 } = await import("./typescript-parser-5ZWLLMWJ.mjs");
|
|
962
1075
|
return new TypeScriptParser2();
|
|
963
1076
|
});
|
|
964
1077
|
this.registerLazyParser("python" /* Python */, async () => {
|
|
965
|
-
const { PythonParser: PythonParser2 } = await import("./python-parser-
|
|
1078
|
+
const { PythonParser: PythonParser2 } = await import("./python-parser-WIJPSRKC.mjs");
|
|
966
1079
|
return new PythonParser2();
|
|
967
1080
|
});
|
|
968
1081
|
this.registerLazyParser("java" /* Java */, async () => {
|
|
969
|
-
const { JavaParser: JavaParser2 } = await import("./java-parser-
|
|
1082
|
+
const { JavaParser: JavaParser2 } = await import("./java-parser-YP5XWLQK.mjs");
|
|
970
1083
|
return new JavaParser2();
|
|
971
1084
|
});
|
|
972
1085
|
this.registerLazyParser("csharp" /* CSharp */, async () => {
|
|
973
|
-
const { CSharpParser: CSharpParser2 } = await import("./csharp-parser-
|
|
1086
|
+
const { CSharpParser: CSharpParser2 } = await import("./csharp-parser-WIAIE3DD.mjs");
|
|
974
1087
|
return new CSharpParser2();
|
|
975
1088
|
});
|
|
976
1089
|
this.registerLazyParser("go" /* Go */, async () => {
|
|
977
|
-
const { GoParser: GoParser2 } = await import("./go-parser-
|
|
1090
|
+
const { GoParser: GoParser2 } = await import("./go-parser-Q3HI32B7.mjs");
|
|
978
1091
|
return new GoParser2();
|
|
979
1092
|
});
|
|
980
1093
|
}
|
|
@@ -1323,8 +1436,7 @@ function estimateTokens(text) {
|
|
|
1323
1436
|
|
|
1324
1437
|
// src/utils/config.ts
|
|
1325
1438
|
import { readFileSync, existsSync as existsSync3 } from "fs";
|
|
1326
|
-
import { join as join3, resolve, dirname as dirname3 } from "path";
|
|
1327
|
-
import { pathToFileURL } from "url";
|
|
1439
|
+
import { join as join3, resolve as resolve2, dirname as dirname3 } from "path";
|
|
1328
1440
|
var CONFIG_FILES = [
|
|
1329
1441
|
"aiready.json",
|
|
1330
1442
|
"aiready.config.json",
|
|
@@ -1333,8 +1445,160 @@ var CONFIG_FILES = [
|
|
|
1333
1445
|
"aiready.config.js",
|
|
1334
1446
|
".aireadyrc.js"
|
|
1335
1447
|
];
|
|
1336
|
-
|
|
1337
|
-
|
|
1448
|
+
var DEFAULT_AUTO_EXCLUDE_PATTERNS = {
|
|
1449
|
+
tests: [
|
|
1450
|
+
"**/*.test.ts",
|
|
1451
|
+
"**/*.test.tsx",
|
|
1452
|
+
"**/*.test.js",
|
|
1453
|
+
"**/*.test.jsx",
|
|
1454
|
+
"**/*.spec.ts",
|
|
1455
|
+
"**/*.spec.tsx",
|
|
1456
|
+
"**/*.spec.js",
|
|
1457
|
+
"**/*.spec.jsx",
|
|
1458
|
+
"**/__tests__/**",
|
|
1459
|
+
"**/tests/**"
|
|
1460
|
+
],
|
|
1461
|
+
mocks: [
|
|
1462
|
+
"**/__mocks__/**",
|
|
1463
|
+
"**/*.mock.ts",
|
|
1464
|
+
"**/*.mock.tsx",
|
|
1465
|
+
"**/*.mock.js",
|
|
1466
|
+
"**/*.mock.jsx"
|
|
1467
|
+
],
|
|
1468
|
+
barrels: ["**/index.ts", "**/index.js"],
|
|
1469
|
+
generated: [
|
|
1470
|
+
"**/.next/**",
|
|
1471
|
+
"**/.sst/**",
|
|
1472
|
+
"**/.cache/**",
|
|
1473
|
+
"**/dist/**",
|
|
1474
|
+
"**/build/**"
|
|
1475
|
+
]
|
|
1476
|
+
};
|
|
1477
|
+
function deepMerge(base, override) {
|
|
1478
|
+
const result = { ...base };
|
|
1479
|
+
for (const key of Object.keys(override)) {
|
|
1480
|
+
const baseVal = base[key];
|
|
1481
|
+
const overrideVal = override[key];
|
|
1482
|
+
if (baseVal && overrideVal && typeof baseVal === "object" && typeof overrideVal === "object" && !Array.isArray(baseVal) && !Array.isArray(overrideVal)) {
|
|
1483
|
+
result[key] = deepMerge(baseVal, overrideVal);
|
|
1484
|
+
} else if (overrideVal !== void 0) {
|
|
1485
|
+
result[key] = overrideVal;
|
|
1486
|
+
}
|
|
1487
|
+
}
|
|
1488
|
+
return result;
|
|
1489
|
+
}
|
|
1490
|
+
function checkPatternWarnings(config, configPath) {
|
|
1491
|
+
const warnings = [];
|
|
1492
|
+
const excludeArray = Array.isArray(config.exclude) ? config.exclude : config.exclude ? Object.values(config.exclude).flat() : [];
|
|
1493
|
+
const seen = /* @__PURE__ */ new Set();
|
|
1494
|
+
for (const pattern of excludeArray) {
|
|
1495
|
+
if (seen.has(pattern)) {
|
|
1496
|
+
warnings.push({
|
|
1497
|
+
rule: "duplicate-exclude",
|
|
1498
|
+
message: `Duplicate pattern '${pattern}' in exclude array`
|
|
1499
|
+
});
|
|
1500
|
+
}
|
|
1501
|
+
seen.add(pattern);
|
|
1502
|
+
if (pattern.match(/^\*\*\/[^/]+\.[^/]+$/)) {
|
|
1503
|
+
warnings.push({
|
|
1504
|
+
rule: "single-file-glob",
|
|
1505
|
+
message: `Single-file glob '${pattern}' - use without ** prefix`,
|
|
1506
|
+
suggestion: pattern.replace(/^\*\*\//, "")
|
|
1507
|
+
});
|
|
1508
|
+
}
|
|
1509
|
+
const normalized = pattern.replace(/^\*\*\//, "").replace(/^\*\//, "");
|
|
1510
|
+
for (const other of seen) {
|
|
1511
|
+
if (other === pattern) continue;
|
|
1512
|
+
const otherNormalized = other.replace(/^\*\*\//, "").replace(/^\*\//, "");
|
|
1513
|
+
if (normalized === otherNormalized) {
|
|
1514
|
+
warnings.push({
|
|
1515
|
+
rule: "overlapping-pattern",
|
|
1516
|
+
message: `Patterns '${pattern}' and '${other}' likely match the same files`
|
|
1517
|
+
});
|
|
1518
|
+
}
|
|
1519
|
+
}
|
|
1520
|
+
}
|
|
1521
|
+
if (config.extends) {
|
|
1522
|
+
warnings.push({
|
|
1523
|
+
rule: "config-inheritance",
|
|
1524
|
+
message: `Config extends '${config.extends}' - ensure base config exists`
|
|
1525
|
+
});
|
|
1526
|
+
}
|
|
1527
|
+
return warnings;
|
|
1528
|
+
}
|
|
1529
|
+
function resolveConfigPath(extendsPath, baseConfigPath) {
|
|
1530
|
+
const baseDir = dirname3(baseConfigPath);
|
|
1531
|
+
return resolve2(baseDir, extendsPath);
|
|
1532
|
+
}
|
|
1533
|
+
async function loadConfigWithInheritance(configPath, alreadyLoaded = /* @__PURE__ */ new Set()) {
|
|
1534
|
+
const resolvedPath = resolve2(configPath);
|
|
1535
|
+
if (alreadyLoaded.has(resolvedPath)) {
|
|
1536
|
+
throw new Error(
|
|
1537
|
+
`Circular config inheritance detected: ${Array.from(alreadyLoaded).join(" -> ")} -> ${resolvedPath}`
|
|
1538
|
+
);
|
|
1539
|
+
}
|
|
1540
|
+
alreadyLoaded.add(resolvedPath);
|
|
1541
|
+
const content = readFileSync(resolvedPath, "utf-8");
|
|
1542
|
+
let rawConfig = JSON.parse(content);
|
|
1543
|
+
const warnings = [];
|
|
1544
|
+
const legacyKeys = ["toolConfigs", "scanConfig", "aiReady"];
|
|
1545
|
+
const foundLegacy = legacyKeys.filter((key) => key in rawConfig);
|
|
1546
|
+
if (foundLegacy.length > 0) {
|
|
1547
|
+
console.warn(
|
|
1548
|
+
`\u26A0\uFE0F Legacy configuration keys found: ${foundLegacy.join(", ")}. Please migrate to the new schema.`
|
|
1549
|
+
);
|
|
1550
|
+
}
|
|
1551
|
+
if (rawConfig.extends) {
|
|
1552
|
+
const baseConfigPath = resolveConfigPath(rawConfig.extends, resolvedPath);
|
|
1553
|
+
if (!existsSync3(baseConfigPath)) {
|
|
1554
|
+
throw new Error(
|
|
1555
|
+
`Base config not found: ${rawConfig.extends} (resolved to ${baseConfigPath})`
|
|
1556
|
+
);
|
|
1557
|
+
}
|
|
1558
|
+
const baseResult = await loadConfigWithInheritance(
|
|
1559
|
+
baseConfigPath,
|
|
1560
|
+
alreadyLoaded
|
|
1561
|
+
);
|
|
1562
|
+
rawConfig = deepMerge(baseResult.config, rawConfig);
|
|
1563
|
+
warnings.push(...baseResult.warnings);
|
|
1564
|
+
}
|
|
1565
|
+
warnings.push(...checkPatternWarnings(rawConfig, resolvedPath));
|
|
1566
|
+
const config = AIReadyConfigSchema.parse(rawConfig);
|
|
1567
|
+
return { config, warnings };
|
|
1568
|
+
}
|
|
1569
|
+
function applyAutoExclusions(config, projectRoot) {
|
|
1570
|
+
const autoExclude = config.autoExclude ?? {
|
|
1571
|
+
tests: true,
|
|
1572
|
+
mocks: true,
|
|
1573
|
+
barrels: false,
|
|
1574
|
+
generated: true
|
|
1575
|
+
};
|
|
1576
|
+
if (!autoExclude.tests && !autoExclude.mocks && !autoExclude.barrels && !autoExclude.generated) {
|
|
1577
|
+
return config;
|
|
1578
|
+
}
|
|
1579
|
+
const patterns = [];
|
|
1580
|
+
if (autoExclude.tests) {
|
|
1581
|
+
patterns.push(...DEFAULT_AUTO_EXCLUDE_PATTERNS.tests);
|
|
1582
|
+
}
|
|
1583
|
+
if (autoExclude.mocks) {
|
|
1584
|
+
patterns.push(...DEFAULT_AUTO_EXCLUDE_PATTERNS.mocks);
|
|
1585
|
+
}
|
|
1586
|
+
if (autoExclude.barrels) {
|
|
1587
|
+
patterns.push(...DEFAULT_AUTO_EXCLUDE_PATTERNS.barrels);
|
|
1588
|
+
}
|
|
1589
|
+
if (autoExclude.generated) {
|
|
1590
|
+
patterns.push(...DEFAULT_AUTO_EXCLUDE_PATTERNS.generated);
|
|
1591
|
+
}
|
|
1592
|
+
const existingExclude = config.exclude ?? [];
|
|
1593
|
+
const existingArray = Array.isArray(existingExclude) ? existingExclude : existingExclude?.global ?? [];
|
|
1594
|
+
return {
|
|
1595
|
+
...config,
|
|
1596
|
+
exclude: [...existingArray, ...patterns]
|
|
1597
|
+
};
|
|
1598
|
+
}
|
|
1599
|
+
async function loadConfig(rootDir, options) {
|
|
1600
|
+
const warnings = [];
|
|
1601
|
+
let currentDir = resolve2(rootDir);
|
|
1338
1602
|
while (true) {
|
|
1339
1603
|
const foundConfigs = [];
|
|
1340
1604
|
for (const configFile of CONFIG_FILES) {
|
|
@@ -1349,39 +1613,17 @@ async function loadConfig(rootDir) {
|
|
|
1349
1613
|
", "
|
|
1350
1614
|
)}. Using ${foundConfigs[0]}.`
|
|
1351
1615
|
);
|
|
1352
|
-
} else {
|
|
1353
1616
|
}
|
|
1354
1617
|
const configFile = foundConfigs[0];
|
|
1355
1618
|
const configPath = join3(currentDir, configFile);
|
|
1356
1619
|
try {
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
config =
|
|
1362
|
-
} else {
|
|
1363
|
-
const content = readFileSync(configPath, "utf-8");
|
|
1364
|
-
config = JSON.parse(content);
|
|
1620
|
+
const result = await loadConfigWithInheritance(configPath);
|
|
1621
|
+
warnings.push(...result.warnings);
|
|
1622
|
+
let config = result.config;
|
|
1623
|
+
if (options?.applyAutoExclude !== false) {
|
|
1624
|
+
config = applyAutoExclusions(config, currentDir);
|
|
1365
1625
|
}
|
|
1366
|
-
|
|
1367
|
-
const rootLevelTools = [
|
|
1368
|
-
"pattern-detect",
|
|
1369
|
-
"context-analyzer",
|
|
1370
|
-
"naming-consistency",
|
|
1371
|
-
"ai-signal-clarity"
|
|
1372
|
-
];
|
|
1373
|
-
const allKeys = Object.keys(config);
|
|
1374
|
-
const foundLegacy = allKeys.filter(
|
|
1375
|
-
(k) => legacyKeys.includes(k) || rootLevelTools.includes(k)
|
|
1376
|
-
);
|
|
1377
|
-
if (foundLegacy.length > 0) {
|
|
1378
|
-
console.warn(
|
|
1379
|
-
`\u26A0\uFE0F Legacy configuration keys found: ${foundLegacy.join(
|
|
1380
|
-
", "
|
|
1381
|
-
)}. These are deprecated and should be moved under the "tools" key.`
|
|
1382
|
-
);
|
|
1383
|
-
}
|
|
1384
|
-
return AIReadyConfigSchema.parse(config);
|
|
1626
|
+
return { config, warnings };
|
|
1385
1627
|
} catch (error) {
|
|
1386
1628
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
1387
1629
|
const configError = new Error(
|
|
@@ -1400,7 +1642,21 @@ async function loadConfig(rootDir) {
|
|
|
1400
1642
|
}
|
|
1401
1643
|
currentDir = parent;
|
|
1402
1644
|
}
|
|
1403
|
-
return null;
|
|
1645
|
+
return { config: null, warnings };
|
|
1646
|
+
}
|
|
1647
|
+
function validateConfig(configPath) {
|
|
1648
|
+
try {
|
|
1649
|
+
const content = readFileSync(configPath, "utf-8");
|
|
1650
|
+
const config = JSON.parse(content);
|
|
1651
|
+
return checkPatternWarnings(config, configPath);
|
|
1652
|
+
} catch (error) {
|
|
1653
|
+
return [
|
|
1654
|
+
{
|
|
1655
|
+
rule: "parse-error",
|
|
1656
|
+
message: `Failed to parse config: ${error instanceof Error ? error.message : String(error)}`
|
|
1657
|
+
}
|
|
1658
|
+
];
|
|
1659
|
+
}
|
|
1404
1660
|
}
|
|
1405
1661
|
function mergeConfigWithDefaults(userConfig, defaults) {
|
|
1406
1662
|
if (!userConfig) return defaults;
|
|
@@ -3644,78 +3900,6 @@ function clearHistory(rootDir) {
|
|
|
3644
3900
|
}
|
|
3645
3901
|
}
|
|
3646
3902
|
|
|
3647
|
-
// src/utils/history-git.ts
|
|
3648
|
-
import { execSync } from "child_process";
|
|
3649
|
-
function getFileCommitTimestamps(file) {
|
|
3650
|
-
const lineStamps = {};
|
|
3651
|
-
try {
|
|
3652
|
-
const output = execSync(`git blame -t "${file}"`, {
|
|
3653
|
-
encoding: "utf-8",
|
|
3654
|
-
stdio: ["ignore", "pipe", "ignore"]
|
|
3655
|
-
});
|
|
3656
|
-
const lines = output.split("\n");
|
|
3657
|
-
for (const line of lines) {
|
|
3658
|
-
if (!line) continue;
|
|
3659
|
-
const match = line.match(/^\S+\s+\(.*?(\d{10,})\s+[-+]\d+\s+(\d+)\)/);
|
|
3660
|
-
if (match) {
|
|
3661
|
-
const ts = parseInt(match[1], 10);
|
|
3662
|
-
const ln = parseInt(match[2], 10);
|
|
3663
|
-
lineStamps[ln] = ts;
|
|
3664
|
-
}
|
|
3665
|
-
}
|
|
3666
|
-
} catch {
|
|
3667
|
-
}
|
|
3668
|
-
return lineStamps;
|
|
3669
|
-
}
|
|
3670
|
-
function getLineRangeLastModifiedCached(lineStamps, startLine, endLine) {
|
|
3671
|
-
let latest = 0;
|
|
3672
|
-
for (let i = startLine; i <= endLine; i++) {
|
|
3673
|
-
if (lineStamps[i] && lineStamps[i] > latest) {
|
|
3674
|
-
latest = lineStamps[i];
|
|
3675
|
-
}
|
|
3676
|
-
}
|
|
3677
|
-
return latest;
|
|
3678
|
-
}
|
|
3679
|
-
function getRepoMetadata(directory) {
|
|
3680
|
-
const metadata = {};
|
|
3681
|
-
try {
|
|
3682
|
-
try {
|
|
3683
|
-
metadata.url = execSync("git config --get remote.origin.url", {
|
|
3684
|
-
cwd: directory,
|
|
3685
|
-
encoding: "utf-8",
|
|
3686
|
-
stdio: ["ignore", "pipe", "ignore"]
|
|
3687
|
-
}).trim();
|
|
3688
|
-
} catch {
|
|
3689
|
-
}
|
|
3690
|
-
try {
|
|
3691
|
-
metadata.branch = execSync("git rev-parse --abbrev-ref HEAD", {
|
|
3692
|
-
cwd: directory,
|
|
3693
|
-
encoding: "utf-8",
|
|
3694
|
-
stdio: ["ignore", "pipe", "ignore"]
|
|
3695
|
-
}).trim();
|
|
3696
|
-
} catch {
|
|
3697
|
-
}
|
|
3698
|
-
try {
|
|
3699
|
-
metadata.commit = execSync("git rev-parse HEAD", {
|
|
3700
|
-
cwd: directory,
|
|
3701
|
-
encoding: "utf-8",
|
|
3702
|
-
stdio: ["ignore", "pipe", "ignore"]
|
|
3703
|
-
}).trim();
|
|
3704
|
-
} catch {
|
|
3705
|
-
}
|
|
3706
|
-
try {
|
|
3707
|
-
metadata.author = execSync("git log -1 --format=%ae", {
|
|
3708
|
-
cwd: directory,
|
|
3709
|
-
encoding: "utf-8",
|
|
3710
|
-
stdio: ["ignore", "pipe", "ignore"]
|
|
3711
|
-
}).trim();
|
|
3712
|
-
} catch {
|
|
3713
|
-
}
|
|
3714
|
-
} catch {
|
|
3715
|
-
}
|
|
3716
|
-
return metadata;
|
|
3717
|
-
}
|
|
3718
|
-
|
|
3719
3903
|
// src/utils/github-utils.ts
|
|
3720
3904
|
function emitAnnotation(params) {
|
|
3721
3905
|
const { level, file, line, col, title, message } = params;
|
|
@@ -3927,6 +4111,188 @@ async function withErrorHandling(operation, context) {
|
|
|
3927
4111
|
return { success: false, error: `${contextPrefix}${message}` };
|
|
3928
4112
|
}
|
|
3929
4113
|
}
|
|
4114
|
+
|
|
4115
|
+
// src/growth/agents.ts
|
|
4116
|
+
import { execSync as execSync2 } from "child_process";
|
|
4117
|
+
var GitHubIssueResolverAgent = class {
|
|
4118
|
+
constructor(options) {
|
|
4119
|
+
this.generate = options.generate;
|
|
4120
|
+
if (!options.trustedAuthors || options.trustedAuthors.length === 0) {
|
|
4121
|
+
throw new Error(
|
|
4122
|
+
"[GitHubIssueResolverAgent] Security Error: trustedAuthors must be explicitly configured."
|
|
4123
|
+
);
|
|
4124
|
+
}
|
|
4125
|
+
this.trustedAuthors = options.trustedAuthors;
|
|
4126
|
+
}
|
|
4127
|
+
async resolve(issue, workingDir) {
|
|
4128
|
+
console.log(
|
|
4129
|
+
`[GitHubIssueResolverAgent] Resolving issue #${issue.number}: ${issue.title}`
|
|
4130
|
+
);
|
|
4131
|
+
const strategy = await this.identifyStrategy(issue);
|
|
4132
|
+
console.log(`[GitHubIssueResolverAgent] Selected Strategy: ${strategy}`);
|
|
4133
|
+
try {
|
|
4134
|
+
switch (strategy) {
|
|
4135
|
+
case "CORE_EVOLUTION_SYNC":
|
|
4136
|
+
if (issue.author && !this.trustedAuthors.includes(issue.author)) {
|
|
4137
|
+
console.warn(
|
|
4138
|
+
`[GitHubIssueResolverAgent] Unauthorized evolution attempt by ${issue.author}. Blocking.`
|
|
4139
|
+
);
|
|
4140
|
+
return {
|
|
4141
|
+
success: false,
|
|
4142
|
+
message: `Unauthorized actor: ${issue.author} is not in trustedAuthors list.`
|
|
4143
|
+
};
|
|
4144
|
+
}
|
|
4145
|
+
return await this.executeSubtreeSync(issue, workingDir);
|
|
4146
|
+
case "EVOLUTION_CONTRIBUTION":
|
|
4147
|
+
return await this.applyContributionPattern(issue, workingDir);
|
|
4148
|
+
case "BUG_FIX":
|
|
4149
|
+
return await this.applyAgenticPatch(issue, workingDir);
|
|
4150
|
+
default:
|
|
4151
|
+
return { success: false, message: `Unknown strategy: ${strategy}` };
|
|
4152
|
+
}
|
|
4153
|
+
} catch (error) {
|
|
4154
|
+
console.error(
|
|
4155
|
+
`[GitHubIssueResolverAgent] Resolution failed for issue #${issue.number}:`,
|
|
4156
|
+
error.message
|
|
4157
|
+
);
|
|
4158
|
+
return {
|
|
4159
|
+
success: false,
|
|
4160
|
+
message: `Resolution failed: ${error.message}`
|
|
4161
|
+
};
|
|
4162
|
+
}
|
|
4163
|
+
}
|
|
4164
|
+
async identifyStrategy(issue) {
|
|
4165
|
+
if (issue.labels.includes("evolution-sync")) return "CORE_EVOLUTION_SYNC";
|
|
4166
|
+
if (issue.labels.includes("evolution-contribution"))
|
|
4167
|
+
return "EVOLUTION_CONTRIBUTION";
|
|
4168
|
+
if (issue.labels.includes("bug")) return "BUG_FIX";
|
|
4169
|
+
const prompt = `
|
|
4170
|
+
Analyze the GitHub Issue:
|
|
4171
|
+
Title: ${issue.title}
|
|
4172
|
+
Labels: ${issue.labels.join(", ")}
|
|
4173
|
+
|
|
4174
|
+
Categorize into: CORE_EVOLUTION_SYNC, EVOLUTION_CONTRIBUTION, BUG_FIX, or UNKNOWN.
|
|
4175
|
+
Only return the category name.
|
|
4176
|
+
`;
|
|
4177
|
+
return (await this.generate(prompt)).trim();
|
|
4178
|
+
}
|
|
4179
|
+
async executeSubtreeSync(issue, workingDir) {
|
|
4180
|
+
const hubVersion = this.extractVersion(issue.body);
|
|
4181
|
+
const prefix = "core/";
|
|
4182
|
+
const hubUrl = "https://github.com/serverlessclaw/serverlessclaw.git";
|
|
4183
|
+
console.log(
|
|
4184
|
+
`[GitHubIssueResolverAgent] Performing Subtree Pull (Hub v${hubVersion}) into ${workingDir}...`
|
|
4185
|
+
);
|
|
4186
|
+
try {
|
|
4187
|
+
try {
|
|
4188
|
+
execSync2(`git remote add hub ${hubUrl}`, {
|
|
4189
|
+
cwd: workingDir,
|
|
4190
|
+
stdio: "ignore"
|
|
4191
|
+
});
|
|
4192
|
+
} catch (e) {
|
|
4193
|
+
if (!e.message.includes("already exists")) {
|
|
4194
|
+
console.warn(
|
|
4195
|
+
`[GitHubIssueResolverAgent] Remote add warning: ${e.message}`
|
|
4196
|
+
);
|
|
4197
|
+
}
|
|
4198
|
+
}
|
|
4199
|
+
execSync2(`git fetch hub`, { cwd: workingDir, stdio: "pipe" });
|
|
4200
|
+
console.log(
|
|
4201
|
+
`[GitHubIssueResolverAgent] Executing subtree pull for v${hubVersion}...`
|
|
4202
|
+
);
|
|
4203
|
+
execSync2(
|
|
4204
|
+
`git subtree pull --prefix=${prefix} hub ${hubVersion} --squash -m "chore(sync): evolution upgrade to ${hubVersion}"`,
|
|
4205
|
+
{
|
|
4206
|
+
cwd: workingDir,
|
|
4207
|
+
env: { ...process.env, GIT_MERGE_AUTOEDIT: "no" }
|
|
4208
|
+
}
|
|
4209
|
+
);
|
|
4210
|
+
return {
|
|
4211
|
+
success: true,
|
|
4212
|
+
message: `Successfully sync'd Hub ${hubVersion} via subtree merge`
|
|
4213
|
+
};
|
|
4214
|
+
} catch (error) {
|
|
4215
|
+
console.error(
|
|
4216
|
+
`[GitHubIssueResolverAgent] Subtree sync failed: ${error.message}`
|
|
4217
|
+
);
|
|
4218
|
+
throw new Error(`Subtree sync failed: ${error.message}`, {
|
|
4219
|
+
cause: error
|
|
4220
|
+
});
|
|
4221
|
+
}
|
|
4222
|
+
}
|
|
4223
|
+
async applyContributionPattern(issue, workingDir) {
|
|
4224
|
+
console.log(
|
|
4225
|
+
`[GitHubIssueResolverAgent] Pattern absorption requested: ${issue.title}`
|
|
4226
|
+
);
|
|
4227
|
+
return {
|
|
4228
|
+
success: true,
|
|
4229
|
+
message: `Contribution strategy identified. Pattern "${issue.title}" is ready for human screening and promotion.`
|
|
4230
|
+
};
|
|
4231
|
+
}
|
|
4232
|
+
async applyAgenticPatch(issue, workingDir) {
|
|
4233
|
+
console.log(`[GitHubIssueResolverAgent] Bug fix requested: ${issue.title}`);
|
|
4234
|
+
return {
|
|
4235
|
+
success: true,
|
|
4236
|
+
message: `Patch strategy identified. Agentic fix for "${issue.title}" is being drafted.`
|
|
4237
|
+
};
|
|
4238
|
+
}
|
|
4239
|
+
extractVersion(body) {
|
|
4240
|
+
const match = body.match(/v\d+\.\d+\.\d+/);
|
|
4241
|
+
if (match) return match[0];
|
|
4242
|
+
const branchMatch = body.match(/branch:?\s*([a-zA-Z0-9.\-_/]+)/i);
|
|
4243
|
+
if (branchMatch) return branchMatch[1];
|
|
4244
|
+
return "main";
|
|
4245
|
+
}
|
|
4246
|
+
};
|
|
4247
|
+
|
|
4248
|
+
// src/services/github-service.ts
|
|
4249
|
+
import { Octokit } from "@octokit/rest";
|
|
4250
|
+
var GitHubService = class {
|
|
4251
|
+
constructor(token) {
|
|
4252
|
+
this.octokit = new Octokit({ auth: token });
|
|
4253
|
+
}
|
|
4254
|
+
/**
|
|
4255
|
+
* Creates an issue in a repository.
|
|
4256
|
+
*/
|
|
4257
|
+
async createHubIssue(owner, repo, issue) {
|
|
4258
|
+
const { data } = await this.octokit.issues.create({
|
|
4259
|
+
owner,
|
|
4260
|
+
repo,
|
|
4261
|
+
title: issue.title,
|
|
4262
|
+
body: issue.body,
|
|
4263
|
+
labels: issue.labels || ["innovation-harvest"]
|
|
4264
|
+
});
|
|
4265
|
+
return data.number;
|
|
4266
|
+
}
|
|
4267
|
+
/**
|
|
4268
|
+
* Creates a Pull Request in a repository.
|
|
4269
|
+
*/
|
|
4270
|
+
async createPullRequest(owner, repo, pr) {
|
|
4271
|
+
const { data } = await this.octokit.pulls.create({
|
|
4272
|
+
owner,
|
|
4273
|
+
repo,
|
|
4274
|
+
title: pr.title,
|
|
4275
|
+
body: pr.body,
|
|
4276
|
+
head: pr.head,
|
|
4277
|
+
base: pr.base
|
|
4278
|
+
});
|
|
4279
|
+
return data.number;
|
|
4280
|
+
}
|
|
4281
|
+
/**
|
|
4282
|
+
* Scans a repository content.
|
|
4283
|
+
*/
|
|
4284
|
+
async listRecentChangesInRepo(owner, repo, path = "") {
|
|
4285
|
+
const { data } = await this.octokit.repos.getContent({
|
|
4286
|
+
owner,
|
|
4287
|
+
repo,
|
|
4288
|
+
path
|
|
4289
|
+
});
|
|
4290
|
+
if (Array.isArray(data)) {
|
|
4291
|
+
return data.map((file) => file.path);
|
|
4292
|
+
}
|
|
4293
|
+
return [];
|
|
4294
|
+
}
|
|
4295
|
+
};
|
|
3930
4296
|
export {
|
|
3931
4297
|
AIReadyConfigSchema,
|
|
3932
4298
|
AWS_CONSTANTS,
|
|
@@ -3936,6 +4302,7 @@ export {
|
|
|
3936
4302
|
COMMON_FINE_TUNING_OPTIONS,
|
|
3937
4303
|
CONTEXT_TIER_THRESHOLDS,
|
|
3938
4304
|
CSharpParser,
|
|
4305
|
+
DEFAULT_AUTO_EXCLUDE_PATTERNS,
|
|
3939
4306
|
DEFAULT_COST_CONFIG,
|
|
3940
4307
|
DEFAULT_EXCLUDE,
|
|
3941
4308
|
DEFAULT_TOOL_WEIGHTS,
|
|
@@ -3944,6 +4311,8 @@ export {
|
|
|
3944
4311
|
FRIENDLY_TOOL_NAMES,
|
|
3945
4312
|
GLOBAL_INFRA_OPTIONS,
|
|
3946
4313
|
GLOBAL_SCAN_OPTIONS,
|
|
4314
|
+
GitHubIssueResolverAgent,
|
|
4315
|
+
GitHubService,
|
|
3947
4316
|
GoParser,
|
|
3948
4317
|
IssueSchema,
|
|
3949
4318
|
IssueType,
|
|
@@ -4048,6 +4417,8 @@ export {
|
|
|
4048
4417
|
generateStatCards,
|
|
4049
4418
|
generateTable,
|
|
4050
4419
|
generateValueChain,
|
|
4420
|
+
getChangedFiles,
|
|
4421
|
+
getDirname,
|
|
4051
4422
|
getElapsedTime,
|
|
4052
4423
|
getErrorMessage,
|
|
4053
4424
|
getFileCommitTimestamps,
|
|
@@ -4116,12 +4487,14 @@ export {
|
|
|
4116
4487
|
resolveOutputPath,
|
|
4117
4488
|
runBatchAnalysis,
|
|
4118
4489
|
runStandardCliAction,
|
|
4490
|
+
safeJsonStringify,
|
|
4119
4491
|
saveScoreEntry,
|
|
4120
4492
|
scanEntries,
|
|
4121
4493
|
scanFiles,
|
|
4122
4494
|
setupParser,
|
|
4123
4495
|
severityToAnnotationLevel,
|
|
4124
4496
|
toErrorMessage,
|
|
4497
|
+
validateConfig,
|
|
4125
4498
|
validateSpokeOutput,
|
|
4126
4499
|
validateWithSchema,
|
|
4127
4500
|
withErrorHandling,
|