@probelabs/visor 0.1.86 → 0.1.88
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/README.md +19 -2
- package/dist/action-cli-bridge.d.ts.map +1 -1
- package/dist/ai-review-service.d.ts +2 -1
- package/dist/ai-review-service.d.ts.map +1 -1
- package/dist/check-execution-engine.d.ts.map +1 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/failure-condition-evaluator.d.ts.map +1 -1
- package/dist/generated/config-schema.d.ts +5 -0
- package/dist/generated/config-schema.d.ts.map +1 -1
- package/dist/generated/config-schema.json +8 -0
- package/dist/github-check-service.d.ts.map +1 -1
- package/dist/index.js +384 -80
- package/dist/output-formatters.d.ts +8 -0
- package/dist/output-formatters.d.ts.map +1 -1
- package/dist/providers/ai-check-provider.d.ts.map +1 -1
- package/dist/reviewer.d.ts +2 -0
- package/dist/reviewer.d.ts.map +1 -1
- package/dist/sdk/{check-execution-engine-WI7LJL2G.mjs → check-execution-engine-D6FPIIKR.mjs} +2 -2
- package/dist/sdk/{chunk-P4XLP7NN.mjs → chunk-N34GS4A5.mjs} +160 -32
- package/dist/sdk/chunk-N34GS4A5.mjs.map +1 -0
- package/dist/sdk/sdk.d.mts +4 -0
- package/dist/sdk/sdk.d.ts +4 -0
- package/dist/sdk/sdk.js +179 -30
- package/dist/sdk/sdk.js.map +1 -1
- package/dist/sdk/sdk.mjs +22 -1
- package/dist/sdk/sdk.mjs.map +1 -1
- package/dist/session-registry.d.ts +5 -0
- package/dist/session-registry.d.ts.map +1 -1
- package/dist/types/config.d.ts +2 -0
- package/dist/types/config.d.ts.map +1 -1
- package/package.json +1 -1
- package/dist/sdk/chunk-P4XLP7NN.mjs.map +0 -1
- /package/dist/sdk/{check-execution-engine-WI7LJL2G.mjs.map → check-execution-engine-D6FPIIKR.mjs.map} +0 -0
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
process.env.VISOR_VERSION = '0.1.
|
|
2
|
+
process.env.VISOR_VERSION = '0.1.88';
|
|
3
3
|
process.env.PROBE_VERSION = '0.6.0-rc124';
|
|
4
4
|
/******/ (() => { // webpackBootstrap
|
|
5
5
|
/******/ var __webpack_modules__ = ({
|
|
@@ -99834,8 +99834,9 @@ class AIReviewService {
|
|
|
99834
99834
|
}
|
|
99835
99835
|
/**
|
|
99836
99836
|
* Execute AI review using session reuse - reuses an existing ProbeAgent session
|
|
99837
|
+
* @param sessionMode - 'clone' (default) clones history, 'append' shares history
|
|
99837
99838
|
*/
|
|
99838
|
-
async executeReviewWithSessionReuse(prInfo, customPrompt, parentSessionId, schema, checkName) {
|
|
99839
|
+
async executeReviewWithSessionReuse(prInfo, customPrompt, parentSessionId, schema, checkName, sessionMode = 'clone') {
|
|
99839
99840
|
const startTime = Date.now();
|
|
99840
99841
|
const timestamp = new Date().toISOString();
|
|
99841
99842
|
// Get the existing session
|
|
@@ -99845,7 +99846,25 @@ class AIReviewService {
|
|
|
99845
99846
|
}
|
|
99846
99847
|
// Build prompt from custom instructions
|
|
99847
99848
|
const prompt = await this.buildCustomPrompt(prInfo, customPrompt, schema);
|
|
99848
|
-
|
|
99849
|
+
// Determine which agent to use based on session mode
|
|
99850
|
+
let agentToUse;
|
|
99851
|
+
let currentSessionId;
|
|
99852
|
+
if (sessionMode === 'clone') {
|
|
99853
|
+
// Clone the session - creates a new agent with copied history
|
|
99854
|
+
currentSessionId = `${parentSessionId}-clone-${Date.now()}`;
|
|
99855
|
+
log(`📋 Cloning AI session ${parentSessionId} → ${currentSessionId}...`);
|
|
99856
|
+
const clonedAgent = await this.sessionRegistry.cloneSession(parentSessionId, currentSessionId);
|
|
99857
|
+
if (!clonedAgent) {
|
|
99858
|
+
throw new Error(`Failed to clone session ${parentSessionId}. Falling back to append mode.`);
|
|
99859
|
+
}
|
|
99860
|
+
agentToUse = clonedAgent;
|
|
99861
|
+
}
|
|
99862
|
+
else {
|
|
99863
|
+
// Append mode - use the same agent instance
|
|
99864
|
+
log(`🔄 Appending to AI session ${parentSessionId} (shared history)...`);
|
|
99865
|
+
agentToUse = existingAgent;
|
|
99866
|
+
currentSessionId = parentSessionId;
|
|
99867
|
+
}
|
|
99849
99868
|
log(`🔧 Debug: Raw schema parameter: ${JSON.stringify(schema)} (type: ${typeof schema})`);
|
|
99850
99869
|
log(`Schema type: ${schema || 'none (no schema)'}`);
|
|
99851
99870
|
let debugInfo;
|
|
@@ -99867,8 +99886,8 @@ class AIReviewService {
|
|
|
99867
99886
|
};
|
|
99868
99887
|
}
|
|
99869
99888
|
try {
|
|
99870
|
-
// Use
|
|
99871
|
-
const { response, effectiveSchema } = await this.callProbeAgentWithExistingSession(
|
|
99889
|
+
// Use the determined agent (cloned or original)
|
|
99890
|
+
const { response, effectiveSchema } = await this.callProbeAgentWithExistingSession(agentToUse, prompt, schema, debugInfo, checkName);
|
|
99872
99891
|
const processingTime = Date.now() - startTime;
|
|
99873
99892
|
if (debugInfo) {
|
|
99874
99893
|
debugInfo.rawResponse = response;
|
|
@@ -99879,6 +99898,11 @@ class AIReviewService {
|
|
|
99879
99898
|
if (debugInfo) {
|
|
99880
99899
|
result.debug = debugInfo;
|
|
99881
99900
|
}
|
|
99901
|
+
// Include the session ID in the result for cleanup tracking
|
|
99902
|
+
// Only include if we created a new cloned session
|
|
99903
|
+
if (sessionMode === 'clone' && currentSessionId !== parentSessionId) {
|
|
99904
|
+
result.sessionId = currentSessionId;
|
|
99905
|
+
}
|
|
99882
99906
|
return result;
|
|
99883
99907
|
}
|
|
99884
99908
|
catch (error) {
|
|
@@ -99975,7 +99999,8 @@ ${prContext}
|
|
|
99975
99999
|
<rule>For INCREMENTAL analysis, ONLY review changes in commit_diff section</rule>
|
|
99976
100000
|
<rule>For FULL analysis, review all changes in full_diff section</rule>
|
|
99977
100001
|
<rule>Reference specific XML elements like files_summary, metadata when providing context</rule>
|
|
99978
|
-
<rule>
|
|
100002
|
+
<rule>STRICT OUTPUT POLICY: Report only actual problems, risks, or deficiencies. Do not write praise, congratulations, or celebratory text. Do not create issues that merely restate improvements or say "no action needed".</rule>
|
|
100003
|
+
<rule>SEVERITY ASSIGNMENT: Assign severity ONLY to problems introduced or left unresolved by this change (critical/error/warning/info as appropriate). Do NOT create issue entries solely to acknowledge improvements; if no problems exist, return zero issues.</rule>
|
|
99979
100004
|
</rules>
|
|
99980
100005
|
</review_request>`;
|
|
99981
100006
|
}
|
|
@@ -102344,10 +102369,12 @@ class CheckExecutionEngine {
|
|
|
102344
102369
|
// - command provider execution/transform failures
|
|
102345
102370
|
// - forEach validation/iteration errors
|
|
102346
102371
|
// - fail_if conditions (global or check-specific)
|
|
102347
|
-
|
|
102372
|
+
let hasFatalFailure = (depRes.issues || []).some(issue => {
|
|
102348
102373
|
const id = issue.ruleId || '';
|
|
102349
102374
|
return (id === 'command/execution_error' ||
|
|
102350
102375
|
id.endsWith('/command/execution_error') ||
|
|
102376
|
+
id === 'command/timeout' ||
|
|
102377
|
+
id.endsWith('/command/timeout') ||
|
|
102351
102378
|
id === 'command/transform_js_error' ||
|
|
102352
102379
|
id.endsWith('/command/transform_js_error') ||
|
|
102353
102380
|
id === 'command/transform_error' ||
|
|
@@ -102358,6 +102385,14 @@ class CheckExecutionEngine {
|
|
|
102358
102385
|
id.endsWith('_fail_if') ||
|
|
102359
102386
|
id.endsWith('/global_fail_if'));
|
|
102360
102387
|
});
|
|
102388
|
+
// As a fallback, evaluate fail_if on the dependency result now (in case the provider path didn't add issues yet)
|
|
102389
|
+
if (!hasFatalFailure && config && (config.fail_if || config.checks[depId]?.fail_if)) {
|
|
102390
|
+
const failIfResults = await this.evaluateFailureConditions(depId, depRes, config);
|
|
102391
|
+
hasFatalFailure = failIfResults.some(r => r.failed);
|
|
102392
|
+
}
|
|
102393
|
+
if (debug) {
|
|
102394
|
+
log(`🔧 Debug: gating check '${checkName}' against dep '${depId}': wasSkipped=${wasSkipped} hasFatalFailure=${hasFatalFailure}`);
|
|
102395
|
+
}
|
|
102361
102396
|
if (wasSkipped || hasFatalFailure)
|
|
102362
102397
|
failedDeps.push(depId);
|
|
102363
102398
|
}
|
|
@@ -102584,6 +102619,23 @@ class CheckExecutionEngine {
|
|
|
102584
102619
|
issues: allIssues,
|
|
102585
102620
|
...(finalOutput !== undefined ? { output: finalOutput } : {}),
|
|
102586
102621
|
};
|
|
102622
|
+
// Evaluate fail_if for aggregated forEach results (applies to the whole check)
|
|
102623
|
+
if (config && (config.fail_if || checkConfig.fail_if)) {
|
|
102624
|
+
const failureResults = await this.evaluateFailureConditions(checkName, finalResult, config);
|
|
102625
|
+
if (failureResults.length > 0) {
|
|
102626
|
+
const failureIssues = failureResults
|
|
102627
|
+
.filter(f => f.failed)
|
|
102628
|
+
.map(f => ({
|
|
102629
|
+
file: 'system',
|
|
102630
|
+
line: 0,
|
|
102631
|
+
ruleId: f.conditionName,
|
|
102632
|
+
message: f.message || `Failure condition met: ${f.expression}`,
|
|
102633
|
+
severity: (f.severity || 'error'),
|
|
102634
|
+
category: 'logic',
|
|
102635
|
+
}));
|
|
102636
|
+
finalResult.issues = [...(finalResult.issues || []), ...failureIssues];
|
|
102637
|
+
}
|
|
102638
|
+
}
|
|
102587
102639
|
// IMPORTANT: Mark this result as forEach-capable so that checks depending on it
|
|
102588
102640
|
// will also iterate over the items (propagate forEach behavior down the chain)
|
|
102589
102641
|
if (allOutputs.length > 0) {
|
|
@@ -102618,12 +102670,31 @@ class CheckExecutionEngine {
|
|
|
102618
102670
|
}
|
|
102619
102671
|
// Execute with retry/routing semantics
|
|
102620
102672
|
finalResult = await this.executeWithRouting(checkName, checkConfig, provider, providerConfig, prInfo, dependencyResults, sessionInfo, config, dependencyGraph, debug, results);
|
|
102673
|
+
// Evaluate fail_if for normal (non-forEach) execution
|
|
102674
|
+
if (config && (config.fail_if || checkConfig.fail_if)) {
|
|
102675
|
+
const failureResults = await this.evaluateFailureConditions(checkName, finalResult, config);
|
|
102676
|
+
if (failureResults.length > 0) {
|
|
102677
|
+
const failureIssues = failureResults
|
|
102678
|
+
.filter(f => f.failed)
|
|
102679
|
+
.map(f => ({
|
|
102680
|
+
file: 'system',
|
|
102681
|
+
line: 0,
|
|
102682
|
+
ruleId: f.conditionName,
|
|
102683
|
+
message: f.message || `Failure condition met: ${f.expression}`,
|
|
102684
|
+
severity: (f.severity || 'error'),
|
|
102685
|
+
category: 'logic',
|
|
102686
|
+
}));
|
|
102687
|
+
finalResult.issues = [...(finalResult.issues || []), ...failureIssues];
|
|
102688
|
+
}
|
|
102689
|
+
}
|
|
102621
102690
|
// Record normal (non-forEach) execution
|
|
102622
102691
|
// Check if this check had fatal errors
|
|
102623
102692
|
const hadFatalError = (finalResult.issues || []).some(issue => {
|
|
102624
102693
|
const id = issue.ruleId || '';
|
|
102625
102694
|
return (id === 'command/execution_error' ||
|
|
102626
102695
|
id.endsWith('/command/execution_error') ||
|
|
102696
|
+
id === 'command/timeout' ||
|
|
102697
|
+
id.endsWith('/command/timeout') ||
|
|
102627
102698
|
id === 'command/transform_js_error' ||
|
|
102628
102699
|
id.endsWith('/command/transform_js_error') ||
|
|
102629
102700
|
id === 'command/transform_error' ||
|
|
@@ -102646,6 +102717,13 @@ class CheckExecutionEngine {
|
|
|
102646
102717
|
if (debug) {
|
|
102647
102718
|
log(`🔧 Debug: Completed check: ${checkName}, issues found: ${(finalResult.issues || []).length}`);
|
|
102648
102719
|
}
|
|
102720
|
+
// Track cloned session IDs for cleanup
|
|
102721
|
+
if (finalResult.sessionId) {
|
|
102722
|
+
sessionIds.set(checkName, finalResult.sessionId);
|
|
102723
|
+
if (debug) {
|
|
102724
|
+
log(`🔧 Debug: Tracked cloned session for cleanup: ${finalResult.sessionId}`);
|
|
102725
|
+
}
|
|
102726
|
+
}
|
|
102649
102727
|
}
|
|
102650
102728
|
// Add checkName, group, schema, template info and timestamp to issues from config
|
|
102651
102729
|
const enrichedIssues = (finalResult.issues || []).map(issue => ({
|
|
@@ -105446,6 +105524,24 @@ class ConfigManager {
|
|
|
105446
105524
|
}
|
|
105447
105525
|
}
|
|
105448
105526
|
}
|
|
105527
|
+
// Validate session_mode configuration
|
|
105528
|
+
if (checkConfig.session_mode !== undefined) {
|
|
105529
|
+
if (checkConfig.session_mode !== 'clone' && checkConfig.session_mode !== 'append') {
|
|
105530
|
+
errors.push({
|
|
105531
|
+
field: `checks.${checkName}.session_mode`,
|
|
105532
|
+
message: `Invalid session_mode value for "${checkName}": must be 'clone' or 'append'`,
|
|
105533
|
+
value: checkConfig.session_mode,
|
|
105534
|
+
});
|
|
105535
|
+
}
|
|
105536
|
+
// session_mode only makes sense with reuse_ai_session
|
|
105537
|
+
if (!checkConfig.reuse_ai_session) {
|
|
105538
|
+
errors.push({
|
|
105539
|
+
field: `checks.${checkName}.session_mode`,
|
|
105540
|
+
message: `Check "${checkName}" has session_mode but no reuse_ai_session. session_mode requires reuse_ai_session to be set.`,
|
|
105541
|
+
value: checkConfig.session_mode,
|
|
105542
|
+
});
|
|
105543
|
+
}
|
|
105544
|
+
}
|
|
105449
105545
|
// Validate tags configuration
|
|
105450
105546
|
if (checkConfig.tags !== undefined) {
|
|
105451
105547
|
if (!Array.isArray(checkConfig.tags)) {
|
|
@@ -106467,26 +106563,37 @@ class FailureConditionEvaluator {
|
|
|
106467
106563
|
// Exclude issues from otherFields since we handle it separately
|
|
106468
106564
|
issues: _issues, // eslint-disable-line @typescript-eslint/no-unused-vars
|
|
106469
106565
|
...otherFields } = reviewSummaryWithOutput;
|
|
106566
|
+
// Build output object with safety for array-based outputs (forEach aggregation)
|
|
106567
|
+
const aggregatedOutput = {
|
|
106568
|
+
issues: (issues || []).map(issue => ({
|
|
106569
|
+
file: issue.file,
|
|
106570
|
+
line: issue.line,
|
|
106571
|
+
endLine: issue.endLine,
|
|
106572
|
+
ruleId: issue.ruleId,
|
|
106573
|
+
message: issue.message,
|
|
106574
|
+
severity: issue.severity,
|
|
106575
|
+
category: issue.category,
|
|
106576
|
+
group: issue.group,
|
|
106577
|
+
schema: issue.schema,
|
|
106578
|
+
suggestion: issue.suggestion,
|
|
106579
|
+
replacement: issue.replacement,
|
|
106580
|
+
})),
|
|
106581
|
+
// Include additional schema-specific data from reviewSummary
|
|
106582
|
+
...otherFields,
|
|
106583
|
+
};
|
|
106584
|
+
if (Array.isArray(extractedOutput)) {
|
|
106585
|
+
// Preserve items array and lift common flags for convenience (e.g., output.error)
|
|
106586
|
+
aggregatedOutput.items = extractedOutput;
|
|
106587
|
+
const anyError = extractedOutput.find(it => it && typeof it === 'object' && it.error);
|
|
106588
|
+
if (anyError && anyError.error !== undefined) {
|
|
106589
|
+
aggregatedOutput.error = anyError.error;
|
|
106590
|
+
}
|
|
106591
|
+
}
|
|
106592
|
+
else if (extractedOutput && typeof extractedOutput === 'object') {
|
|
106593
|
+
Object.assign(aggregatedOutput, extractedOutput);
|
|
106594
|
+
}
|
|
106470
106595
|
const context = {
|
|
106471
|
-
output:
|
|
106472
|
-
issues: (issues || []).map(issue => ({
|
|
106473
|
-
file: issue.file,
|
|
106474
|
-
line: issue.line,
|
|
106475
|
-
endLine: issue.endLine,
|
|
106476
|
-
ruleId: issue.ruleId,
|
|
106477
|
-
message: issue.message,
|
|
106478
|
-
severity: issue.severity,
|
|
106479
|
-
category: issue.category,
|
|
106480
|
-
group: issue.group,
|
|
106481
|
-
schema: issue.schema,
|
|
106482
|
-
suggestion: issue.suggestion,
|
|
106483
|
-
replacement: issue.replacement,
|
|
106484
|
-
})),
|
|
106485
|
-
// Include additional schema-specific data from reviewSummary
|
|
106486
|
-
...otherFields,
|
|
106487
|
-
// Spread the extracted output directly (avoid output.output nesting)
|
|
106488
|
-
...(extractedOutput && typeof extractedOutput === 'object' ? extractedOutput : {}),
|
|
106489
|
-
},
|
|
106596
|
+
output: aggregatedOutput,
|
|
106490
106597
|
outputs: (() => {
|
|
106491
106598
|
if (!previousOutputs)
|
|
106492
106599
|
return {};
|
|
@@ -106813,6 +106920,11 @@ exports.configSchema = {
|
|
|
106813
106920
|
type: ['string', 'boolean'],
|
|
106814
106921
|
description: 'Check name to reuse AI session from, or true to use first dependency (only works with depends_on)',
|
|
106815
106922
|
},
|
|
106923
|
+
session_mode: {
|
|
106924
|
+
type: 'string',
|
|
106925
|
+
enum: ['clone', 'append'],
|
|
106926
|
+
description: "How to reuse AI session: 'clone' (default, copy history) or 'append' (share history)",
|
|
106927
|
+
},
|
|
106816
106928
|
fail_if: {
|
|
106817
106929
|
type: 'string',
|
|
106818
106930
|
description: 'Simple fail condition - fails check if expression evaluates to true',
|
|
@@ -107939,11 +108051,13 @@ class GitHubCheckService {
|
|
|
107939
108051
|
await this.clearOldAnnotations(owner, repo, prNumber, checkName, currentCommitSha, check_run_id);
|
|
107940
108052
|
}
|
|
107941
108053
|
const { conclusion, summary } = this.determineCheckRunConclusion(checkName, failureResults, reviewIssues, executionError);
|
|
108054
|
+
// Filter out system-level issues (fail_if conditions, internal errors)
|
|
108055
|
+
// These should not appear as annotations but affect the check conclusion
|
|
108056
|
+
let filteredIssues = reviewIssues.filter(issue => !(issue.file === 'system' && issue.line === 0));
|
|
107942
108057
|
// Filter annotations to only include files changed in this commit
|
|
107943
108058
|
// This prevents old annotations from previous commits showing up in the Files tab
|
|
107944
|
-
let filteredIssues = reviewIssues;
|
|
107945
108059
|
if (filesChangedInCommit && filesChangedInCommit.length > 0) {
|
|
107946
|
-
filteredIssues =
|
|
108060
|
+
filteredIssues = filteredIssues.filter(issue => filesChangedInCommit.some(changedFile => issue.file === changedFile));
|
|
107947
108061
|
}
|
|
107948
108062
|
const annotations = this.convertIssuesToAnnotations(filteredIssues);
|
|
107949
108063
|
await this.octokit.rest.checks.update({
|
|
@@ -108926,7 +109040,39 @@ async function handleEvent(octokit, inputs, eventName, context, config) {
|
|
|
108926
109040
|
if (!owner || !repo) {
|
|
108927
109041
|
throw new Error('Owner and repo are required');
|
|
108928
109042
|
}
|
|
108929
|
-
|
|
109043
|
+
// Determine context type for better logging
|
|
109044
|
+
const isPullRequest = eventName === 'pull_request';
|
|
109045
|
+
const isIssue = eventName === 'issues';
|
|
109046
|
+
const isIssueComment = eventName === 'issue_comment';
|
|
109047
|
+
const isManualCLI = !eventName || eventName === 'unknown';
|
|
109048
|
+
// Map GitHub event to our event trigger format
|
|
109049
|
+
const eventType = mapGitHubEventToTrigger(eventName, context.event?.action);
|
|
109050
|
+
// Enhanced event logging with context
|
|
109051
|
+
if (isManualCLI) {
|
|
109052
|
+
console.log(`🖥️ Mode: Manual CLI`);
|
|
109053
|
+
console.log(`📂 Repository: ${owner}/${repo}`);
|
|
109054
|
+
}
|
|
109055
|
+
else {
|
|
109056
|
+
console.log(`🤖 Mode: GitHub Action`);
|
|
109057
|
+
console.log(`📂 Repository: ${owner}/${repo}`);
|
|
109058
|
+
console.log(`📋 Event: ${eventName}${context.event?.action ? ` (action: ${context.event?.action})` : ''}`);
|
|
109059
|
+
console.log(`🎯 Trigger: ${eventType}`);
|
|
109060
|
+
// Show context-specific information
|
|
109061
|
+
if (isPullRequest) {
|
|
109062
|
+
const prNumber = context.event?.pull_request?.number;
|
|
109063
|
+
console.log(`🔀 Context: Pull Request #${prNumber}`);
|
|
109064
|
+
}
|
|
109065
|
+
else if (isIssue) {
|
|
109066
|
+
const issueNumber = context.event?.issue?.number;
|
|
109067
|
+
console.log(`🎫 Context: Issue #${issueNumber}`);
|
|
109068
|
+
}
|
|
109069
|
+
else if (isIssueComment) {
|
|
109070
|
+
const issueOrPR = context.event?.issue;
|
|
109071
|
+
const isPR = issueOrPR?.pull_request ? true : false;
|
|
109072
|
+
const number = issueOrPR?.number;
|
|
109073
|
+
console.log(`💬 Context: Comment on ${isPR ? 'Pull Request' : 'Issue'} #${number}`);
|
|
109074
|
+
}
|
|
109075
|
+
}
|
|
108930
109076
|
// Debug: Log the checks that are available in the loaded config
|
|
108931
109077
|
const allChecks = Object.keys(config.checks || {});
|
|
108932
109078
|
console.log(`📚 Total checks in loaded config: ${allChecks.length}`);
|
|
@@ -108934,8 +109080,6 @@ async function handleEvent(octokit, inputs, eventName, context, config) {
|
|
|
108934
109080
|
// Only log check names if there aren't too many
|
|
108935
109081
|
console.log(`📚 Available checks: ${allChecks.join(', ')}`);
|
|
108936
109082
|
}
|
|
108937
|
-
// Map GitHub event to our event trigger format
|
|
108938
|
-
const eventType = mapGitHubEventToTrigger(eventName, context.event?.action);
|
|
108939
109083
|
// Find checks that should run for this event
|
|
108940
109084
|
let checksToRun = [];
|
|
108941
109085
|
// First, get all checks that are configured for this event type
|
|
@@ -109059,7 +109203,7 @@ async function handleIssueEvent(octokit, owner, repo, context, inputs, config, c
|
|
|
109059
109203
|
console.log('Skipping PR-related issue event');
|
|
109060
109204
|
return;
|
|
109061
109205
|
}
|
|
109062
|
-
console.log(
|
|
109206
|
+
console.log(`📋 Processing issue #${issue.number} event: ${action} with ${checksToRun.length} check(s): ${checksToRun.join(', ')}`);
|
|
109063
109207
|
// For issue events, we need to create a PR-like structure for the checks to process
|
|
109064
109208
|
// This allows us to reuse the existing check infrastructure
|
|
109065
109209
|
const prInfo = {
|
|
@@ -109098,6 +109242,19 @@ async function handleIssueEvent(octokit, owner, repo, context, inputs, config, c
|
|
|
109098
109242
|
config, undefined, // outputFormat
|
|
109099
109243
|
inputs.debug === 'true');
|
|
109100
109244
|
const { results } = executionResult;
|
|
109245
|
+
// Log execution results for debugging (only in debug mode)
|
|
109246
|
+
if (inputs.debug === 'true') {
|
|
109247
|
+
console.log(`📊 Check execution completed: ${Object.keys(results).length} group(s)`);
|
|
109248
|
+
for (const [group, checks] of Object.entries(results)) {
|
|
109249
|
+
console.log(` Group "${group}": ${checks.length} check(s)`);
|
|
109250
|
+
for (const check of checks) {
|
|
109251
|
+
const hasContent = check.content && check.content.trim();
|
|
109252
|
+
const contentLength = hasContent ? check.content.trim().length : 0;
|
|
109253
|
+
const issueCount = check.issues?.length || 0;
|
|
109254
|
+
console.log(` - ${check.checkName}: ${hasContent ? `${contentLength} chars` : 'empty'}, ${issueCount} issue(s)`);
|
|
109255
|
+
}
|
|
109256
|
+
}
|
|
109257
|
+
}
|
|
109101
109258
|
// Format and post results as a comment on the issue
|
|
109102
109259
|
if (Object.keys(results).length > 0) {
|
|
109103
109260
|
let commentBody = '';
|
|
@@ -109109,18 +109266,24 @@ async function handleIssueEvent(octokit, owner, repo, context, inputs, config, c
|
|
|
109109
109266
|
}
|
|
109110
109267
|
}
|
|
109111
109268
|
}
|
|
109112
|
-
|
|
109113
|
-
|
|
109114
|
-
|
|
109115
|
-
|
|
109116
|
-
|
|
109117
|
-
|
|
109118
|
-
|
|
109119
|
-
|
|
109120
|
-
|
|
109269
|
+
// Only post if there's actual content (not just empty checks)
|
|
109270
|
+
if (commentBody.trim()) {
|
|
109271
|
+
commentBody += `\n---\n*Powered by [Visor](https://github.com/probelabs/visor)*`;
|
|
109272
|
+
// Post comment to the issue
|
|
109273
|
+
await octokit.rest.issues.createComment({
|
|
109274
|
+
owner,
|
|
109275
|
+
repo,
|
|
109276
|
+
issue_number: issue.number,
|
|
109277
|
+
body: commentBody,
|
|
109278
|
+
});
|
|
109279
|
+
console.log(`✅ Posted issue assistant results to issue #${issue.number}`);
|
|
109280
|
+
}
|
|
109281
|
+
else {
|
|
109282
|
+
console.log('ℹ️ No content to post - all checks returned empty results');
|
|
109283
|
+
}
|
|
109121
109284
|
}
|
|
109122
109285
|
else {
|
|
109123
|
-
console.log('No results from issue assistant checks');
|
|
109286
|
+
console.log('⚠️ No results from issue assistant checks');
|
|
109124
109287
|
}
|
|
109125
109288
|
// Set outputs for GitHub Actions
|
|
109126
109289
|
(0, core_1.setOutput)('review-completed', 'true');
|
|
@@ -109150,7 +109313,7 @@ async function handleIssueComment(octokit, owner, repo, context, inputs, actionC
|
|
|
109150
109313
|
comment.body.includes('*Powered by [Visor](https://probelabs.com/visor)') ||
|
|
109151
109314
|
comment.body.includes('*Powered by [Visor](https://github.com/probelabs/visor)'));
|
|
109152
109315
|
if (isVisorBot || hasVisorMarkers) {
|
|
109153
|
-
console.log(
|
|
109316
|
+
console.log(`✓ Skipping bot's own comment to prevent recursion. Author: ${comment.user?.login}, Type: ${comment.user?.type}, Has markers: ${hasVisorMarkers}`);
|
|
109154
109317
|
return;
|
|
109155
109318
|
}
|
|
109156
109319
|
// Process comments on both issues and PRs
|
|
@@ -109577,7 +109740,11 @@ async function createGitHubChecks(octokit, inputs, owner, repo, headSha, checksT
|
|
|
109577
109740
|
console.log(`✅ Created check run for ${checkName}: ${checkRun.url}`);
|
|
109578
109741
|
}
|
|
109579
109742
|
catch (error) {
|
|
109580
|
-
|
|
109743
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
109744
|
+
// Extract just the meaningful error message without stack trace
|
|
109745
|
+
const cleanMessage = errorMessage.split('\n')[0].replace('Error: ', '');
|
|
109746
|
+
console.error(`⚠️ Could not create check run for ${checkName}: ${cleanMessage}`);
|
|
109747
|
+
console.log('💬 Review will continue using PR comments instead');
|
|
109581
109748
|
// Continue with other checks even if one fails
|
|
109582
109749
|
}
|
|
109583
109750
|
}
|
|
@@ -109603,7 +109770,10 @@ async function createGitHubChecks(octokit, inputs, owner, repo, headSha, checksT
|
|
|
109603
109770
|
console.log(`✅ Created combined check run: ${checkRun.url}`);
|
|
109604
109771
|
}
|
|
109605
109772
|
catch (error) {
|
|
109606
|
-
|
|
109773
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
109774
|
+
const cleanMessage = errorMessage.split('\n')[0].replace('Error: ', '');
|
|
109775
|
+
console.error(`⚠️ Could not create combined check run: ${cleanMessage}`);
|
|
109776
|
+
console.log('💬 Review will continue using PR comments instead');
|
|
109607
109777
|
}
|
|
109608
109778
|
}
|
|
109609
109779
|
return {
|
|
@@ -109627,7 +109797,10 @@ async function createGitHubChecks(octokit, inputs, owner, repo, headSha, checksT
|
|
|
109627
109797
|
};
|
|
109628
109798
|
}
|
|
109629
109799
|
else {
|
|
109630
|
-
|
|
109800
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
109801
|
+
const cleanMessage = errorMessage.split('\n')[0].replace('Error: ', '');
|
|
109802
|
+
console.error(`⚠️ Could not create GitHub check runs: ${cleanMessage}`);
|
|
109803
|
+
console.log('💬 Review will continue using PR comments instead');
|
|
109631
109804
|
return {
|
|
109632
109805
|
checkRunMap: null,
|
|
109633
109806
|
checksApiAvailable: false,
|
|
@@ -110280,14 +110453,22 @@ exports.OutputFormatters = void 0;
|
|
|
110280
110453
|
const cli_table3_1 = __importDefault(__nccwpck_require__(25832));
|
|
110281
110454
|
const reviewer_1 = __nccwpck_require__(532);
|
|
110282
110455
|
class OutputFormatters {
|
|
110456
|
+
// Hard safety limits to prevent pathological table rendering hangs
|
|
110457
|
+
// Can be tuned via env vars if needed
|
|
110458
|
+
static MAX_CELL_CHARS = parseInt(process.env.VISOR_MAX_TABLE_CELL || '4000', 10);
|
|
110459
|
+
static MAX_CODE_LINES = parseInt(process.env.VISOR_MAX_TABLE_CODE_LINES || '120', 10);
|
|
110460
|
+
static WRAP_WIDTH_MESSAGE = 55;
|
|
110461
|
+
static WRAP_WIDTH_MESSAGE_NARROW = 45;
|
|
110462
|
+
static WRAP_WIDTH_CODE = 58; // fits into Message col width ~60
|
|
110283
110463
|
/**
|
|
110284
110464
|
* Format analysis results as a table using cli-table3
|
|
110285
110465
|
*/
|
|
110286
110466
|
static formatAsTable(result, options = {}) {
|
|
110287
110467
|
const { showDetails = false, groupByCategory = true } = options;
|
|
110288
110468
|
let output = '';
|
|
110289
|
-
//
|
|
110290
|
-
|
|
110469
|
+
// Filter out system-level issues (fail_if conditions, internal errors)
|
|
110470
|
+
// These should not appear in user-facing output
|
|
110471
|
+
const issues = (result.reviewSummary.issues || []).filter(issue => !(issue.file === 'system' && issue.line === 0));
|
|
110291
110472
|
const totalIssues = issues.length;
|
|
110292
110473
|
const criticalIssues = issues.filter(i => i.severity === 'critical').length;
|
|
110293
110474
|
// Check if this is a code review context
|
|
@@ -110314,7 +110495,7 @@ class OutputFormatters {
|
|
|
110314
110495
|
summaryTable.push(['Files Analyzed', result.repositoryInfo.files.length.toString()], ['Total Additions', result.repositoryInfo.totalAdditions.toString()], ['Total Deletions', result.repositoryInfo.totalDeletions.toString()]);
|
|
110315
110496
|
}
|
|
110316
110497
|
// Always show execution time and checks executed
|
|
110317
|
-
summaryTable.push(['Execution Time', `${result.executionTime}ms`], ['Checks Executed', result.checksExecuted.join(', ')]);
|
|
110498
|
+
summaryTable.push(['Execution Time', `${result.executionTime}ms`], ['Checks Executed', this.truncateCell(result.checksExecuted.join(', '))]);
|
|
110318
110499
|
output += 'Analysis Summary\n';
|
|
110319
110500
|
output += summaryTable.toString() + '\n';
|
|
110320
110501
|
output += '\n';
|
|
@@ -110329,7 +110510,8 @@ class OutputFormatters {
|
|
|
110329
110510
|
const categoryTable = new cli_table3_1.default({
|
|
110330
110511
|
head: ['File', 'Line', 'Severity', 'Message'],
|
|
110331
110512
|
colWidths: [25, 8, 15, 60],
|
|
110332
|
-
|
|
110513
|
+
// We pre-wrap and truncate ourselves to avoid expensive wrap-ansi work
|
|
110514
|
+
wordWrap: false,
|
|
110333
110515
|
style: {
|
|
110334
110516
|
head: ['cyan', 'bold'],
|
|
110335
110517
|
border: ['grey'],
|
|
@@ -110339,25 +110521,24 @@ class OutputFormatters {
|
|
|
110339
110521
|
for (const comment of comments.slice(0, showDetails ? comments.length : 5)) {
|
|
110340
110522
|
// Convert comment back to issue to access suggestion/replacement fields
|
|
110341
110523
|
const issue = (issues || []).find(i => i.file === comment.file && i.line === comment.line);
|
|
110342
|
-
|
|
110524
|
+
// Pre-wrap and truncate content to keep cli-table3 fast and responsive
|
|
110525
|
+
let messageContent = this.safeWrapAndTruncate(comment.message, OutputFormatters.WRAP_WIDTH_MESSAGE);
|
|
110343
110526
|
// Add suggestion if available
|
|
110344
110527
|
if (issue?.suggestion) {
|
|
110345
|
-
messageContent +=
|
|
110528
|
+
messageContent +=
|
|
110529
|
+
'\nSuggestion: ' +
|
|
110530
|
+
this.safeWrapAndTruncate(issue.suggestion, OutputFormatters.WRAP_WIDTH_MESSAGE - 2);
|
|
110346
110531
|
}
|
|
110347
110532
|
// Add replacement code if available
|
|
110348
110533
|
if (issue?.replacement) {
|
|
110349
|
-
|
|
110350
|
-
|
|
110351
|
-
issue.replacement
|
|
110352
|
-
.split('\n')
|
|
110353
|
-
.map(line => ' ' + line)
|
|
110354
|
-
.join('\n');
|
|
110534
|
+
const code = this.formatCodeBlock(issue.replacement);
|
|
110535
|
+
messageContent += '\nCode fix:\n' + code;
|
|
110355
110536
|
}
|
|
110356
110537
|
categoryTable.push([
|
|
110357
110538
|
comment.file,
|
|
110358
110539
|
comment.line.toString(),
|
|
110359
110540
|
{ content: this.formatSeverity(comment.severity), hAlign: 'center' },
|
|
110360
|
-
messageContent,
|
|
110541
|
+
this.truncateCell(messageContent),
|
|
110361
110542
|
]);
|
|
110362
110543
|
}
|
|
110363
110544
|
output += categoryTable.toString() + '\n';
|
|
@@ -110372,7 +110553,7 @@ class OutputFormatters {
|
|
|
110372
110553
|
const issuesTable = new cli_table3_1.default({
|
|
110373
110554
|
head: ['File', 'Line', 'Category', 'Severity', 'Message'],
|
|
110374
110555
|
colWidths: [20, 6, 12, 15, 50],
|
|
110375
|
-
wordWrap:
|
|
110556
|
+
wordWrap: false,
|
|
110376
110557
|
style: {
|
|
110377
110558
|
head: ['cyan', 'bold'],
|
|
110378
110559
|
border: ['grey'],
|
|
@@ -110380,26 +110561,24 @@ class OutputFormatters {
|
|
|
110380
110561
|
});
|
|
110381
110562
|
output += 'All Issues\n';
|
|
110382
110563
|
for (const issue of issues.slice(0, showDetails ? undefined : 10)) {
|
|
110383
|
-
let messageContent = this.
|
|
110564
|
+
let messageContent = this.safeWrapAndTruncate(issue.message, OutputFormatters.WRAP_WIDTH_MESSAGE_NARROW);
|
|
110384
110565
|
// Add suggestion if available
|
|
110385
110566
|
if (issue.suggestion) {
|
|
110386
|
-
messageContent +=
|
|
110567
|
+
messageContent +=
|
|
110568
|
+
'\nSuggestion: ' +
|
|
110569
|
+
this.safeWrapAndTruncate(issue.suggestion, OutputFormatters.WRAP_WIDTH_MESSAGE_NARROW - 2);
|
|
110387
110570
|
}
|
|
110388
110571
|
// Add replacement code if available
|
|
110389
110572
|
if (issue.replacement) {
|
|
110390
|
-
|
|
110391
|
-
|
|
110392
|
-
issue.replacement
|
|
110393
|
-
.split('\n')
|
|
110394
|
-
.map(line => ' ' + line)
|
|
110395
|
-
.join('\n');
|
|
110573
|
+
const code = this.formatCodeBlock(issue.replacement);
|
|
110574
|
+
messageContent += '\nCode fix:\n' + code;
|
|
110396
110575
|
}
|
|
110397
110576
|
issuesTable.push([
|
|
110398
110577
|
this.truncateText(issue.file, 18),
|
|
110399
110578
|
issue.line.toString(),
|
|
110400
110579
|
issue.category,
|
|
110401
110580
|
this.formatSeverity(issue.severity),
|
|
110402
|
-
messageContent,
|
|
110581
|
+
this.truncateCell(messageContent),
|
|
110403
110582
|
]);
|
|
110404
110583
|
}
|
|
110405
110584
|
output += issuesTable.toString() + '\n\n';
|
|
@@ -110439,8 +110618,8 @@ class OutputFormatters {
|
|
|
110439
110618
|
* Format analysis results as JSON
|
|
110440
110619
|
*/
|
|
110441
110620
|
static formatAsJSON(result, options = {}) {
|
|
110442
|
-
//
|
|
110443
|
-
const issues = result.reviewSummary.issues;
|
|
110621
|
+
// Filter out system-level issues (fail_if conditions, internal errors)
|
|
110622
|
+
const issues = (result.reviewSummary.issues || []).filter(issue => !(issue.file === 'system' && issue.line === 0));
|
|
110444
110623
|
const totalIssues = (0, reviewer_1.calculateTotalIssues)(issues);
|
|
110445
110624
|
const criticalIssues = (0, reviewer_1.calculateCriticalIssues)(issues);
|
|
110446
110625
|
const jsonResult = {
|
|
@@ -110475,8 +110654,8 @@ class OutputFormatters {
|
|
|
110475
110654
|
* Format analysis results as SARIF 2.1.0
|
|
110476
110655
|
*/
|
|
110477
110656
|
static formatAsSarif(result, _options = {}) {
|
|
110478
|
-
//
|
|
110479
|
-
const issues = result.reviewSummary.issues;
|
|
110657
|
+
// Filter out system-level issues (fail_if conditions, internal errors)
|
|
110658
|
+
const issues = (result.reviewSummary.issues || []).filter(issue => !(issue.file === 'system' && issue.line === 0));
|
|
110480
110659
|
// Generate unique rule definitions for each issue category
|
|
110481
110660
|
const rules = [
|
|
110482
110661
|
{
|
|
@@ -110598,8 +110777,8 @@ class OutputFormatters {
|
|
|
110598
110777
|
static formatAsMarkdown(result, options = {}) {
|
|
110599
110778
|
const { showDetails = false, groupByCategory = true } = options;
|
|
110600
110779
|
let output = '';
|
|
110601
|
-
//
|
|
110602
|
-
const issues = result.reviewSummary.issues;
|
|
110780
|
+
// Filter out system-level issues (fail_if conditions, internal errors)
|
|
110781
|
+
const issues = (result.reviewSummary.issues || []).filter(issue => !(issue.file === 'system' && issue.line === 0));
|
|
110603
110782
|
const totalIssues = (0, reviewer_1.calculateTotalIssues)(issues);
|
|
110604
110783
|
const criticalIssues = (0, reviewer_1.calculateCriticalIssues)(issues);
|
|
110605
110784
|
// Header with summary
|
|
@@ -110876,13 +111055,50 @@ class OutputFormatters {
|
|
|
110876
111055
|
else {
|
|
110877
111056
|
if (currentLine)
|
|
110878
111057
|
lines.push(currentLine);
|
|
110879
|
-
|
|
111058
|
+
// Break overly-long words to avoid pathological wrapping in cli-table3
|
|
111059
|
+
if (word.length > width) {
|
|
111060
|
+
const chunks = word.match(new RegExp(`.{1,${width}}`, 'g')) || [word];
|
|
111061
|
+
// First chunk becomes current line, the rest are full lines
|
|
111062
|
+
currentLine = chunks.shift() || '';
|
|
111063
|
+
for (const chunk of chunks)
|
|
111064
|
+
lines.push(chunk);
|
|
111065
|
+
}
|
|
111066
|
+
else {
|
|
111067
|
+
currentLine = word;
|
|
111068
|
+
}
|
|
110880
111069
|
}
|
|
110881
111070
|
}
|
|
110882
111071
|
if (currentLine)
|
|
110883
111072
|
lines.push(currentLine);
|
|
110884
111073
|
return lines.join('\n');
|
|
110885
111074
|
}
|
|
111075
|
+
// Truncate any cell content defensively
|
|
111076
|
+
static truncateCell(text) {
|
|
111077
|
+
if (text.length <= OutputFormatters.MAX_CELL_CHARS)
|
|
111078
|
+
return text;
|
|
111079
|
+
return text.substring(0, OutputFormatters.MAX_CELL_CHARS - 12) + '\n… [truncated]\n';
|
|
111080
|
+
}
|
|
111081
|
+
// Safer wrapper that first wraps, then truncates
|
|
111082
|
+
static safeWrapAndTruncate(text, width) {
|
|
111083
|
+
return this.truncateCell(this.wrapText(text, width));
|
|
111084
|
+
}
|
|
111085
|
+
// Format code blocks with line and width limits to keep rendering fast
|
|
111086
|
+
static formatCodeBlock(code) {
|
|
111087
|
+
const lines = code.split('\n');
|
|
111088
|
+
const limited = lines.slice(0, OutputFormatters.MAX_CODE_LINES).map(line => {
|
|
111089
|
+
// Soft-wrap code lines to avoid cli-table heavy wrapping
|
|
111090
|
+
const chunks = line.match(new RegExp(`.{1,${OutputFormatters.WRAP_WIDTH_CODE}}`, 'g')) || [
|
|
111091
|
+
'',
|
|
111092
|
+
];
|
|
111093
|
+
return chunks.map(c => ' ' + c).join('\n');
|
|
111094
|
+
});
|
|
111095
|
+
let out = limited.join('\n');
|
|
111096
|
+
// Indicate truncation of extra lines
|
|
111097
|
+
if (lines.length > OutputFormatters.MAX_CODE_LINES) {
|
|
111098
|
+
out += `\n … [${lines.length - OutputFormatters.MAX_CODE_LINES} more lines truncated]`;
|
|
111099
|
+
}
|
|
111100
|
+
return this.truncateCell(out);
|
|
111101
|
+
}
|
|
110886
111102
|
}
|
|
110887
111103
|
exports.OutputFormatters = OutputFormatters;
|
|
110888
111104
|
|
|
@@ -111535,10 +111751,12 @@ class AICheckProvider extends check_provider_interface_1.CheckProvider {
|
|
|
111535
111751
|
let result;
|
|
111536
111752
|
// Check if we should use session reuse
|
|
111537
111753
|
if (sessionInfo?.reuseSession && sessionInfo.parentSessionId) {
|
|
111754
|
+
// Get session_mode from config, default to 'clone'
|
|
111755
|
+
const sessionMode = config.session_mode || 'clone';
|
|
111538
111756
|
if (aiConfig.debug) {
|
|
111539
|
-
console.error(`🔄 Debug: Using session reuse with parent session: ${sessionInfo.parentSessionId}`);
|
|
111757
|
+
console.error(`🔄 Debug: Using session reuse with parent session: ${sessionInfo.parentSessionId} (mode: ${sessionMode})`);
|
|
111540
111758
|
}
|
|
111541
|
-
result = await service.executeReviewWithSessionReuse(prInfo, processedPrompt, sessionInfo.parentSessionId, schema, config.checkName);
|
|
111759
|
+
result = await service.executeReviewWithSessionReuse(prInfo, processedPrompt, sessionInfo.parentSessionId, schema, config.checkName, sessionMode);
|
|
111542
111760
|
}
|
|
111543
111761
|
else {
|
|
111544
111762
|
if (aiConfig.debug) {
|
|
@@ -114317,10 +114535,43 @@ exports.PRReviewer = PRReviewer;
|
|
|
114317
114535
|
/***/ }),
|
|
114318
114536
|
|
|
114319
114537
|
/***/ 46059:
|
|
114320
|
-
/***/ ((__unused_webpack_module, exports)
|
|
114538
|
+
/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {
|
|
114321
114539
|
|
|
114322
114540
|
"use strict";
|
|
114323
114541
|
|
|
114542
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
114543
|
+
if (k2 === undefined) k2 = k;
|
|
114544
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
114545
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
114546
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
114547
|
+
}
|
|
114548
|
+
Object.defineProperty(o, k2, desc);
|
|
114549
|
+
}) : (function(o, m, k, k2) {
|
|
114550
|
+
if (k2 === undefined) k2 = k;
|
|
114551
|
+
o[k2] = m[k];
|
|
114552
|
+
}));
|
|
114553
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
114554
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
114555
|
+
}) : function(o, v) {
|
|
114556
|
+
o["default"] = v;
|
|
114557
|
+
});
|
|
114558
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
114559
|
+
var ownKeys = function(o) {
|
|
114560
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
114561
|
+
var ar = [];
|
|
114562
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
114563
|
+
return ar;
|
|
114564
|
+
};
|
|
114565
|
+
return ownKeys(o);
|
|
114566
|
+
};
|
|
114567
|
+
return function (mod) {
|
|
114568
|
+
if (mod && mod.__esModule) return mod;
|
|
114569
|
+
var result = {};
|
|
114570
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
114571
|
+
__setModuleDefault(result, mod);
|
|
114572
|
+
return result;
|
|
114573
|
+
};
|
|
114574
|
+
})();
|
|
114324
114575
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
114325
114576
|
exports.SessionRegistry = void 0;
|
|
114326
114577
|
/**
|
|
@@ -114413,6 +114664,59 @@ class SessionRegistry {
|
|
|
114413
114664
|
hasSession(sessionId) {
|
|
114414
114665
|
return this.sessions.has(sessionId);
|
|
114415
114666
|
}
|
|
114667
|
+
/**
|
|
114668
|
+
* Clone a session with a new session ID
|
|
114669
|
+
* Creates a new ProbeAgent with a copy of the conversation history
|
|
114670
|
+
*/
|
|
114671
|
+
async cloneSession(sourceSessionId, newSessionId) {
|
|
114672
|
+
const sourceAgent = this.sessions.get(sourceSessionId);
|
|
114673
|
+
if (!sourceAgent) {
|
|
114674
|
+
console.error(`⚠️ Cannot clone session: ${sourceSessionId} not found`);
|
|
114675
|
+
return undefined;
|
|
114676
|
+
}
|
|
114677
|
+
try {
|
|
114678
|
+
// Access the conversation history from the source agent
|
|
114679
|
+
// ProbeAgent stores history in a private field, we need to access it via 'any'
|
|
114680
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
114681
|
+
const sourceHistory = sourceAgent.conversationHistory || [];
|
|
114682
|
+
// Create a new agent with the same configuration
|
|
114683
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
114684
|
+
const sourceOptions = sourceAgent.options || {};
|
|
114685
|
+
// Import ProbeAgent dynamically to create new instance
|
|
114686
|
+
const { ProbeAgent: ProbeAgentClass } = await Promise.resolve().then(() => __importStar(__nccwpck_require__(83841)));
|
|
114687
|
+
const clonedAgent = new ProbeAgentClass({
|
|
114688
|
+
...sourceOptions,
|
|
114689
|
+
sessionId: newSessionId,
|
|
114690
|
+
});
|
|
114691
|
+
// Deep copy the conversation history to ensure complete isolation
|
|
114692
|
+
// Use JSON serialization for deep cloning to prevent shared object references
|
|
114693
|
+
if (sourceHistory.length > 0) {
|
|
114694
|
+
try {
|
|
114695
|
+
// Deep clone the history array and all message objects within it
|
|
114696
|
+
const deepClonedHistory = JSON.parse(JSON.stringify(sourceHistory));
|
|
114697
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
114698
|
+
clonedAgent.conversationHistory = deepClonedHistory;
|
|
114699
|
+
console.error(`📋 Cloned session ${sourceSessionId} → ${newSessionId} (${sourceHistory.length} messages, deep copy)`);
|
|
114700
|
+
}
|
|
114701
|
+
catch (cloneError) {
|
|
114702
|
+
// Fallback to shallow copy if deep clone fails (e.g., circular references)
|
|
114703
|
+
console.error(`⚠️ Warning: Deep clone failed for session ${sourceSessionId}, using shallow copy: ${cloneError}`);
|
|
114704
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
114705
|
+
clonedAgent.conversationHistory = [...sourceHistory];
|
|
114706
|
+
}
|
|
114707
|
+
}
|
|
114708
|
+
else {
|
|
114709
|
+
console.error(`📋 Cloned session ${sourceSessionId} → ${newSessionId} (no history)`);
|
|
114710
|
+
}
|
|
114711
|
+
// Register the cloned session
|
|
114712
|
+
this.registerSession(newSessionId, clonedAgent);
|
|
114713
|
+
return clonedAgent;
|
|
114714
|
+
}
|
|
114715
|
+
catch (error) {
|
|
114716
|
+
console.error(`⚠️ Failed to clone session ${sourceSessionId}: ${error}`);
|
|
114717
|
+
return undefined;
|
|
114718
|
+
}
|
|
114719
|
+
}
|
|
114416
114720
|
/**
|
|
114417
114721
|
* Register process exit handlers to cleanup sessions on exit
|
|
114418
114722
|
*/
|
|
@@ -231977,7 +232281,7 @@ module.exports = /*#__PURE__*/JSON.parse('{"application/1d-interleaved-parityfec
|
|
|
231977
232281
|
/***/ ((module) => {
|
|
231978
232282
|
|
|
231979
232283
|
"use strict";
|
|
231980
|
-
module.exports = {"rE":"0.1.
|
|
232284
|
+
module.exports = {"rE":"0.1.88"};
|
|
231981
232285
|
|
|
231982
232286
|
/***/ })
|
|
231983
232287
|
|