@probelabs/visor 0.1.40 → 0.1.41
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/ai-review-service.d.ts.map +1 -1
- package/dist/cli-main.d.ts.map +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/git-repository-analyzer.d.ts +2 -2
- package/dist/git-repository-analyzer.d.ts.map +1 -1
- package/dist/index.js +389 -65
- package/dist/types/cli.d.ts +2 -0
- package/dist/types/cli.d.ts.map +1 -1
- package/package.json +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"","sourceRoot":"","sources":["file:///home/runner/work/visor/visor/src/ai-review-service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAE9C,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AACvC,OAAO,EAAE,aAAa,EAAe,MAAM,YAAY,CAAC;AAcxD,MAAM,WAAW,cAAc;IAC7B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,QAAQ,GAAG,WAAW,GAAG,QAAQ,GAAG,MAAM,GAAG,aAAa,CAAC;IACtE,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,KAAK,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;KAAE,CAAC,CAAC;CACzD;AAED,MAAM,WAAW,WAAW;IAC1B,gCAAgC;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,uCAAuC;IACvC,WAAW,EAAE,MAAM,CAAC;IACpB,gDAAgD;IAChD,QAAQ,EAAE,MAAM,CAAC;IACjB,iBAAiB;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,4DAA4D;IAC5D,YAAY,EAAE,MAAM,CAAC;IACrB,sCAAsC;IACtC,cAAc,EAAE,MAAM,CAAC;IACvB,kCAAkC;IAClC,YAAY,EAAE,MAAM,CAAC;IACrB,oCAAoC;IACpC,cAAc,EAAE,MAAM,CAAC;IACvB,6BAA6B;IAC7B,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,qCAAqC;IACrC,gBAAgB,EAAE,OAAO,CAAC;IAC1B,0CAA0C;IAC1C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,iCAAiC;IACjC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,yCAAyC;IACzC,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,0CAA0C;IAC1C,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,sCAAsC;IACtC,SAAS,EAAE,MAAM,CAAC;IAClB,2BAA2B;IAC3B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,mCAAmC;IACnC,cAAc,CAAC,EAAE,KAAK,CAAC;QACrB,SAAS,EAAE,MAAM,CAAC;QAClB,QAAQ,EAAE,MAAM,CAAC;QACjB,KAAK,EAAE,MAAM,CAAC;QACd,cAAc,EAAE,MAAM,CAAC;QACvB,OAAO,EAAE,OAAO,CAAC;KAClB,CAAC,CAAC;CACJ;AAmBD,qBAAa,eAAe;IAC1B,OAAO,CAAC,MAAM,CAAiB;IAC/B,OAAO,CAAC,eAAe,CAAkB;gBAE7B,MAAM,GAAE,cAAmB;IA+BvC;;OAEG;IACG,aAAa,CACjB,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,MAAM,EACpB,MAAM,CAAC,EAAE,MAAM,EACf,UAAU,CAAC,EAAE,MAAM,EACnB,SAAS,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC,aAAa,CAAC;IA+GzB;;OAEG;IACG,6BAA6B,CACjC,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,MAAM,EACpB,eAAe,EAAE,MAAM,EACvB,MAAM,CAAC,EAAE,MAAM,EACf,SAAS,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC,aAAa,CAAC;IAsFzB;;OAEG;IACH,eAAe,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,GAAG,IAAI;IAI3D;;OAEG;IACH,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAIvC;;OAEG;YACW,iBAAiB;IAsE/B;;OAEG;IACH,OAAO,CAAC,eAAe;
|
|
1
|
+
{"version":3,"file":"","sourceRoot":"","sources":["file:///home/runner/work/visor/visor/src/ai-review-service.ts"],"names":[],"mappings":"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"}
|
package/dist/cli-main.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"","sourceRoot":"","sources":["file:///home/runner/work/visor/visor/src/cli-main.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"","sourceRoot":"","sources":["file:///home/runner/work/visor/visor/src/cli-main.ts"],"names":[],"mappings":"AAOA;;GAEG;AACH,wBAAsB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CA2P1C"}
|
package/dist/cli.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"","sourceRoot":"","sources":["file:///home/runner/work/visor/visor/src/cli.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAA2B,MAAM,aAAa,CAAC;AAIlE;;GAEG;AACH,qBAAa,GAAG;IACd,OAAO,CAAC,OAAO,CAAU;IACzB,OAAO,CAAC,WAAW,CAA4E;IAC/F,OAAO,CAAC,YAAY,CAA0D;;IAO9E;;OAEG;IACH,OAAO,CAAC,YAAY;
|
|
1
|
+
{"version":3,"file":"","sourceRoot":"","sources":["file:///home/runner/work/visor/visor/src/cli.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAA2B,MAAM,aAAa,CAAC;AAIlE;;GAEG;AACH,qBAAa,GAAG;IACd,OAAO,CAAC,OAAO,CAAU;IACzB,OAAO,CAAC,WAAW,CAA4E;IAC/F,OAAO,CAAC,YAAY,CAA0D;;IAO9E;;OAEG;IACH,OAAO,CAAC,YAAY;IAwCpB;;OAEG;IACH,OAAO,CAAC,aAAa,CAEnB;IAEF;;OAEG;IACI,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,UAAU;IAkI5C;;OAEG;IACH,OAAO,CAAC,eAAe;IAkCvB;;OAEG;IACI,WAAW,IAAI,MAAM;IAsC5B;;OAEG;IACI,UAAU,IAAI,MAAM;IAa3B;;OAEG;IACI,eAAe,IAAI,MAAM;IAiBhC;;OAEG;IACI,QAAQ,IAAI,IAAI;IAIvB;;OAEG;IACI,WAAW,IAAI,IAAI;CAG3B"}
|
|
@@ -27,11 +27,11 @@ export declare class GitRepositoryAnalyzer {
|
|
|
27
27
|
/**
|
|
28
28
|
* Analyze the current git repository state and return data compatible with PRInfo interface
|
|
29
29
|
*/
|
|
30
|
-
analyzeRepository(): Promise<GitRepositoryInfo>;
|
|
30
|
+
analyzeRepository(includeContext?: boolean): Promise<GitRepositoryInfo>;
|
|
31
31
|
/**
|
|
32
32
|
* Convert GitRepositoryInfo to PRInfo format for compatibility with existing PRReviewer
|
|
33
33
|
*/
|
|
34
|
-
toPRInfo(repositoryInfo: GitRepositoryInfo): PRInfo;
|
|
34
|
+
toPRInfo(repositoryInfo: GitRepositoryInfo, includeContext?: boolean): PRInfo;
|
|
35
35
|
private isGitRepository;
|
|
36
36
|
private getCurrentBranch;
|
|
37
37
|
private getBaseBranch;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"","sourceRoot":"","sources":["file:///home/runner/work/visor/visor/src/git-repository-analyzer.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,MAAM,EAAU,MAAM,eAAe,CAAC;AAE/C,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,OAAO,GAAG,SAAS,GAAG,UAAU,GAAG,SAAS,CAAC;IACrD,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,aAAa,EAAE,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;IACvB,eAAe,EAAE,OAAO,CAAC;IACzB,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED,qBAAa,qBAAqB;IAChC,OAAO,CAAC,GAAG,CAAY;IACvB,OAAO,CAAC,GAAG,CAAS;gBAER,gBAAgB,GAAE,MAAsB;IAKpD;;OAEG;IACG,iBAAiB,
|
|
1
|
+
{"version":3,"file":"","sourceRoot":"","sources":["file:///home/runner/work/visor/visor/src/git-repository-analyzer.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,MAAM,EAAU,MAAM,eAAe,CAAC;AAE/C,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,OAAO,GAAG,SAAS,GAAG,UAAU,GAAG,SAAS,CAAC;IACrD,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,aAAa,EAAE,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;IACvB,eAAe,EAAE,OAAO,CAAC;IACzB,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED,qBAAa,qBAAqB;IAChC,OAAO,CAAC,GAAG,CAAY;IACvB,OAAO,CAAC,GAAG,CAAS;gBAER,gBAAgB,GAAE,MAAsB;IAKpD;;OAEG;IACG,iBAAiB,CAAC,cAAc,GAAE,OAAc,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAgEnF;;OAEG;IACH,QAAQ,CAAC,cAAc,EAAE,iBAAiB,EAAE,cAAc,GAAE,OAAc,GAAG,MAAM;YAmCrE,eAAe;YASf,gBAAgB;YAShB,aAAa;YAmBb,aAAa;YAYb,qBAAqB;YA6BrB,iBAAiB;IAsE/B,OAAO,CAAC,aAAa;IAcrB,OAAO,CAAC,mBAAmB;IA4B3B,OAAO,CAAC,yBAAyB;CAclC"}
|
package/dist/index.js
CHANGED
|
@@ -94115,6 +94115,21 @@ ${prContext}
|
|
|
94115
94115
|
formatPRContext(prInfo) {
|
|
94116
94116
|
// Check if this is an issue (not a PR)
|
|
94117
94117
|
const isIssue = prInfo.isIssue === true;
|
|
94118
|
+
// Check if we should include code context (diffs)
|
|
94119
|
+
const isPRContext = prInfo.isPRContext === true;
|
|
94120
|
+
// In PR context, always include diffs. Otherwise check the flag.
|
|
94121
|
+
const includeCodeContext = isPRContext || prInfo.includeCodeContext !== false;
|
|
94122
|
+
// Log the decision for transparency
|
|
94123
|
+
const log = this.config.debug ? console.error : () => { };
|
|
94124
|
+
if (isPRContext) {
|
|
94125
|
+
log('🔍 Including full code diffs in AI context (PR mode)');
|
|
94126
|
+
}
|
|
94127
|
+
else if (!includeCodeContext) {
|
|
94128
|
+
log('📊 Including only file summary in AI context (no diffs)');
|
|
94129
|
+
}
|
|
94130
|
+
else {
|
|
94131
|
+
log('🔍 Including code diffs in AI context');
|
|
94132
|
+
}
|
|
94118
94133
|
if (isIssue) {
|
|
94119
94134
|
// Format as issue context
|
|
94120
94135
|
let context = `<issue>
|
|
@@ -94236,31 +94251,39 @@ ${this.escapeXml(prInfo.body)}
|
|
|
94236
94251
|
${this.escapeXml(prInfo.body)}
|
|
94237
94252
|
</description>`;
|
|
94238
94253
|
}
|
|
94239
|
-
// Add
|
|
94240
|
-
if (
|
|
94241
|
-
|
|
94254
|
+
// Add diffs only if includeCodeContext is true (or in PR mode)
|
|
94255
|
+
if (includeCodeContext) {
|
|
94256
|
+
// Add full diff if available (for complete PR review)
|
|
94257
|
+
if (prInfo.fullDiff) {
|
|
94258
|
+
context += `
|
|
94242
94259
|
<!-- Complete unified diff showing all changes in the pull request -->
|
|
94243
94260
|
<full_diff>
|
|
94244
94261
|
${this.escapeXml(prInfo.fullDiff)}
|
|
94245
94262
|
</full_diff>`;
|
|
94246
|
-
|
|
94247
|
-
|
|
94248
|
-
|
|
94249
|
-
|
|
94250
|
-
|
|
94263
|
+
}
|
|
94264
|
+
// Add incremental commit diff if available (for new commit analysis)
|
|
94265
|
+
if (prInfo.isIncremental) {
|
|
94266
|
+
if (prInfo.commitDiff && prInfo.commitDiff.length > 0) {
|
|
94267
|
+
context += `
|
|
94251
94268
|
<!-- Diff of only the latest commit for incremental analysis -->
|
|
94252
94269
|
<commit_diff>
|
|
94253
94270
|
${this.escapeXml(prInfo.commitDiff)}
|
|
94254
94271
|
</commit_diff>`;
|
|
94255
|
-
|
|
94256
|
-
|
|
94257
|
-
|
|
94272
|
+
}
|
|
94273
|
+
else {
|
|
94274
|
+
context += `
|
|
94258
94275
|
<!-- Commit diff could not be retrieved - falling back to full diff analysis -->
|
|
94259
94276
|
<commit_diff>
|
|
94260
94277
|
${prInfo.fullDiff ? this.escapeXml(prInfo.fullDiff) : ''}
|
|
94261
94278
|
</commit_diff>`;
|
|
94279
|
+
}
|
|
94262
94280
|
}
|
|
94263
94281
|
}
|
|
94282
|
+
else {
|
|
94283
|
+
// When not including diffs, add a note about it
|
|
94284
|
+
context += `
|
|
94285
|
+
<!-- Code diffs excluded to reduce token usage (no code-review schema detected or disabled by flag) -->`;
|
|
94286
|
+
}
|
|
94264
94287
|
// Add file summary for context
|
|
94265
94288
|
if (prInfo.files.length > 0) {
|
|
94266
94289
|
context += `
|
|
@@ -96869,10 +96892,6 @@ async function main() {
|
|
|
96869
96892
|
.findAndLoadConfig()
|
|
96870
96893
|
.catch(() => configManager.getDefaultConfig());
|
|
96871
96894
|
}
|
|
96872
|
-
// Get repository info using GitRepositoryAnalyzer
|
|
96873
|
-
const { GitRepositoryAnalyzer } = await Promise.resolve().then(() => __importStar(__nccwpck_require__(71259)));
|
|
96874
|
-
const analyzer = new GitRepositoryAnalyzer(process.cwd());
|
|
96875
|
-
const repositoryInfo = await analyzer.analyzeRepository();
|
|
96876
96895
|
// Determine checks to run and validate check types early
|
|
96877
96896
|
const checksToRun = options.checks.length > 0 ? options.checks : Object.keys(config.checks || {});
|
|
96878
96897
|
// Validate that all requested checks exist in the configuration
|
|
@@ -96882,13 +96901,58 @@ async function main() {
|
|
|
96882
96901
|
console.error(`❌ Error: No configuration found for check: ${invalidChecks[0]}`);
|
|
96883
96902
|
process.exit(1);
|
|
96884
96903
|
}
|
|
96885
|
-
//
|
|
96904
|
+
// Use stderr for status messages when outputting formatted results to stdout
|
|
96905
|
+
const logFn = console.error;
|
|
96906
|
+
// Determine if we should include code context (diffs)
|
|
96907
|
+
// In CLI mode (local), we do smart detection. PR mode always includes context.
|
|
96908
|
+
const isPRContext = false; // This is CLI mode, not GitHub Action
|
|
96909
|
+
let includeCodeContext = false;
|
|
96910
|
+
if (isPRContext) {
|
|
96911
|
+
// ALWAYS include full context in PR/GitHub Action mode
|
|
96912
|
+
includeCodeContext = true;
|
|
96913
|
+
logFn('📝 Code context: ENABLED (PR context - always included)');
|
|
96914
|
+
}
|
|
96915
|
+
else if (options.codeContext === 'enabled') {
|
|
96916
|
+
includeCodeContext = true;
|
|
96917
|
+
logFn('📝 Code context: ENABLED (forced by --enable-code-context)');
|
|
96918
|
+
}
|
|
96919
|
+
else if (options.codeContext === 'disabled') {
|
|
96920
|
+
includeCodeContext = false;
|
|
96921
|
+
logFn('📝 Code context: DISABLED (forced by --disable-code-context)');
|
|
96922
|
+
}
|
|
96923
|
+
else {
|
|
96924
|
+
// Auto-detect based on schemas (CLI mode only)
|
|
96925
|
+
const hasCodeReviewSchema = checksToRun.some(check => config.checks?.[check]?.schema === 'code-review');
|
|
96926
|
+
includeCodeContext = hasCodeReviewSchema;
|
|
96927
|
+
if (hasCodeReviewSchema) {
|
|
96928
|
+
logFn('📝 Code context: ENABLED (code-review schema detected in local mode)');
|
|
96929
|
+
}
|
|
96930
|
+
else {
|
|
96931
|
+
logFn('📝 Code context: DISABLED (no code-review schema found in local mode)');
|
|
96932
|
+
}
|
|
96933
|
+
}
|
|
96934
|
+
// Get repository info using GitRepositoryAnalyzer
|
|
96935
|
+
const { GitRepositoryAnalyzer } = await Promise.resolve().then(() => __importStar(__nccwpck_require__(71259)));
|
|
96936
|
+
const analyzer = new GitRepositoryAnalyzer(process.cwd());
|
|
96937
|
+
let repositoryInfo;
|
|
96938
|
+
try {
|
|
96939
|
+
repositoryInfo = await analyzer.analyzeRepository(includeCodeContext);
|
|
96940
|
+
}
|
|
96941
|
+
catch (error) {
|
|
96942
|
+
console.error('❌ Error analyzing git repository:', error);
|
|
96943
|
+
console.error('💡 Make sure you are in a git repository or initialize one with "git init"');
|
|
96944
|
+
process.exit(1);
|
|
96945
|
+
}
|
|
96946
|
+
// Check if we're in a git repository
|
|
96886
96947
|
if (!repositoryInfo.isGitRepository) {
|
|
96887
|
-
console.error('❌ Error: Not a git repository
|
|
96948
|
+
console.error('❌ Error: Not a git repository. Run "git init" to initialize a repository.');
|
|
96949
|
+
process.exit(1);
|
|
96950
|
+
}
|
|
96951
|
+
// Check if there are any changes to analyze
|
|
96952
|
+
if (repositoryInfo.files.length === 0) {
|
|
96953
|
+
console.error('❌ Error: No changes to analyze. Make some file changes first.');
|
|
96888
96954
|
process.exit(1);
|
|
96889
96955
|
}
|
|
96890
|
-
// Use stderr for status messages when outputting formatted results to stdout
|
|
96891
|
-
const logFn = console.error;
|
|
96892
96956
|
logFn('🔍 Visor - AI-powered code review tool');
|
|
96893
96957
|
logFn(`Configuration version: ${config.version}`);
|
|
96894
96958
|
logFn(`Configuration source: ${options.configPath || 'default search locations'}`);
|
|
@@ -96911,8 +96975,12 @@ async function main() {
|
|
|
96911
96975
|
exclude: options.excludeTags,
|
|
96912
96976
|
}
|
|
96913
96977
|
: undefined;
|
|
96914
|
-
//
|
|
96915
|
-
const
|
|
96978
|
+
// Convert repository info to PRInfo format
|
|
96979
|
+
const prInfo = analyzer.toPRInfo(repositoryInfo, includeCodeContext);
|
|
96980
|
+
// Store the includeCodeContext flag in prInfo for downstream use
|
|
96981
|
+
prInfo.includeCodeContext = includeCodeContext;
|
|
96982
|
+
// Execute checks with proper parameters
|
|
96983
|
+
const groupedResults = await engine.executeGroupedChecks(prInfo, checksToRun, options.timeout, config, options.output, options.debug || false, options.maxParallelism, options.failFast, tagFilter);
|
|
96916
96984
|
// Format output based on format type
|
|
96917
96985
|
let output;
|
|
96918
96986
|
if (options.output === 'json') {
|
|
@@ -97081,6 +97149,8 @@ class CLI {
|
|
|
97081
97149
|
.option('--tags <tags>', 'Include checks with these tags (comma-separated)')
|
|
97082
97150
|
.option('--exclude-tags <tags>', 'Exclude checks with these tags (comma-separated)')
|
|
97083
97151
|
.option('--no-remote-extends', 'Disable loading configurations from remote URLs')
|
|
97152
|
+
.option('--enable-code-context', 'Force include code diffs in analysis (CLI mode)')
|
|
97153
|
+
.option('--disable-code-context', 'Force exclude code diffs from analysis (CLI mode)')
|
|
97084
97154
|
.addHelpText('after', this.getExamplesText())
|
|
97085
97155
|
.exitOverride(); // Prevent automatic process.exit for better error handling
|
|
97086
97156
|
// Add validation for options
|
|
@@ -97118,6 +97188,8 @@ class CLI {
|
|
|
97118
97188
|
.option('--tags <tags>', 'Include checks with these tags (comma-separated)')
|
|
97119
97189
|
.option('--exclude-tags <tags>', 'Exclude checks with these tags (comma-separated)')
|
|
97120
97190
|
.option('--allowed-remote-patterns <patterns>', 'Comma-separated list of allowed URL prefixes for remote config extends (e.g., "https://github.com/,https://raw.githubusercontent.com/")')
|
|
97191
|
+
.option('--enable-code-context', 'Force include code diffs in analysis (CLI mode)')
|
|
97192
|
+
.option('--disable-code-context', 'Force exclude code diffs from analysis (CLI mode)')
|
|
97121
97193
|
.allowUnknownOption(false)
|
|
97122
97194
|
.allowExcessArguments(false) // Don't allow positional arguments
|
|
97123
97195
|
.addHelpText('after', this.getExamplesText())
|
|
@@ -97148,6 +97220,14 @@ class CLI {
|
|
|
97148
97220
|
if (options.excludeTags) {
|
|
97149
97221
|
excludeTags = options.excludeTags.split(',').map((t) => t.trim());
|
|
97150
97222
|
}
|
|
97223
|
+
// Determine code context mode
|
|
97224
|
+
let codeContext = 'auto';
|
|
97225
|
+
if (options.enableCodeContext) {
|
|
97226
|
+
codeContext = 'enabled';
|
|
97227
|
+
}
|
|
97228
|
+
else if (options.disableCodeContext) {
|
|
97229
|
+
codeContext = 'disabled';
|
|
97230
|
+
}
|
|
97151
97231
|
return {
|
|
97152
97232
|
checks: uniqueChecks,
|
|
97153
97233
|
output: options.output,
|
|
@@ -97161,6 +97241,7 @@ class CLI {
|
|
|
97161
97241
|
allowedRemotePatterns,
|
|
97162
97242
|
help: options.help,
|
|
97163
97243
|
version: options.version,
|
|
97244
|
+
codeContext,
|
|
97164
97245
|
};
|
|
97165
97246
|
}
|
|
97166
97247
|
catch (error) {
|
|
@@ -97229,6 +97310,10 @@ class CLI {
|
|
|
97229
97310
|
.option('--max-parallelism <count>', 'Maximum number of checks to run in parallel (default: 3)', value => parseInt(value, 10))
|
|
97230
97311
|
.option('--debug', 'Enable debug mode for detailed output')
|
|
97231
97312
|
.option('--fail-fast', 'Stop execution on first failure condition')
|
|
97313
|
+
.option('--tags <tags>', 'Include checks with these tags (comma-separated)')
|
|
97314
|
+
.option('--exclude-tags <tags>', 'Exclude checks with these tags (comma-separated)')
|
|
97315
|
+
.option('--enable-code-context', 'Force include code diffs in analysis (CLI mode)')
|
|
97316
|
+
.option('--disable-code-context', 'Force exclude code diffs from analysis (CLI mode)')
|
|
97232
97317
|
.addHelpText('after', this.getExamplesText());
|
|
97233
97318
|
// Get the basic help and append examples manually if addHelpText doesn't work
|
|
97234
97319
|
const basicHelp = tempProgram.helpInformation();
|
|
@@ -98780,7 +98865,7 @@ class GitRepositoryAnalyzer {
|
|
|
98780
98865
|
/**
|
|
98781
98866
|
* Analyze the current git repository state and return data compatible with PRInfo interface
|
|
98782
98867
|
*/
|
|
98783
|
-
async analyzeRepository() {
|
|
98868
|
+
async analyzeRepository(includeContext = true) {
|
|
98784
98869
|
// Check if we're in a git repository
|
|
98785
98870
|
const isRepo = await this.isGitRepository();
|
|
98786
98871
|
if (!isRepo) {
|
|
@@ -98793,15 +98878,36 @@ class GitRepositoryAnalyzer {
|
|
|
98793
98878
|
this.getCurrentBranch(),
|
|
98794
98879
|
]);
|
|
98795
98880
|
// Get uncommitted changes
|
|
98796
|
-
const uncommittedFiles = await this.getUncommittedChanges();
|
|
98797
|
-
// Get recent commit info
|
|
98798
|
-
|
|
98799
|
-
|
|
98881
|
+
const uncommittedFiles = await this.getUncommittedChanges(includeContext);
|
|
98882
|
+
// Get recent commit info (handle repos with no commits)
|
|
98883
|
+
let lastCommit = null;
|
|
98884
|
+
try {
|
|
98885
|
+
const recentCommits = await this.git.log({ maxCount: 1 });
|
|
98886
|
+
lastCommit = recentCommits.latest;
|
|
98887
|
+
}
|
|
98888
|
+
catch {
|
|
98889
|
+
// Repository has no commits yet - this is OK
|
|
98890
|
+
console.log('📝 Repository has no commits yet, analyzing uncommitted changes');
|
|
98891
|
+
}
|
|
98892
|
+
// Get author from git config if no commits exist
|
|
98893
|
+
let author = lastCommit?.author_name;
|
|
98894
|
+
if (!author) {
|
|
98895
|
+
try {
|
|
98896
|
+
const [userName, userEmail] = await Promise.all([
|
|
98897
|
+
this.git.raw(['config', 'user.name']).catch(() => null),
|
|
98898
|
+
this.git.raw(['config', 'user.email']).catch(() => null),
|
|
98899
|
+
]);
|
|
98900
|
+
author = userName?.trim() || userEmail?.trim() || 'unknown';
|
|
98901
|
+
}
|
|
98902
|
+
catch {
|
|
98903
|
+
author = 'unknown';
|
|
98904
|
+
}
|
|
98905
|
+
}
|
|
98800
98906
|
// Create repository info
|
|
98801
98907
|
const repositoryInfo = {
|
|
98802
98908
|
title: this.generateTitle(status, currentBranch),
|
|
98803
98909
|
body: this.generateDescription(status, lastCommit),
|
|
98804
|
-
author
|
|
98910
|
+
author,
|
|
98805
98911
|
base: await this.getBaseBranch(),
|
|
98806
98912
|
head: currentBranch,
|
|
98807
98913
|
files: uncommittedFiles,
|
|
@@ -98813,14 +98919,32 @@ class GitRepositoryAnalyzer {
|
|
|
98813
98919
|
return repositoryInfo;
|
|
98814
98920
|
}
|
|
98815
98921
|
catch (error) {
|
|
98816
|
-
|
|
98922
|
+
// Don't log the full error object to avoid confusing stack traces
|
|
98923
|
+
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
|
98924
|
+
console.error('Error analyzing git repository:', errorMessage);
|
|
98817
98925
|
return this.createEmptyRepositoryInfo('Error analyzing git repository');
|
|
98818
98926
|
}
|
|
98819
98927
|
}
|
|
98820
98928
|
/**
|
|
98821
98929
|
* Convert GitRepositoryInfo to PRInfo format for compatibility with existing PRReviewer
|
|
98822
98930
|
*/
|
|
98823
|
-
toPRInfo(repositoryInfo) {
|
|
98931
|
+
toPRInfo(repositoryInfo, includeContext = true) {
|
|
98932
|
+
const files = repositoryInfo.files.map((file) => ({
|
|
98933
|
+
filename: file.filename,
|
|
98934
|
+
additions: file.additions,
|
|
98935
|
+
deletions: file.deletions,
|
|
98936
|
+
changes: file.changes,
|
|
98937
|
+
patch: includeContext ? file.patch : undefined,
|
|
98938
|
+
status: file.status,
|
|
98939
|
+
}));
|
|
98940
|
+
// Generate fullDiff from patches if includeContext is true
|
|
98941
|
+
let fullDiff;
|
|
98942
|
+
if (includeContext) {
|
|
98943
|
+
fullDiff = files
|
|
98944
|
+
.filter(file => file.patch)
|
|
98945
|
+
.map(file => `--- ${file.filename}\n${file.patch}`)
|
|
98946
|
+
.join('\n\n');
|
|
98947
|
+
}
|
|
98824
98948
|
return {
|
|
98825
98949
|
number: 0, // Local analysis doesn't have PR number
|
|
98826
98950
|
title: repositoryInfo.title,
|
|
@@ -98828,16 +98952,10 @@ class GitRepositoryAnalyzer {
|
|
|
98828
98952
|
author: repositoryInfo.author,
|
|
98829
98953
|
base: repositoryInfo.base,
|
|
98830
98954
|
head: repositoryInfo.head,
|
|
98831
|
-
files
|
|
98832
|
-
filename: file.filename,
|
|
98833
|
-
additions: file.additions,
|
|
98834
|
-
deletions: file.deletions,
|
|
98835
|
-
changes: file.changes,
|
|
98836
|
-
patch: file.patch,
|
|
98837
|
-
status: file.status,
|
|
98838
|
-
})),
|
|
98955
|
+
files,
|
|
98839
98956
|
totalAdditions: repositoryInfo.totalAdditions,
|
|
98840
98957
|
totalDeletions: repositoryInfo.totalDeletions,
|
|
98958
|
+
fullDiff,
|
|
98841
98959
|
};
|
|
98842
98960
|
}
|
|
98843
98961
|
async isGitRepository() {
|
|
@@ -98887,7 +99005,7 @@ class GitRepositoryAnalyzer {
|
|
|
98887
99005
|
return null;
|
|
98888
99006
|
}
|
|
98889
99007
|
}
|
|
98890
|
-
async getUncommittedChanges() {
|
|
99008
|
+
async getUncommittedChanges(includeContext = true) {
|
|
98891
99009
|
try {
|
|
98892
99010
|
const status = await this.git.status();
|
|
98893
99011
|
const changes = [];
|
|
@@ -98903,7 +99021,7 @@ class GitRepositoryAnalyzer {
|
|
|
98903
99021
|
];
|
|
98904
99022
|
for (const { file, status } of fileChanges) {
|
|
98905
99023
|
const filePath = path.join(this.cwd, file);
|
|
98906
|
-
const fileChange = await this.analyzeFileChange(file, status, filePath);
|
|
99024
|
+
const fileChange = await this.analyzeFileChange(file, status, filePath, includeContext);
|
|
98907
99025
|
changes.push(fileChange);
|
|
98908
99026
|
}
|
|
98909
99027
|
return changes;
|
|
@@ -98913,14 +99031,14 @@ class GitRepositoryAnalyzer {
|
|
|
98913
99031
|
return [];
|
|
98914
99032
|
}
|
|
98915
99033
|
}
|
|
98916
|
-
async analyzeFileChange(filename, status, filePath) {
|
|
99034
|
+
async analyzeFileChange(filename, status, filePath, includeContext = true) {
|
|
98917
99035
|
let additions = 0;
|
|
98918
99036
|
let deletions = 0;
|
|
98919
99037
|
let patch;
|
|
98920
99038
|
let content;
|
|
98921
99039
|
try {
|
|
98922
99040
|
// Get diff for the file if it exists and is not binary
|
|
98923
|
-
if (status !== 'added' && fs.existsSync(filePath)) {
|
|
99041
|
+
if (includeContext && status !== 'added' && fs.existsSync(filePath)) {
|
|
98924
99042
|
const diff = await this.git.diff(['--', filename]).catch(() => '');
|
|
98925
99043
|
if (diff) {
|
|
98926
99044
|
patch = diff;
|
|
@@ -98930,15 +99048,28 @@ class GitRepositoryAnalyzer {
|
|
|
98930
99048
|
deletions = lines.filter(line => line.startsWith('-')).length;
|
|
98931
99049
|
}
|
|
98932
99050
|
}
|
|
98933
|
-
|
|
99051
|
+
else if (status !== 'added' && fs.existsSync(filePath)) {
|
|
99052
|
+
// If not including context, still count changes for statistics
|
|
99053
|
+
const diff = await this.git.diff(['--', filename]).catch(() => '');
|
|
99054
|
+
if (diff) {
|
|
99055
|
+
const lines = diff.split('\n');
|
|
99056
|
+
additions = lines.filter(line => line.startsWith('+')).length;
|
|
99057
|
+
deletions = lines.filter(line => line.startsWith('-')).length;
|
|
99058
|
+
}
|
|
99059
|
+
}
|
|
99060
|
+
// For added files
|
|
98934
99061
|
if (status === 'added' && fs.existsSync(filePath)) {
|
|
98935
99062
|
try {
|
|
98936
99063
|
const stats = fs.statSync(filePath);
|
|
98937
99064
|
if (stats.isFile() && stats.size < 1024 * 1024) {
|
|
98938
99065
|
// Skip files larger than 1MB
|
|
98939
|
-
|
|
98940
|
-
|
|
98941
|
-
|
|
99066
|
+
if (includeContext) {
|
|
99067
|
+
content = fs.readFileSync(filePath, 'utf8');
|
|
99068
|
+
patch = content; // For new files, the entire content is the "patch"
|
|
99069
|
+
}
|
|
99070
|
+
// Always count additions for statistics
|
|
99071
|
+
const fileContent = includeContext ? content : fs.readFileSync(filePath, 'utf8');
|
|
99072
|
+
additions = fileContent.split('\n').length;
|
|
98942
99073
|
}
|
|
98943
99074
|
}
|
|
98944
99075
|
catch {
|
|
@@ -100320,6 +100451,9 @@ async function handleIssueComment(octokit, owner, repo, context, inputs, actionC
|
|
|
100320
100451
|
prInfo = await analyzer.fetchPRDiff(owner, repo, prNumber, undefined, 'issue_comment');
|
|
100321
100452
|
// Add event context for templates and XML generation
|
|
100322
100453
|
prInfo.eventContext = context.event;
|
|
100454
|
+
// PR context always includes code diffs
|
|
100455
|
+
prInfo.includeCodeContext = true;
|
|
100456
|
+
prInfo.isPRContext = true;
|
|
100323
100457
|
}
|
|
100324
100458
|
else {
|
|
100325
100459
|
// It's an issue comment - create a minimal PRInfo structure for issue assistant
|
|
@@ -100425,11 +100559,16 @@ async function handlePullRequestWithConfig(octokit, owner, repo, inputs, config,
|
|
|
100425
100559
|
// Map the action to event type
|
|
100426
100560
|
const eventType = mapGitHubEventToTrigger('pull_request', action);
|
|
100427
100561
|
// Fetch PR diff (handle test scenarios gracefully)
|
|
100562
|
+
// In PR context, ALWAYS include full diffs for proper code review
|
|
100563
|
+
console.log('📝 Code context: ENABLED (PR context - always included)');
|
|
100428
100564
|
let prInfo;
|
|
100429
100565
|
try {
|
|
100430
100566
|
prInfo = await analyzer.fetchPRDiff(owner, repo, prNumber, undefined, eventType);
|
|
100431
100567
|
// Add event context for templates and XML generation
|
|
100432
100568
|
prInfo.eventContext = context.event;
|
|
100569
|
+
// Mark that we're in PR context and should always include diffs
|
|
100570
|
+
prInfo.includeCodeContext = true;
|
|
100571
|
+
prInfo.isPRContext = true;
|
|
100433
100572
|
}
|
|
100434
100573
|
catch (error) {
|
|
100435
100574
|
// Handle test scenarios with mock repos
|
|
@@ -125847,7 +125986,7 @@ async function delegate({ task, timeout = 300, debug = false, currentIteration =
|
|
|
125847
125986
|
console.error(`[DELEGATE] Using binary at: ${binaryPath}`);
|
|
125848
125987
|
console.error(`[DELEGATE] Command args: ${args.join(" ")}`);
|
|
125849
125988
|
}
|
|
125850
|
-
return new Promise((
|
|
125989
|
+
return new Promise((resolve2, reject) => {
|
|
125851
125990
|
const delegationSpan = tracer ? tracer.createDelegationSpan(sessionId, task) : null;
|
|
125852
125991
|
const process2 = (0, import_child_process5.spawn)(binaryPath, args, {
|
|
125853
125992
|
stdio: ["pipe", "pipe", "pipe"],
|
|
@@ -125912,7 +126051,7 @@ async function delegate({ task, timeout = 300, debug = false, currentIteration =
|
|
|
125912
126051
|
delegationSpan.end();
|
|
125913
126052
|
}
|
|
125914
126053
|
}
|
|
125915
|
-
|
|
126054
|
+
resolve2(response);
|
|
125916
126055
|
} else {
|
|
125917
126056
|
const errorMessage = stderr.trim() || `Delegate process failed with exit code ${code}`;
|
|
125918
126057
|
if (debug) {
|
|
@@ -127172,7 +127311,7 @@ function createMockProvider() {
|
|
|
127172
127311
|
provider: "mock",
|
|
127173
127312
|
// Mock the doGenerate method used by Vercel AI SDK
|
|
127174
127313
|
doGenerate: async ({ messages, tools: tools2 }) => {
|
|
127175
|
-
await new Promise((
|
|
127314
|
+
await new Promise((resolve2) => setTimeout(resolve2, 10));
|
|
127176
127315
|
return {
|
|
127177
127316
|
text: "This is a mock response for testing",
|
|
127178
127317
|
toolCalls: [],
|
|
@@ -128997,7 +129136,7 @@ var ProbeAgent_exports = {};
|
|
|
128997
129136
|
__export(ProbeAgent_exports, {
|
|
128998
129137
|
ProbeAgent: () => ProbeAgent
|
|
128999
129138
|
});
|
|
129000
|
-
var import_anthropic, import_openai, import_google, import_ai2, import_crypto5, import_events2, MAX_TOOL_ITERATIONS, MAX_HISTORY_MESSAGES, ProbeAgent;
|
|
129139
|
+
var import_anthropic, import_openai, import_google, import_ai2, import_crypto5, import_events2, import_fs5, import_promises, import_path7, MAX_TOOL_ITERATIONS, MAX_HISTORY_MESSAGES, SUPPORTED_IMAGE_EXTENSIONS, MAX_IMAGE_FILE_SIZE, ProbeAgent;
|
|
129001
129140
|
var init_ProbeAgent = __esm({
|
|
129002
129141
|
"src/agent/ProbeAgent.js"() {
|
|
129003
129142
|
"use strict";
|
|
@@ -129007,6 +129146,9 @@ var init_ProbeAgent = __esm({
|
|
|
129007
129146
|
import_ai2 = __nccwpck_require__(86619);
|
|
129008
129147
|
import_crypto5 = __nccwpck_require__(76982);
|
|
129009
129148
|
import_events2 = __nccwpck_require__(24434);
|
|
129149
|
+
import_fs5 = __nccwpck_require__(79896);
|
|
129150
|
+
import_promises = __nccwpck_require__(91943);
|
|
129151
|
+
import_path7 = __nccwpck_require__(16928);
|
|
129010
129152
|
init_tokenCounter();
|
|
129011
129153
|
init_tools2();
|
|
129012
129154
|
init_common();
|
|
@@ -129017,6 +129159,8 @@ var init_ProbeAgent = __esm({
|
|
|
129017
129159
|
init_mcp();
|
|
129018
129160
|
MAX_TOOL_ITERATIONS = parseInt(process.env.MAX_TOOL_ITERATIONS || "30", 10);
|
|
129019
129161
|
MAX_HISTORY_MESSAGES = 100;
|
|
129162
|
+
SUPPORTED_IMAGE_EXTENSIONS = ["png", "jpg", "jpeg", "webp", "gif", "bmp", "svg"];
|
|
129163
|
+
MAX_IMAGE_FILE_SIZE = 20 * 1024 * 1024;
|
|
129020
129164
|
ProbeAgent = class {
|
|
129021
129165
|
/**
|
|
129022
129166
|
* Create a new ProbeAgent instance
|
|
@@ -129060,6 +129204,8 @@ var init_ProbeAgent = __esm({
|
|
|
129060
129204
|
}
|
|
129061
129205
|
this.initializeTools();
|
|
129062
129206
|
this.history = [];
|
|
129207
|
+
this.pendingImages = /* @__PURE__ */ new Map();
|
|
129208
|
+
this.currentImages = [];
|
|
129063
129209
|
this.events = new import_events2.EventEmitter();
|
|
129064
129210
|
this.enableMcp = !!options.enableMcp || process.env.ENABLE_MCP === "1";
|
|
129065
129211
|
this.mcpConfigPath = options.mcpConfigPath || null;
|
|
@@ -129185,6 +129331,175 @@ var init_ProbeAgent = __esm({
|
|
|
129185
129331
|
console.log(`Using Google API with model: ${this.model}${apiUrl ? ` (URL: ${apiUrl})` : ""}`);
|
|
129186
129332
|
}
|
|
129187
129333
|
}
|
|
129334
|
+
/**
|
|
129335
|
+
* Process assistant response content and detect/load image references
|
|
129336
|
+
* @param {string} content - The assistant's response content
|
|
129337
|
+
* @returns {Promise<void>}
|
|
129338
|
+
*/
|
|
129339
|
+
async processImageReferences(content) {
|
|
129340
|
+
if (!content) return;
|
|
129341
|
+
const extensionsPattern = `(?:${SUPPORTED_IMAGE_EXTENSIONS.join("|")})`;
|
|
129342
|
+
const imagePatterns = [
|
|
129343
|
+
// Direct file path mentions: "./screenshot.png", "/path/to/image.jpg", etc.
|
|
129344
|
+
new RegExp(`(?:\\.?\\.\\/)?[^\\s"'<>\\[\\]]+\\.${extensionsPattern}(?!\\w)`, "gi"),
|
|
129345
|
+
// Contextual mentions: "look at image.png", "the file screenshot.jpg shows"
|
|
129346
|
+
new RegExp(`(?:image|file|screenshot|diagram|photo|picture|graphic)\\s*:?\\s*([^\\s"'<>\\[\\]]+\\.${extensionsPattern})(?!\\w)`, "gi"),
|
|
129347
|
+
// Tool result mentions: often contain file paths
|
|
129348
|
+
new RegExp(`(?:found|saved|created|generated).*?([^\\s"'<>\\[\\]]+\\.${extensionsPattern})(?!\\w)`, "gi")
|
|
129349
|
+
];
|
|
129350
|
+
const foundPaths = /* @__PURE__ */ new Set();
|
|
129351
|
+
for (const pattern of imagePatterns) {
|
|
129352
|
+
let match;
|
|
129353
|
+
while ((match = pattern.exec(content)) !== null) {
|
|
129354
|
+
const imagePath = match[1] || match[0];
|
|
129355
|
+
if (imagePath && imagePath.length > 0) {
|
|
129356
|
+
foundPaths.add(imagePath.trim());
|
|
129357
|
+
}
|
|
129358
|
+
}
|
|
129359
|
+
}
|
|
129360
|
+
if (foundPaths.size === 0) return;
|
|
129361
|
+
if (this.debug) {
|
|
129362
|
+
console.log(`[DEBUG] Found ${foundPaths.size} potential image references:`, Array.from(foundPaths));
|
|
129363
|
+
}
|
|
129364
|
+
for (const imagePath of foundPaths) {
|
|
129365
|
+
await this.loadImageIfValid(imagePath);
|
|
129366
|
+
}
|
|
129367
|
+
}
|
|
129368
|
+
/**
|
|
129369
|
+
* Load and cache an image if it's valid and accessible
|
|
129370
|
+
* @param {string} imagePath - Path to the image file
|
|
129371
|
+
* @returns {Promise<boolean>} - True if image was loaded successfully
|
|
129372
|
+
*/
|
|
129373
|
+
async loadImageIfValid(imagePath) {
|
|
129374
|
+
try {
|
|
129375
|
+
if (this.pendingImages.has(imagePath)) {
|
|
129376
|
+
if (this.debug) {
|
|
129377
|
+
console.log(`[DEBUG] Image already loaded: ${imagePath}`);
|
|
129378
|
+
}
|
|
129379
|
+
return true;
|
|
129380
|
+
}
|
|
129381
|
+
const allowedDirs = this.allowedFolders && this.allowedFolders.length > 0 ? this.allowedFolders : [process.cwd()];
|
|
129382
|
+
let absolutePath;
|
|
129383
|
+
let isPathAllowed = false;
|
|
129384
|
+
if ((0, import_path7.isAbsolute)(imagePath)) {
|
|
129385
|
+
absolutePath = imagePath;
|
|
129386
|
+
isPathAllowed = allowedDirs.some((dir) => absolutePath.startsWith((0, import_path7.resolve)(dir)));
|
|
129387
|
+
} else {
|
|
129388
|
+
for (const dir of allowedDirs) {
|
|
129389
|
+
const resolvedPath = (0, import_path7.resolve)(dir, imagePath);
|
|
129390
|
+
if (resolvedPath.startsWith((0, import_path7.resolve)(dir))) {
|
|
129391
|
+
absolutePath = resolvedPath;
|
|
129392
|
+
isPathAllowed = true;
|
|
129393
|
+
break;
|
|
129394
|
+
}
|
|
129395
|
+
}
|
|
129396
|
+
}
|
|
129397
|
+
if (!isPathAllowed) {
|
|
129398
|
+
if (this.debug) {
|
|
129399
|
+
console.log(`[DEBUG] Image path outside allowed directories: ${imagePath}`);
|
|
129400
|
+
}
|
|
129401
|
+
return false;
|
|
129402
|
+
}
|
|
129403
|
+
let fileStats;
|
|
129404
|
+
try {
|
|
129405
|
+
fileStats = await (0, import_promises.stat)(absolutePath);
|
|
129406
|
+
} catch (error) {
|
|
129407
|
+
if (this.debug) {
|
|
129408
|
+
console.log(`[DEBUG] Image file not found: ${absolutePath}`);
|
|
129409
|
+
}
|
|
129410
|
+
return false;
|
|
129411
|
+
}
|
|
129412
|
+
if (fileStats.size > MAX_IMAGE_FILE_SIZE) {
|
|
129413
|
+
if (this.debug) {
|
|
129414
|
+
console.log(`[DEBUG] Image file too large: ${absolutePath} (${fileStats.size} bytes, max: ${MAX_IMAGE_FILE_SIZE})`);
|
|
129415
|
+
}
|
|
129416
|
+
return false;
|
|
129417
|
+
}
|
|
129418
|
+
const extension = absolutePath.toLowerCase().split(".").pop();
|
|
129419
|
+
if (!SUPPORTED_IMAGE_EXTENSIONS.includes(extension)) {
|
|
129420
|
+
if (this.debug) {
|
|
129421
|
+
console.log(`[DEBUG] Unsupported image format: ${extension}`);
|
|
129422
|
+
}
|
|
129423
|
+
return false;
|
|
129424
|
+
}
|
|
129425
|
+
const mimeTypes = {
|
|
129426
|
+
"png": "image/png",
|
|
129427
|
+
"jpg": "image/jpeg",
|
|
129428
|
+
"jpeg": "image/jpeg",
|
|
129429
|
+
"webp": "image/webp",
|
|
129430
|
+
"gif": "image/gif",
|
|
129431
|
+
"bmp": "image/bmp",
|
|
129432
|
+
"svg": "image/svg+xml"
|
|
129433
|
+
};
|
|
129434
|
+
const mimeType = mimeTypes[extension];
|
|
129435
|
+
const fileBuffer = await (0, import_promises.readFile)(absolutePath);
|
|
129436
|
+
const base64Data = fileBuffer.toString("base64");
|
|
129437
|
+
const dataUrl = `data:${mimeType};base64,${base64Data}`;
|
|
129438
|
+
this.pendingImages.set(imagePath, dataUrl);
|
|
129439
|
+
if (this.debug) {
|
|
129440
|
+
console.log(`[DEBUG] Successfully loaded image: ${imagePath} (${fileBuffer.length} bytes)`);
|
|
129441
|
+
}
|
|
129442
|
+
return true;
|
|
129443
|
+
} catch (error) {
|
|
129444
|
+
if (this.debug) {
|
|
129445
|
+
console.log(`[DEBUG] Failed to load image ${imagePath}: ${error.message}`);
|
|
129446
|
+
}
|
|
129447
|
+
return false;
|
|
129448
|
+
}
|
|
129449
|
+
}
|
|
129450
|
+
/**
|
|
129451
|
+
* Get all currently loaded images as an array for AI model consumption
|
|
129452
|
+
* @returns {Array<string>} - Array of base64 data URLs
|
|
129453
|
+
*/
|
|
129454
|
+
getCurrentImages() {
|
|
129455
|
+
return Array.from(this.pendingImages.values());
|
|
129456
|
+
}
|
|
129457
|
+
/**
|
|
129458
|
+
* Clear loaded images (useful for new conversations)
|
|
129459
|
+
*/
|
|
129460
|
+
clearLoadedImages() {
|
|
129461
|
+
this.pendingImages.clear();
|
|
129462
|
+
this.currentImages = [];
|
|
129463
|
+
if (this.debug) {
|
|
129464
|
+
console.log("[DEBUG] Cleared all loaded images");
|
|
129465
|
+
}
|
|
129466
|
+
}
|
|
129467
|
+
/**
|
|
129468
|
+
* Prepare messages for AI consumption, adding images to the latest user message if available
|
|
129469
|
+
* @param {Array} messages - Current conversation messages
|
|
129470
|
+
* @returns {Array} - Messages formatted for AI SDK with potential image content
|
|
129471
|
+
*/
|
|
129472
|
+
prepareMessagesWithImages(messages) {
|
|
129473
|
+
const loadedImages = this.getCurrentImages();
|
|
129474
|
+
if (loadedImages.length === 0) {
|
|
129475
|
+
return messages;
|
|
129476
|
+
}
|
|
129477
|
+
const messagesWithImages = [...messages];
|
|
129478
|
+
const lastUserMessageIndex = messagesWithImages.map((m) => m.role).lastIndexOf("user");
|
|
129479
|
+
if (lastUserMessageIndex === -1) {
|
|
129480
|
+
if (this.debug) {
|
|
129481
|
+
console.log("[DEBUG] No user messages found to attach images to");
|
|
129482
|
+
}
|
|
129483
|
+
return messages;
|
|
129484
|
+
}
|
|
129485
|
+
const lastUserMessage = messagesWithImages[lastUserMessageIndex];
|
|
129486
|
+
if (typeof lastUserMessage.content === "string") {
|
|
129487
|
+
messagesWithImages[lastUserMessageIndex] = {
|
|
129488
|
+
...lastUserMessage,
|
|
129489
|
+
content: [
|
|
129490
|
+
{ type: "text", text: lastUserMessage.content },
|
|
129491
|
+
...loadedImages.map((imageData) => ({
|
|
129492
|
+
type: "image",
|
|
129493
|
+
image: imageData
|
|
129494
|
+
}))
|
|
129495
|
+
]
|
|
129496
|
+
};
|
|
129497
|
+
if (this.debug) {
|
|
129498
|
+
console.log(`[DEBUG] Added ${loadedImages.length} images to the latest user message`);
|
|
129499
|
+
}
|
|
129500
|
+
}
|
|
129501
|
+
return messagesWithImages;
|
|
129502
|
+
}
|
|
129188
129503
|
/**
|
|
129189
129504
|
* Initialize mock model for testing
|
|
129190
129505
|
*/
|
|
@@ -129566,9 +129881,10 @@ You are working with a repository located at: ${searchDirectory}
|
|
|
129566
129881
|
let assistantResponseContent = "";
|
|
129567
129882
|
try {
|
|
129568
129883
|
const executeAIRequest = async () => {
|
|
129884
|
+
const messagesForAI = this.prepareMessagesWithImages(currentMessages);
|
|
129569
129885
|
const result = await (0, import_ai2.streamText)({
|
|
129570
129886
|
model: this.provider(this.model),
|
|
129571
|
-
messages:
|
|
129887
|
+
messages: messagesForAI,
|
|
129572
129888
|
maxTokens: maxResponseTokens,
|
|
129573
129889
|
temperature: 0.3
|
|
129574
129890
|
});
|
|
@@ -129602,6 +129918,9 @@ You are working with a repository located at: ${searchDirectory}
|
|
|
129602
129918
|
const assistantPreview = createMessagePreview(assistantResponseContent);
|
|
129603
129919
|
console.log(`[DEBUG] Assistant response (${assistantResponseContent.length} chars): ${assistantPreview}`);
|
|
129604
129920
|
}
|
|
129921
|
+
if (assistantResponseContent) {
|
|
129922
|
+
await this.processImageReferences(assistantResponseContent);
|
|
129923
|
+
}
|
|
129605
129924
|
const validTools = [
|
|
129606
129925
|
"search",
|
|
129607
129926
|
"query",
|
|
@@ -129726,12 +130045,17 @@ ${toolResultContent}
|
|
|
129726
130045
|
throw toolError;
|
|
129727
130046
|
}
|
|
129728
130047
|
currentMessages.push({ role: "assistant", content: assistantResponseContent });
|
|
130048
|
+
const toolResultContent = typeof toolResult === "string" ? toolResult : JSON.stringify(toolResult, null, 2);
|
|
130049
|
+
const toolResultMessage = `<tool_result>
|
|
130050
|
+
${toolResultContent}
|
|
130051
|
+
</tool_result>`;
|
|
129729
130052
|
currentMessages.push({
|
|
129730
130053
|
role: "user",
|
|
129731
|
-
content:
|
|
129732
|
-
${typeof toolResult === "string" ? toolResult : JSON.stringify(toolResult, null, 2)}
|
|
129733
|
-
</tool_result>`
|
|
130054
|
+
content: toolResultMessage
|
|
129734
130055
|
});
|
|
130056
|
+
if (toolResultContent) {
|
|
130057
|
+
await this.processImageReferences(toolResultContent);
|
|
130058
|
+
}
|
|
129735
130059
|
if (this.debug) {
|
|
129736
130060
|
console.log(`[DEBUG] Tool ${toolName} executed successfully. Result length: ${typeof toolResult === "string" ? toolResult.length : JSON.stringify(toolResult).length}`);
|
|
129737
130061
|
}
|
|
@@ -130229,12 +130553,12 @@ function initializeSimpleTelemetryFromOptions(options) {
|
|
|
130229
130553
|
});
|
|
130230
130554
|
return telemetry;
|
|
130231
130555
|
}
|
|
130232
|
-
var
|
|
130556
|
+
var import_fs6, import_path8, SimpleTelemetry, SimpleAppTracer;
|
|
130233
130557
|
var init_simpleTelemetry = __esm({
|
|
130234
130558
|
"src/agent/simpleTelemetry.js"() {
|
|
130235
130559
|
"use strict";
|
|
130236
|
-
|
|
130237
|
-
|
|
130560
|
+
import_fs6 = __nccwpck_require__(79896);
|
|
130561
|
+
import_path8 = __nccwpck_require__(16928);
|
|
130238
130562
|
SimpleTelemetry = class {
|
|
130239
130563
|
constructor(options = {}) {
|
|
130240
130564
|
this.serviceName = options.serviceName || "probe-agent";
|
|
@@ -130248,11 +130572,11 @@ var init_simpleTelemetry = __esm({
|
|
|
130248
130572
|
}
|
|
130249
130573
|
initializeFileExporter() {
|
|
130250
130574
|
try {
|
|
130251
|
-
const dir = (0,
|
|
130252
|
-
if (!(0,
|
|
130253
|
-
(0,
|
|
130575
|
+
const dir = (0, import_path8.dirname)(this.filePath);
|
|
130576
|
+
if (!(0, import_fs6.existsSync)(dir)) {
|
|
130577
|
+
(0, import_fs6.mkdirSync)(dir, { recursive: true });
|
|
130254
130578
|
}
|
|
130255
|
-
this.stream = (0,
|
|
130579
|
+
this.stream = (0, import_fs6.createWriteStream)(this.filePath, { flags: "a" });
|
|
130256
130580
|
this.stream.on("error", (error) => {
|
|
130257
130581
|
console.error(`[SimpleTelemetry] Stream error: ${error.message}`);
|
|
130258
130582
|
});
|
|
@@ -130313,20 +130637,20 @@ var init_simpleTelemetry = __esm({
|
|
|
130313
130637
|
}
|
|
130314
130638
|
async flush() {
|
|
130315
130639
|
if (this.stream) {
|
|
130316
|
-
return new Promise((
|
|
130317
|
-
this.stream.once("drain",
|
|
130640
|
+
return new Promise((resolve2) => {
|
|
130641
|
+
this.stream.once("drain", resolve2);
|
|
130318
130642
|
if (!this.stream.writableNeedDrain) {
|
|
130319
|
-
|
|
130643
|
+
resolve2();
|
|
130320
130644
|
}
|
|
130321
130645
|
});
|
|
130322
130646
|
}
|
|
130323
130647
|
}
|
|
130324
130648
|
async shutdown() {
|
|
130325
130649
|
if (this.stream) {
|
|
130326
|
-
return new Promise((
|
|
130650
|
+
return new Promise((resolve2) => {
|
|
130327
130651
|
this.stream.end(() => {
|
|
130328
130652
|
console.log(`[SimpleTelemetry] File stream closed: ${this.filePath}`);
|
|
130329
|
-
|
|
130653
|
+
resolve2();
|
|
130330
130654
|
});
|
|
130331
130655
|
});
|
|
130332
130656
|
}
|
package/dist/types/cli.d.ts
CHANGED
|
@@ -34,6 +34,8 @@ export interface CliOptions {
|
|
|
34
34
|
help?: boolean;
|
|
35
35
|
/** Show version */
|
|
36
36
|
version?: boolean;
|
|
37
|
+
/** Code context mode: auto (default), enabled (force include), disabled (force exclude) */
|
|
38
|
+
codeContext?: 'auto' | 'enabled' | 'disabled';
|
|
37
39
|
}
|
|
38
40
|
/**
|
|
39
41
|
* CLI command configuration
|
package/dist/types/cli.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["file:///home/runner/work/visor/visor/src/types/cli.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,MAAM,SAAS,GAAG,aAAa,GAAG,cAAc,GAAG,UAAU,GAAG,OAAO,GAAG,KAAK,CAAC;AAEtF;;GAEG;AACH,MAAM,MAAM,YAAY,GAAG,OAAO,GAAG,MAAM,GAAG,UAAU,GAAG,OAAO,CAAC;AAEnE;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,sCAAsC;IACtC,MAAM,EAAE,SAAS,EAAE,CAAC;IACpB,gCAAgC;IAChC,MAAM,EAAE,YAAY,CAAC;IACrB,iCAAiC;IACjC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,oFAAoF;IACpF,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,+DAA+D;IAC/D,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,4CAA4C;IAC5C,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,gDAAgD;IAChD,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,oEAAoE;IACpE,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,sEAAsE;IACtE,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,qDAAqD;IACrD,qBAAqB,CAAC,EAAE,MAAM,EAAE,CAAC;IACjC,qBAAqB;IACrB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,mBAAmB;IACnB,OAAO,CAAC,EAAE,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["file:///home/runner/work/visor/visor/src/types/cli.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,MAAM,SAAS,GAAG,aAAa,GAAG,cAAc,GAAG,UAAU,GAAG,OAAO,GAAG,KAAK,CAAC;AAEtF;;GAEG;AACH,MAAM,MAAM,YAAY,GAAG,OAAO,GAAG,MAAM,GAAG,UAAU,GAAG,OAAO,CAAC;AAEnE;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,sCAAsC;IACtC,MAAM,EAAE,SAAS,EAAE,CAAC;IACpB,gCAAgC;IAChC,MAAM,EAAE,YAAY,CAAC;IACrB,iCAAiC;IACjC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,oFAAoF;IACpF,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,+DAA+D;IAC/D,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,4CAA4C;IAC5C,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,gDAAgD;IAChD,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,oEAAoE;IACpE,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,sEAAsE;IACtE,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,qDAAqD;IACrD,qBAAqB,CAAC,EAAE,MAAM,EAAE,CAAC;IACjC,qBAAqB;IACrB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,mBAAmB;IACnB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,2FAA2F;IAC3F,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,UAAU,CAAC;CAC/C;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,mBAAmB;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,0BAA0B;IAC1B,WAAW,EAAE,MAAM,CAAC;IACpB,sBAAsB;IACtB,OAAO,EAAE,UAAU,CAAC;CACrB"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@probelabs/visor",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.41",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"bin": {
|
|
6
6
|
"visor": "./dist/index.js"
|
|
@@ -66,7 +66,7 @@
|
|
|
66
66
|
"@octokit/auth-app": "^8.1.0",
|
|
67
67
|
"@octokit/core": "^7.0.3",
|
|
68
68
|
"@octokit/rest": "^22.0.0",
|
|
69
|
-
"@probelabs/probe": "^0.6.0-
|
|
69
|
+
"@probelabs/probe": "^0.6.0-rc103",
|
|
70
70
|
"@types/commander": "^2.12.0",
|
|
71
71
|
"@types/uuid": "^10.0.0",
|
|
72
72
|
"cli-table3": "^0.6.5",
|