@eldrforge/ai-service 0.1.21 → 0.1.22
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/__vite-browser-external-l0sNRNKZ.js +2 -0
- package/dist/__vite-browser-external-l0sNRNKZ.js.map +1 -0
- package/dist/index-Bim8aOsc.js +1964 -0
- package/dist/index-Bim8aOsc.js.map +1 -0
- package/dist/index.js +753 -19
- package/dist/index.js.map +1 -1
- package/dist/src/agentic/dependency.d.ts +72 -0
- package/dist/src/agentic/dependency.d.ts.map +1 -0
- package/dist/src/index.d.ts +2 -0
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/tools/dependency-tools.d.ts +6 -0
- package/dist/src/tools/dependency-tools.d.ts.map +1 -0
- package/package.json +6 -3
package/dist/index.js
CHANGED
|
@@ -1706,8 +1706,8 @@ async function runAgenticCommit(config) {
|
|
|
1706
1706
|
explainWhenToUse: true,
|
|
1707
1707
|
includeCategories: true
|
|
1708
1708
|
});
|
|
1709
|
-
const systemPrompt = buildSystemPrompt$
|
|
1710
|
-
const userMessage = buildUserMessage$
|
|
1709
|
+
const systemPrompt = buildSystemPrompt$3(toolGuidance);
|
|
1710
|
+
const userMessage = buildUserMessage$2(changedFiles, diffContent, userDirection, logContext);
|
|
1711
1711
|
const messages = [
|
|
1712
1712
|
{ role: "system", content: systemPrompt },
|
|
1713
1713
|
{ role: "user", content: userMessage }
|
|
@@ -1741,7 +1741,7 @@ async function runAgenticCommit(config) {
|
|
|
1741
1741
|
toolMetrics: result.toolMetrics
|
|
1742
1742
|
};
|
|
1743
1743
|
}
|
|
1744
|
-
function buildSystemPrompt$
|
|
1744
|
+
function buildSystemPrompt$3(toolGuidance) {
|
|
1745
1745
|
return `You are a professional software engineer writing commit messages for your team.
|
|
1746
1746
|
|
|
1747
1747
|
${toolGuidance}
|
|
@@ -1850,7 +1850,7 @@ Split 3:
|
|
|
1850
1850
|
|
|
1851
1851
|
Output only the commit message and splits. No conversational remarks or follow-up offers.`;
|
|
1852
1852
|
}
|
|
1853
|
-
function buildUserMessage$
|
|
1853
|
+
function buildUserMessage$2(changedFiles, diffContent, userDirection, logContext) {
|
|
1854
1854
|
const fileCount = changedFiles.length;
|
|
1855
1855
|
const manyFiles = fileCount >= 5;
|
|
1856
1856
|
let message = `I have staged changes that need a commit message.
|
|
@@ -1893,6 +1893,20 @@ If context information is provided, use it only if relevant to these specific ch
|
|
|
1893
1893
|
Don't force connections that don't exist - focus on what actually changed.`;
|
|
1894
1894
|
return message;
|
|
1895
1895
|
}
|
|
1896
|
+
function sanitizeFilePath(filePath) {
|
|
1897
|
+
return filePath.trim().replace(/^[-*]\s*/, "").replace(/^["']|["']$/g, "").replace(/\s*\([^)]*\)\s*$/, "").replace(/^["']|["']$/g, "").trim();
|
|
1898
|
+
}
|
|
1899
|
+
function parseFilesText(filesText) {
|
|
1900
|
+
if (filesText.startsWith("[") && filesText.includes("]")) {
|
|
1901
|
+
const closeIndex = filesText.indexOf("]");
|
|
1902
|
+
const bracketed = filesText.slice(1, closeIndex);
|
|
1903
|
+
return bracketed.split(",").map((f) => sanitizeFilePath(f)).filter((f) => f.length > 0);
|
|
1904
|
+
}
|
|
1905
|
+
if (filesText.match(/^["']/) && filesText.includes('", "')) {
|
|
1906
|
+
return filesText.split(/["'],\s*["']/).map((f) => sanitizeFilePath(f)).filter((f) => f.length > 0);
|
|
1907
|
+
}
|
|
1908
|
+
return filesText.split("\n").map((line) => sanitizeFilePath(line)).filter((line) => line.length > 0);
|
|
1909
|
+
}
|
|
1896
1910
|
function parseAgenticResult$1(finalMessage) {
|
|
1897
1911
|
const commitMatch = finalMessage.match(/COMMIT_MESSAGE:\s*\n([\s\S]*?)(?=\n\nSUGGESTED_SPLITS:|$)/);
|
|
1898
1912
|
const commitMessage = commitMatch ? commitMatch[1].trim() : finalMessage.trim();
|
|
@@ -1904,13 +1918,7 @@ function parseAgenticResult$1(finalMessage) {
|
|
|
1904
1918
|
let match;
|
|
1905
1919
|
while ((match = splitRegex.exec(splitsText)) !== null) {
|
|
1906
1920
|
const filesText = match[1].trim();
|
|
1907
|
-
|
|
1908
|
-
if (filesText.startsWith("[") && filesText.endsWith("]")) {
|
|
1909
|
-
const bracketed = filesText.slice(1, -1);
|
|
1910
|
-
files = bracketed.split(",").map((f) => f.trim()).filter((f) => f.length > 0);
|
|
1911
|
-
} else {
|
|
1912
|
-
files = filesText.split("\n").map((line) => line.trim().replace(/^[-*]\s*/, "")).filter((line) => line.length > 0);
|
|
1913
|
-
}
|
|
1921
|
+
const files = parseFilesText(filesText);
|
|
1914
1922
|
suggestedSplits.push({
|
|
1915
1923
|
files,
|
|
1916
1924
|
rationale: match[2].trim(),
|
|
@@ -2616,8 +2624,8 @@ async function runAgenticRelease(config) {
|
|
|
2616
2624
|
explainWhenToUse: true,
|
|
2617
2625
|
includeCategories: true
|
|
2618
2626
|
});
|
|
2619
|
-
const systemPrompt = buildSystemPrompt$
|
|
2620
|
-
const userMessage = buildUserMessage({
|
|
2627
|
+
const systemPrompt = buildSystemPrompt$2(toolGuidance);
|
|
2628
|
+
const userMessage = buildUserMessage$1({
|
|
2621
2629
|
fromRef,
|
|
2622
2630
|
toRef,
|
|
2623
2631
|
logContent,
|
|
@@ -2658,7 +2666,7 @@ async function runAgenticRelease(config) {
|
|
|
2658
2666
|
toolMetrics: result.toolMetrics
|
|
2659
2667
|
};
|
|
2660
2668
|
}
|
|
2661
|
-
function buildSystemPrompt$
|
|
2669
|
+
function buildSystemPrompt$2(toolGuidance) {
|
|
2662
2670
|
return `You are a professional software engineer writing release notes for your team and users.
|
|
2663
2671
|
|
|
2664
2672
|
${toolGuidance}
|
|
@@ -2733,7 +2741,7 @@ RELEASE_NOTES:
|
|
|
2733
2741
|
|
|
2734
2742
|
Output only the JSON. No conversational remarks or follow-up offers.`;
|
|
2735
2743
|
}
|
|
2736
|
-
function buildUserMessage(params) {
|
|
2744
|
+
function buildUserMessage$1(params) {
|
|
2737
2745
|
const { fromRef, toRef, logContent, diffContent, milestoneIssues, releaseFocus, userContext } = params;
|
|
2738
2746
|
let message = `I need comprehensive release notes for changes from ${fromRef} to ${toRef}.
|
|
2739
2747
|
|
|
@@ -3272,7 +3280,7 @@ async function runAgenticPublish(config) {
|
|
|
3272
3280
|
};
|
|
3273
3281
|
const tools = createToolRegistry(toolContext);
|
|
3274
3282
|
tools.registerAll(createPublishTools());
|
|
3275
|
-
const systemPrompt = buildSystemPrompt(issue, dryRun);
|
|
3283
|
+
const systemPrompt = buildSystemPrompt$1(issue, dryRun);
|
|
3276
3284
|
const userPrompt = buildUserPrompt({
|
|
3277
3285
|
issue,
|
|
3278
3286
|
targetBranch,
|
|
@@ -3299,7 +3307,7 @@ async function runAgenticPublish(config) {
|
|
|
3299
3307
|
storage,
|
|
3300
3308
|
logger: logger2
|
|
3301
3309
|
});
|
|
3302
|
-
const analysis = parseAgentResponse(result.finalMessage);
|
|
3310
|
+
const analysis = parseAgentResponse$1(result.finalMessage);
|
|
3303
3311
|
return {
|
|
3304
3312
|
success: analysis.success,
|
|
3305
3313
|
message: result.finalMessage,
|
|
@@ -3310,7 +3318,7 @@ async function runAgenticPublish(config) {
|
|
|
3310
3318
|
manualSteps: analysis.manualSteps
|
|
3311
3319
|
};
|
|
3312
3320
|
}
|
|
3313
|
-
function buildSystemPrompt(issue, dryRun) {
|
|
3321
|
+
function buildSystemPrompt$1(issue, dryRun) {
|
|
3314
3322
|
const modeNote = dryRun ? "\n\nIMPORTANT: This is a DRY RUN. Do not use tools that make destructive changes (like reset_branch or sync_branch). Only use diagnostic tools to analyze the issue and provide recommendations." : "";
|
|
3315
3323
|
return `You are an expert Git operations assistant helping to diagnose and fix issues that prevent publishing a software package.
|
|
3316
3324
|
|
|
@@ -3367,7 +3375,7 @@ Please investigate this issue and ${process.env.DRY_RUN ? "recommend how to fix
|
|
|
3367
3375
|
|
|
3368
3376
|
If the issue requires manual intervention, please explain why and provide clear steps.`;
|
|
3369
3377
|
}
|
|
3370
|
-
function parseAgentResponse(message) {
|
|
3378
|
+
function parseAgentResponse$1(message) {
|
|
3371
3379
|
const successIndicators = [
|
|
3372
3380
|
"successfully",
|
|
3373
3381
|
"resolved",
|
|
@@ -3469,6 +3477,729 @@ function formatAgenticPublishResult(result) {
|
|
|
3469
3477
|
lines.push("");
|
|
3470
3478
|
return lines.join("\n");
|
|
3471
3479
|
}
|
|
3480
|
+
function createDependencyTools() {
|
|
3481
|
+
return [
|
|
3482
|
+
createGetNpmPackageInfoTool(),
|
|
3483
|
+
createCheckPeerDependenciesTool(),
|
|
3484
|
+
createGetLatestVersionsTool(),
|
|
3485
|
+
createAnalyzeVersionCompatibilityTool(),
|
|
3486
|
+
createGetPackageChangelogTool(),
|
|
3487
|
+
createSuggestVersionAlignmentTool()
|
|
3488
|
+
];
|
|
3489
|
+
}
|
|
3490
|
+
function createGetNpmPackageInfoTool() {
|
|
3491
|
+
return {
|
|
3492
|
+
name: "get_npm_package_info",
|
|
3493
|
+
description: "Get detailed information about an npm package including latest version, description, peer dependencies, and recent versions. Use this to understand what version is available and what its requirements are.",
|
|
3494
|
+
category: "Research",
|
|
3495
|
+
cost: "moderate",
|
|
3496
|
+
parameters: {
|
|
3497
|
+
type: "object",
|
|
3498
|
+
properties: {
|
|
3499
|
+
packageName: {
|
|
3500
|
+
type: "string",
|
|
3501
|
+
description: 'The npm package name (e.g., "openai", "@riotprompt/riotprompt")'
|
|
3502
|
+
}
|
|
3503
|
+
},
|
|
3504
|
+
required: ["packageName"]
|
|
3505
|
+
},
|
|
3506
|
+
examples: [
|
|
3507
|
+
{
|
|
3508
|
+
scenario: "Check latest version of openai package",
|
|
3509
|
+
params: { packageName: "openai" },
|
|
3510
|
+
expectedResult: '{ "name": "openai", "version": "6.16.0", "peerDependencies": { "zod": "^3.23.8" }, "versions": ["6.16.0", "6.15.0", ...] }'
|
|
3511
|
+
}
|
|
3512
|
+
],
|
|
3513
|
+
execute: async (params, _context) => {
|
|
3514
|
+
const { packageName } = params;
|
|
3515
|
+
try {
|
|
3516
|
+
const { exec } = await import("child_process");
|
|
3517
|
+
const { promisify } = await import("./__vite-browser-external-l0sNRNKZ.js");
|
|
3518
|
+
const execAsync = promisify(exec);
|
|
3519
|
+
const { stdout } = await execAsync(`npm view ${packageName} --json`, {
|
|
3520
|
+
timeout: 3e4
|
|
3521
|
+
});
|
|
3522
|
+
const info = JSON.parse(stdout);
|
|
3523
|
+
return {
|
|
3524
|
+
name: info.name,
|
|
3525
|
+
version: info.version,
|
|
3526
|
+
description: info.description,
|
|
3527
|
+
peerDependencies: info.peerDependencies || {},
|
|
3528
|
+
peerDependenciesMeta: info.peerDependenciesMeta || {},
|
|
3529
|
+
dependencies: Object.keys(info.dependencies || {}).length,
|
|
3530
|
+
versions: (info.versions || []).slice(-10),
|
|
3531
|
+
// Last 10 versions
|
|
3532
|
+
repository: info.repository?.url || null,
|
|
3533
|
+
homepage: info.homepage || null
|
|
3534
|
+
};
|
|
3535
|
+
} catch (error) {
|
|
3536
|
+
return {
|
|
3537
|
+
error: `Failed to get package info for ${packageName}: ${error.message}`
|
|
3538
|
+
};
|
|
3539
|
+
}
|
|
3540
|
+
}
|
|
3541
|
+
};
|
|
3542
|
+
}
|
|
3543
|
+
function createCheckPeerDependenciesTool() {
|
|
3544
|
+
return {
|
|
3545
|
+
name: "check_peer_dependencies",
|
|
3546
|
+
description: "Check if a specific version of a package is compatible with another package based on peer dependency requirements. Use this to verify if updating one package would break compatibility with another.",
|
|
3547
|
+
category: "Analysis",
|
|
3548
|
+
cost: "moderate",
|
|
3549
|
+
parameters: {
|
|
3550
|
+
type: "object",
|
|
3551
|
+
properties: {
|
|
3552
|
+
packageName: {
|
|
3553
|
+
type: "string",
|
|
3554
|
+
description: "The package to check peer dependencies for"
|
|
3555
|
+
},
|
|
3556
|
+
packageVersion: {
|
|
3557
|
+
type: "string",
|
|
3558
|
+
description: "The version of the package to check"
|
|
3559
|
+
},
|
|
3560
|
+
dependencyName: {
|
|
3561
|
+
type: "string",
|
|
3562
|
+
description: "The dependency to check compatibility with"
|
|
3563
|
+
},
|
|
3564
|
+
dependencyVersion: {
|
|
3565
|
+
type: "string",
|
|
3566
|
+
description: "The version of the dependency currently installed"
|
|
3567
|
+
}
|
|
3568
|
+
},
|
|
3569
|
+
required: ["packageName", "packageVersion", "dependencyName", "dependencyVersion"]
|
|
3570
|
+
},
|
|
3571
|
+
examples: [
|
|
3572
|
+
{
|
|
3573
|
+
scenario: "Check if @riotprompt/riotprompt@0.0.21 is compatible with openai@4.104.0",
|
|
3574
|
+
params: {
|
|
3575
|
+
packageName: "@riotprompt/riotprompt",
|
|
3576
|
+
packageVersion: "0.0.21",
|
|
3577
|
+
dependencyName: "openai",
|
|
3578
|
+
dependencyVersion: "4.104.0"
|
|
3579
|
+
},
|
|
3580
|
+
expectedResult: '{ "compatible": false, "required": "^6.15.0", "current": "4.104.0", "recommendation": "Upgrade openai to ^6.15.0" }'
|
|
3581
|
+
}
|
|
3582
|
+
],
|
|
3583
|
+
execute: async (params) => {
|
|
3584
|
+
const { packageName, packageVersion, dependencyName, dependencyVersion } = params;
|
|
3585
|
+
try {
|
|
3586
|
+
const { exec } = await import("child_process");
|
|
3587
|
+
const { promisify } = await import("./__vite-browser-external-l0sNRNKZ.js");
|
|
3588
|
+
const execAsync = promisify(exec);
|
|
3589
|
+
const semver = await import("./index-Bim8aOsc.js").then((n) => n.i);
|
|
3590
|
+
const { stdout } = await execAsync(`npm view ${packageName}@${packageVersion} peerDependencies peerDependenciesMeta --json`, {
|
|
3591
|
+
timeout: 3e4
|
|
3592
|
+
});
|
|
3593
|
+
const info = JSON.parse(stdout);
|
|
3594
|
+
const peerDeps = info.peerDependencies || info || {};
|
|
3595
|
+
const peerDepsMeta = info.peerDependenciesMeta || {};
|
|
3596
|
+
const requiredRange = peerDeps[dependencyName];
|
|
3597
|
+
if (!requiredRange) {
|
|
3598
|
+
return {
|
|
3599
|
+
compatible: true,
|
|
3600
|
+
reason: `${packageName}@${packageVersion} does not have a peer dependency on ${dependencyName}`
|
|
3601
|
+
};
|
|
3602
|
+
}
|
|
3603
|
+
const isOptional = peerDepsMeta[dependencyName]?.optional === true;
|
|
3604
|
+
const satisfies = semver.satisfies(dependencyVersion, requiredRange);
|
|
3605
|
+
return {
|
|
3606
|
+
compatible: satisfies,
|
|
3607
|
+
required: requiredRange,
|
|
3608
|
+
current: dependencyVersion,
|
|
3609
|
+
optional: isOptional,
|
|
3610
|
+
recommendation: satisfies ? "Current version is compatible" : `${isOptional ? "(Optional) " : ""}Update ${dependencyName} to ${requiredRange} to satisfy peer dependency`
|
|
3611
|
+
};
|
|
3612
|
+
} catch (error) {
|
|
3613
|
+
return {
|
|
3614
|
+
error: `Failed to check peer dependencies: ${error.message}`
|
|
3615
|
+
};
|
|
3616
|
+
}
|
|
3617
|
+
}
|
|
3618
|
+
};
|
|
3619
|
+
}
|
|
3620
|
+
function createGetLatestVersionsTool() {
|
|
3621
|
+
return {
|
|
3622
|
+
name: "get_latest_versions",
|
|
3623
|
+
description: "Get the latest versions of multiple npm packages at once. Use this to quickly check if packages are outdated.",
|
|
3624
|
+
category: "Research",
|
|
3625
|
+
cost: "moderate",
|
|
3626
|
+
parameters: {
|
|
3627
|
+
type: "object",
|
|
3628
|
+
properties: {
|
|
3629
|
+
packages: {
|
|
3630
|
+
type: "array",
|
|
3631
|
+
description: "Array of package names to check",
|
|
3632
|
+
items: {
|
|
3633
|
+
type: "string",
|
|
3634
|
+
description: "Package name"
|
|
3635
|
+
}
|
|
3636
|
+
}
|
|
3637
|
+
},
|
|
3638
|
+
required: ["packages"]
|
|
3639
|
+
},
|
|
3640
|
+
examples: [
|
|
3641
|
+
{
|
|
3642
|
+
scenario: "Check latest versions of openai and zod",
|
|
3643
|
+
params: { packages: ["openai", "zod"] },
|
|
3644
|
+
expectedResult: '{ "openai": "6.16.0", "zod": "3.25.76" }'
|
|
3645
|
+
}
|
|
3646
|
+
],
|
|
3647
|
+
execute: async (params) => {
|
|
3648
|
+
const { packages } = params;
|
|
3649
|
+
const results = {};
|
|
3650
|
+
const { exec } = await import("child_process");
|
|
3651
|
+
const { promisify } = await import("./__vite-browser-external-l0sNRNKZ.js");
|
|
3652
|
+
const execAsync = promisify(exec);
|
|
3653
|
+
const batchSize = 5;
|
|
3654
|
+
for (let i = 0; i < packages.length; i += batchSize) {
|
|
3655
|
+
const batch = packages.slice(i, i + batchSize);
|
|
3656
|
+
await Promise.all(
|
|
3657
|
+
batch.map(async (pkg) => {
|
|
3658
|
+
try {
|
|
3659
|
+
const { stdout } = await execAsync(`npm view ${pkg} version`, {
|
|
3660
|
+
timeout: 15e3
|
|
3661
|
+
});
|
|
3662
|
+
results[pkg] = stdout.trim();
|
|
3663
|
+
} catch (error) {
|
|
3664
|
+
results[pkg] = { error: error.message };
|
|
3665
|
+
}
|
|
3666
|
+
})
|
|
3667
|
+
);
|
|
3668
|
+
}
|
|
3669
|
+
return results;
|
|
3670
|
+
}
|
|
3671
|
+
};
|
|
3672
|
+
}
|
|
3673
|
+
function createAnalyzeVersionCompatibilityTool() {
|
|
3674
|
+
return {
|
|
3675
|
+
name: "analyze_version_compatibility",
|
|
3676
|
+
description: "Analyze if a target version of a package is compatible with the current project setup by checking all peer dependencies recursively. Use this before recommending an upgrade.",
|
|
3677
|
+
category: "Analysis",
|
|
3678
|
+
cost: "expensive",
|
|
3679
|
+
parameters: {
|
|
3680
|
+
type: "object",
|
|
3681
|
+
properties: {
|
|
3682
|
+
packageName: {
|
|
3683
|
+
type: "string",
|
|
3684
|
+
description: "The package to analyze upgrading to"
|
|
3685
|
+
},
|
|
3686
|
+
targetVersion: {
|
|
3687
|
+
type: "string",
|
|
3688
|
+
description: "The target version to upgrade to"
|
|
3689
|
+
},
|
|
3690
|
+
currentDependencies: {
|
|
3691
|
+
type: "object",
|
|
3692
|
+
description: "Current dependencies and their versions (as key-value pairs)"
|
|
3693
|
+
}
|
|
3694
|
+
},
|
|
3695
|
+
required: ["packageName", "targetVersion", "currentDependencies"]
|
|
3696
|
+
},
|
|
3697
|
+
execute: async (params) => {
|
|
3698
|
+
const { packageName, targetVersion, currentDependencies } = params;
|
|
3699
|
+
try {
|
|
3700
|
+
const { exec } = await import("child_process");
|
|
3701
|
+
const { promisify } = await import("./__vite-browser-external-l0sNRNKZ.js");
|
|
3702
|
+
const execAsync = promisify(exec);
|
|
3703
|
+
const semver = await import("./index-Bim8aOsc.js").then((n) => n.i);
|
|
3704
|
+
const { stdout } = await execAsync(`npm view ${packageName}@${targetVersion} peerDependencies peerDependenciesMeta --json`, {
|
|
3705
|
+
timeout: 3e4
|
|
3706
|
+
});
|
|
3707
|
+
const info = JSON.parse(stdout);
|
|
3708
|
+
const peerDeps = info.peerDependencies || info || {};
|
|
3709
|
+
const peerDepsMeta = info.peerDependenciesMeta || {};
|
|
3710
|
+
const conflicts = [];
|
|
3711
|
+
const compatible = [];
|
|
3712
|
+
for (const [dep, requiredRange] of Object.entries(peerDeps)) {
|
|
3713
|
+
const currentVersion = currentDependencies[dep];
|
|
3714
|
+
const isOptional = peerDepsMeta[dep]?.optional === true;
|
|
3715
|
+
if (!currentVersion) {
|
|
3716
|
+
if (!isOptional) {
|
|
3717
|
+
conflicts.push({
|
|
3718
|
+
dependency: dep,
|
|
3719
|
+
required: requiredRange,
|
|
3720
|
+
current: "not installed",
|
|
3721
|
+
optional: false
|
|
3722
|
+
});
|
|
3723
|
+
}
|
|
3724
|
+
continue;
|
|
3725
|
+
}
|
|
3726
|
+
const cleanCurrent = currentVersion.replace(/^[\^~]/, "");
|
|
3727
|
+
const satisfies = semver.satisfies(cleanCurrent, requiredRange);
|
|
3728
|
+
if (satisfies) {
|
|
3729
|
+
compatible.push({
|
|
3730
|
+
dependency: dep,
|
|
3731
|
+
required: requiredRange,
|
|
3732
|
+
current: currentVersion
|
|
3733
|
+
});
|
|
3734
|
+
} else {
|
|
3735
|
+
conflicts.push({
|
|
3736
|
+
dependency: dep,
|
|
3737
|
+
required: requiredRange,
|
|
3738
|
+
current: currentVersion,
|
|
3739
|
+
optional: isOptional
|
|
3740
|
+
});
|
|
3741
|
+
}
|
|
3742
|
+
}
|
|
3743
|
+
return {
|
|
3744
|
+
canUpgrade: conflicts.filter((c) => !c.optional).length === 0,
|
|
3745
|
+
packageName,
|
|
3746
|
+
targetVersion,
|
|
3747
|
+
conflicts,
|
|
3748
|
+
compatible,
|
|
3749
|
+
summary: conflicts.length === 0 ? `Safe to upgrade ${packageName} to ${targetVersion}` : `Upgrading ${packageName} to ${targetVersion} requires updating: ${conflicts.map((c) => `${c.dependency} to ${c.required}`).join(", ")}`
|
|
3750
|
+
};
|
|
3751
|
+
} catch (error) {
|
|
3752
|
+
return {
|
|
3753
|
+
error: `Failed to analyze compatibility: ${error.message}`
|
|
3754
|
+
};
|
|
3755
|
+
}
|
|
3756
|
+
}
|
|
3757
|
+
};
|
|
3758
|
+
}
|
|
3759
|
+
function createGetPackageChangelogTool() {
|
|
3760
|
+
return {
|
|
3761
|
+
name: "get_package_changelog",
|
|
3762
|
+
description: "Get recent release notes or changelog information for a package to understand what changed between versions. Use this when evaluating whether to upgrade.",
|
|
3763
|
+
category: "Research",
|
|
3764
|
+
cost: "moderate",
|
|
3765
|
+
parameters: {
|
|
3766
|
+
type: "object",
|
|
3767
|
+
properties: {
|
|
3768
|
+
packageName: {
|
|
3769
|
+
type: "string",
|
|
3770
|
+
description: "The npm package name"
|
|
3771
|
+
},
|
|
3772
|
+
fromVersion: {
|
|
3773
|
+
type: "string",
|
|
3774
|
+
description: "The version to compare from (optional)"
|
|
3775
|
+
},
|
|
3776
|
+
toVersion: {
|
|
3777
|
+
type: "string",
|
|
3778
|
+
description: "The version to compare to (optional, defaults to latest)"
|
|
3779
|
+
}
|
|
3780
|
+
},
|
|
3781
|
+
required: ["packageName"]
|
|
3782
|
+
},
|
|
3783
|
+
execute: async (params) => {
|
|
3784
|
+
const { packageName, fromVersion } = params;
|
|
3785
|
+
try {
|
|
3786
|
+
const { exec } = await import("child_process");
|
|
3787
|
+
const { promisify } = await import("./__vite-browser-external-l0sNRNKZ.js");
|
|
3788
|
+
const execAsync = promisify(exec);
|
|
3789
|
+
const { stdout: infoJson } = await execAsync(`npm view ${packageName} repository.url homepage --json`, {
|
|
3790
|
+
timeout: 15e3
|
|
3791
|
+
});
|
|
3792
|
+
const info = JSON.parse(infoJson);
|
|
3793
|
+
const repoUrl = info["repository.url"] || info.repository?.url || "";
|
|
3794
|
+
const homepage = info.homepage || "";
|
|
3795
|
+
const { stdout: versionsJson } = await execAsync(`npm view ${packageName} time --json`, {
|
|
3796
|
+
timeout: 15e3
|
|
3797
|
+
});
|
|
3798
|
+
const times = JSON.parse(versionsJson);
|
|
3799
|
+
const versions = Object.entries(times).filter(([v]) => v !== "created" && v !== "modified").map(([version, time]) => ({ version, time })).sort((a, b) => new Date(b.time).getTime() - new Date(a.time).getTime()).slice(0, 10);
|
|
3800
|
+
let releasesUrl = "";
|
|
3801
|
+
const match = repoUrl.match(/github\.com[/:]([^/]+\/[^/.]+)/);
|
|
3802
|
+
if (match) {
|
|
3803
|
+
releasesUrl = `https://github.com/${match[1]}/releases`;
|
|
3804
|
+
}
|
|
3805
|
+
return {
|
|
3806
|
+
packageName,
|
|
3807
|
+
currentVersion: fromVersion || "unknown",
|
|
3808
|
+
latestVersion: versions[0]?.version || "unknown",
|
|
3809
|
+
recentVersions: versions,
|
|
3810
|
+
releasesUrl: releasesUrl || "Unable to determine releases URL",
|
|
3811
|
+
homepage,
|
|
3812
|
+
note: "Check the releases URL for detailed changelog information"
|
|
3813
|
+
};
|
|
3814
|
+
} catch (error) {
|
|
3815
|
+
return {
|
|
3816
|
+
error: `Failed to get changelog info: ${error.message}`
|
|
3817
|
+
};
|
|
3818
|
+
}
|
|
3819
|
+
}
|
|
3820
|
+
};
|
|
3821
|
+
}
|
|
3822
|
+
function createSuggestVersionAlignmentTool() {
|
|
3823
|
+
return {
|
|
3824
|
+
name: "suggest_version_alignment",
|
|
3825
|
+
description: "Given a list of packages with version conflicts, suggest which versions to align on and in what order to update them. Use this to create a coherent upgrade plan.",
|
|
3826
|
+
category: "Planning",
|
|
3827
|
+
cost: "cheap",
|
|
3828
|
+
parameters: {
|
|
3829
|
+
type: "object",
|
|
3830
|
+
properties: {
|
|
3831
|
+
conflicts: {
|
|
3832
|
+
type: "array",
|
|
3833
|
+
description: "Array of version conflicts",
|
|
3834
|
+
items: {
|
|
3835
|
+
type: "object",
|
|
3836
|
+
description: "A version conflict entry",
|
|
3837
|
+
properties: {
|
|
3838
|
+
packageName: { type: "string", description: "Package name" },
|
|
3839
|
+
versions: {
|
|
3840
|
+
type: "array",
|
|
3841
|
+
description: "Different versions in use",
|
|
3842
|
+
items: { type: "string", description: "Version string" }
|
|
3843
|
+
},
|
|
3844
|
+
usedBy: {
|
|
3845
|
+
type: "array",
|
|
3846
|
+
description: "Which projects use each version",
|
|
3847
|
+
items: { type: "string", description: "Project name" }
|
|
3848
|
+
}
|
|
3849
|
+
}
|
|
3850
|
+
}
|
|
3851
|
+
},
|
|
3852
|
+
strategy: {
|
|
3853
|
+
type: "string",
|
|
3854
|
+
description: 'Alignment strategy: "latest" (prefer latest), "conservative" (prefer most common), "compatible" (prefer most compatible)',
|
|
3855
|
+
enum: ["latest", "conservative", "compatible"]
|
|
3856
|
+
}
|
|
3857
|
+
},
|
|
3858
|
+
required: ["conflicts", "strategy"]
|
|
3859
|
+
},
|
|
3860
|
+
execute: async (params) => {
|
|
3861
|
+
const { conflicts, strategy } = params;
|
|
3862
|
+
const semver = await import("./index-Bim8aOsc.js").then((n) => n.i);
|
|
3863
|
+
const recommendations = [];
|
|
3864
|
+
for (const conflict of conflicts) {
|
|
3865
|
+
const { packageName, versions } = conflict;
|
|
3866
|
+
const sortedVersions = [...versions].map((v) => v.replace(/^[\^~]/, "")).filter((v) => semver.valid(v)).sort((a, b) => semver.compare(b, a));
|
|
3867
|
+
let recommendedVersion;
|
|
3868
|
+
let reason;
|
|
3869
|
+
switch (strategy) {
|
|
3870
|
+
case "latest":
|
|
3871
|
+
recommendedVersion = `^${sortedVersions[0]}`;
|
|
3872
|
+
reason = "Using latest version for newest features and security fixes";
|
|
3873
|
+
break;
|
|
3874
|
+
case "conservative": {
|
|
3875
|
+
const versionCounts = /* @__PURE__ */ new Map();
|
|
3876
|
+
for (const v of versions) {
|
|
3877
|
+
const clean = v.replace(/^[\^~]/, "");
|
|
3878
|
+
versionCounts.set(clean, (versionCounts.get(clean) || 0) + 1);
|
|
3879
|
+
}
|
|
3880
|
+
const mostCommon = [...versionCounts.entries()].sort((a, b) => b[1] - a[1])[0];
|
|
3881
|
+
recommendedVersion = `^${mostCommon[0]}`;
|
|
3882
|
+
reason = `Most commonly used version (${mostCommon[1]} packages)`;
|
|
3883
|
+
break;
|
|
3884
|
+
}
|
|
3885
|
+
case "compatible":
|
|
3886
|
+
default:
|
|
3887
|
+
recommendedVersion = `^${sortedVersions[sortedVersions.length - 1]}`;
|
|
3888
|
+
reason = "Lowest common version for maximum compatibility";
|
|
3889
|
+
break;
|
|
3890
|
+
}
|
|
3891
|
+
recommendations.push({
|
|
3892
|
+
packageName,
|
|
3893
|
+
currentVersions: versions,
|
|
3894
|
+
recommendedVersion,
|
|
3895
|
+
reason,
|
|
3896
|
+
updateOrder: recommendations.length + 1
|
|
3897
|
+
});
|
|
3898
|
+
}
|
|
3899
|
+
return {
|
|
3900
|
+
strategy,
|
|
3901
|
+
recommendations,
|
|
3902
|
+
summary: `Analyzed ${conflicts.length} packages with version conflicts. Strategy: ${strategy}`
|
|
3903
|
+
};
|
|
3904
|
+
}
|
|
3905
|
+
};
|
|
3906
|
+
}
|
|
3907
|
+
async function runAgenticDependencyAnalysis(config) {
|
|
3908
|
+
const {
|
|
3909
|
+
reportData,
|
|
3910
|
+
strategy = "latest",
|
|
3911
|
+
focusPackages,
|
|
3912
|
+
model = "gpt-4o",
|
|
3913
|
+
maxIterations = 15,
|
|
3914
|
+
debug = false,
|
|
3915
|
+
debugRequestFile,
|
|
3916
|
+
debugResponseFile,
|
|
3917
|
+
storage,
|
|
3918
|
+
logger: logger2,
|
|
3919
|
+
openaiReasoning
|
|
3920
|
+
} = config;
|
|
3921
|
+
const toolRegistry = createToolRegistry({
|
|
3922
|
+
workingDirectory: process.cwd(),
|
|
3923
|
+
storage,
|
|
3924
|
+
logger: logger2
|
|
3925
|
+
});
|
|
3926
|
+
const tools = createDependencyTools();
|
|
3927
|
+
toolRegistry.registerAll(tools);
|
|
3928
|
+
const toolGuidance = generateToolGuidance(tools, {
|
|
3929
|
+
strategy: "adaptive",
|
|
3930
|
+
includeExamples: true,
|
|
3931
|
+
explainWhenToUse: true,
|
|
3932
|
+
includeCategories: true
|
|
3933
|
+
});
|
|
3934
|
+
const systemPrompt = buildSystemPrompt(strategy, toolGuidance);
|
|
3935
|
+
const userMessage = buildUserMessage(reportData, strategy, focusPackages);
|
|
3936
|
+
const messages = [
|
|
3937
|
+
{ role: "system", content: systemPrompt },
|
|
3938
|
+
{ role: "user", content: userMessage }
|
|
3939
|
+
];
|
|
3940
|
+
const agenticConfig = {
|
|
3941
|
+
messages,
|
|
3942
|
+
tools: toolRegistry,
|
|
3943
|
+
model,
|
|
3944
|
+
maxIterations,
|
|
3945
|
+
debug,
|
|
3946
|
+
debugRequestFile,
|
|
3947
|
+
debugResponseFile,
|
|
3948
|
+
storage,
|
|
3949
|
+
logger: logger2,
|
|
3950
|
+
openaiReasoning,
|
|
3951
|
+
tokenBudget: {
|
|
3952
|
+
max: 1e5,
|
|
3953
|
+
reserveForResponse: 4e3,
|
|
3954
|
+
strategy: "fifo",
|
|
3955
|
+
onBudgetExceeded: "compress"
|
|
3956
|
+
}
|
|
3957
|
+
};
|
|
3958
|
+
const result = await runAgentic(agenticConfig);
|
|
3959
|
+
const analysis = parseAgentResponse(result.finalMessage, reportData);
|
|
3960
|
+
return {
|
|
3961
|
+
recommendations: analysis.recommendations,
|
|
3962
|
+
summary: analysis.summary,
|
|
3963
|
+
upgradeOrder: analysis.upgradeOrder,
|
|
3964
|
+
warnings: analysis.warnings,
|
|
3965
|
+
iterations: result.iterations,
|
|
3966
|
+
toolCallsExecuted: result.toolCallsExecuted,
|
|
3967
|
+
conversationHistory: result.conversationHistory,
|
|
3968
|
+
toolMetrics: result.toolMetrics
|
|
3969
|
+
};
|
|
3970
|
+
}
|
|
3971
|
+
function buildSystemPrompt(strategy, toolGuidance) {
|
|
3972
|
+
return `You are an expert dependency management advisor for JavaScript/TypeScript monorepos.
|
|
3973
|
+
|
|
3974
|
+
Your goal is to analyze dependency conflicts and version inconsistencies across a monorepo and provide actionable recommendations for version alignment and upgrades.
|
|
3975
|
+
|
|
3976
|
+
## Your Strategy: ${strategy.toUpperCase()}
|
|
3977
|
+
|
|
3978
|
+
${strategy === "latest" ? `
|
|
3979
|
+
- Prioritize upgrading to the latest stable versions
|
|
3980
|
+
- Security and new features are important
|
|
3981
|
+
- Breaking changes are acceptable if the benefits outweigh the migration cost
|
|
3982
|
+
` : strategy === "conservative" ? `
|
|
3983
|
+
- Prefer the most commonly used version across projects
|
|
3984
|
+
- Minimize disruption to the codebase
|
|
3985
|
+
- Only recommend upgrades when there's a clear benefit
|
|
3986
|
+
` : `
|
|
3987
|
+
- Find versions that work for all packages
|
|
3988
|
+
- Prioritize compatibility over new features
|
|
3989
|
+
- Recommend the minimum viable upgrade
|
|
3990
|
+
`}
|
|
3991
|
+
|
|
3992
|
+
## Analysis Process
|
|
3993
|
+
|
|
3994
|
+
1. **Review Conflicts**: Examine each version conflict in the report
|
|
3995
|
+
2. **Research Packages**: Use tools to look up package information and peer dependencies
|
|
3996
|
+
3. **Check Compatibility**: Verify that recommended versions are compatible
|
|
3997
|
+
4. **Create Upgrade Plan**: Determine the order in which packages should be updated
|
|
3998
|
+
5. **Identify Breaking Changes**: Flag any upgrades that might require code changes
|
|
3999
|
+
|
|
4000
|
+
## Tools Available
|
|
4001
|
+
|
|
4002
|
+
${toolGuidance}
|
|
4003
|
+
|
|
4004
|
+
## Output Format
|
|
4005
|
+
|
|
4006
|
+
After your analysis, provide recommendations in this format:
|
|
4007
|
+
|
|
4008
|
+
### SUMMARY
|
|
4009
|
+
A brief overview of the analysis findings.
|
|
4010
|
+
|
|
4011
|
+
### RECOMMENDATIONS
|
|
4012
|
+
For each recommendation:
|
|
4013
|
+
- **Package**: package name
|
|
4014
|
+
- **Current**: list of current versions in use
|
|
4015
|
+
- **Recommended**: the version to align on
|
|
4016
|
+
- **Priority**: high/medium/low
|
|
4017
|
+
- **Reason**: why this upgrade is recommended
|
|
4018
|
+
- **Breaking Changes**: yes/no and what to watch for
|
|
4019
|
+
- **Affected Projects**: which projects need to be updated
|
|
4020
|
+
|
|
4021
|
+
### UPGRADE ORDER
|
|
4022
|
+
List the packages in the order they should be upgraded (dependencies first).
|
|
4023
|
+
|
|
4024
|
+
### WARNINGS
|
|
4025
|
+
Any concerns or things to watch out for.
|
|
4026
|
+
|
|
4027
|
+
Be thorough but concise. Focus on the most impactful changes first.`;
|
|
4028
|
+
}
|
|
4029
|
+
function buildUserMessage(reportData, strategy, focusPackages) {
|
|
4030
|
+
const conflictsSummary = reportData.conflicts.map((c) => {
|
|
4031
|
+
const usageInfo = c.usages.map((u) => `${u.version} (used by: ${u.usedBy.join(", ")})`).join("\n - ");
|
|
4032
|
+
return ` - ${c.packageName}:
|
|
4033
|
+
- ${usageInfo}`;
|
|
4034
|
+
}).join("\n");
|
|
4035
|
+
const sharedSummary = reportData.sharedDependencies.slice(0, 20).map((s) => ` - ${s.name}: ${s.versions.join(" | ")} (${s.packageCount} packages)`).join("\n");
|
|
4036
|
+
const packagesSummary = reportData.packageSummaries.map((p) => ` - ${p.name}: ${p.deps} deps, ${p.devDeps} devDeps, ${p.total} total`).join("\n");
|
|
4037
|
+
let focusNote = "";
|
|
4038
|
+
if (focusPackages && focusPackages.length > 0) {
|
|
4039
|
+
focusNote = `
|
|
4040
|
+
|
|
4041
|
+
**FOCUS**: Please pay special attention to these packages: ${focusPackages.join(", ")}`;
|
|
4042
|
+
}
|
|
4043
|
+
return `Please analyze the following dependency report and provide upgrade recommendations using the "${strategy}" strategy.
|
|
4044
|
+
|
|
4045
|
+
## Dependency Report Summary
|
|
4046
|
+
|
|
4047
|
+
- **Packages in monorepo**: ${reportData.packageCount}
|
|
4048
|
+
- **Total dependencies**: ${reportData.totalDependencies}
|
|
4049
|
+
- **Unique dependencies**: ${reportData.uniqueDependencies}
|
|
4050
|
+
- **Version conflicts**: ${reportData.conflictCount}
|
|
4051
|
+
|
|
4052
|
+
## Version Conflicts (${reportData.conflictCount} packages)
|
|
4053
|
+
|
|
4054
|
+
${conflictsSummary || "No version conflicts found."}
|
|
4055
|
+
|
|
4056
|
+
## Most Shared Dependencies (top 20)
|
|
4057
|
+
|
|
4058
|
+
${sharedSummary}
|
|
4059
|
+
|
|
4060
|
+
## Package Summary
|
|
4061
|
+
|
|
4062
|
+
${packagesSummary}
|
|
4063
|
+
${focusNote}
|
|
4064
|
+
|
|
4065
|
+
Please use the available tools to research these packages, check their peer dependencies, and provide a comprehensive upgrade plan.`;
|
|
4066
|
+
}
|
|
4067
|
+
function parseAgentResponse(response, reportData) {
|
|
4068
|
+
const recommendations = [];
|
|
4069
|
+
const warnings = [];
|
|
4070
|
+
let summary = "";
|
|
4071
|
+
let upgradeOrder = [];
|
|
4072
|
+
const summaryMatch = response.match(/###\s*SUMMARY\s*\n([\s\S]*?)(?=###|$)/i);
|
|
4073
|
+
if (summaryMatch) {
|
|
4074
|
+
summary = summaryMatch[1].trim();
|
|
4075
|
+
}
|
|
4076
|
+
const recsMatch = response.match(/###\s*RECOMMENDATIONS?\s*\n([\s\S]*?)(?=###|$)/i);
|
|
4077
|
+
if (recsMatch) {
|
|
4078
|
+
const recsText = recsMatch[1];
|
|
4079
|
+
const recBlocks = recsText.split(/\n(?=\*\*Package\*\*:|\d+\.\s+\*\*)/);
|
|
4080
|
+
let order = 1;
|
|
4081
|
+
for (const block of recBlocks) {
|
|
4082
|
+
if (!block.trim()) continue;
|
|
4083
|
+
const packageMatch = block.match(/\*\*Package\*\*:\s*([^\n]+)/i);
|
|
4084
|
+
const currentMatch = block.match(/\*\*Current\*\*:\s*([^\n]+)/i);
|
|
4085
|
+
const recommendedMatch = block.match(/\*\*Recommended\*\*:\s*([^\n]+)/i);
|
|
4086
|
+
const priorityMatch = block.match(/\*\*Priority\*\*:\s*(high|medium|low)/i);
|
|
4087
|
+
const reasonMatch = block.match(/\*\*Reason\*\*:\s*([^\n]+)/i);
|
|
4088
|
+
const breakingMatch = block.match(/\*\*Breaking\s*Changes?\*\*:\s*([^\n]+)/i);
|
|
4089
|
+
const affectedMatch = block.match(/\*\*Affected\s*Projects?\*\*:\s*([^\n]+)/i);
|
|
4090
|
+
if (packageMatch) {
|
|
4091
|
+
recommendations.push({
|
|
4092
|
+
packageName: packageMatch[1].trim(),
|
|
4093
|
+
currentVersions: currentMatch ? currentMatch[1].split(/[,|]/).map((v) => v.trim()) : [],
|
|
4094
|
+
recommendedVersion: recommendedMatch ? recommendedMatch[1].trim() : "unknown",
|
|
4095
|
+
priority: priorityMatch ? priorityMatch[1].toLowerCase() : "medium",
|
|
4096
|
+
reason: reasonMatch ? reasonMatch[1].trim() : "",
|
|
4097
|
+
updateOrder: order++,
|
|
4098
|
+
affectedProjects: affectedMatch ? affectedMatch[1].split(/[,|]/).map((p) => p.trim()) : [],
|
|
4099
|
+
breakingChanges: breakingMatch ? breakingMatch[1].toLowerCase().includes("yes") : false
|
|
4100
|
+
});
|
|
4101
|
+
}
|
|
4102
|
+
}
|
|
4103
|
+
}
|
|
4104
|
+
const orderMatch = response.match(/###\s*UPGRADE\s*ORDER\s*\n([\s\S]*?)(?=###|$)/i);
|
|
4105
|
+
if (orderMatch) {
|
|
4106
|
+
const orderText = orderMatch[1];
|
|
4107
|
+
upgradeOrder = orderText.split("\n").filter((line) => line.trim()).map((line) => line.replace(/^[\d.*-]+\s*/, "").trim()).filter(Boolean);
|
|
4108
|
+
}
|
|
4109
|
+
const warningsMatch = response.match(/###\s*WARNINGS?\s*\n([\s\S]*?)(?=###|$)/i);
|
|
4110
|
+
if (warningsMatch) {
|
|
4111
|
+
const warningsText = warningsMatch[1];
|
|
4112
|
+
warnings.push(
|
|
4113
|
+
...warningsText.split("\n").filter((line) => line.trim()).map((line) => line.replace(/^[-*]+\s*/, "").trim()).filter(Boolean)
|
|
4114
|
+
);
|
|
4115
|
+
}
|
|
4116
|
+
if (recommendations.length === 0 && reportData.conflicts.length > 0) {
|
|
4117
|
+
for (const conflict of reportData.conflicts.slice(0, 10)) {
|
|
4118
|
+
recommendations.push({
|
|
4119
|
+
packageName: conflict.packageName,
|
|
4120
|
+
currentVersions: conflict.versions,
|
|
4121
|
+
recommendedVersion: "See analysis",
|
|
4122
|
+
priority: "medium",
|
|
4123
|
+
reason: "Version conflict detected - manual review recommended",
|
|
4124
|
+
updateOrder: recommendations.length + 1,
|
|
4125
|
+
affectedProjects: conflict.usages.flatMap((u) => u.usedBy),
|
|
4126
|
+
breakingChanges: false
|
|
4127
|
+
});
|
|
4128
|
+
}
|
|
4129
|
+
summary = response.slice(0, 500) + "...";
|
|
4130
|
+
}
|
|
4131
|
+
return {
|
|
4132
|
+
recommendations,
|
|
4133
|
+
summary: summary || "Analysis complete. See recommendations below.",
|
|
4134
|
+
upgradeOrder,
|
|
4135
|
+
warnings
|
|
4136
|
+
};
|
|
4137
|
+
}
|
|
4138
|
+
function formatDependencyAnalysisReport(result) {
|
|
4139
|
+
const lines = [];
|
|
4140
|
+
lines.push("");
|
|
4141
|
+
lines.push("╔═══════════════════════════════════════════════════════════════════╗");
|
|
4142
|
+
lines.push("║ 🤖 AI DEPENDENCY ANALYSIS REPORT ║");
|
|
4143
|
+
lines.push("╚═══════════════════════════════════════════════════════════════════╝");
|
|
4144
|
+
lines.push("");
|
|
4145
|
+
lines.push(`📊 Analysis completed in ${result.iterations} iterations with ${result.toolCallsExecuted} tool calls`);
|
|
4146
|
+
lines.push("");
|
|
4147
|
+
lines.push("┌─ 📝 SUMMARY");
|
|
4148
|
+
lines.push("│");
|
|
4149
|
+
const summaryLines = result.summary.split("\n");
|
|
4150
|
+
for (const line of summaryLines) {
|
|
4151
|
+
lines.push(`│ ${line}`);
|
|
4152
|
+
}
|
|
4153
|
+
lines.push("");
|
|
4154
|
+
if (result.recommendations.length > 0) {
|
|
4155
|
+
lines.push("┌─ 💡 RECOMMENDATIONS");
|
|
4156
|
+
lines.push("│");
|
|
4157
|
+
const priorityOrder = { high: 0, medium: 1, low: 2 };
|
|
4158
|
+
const sortedRecs = [...result.recommendations].sort((a, b) => {
|
|
4159
|
+
const pDiff = priorityOrder[a.priority] - priorityOrder[b.priority];
|
|
4160
|
+
return pDiff !== 0 ? pDiff : a.updateOrder - b.updateOrder;
|
|
4161
|
+
});
|
|
4162
|
+
for (let i = 0; i < sortedRecs.length; i++) {
|
|
4163
|
+
const rec = sortedRecs[i];
|
|
4164
|
+
const isLast = i === sortedRecs.length - 1;
|
|
4165
|
+
const priorityIcon = rec.priority === "high" ? "🔴" : rec.priority === "medium" ? "🟡" : "🟢";
|
|
4166
|
+
const breakingIcon = rec.breakingChanges ? " ⚠️" : "";
|
|
4167
|
+
lines.push(`│ ${isLast ? "└─" : "├─"} ${priorityIcon} ${rec.packageName}${breakingIcon}`);
|
|
4168
|
+
lines.push(`│ ${isLast ? " " : "│ "} Current: ${rec.currentVersions.join(", ")}`);
|
|
4169
|
+
lines.push(`│ ${isLast ? " " : "│ "} Recommended: ${rec.recommendedVersion}`);
|
|
4170
|
+
lines.push(`│ ${isLast ? " " : "│ "} Reason: ${rec.reason}`);
|
|
4171
|
+
if (rec.affectedProjects.length > 0) {
|
|
4172
|
+
lines.push(`│ ${isLast ? " " : "│ "} Affects: ${rec.affectedProjects.slice(0, 5).join(", ")}${rec.affectedProjects.length > 5 ? ` +${rec.affectedProjects.length - 5} more` : ""}`);
|
|
4173
|
+
}
|
|
4174
|
+
}
|
|
4175
|
+
lines.push("");
|
|
4176
|
+
}
|
|
4177
|
+
if (result.upgradeOrder.length > 0) {
|
|
4178
|
+
lines.push("┌─ 📋 UPGRADE ORDER");
|
|
4179
|
+
lines.push("│");
|
|
4180
|
+
for (let i = 0; i < result.upgradeOrder.length; i++) {
|
|
4181
|
+
const pkg = result.upgradeOrder[i];
|
|
4182
|
+
const isLast = i === result.upgradeOrder.length - 1;
|
|
4183
|
+
lines.push(`│ ${isLast ? "└─" : "├─"} ${i + 1}. ${pkg}`);
|
|
4184
|
+
}
|
|
4185
|
+
lines.push("");
|
|
4186
|
+
}
|
|
4187
|
+
if (result.warnings.length > 0) {
|
|
4188
|
+
lines.push("┌─ ⚠️ WARNINGS");
|
|
4189
|
+
lines.push("│");
|
|
4190
|
+
for (let i = 0; i < result.warnings.length; i++) {
|
|
4191
|
+
const warning = result.warnings[i];
|
|
4192
|
+
const isLast = i === result.warnings.length - 1;
|
|
4193
|
+
lines.push(`│ ${isLast ? "└─" : "├─"} ${warning}`);
|
|
4194
|
+
}
|
|
4195
|
+
lines.push("");
|
|
4196
|
+
}
|
|
4197
|
+
lines.push("╔═══════════════════════════════════════════════════════════════════╗");
|
|
4198
|
+
lines.push("║ END OF AI ANALYSIS ║");
|
|
4199
|
+
lines.push("╚═══════════════════════════════════════════════════════════════════╝");
|
|
4200
|
+
lines.push("");
|
|
4201
|
+
return lines.join("\n");
|
|
4202
|
+
}
|
|
3472
4203
|
function createConversationLogger(config) {
|
|
3473
4204
|
const {
|
|
3474
4205
|
outputDir,
|
|
@@ -3875,6 +4606,7 @@ export {
|
|
|
3875
4606
|
createCompletion,
|
|
3876
4607
|
createCompletionWithRetry,
|
|
3877
4608
|
createConversationLogger,
|
|
4609
|
+
createDependencyTools,
|
|
3878
4610
|
createMetricsCollector,
|
|
3879
4611
|
createNoOpLogger,
|
|
3880
4612
|
createPublishTools,
|
|
@@ -3885,6 +4617,7 @@ export {
|
|
|
3885
4617
|
createToolRegistry,
|
|
3886
4618
|
editContentInEditor,
|
|
3887
4619
|
formatAgenticPublishResult,
|
|
4620
|
+
formatDependencyAnalysisReport,
|
|
3888
4621
|
generateConversationId,
|
|
3889
4622
|
generateReflectionReport,
|
|
3890
4623
|
getLLMFeedbackInEditor,
|
|
@@ -3899,6 +4632,7 @@ export {
|
|
|
3899
4632
|
requireTTY,
|
|
3900
4633
|
runAgentic,
|
|
3901
4634
|
runAgenticCommit,
|
|
4635
|
+
runAgenticDependencyAnalysis,
|
|
3902
4636
|
runAgenticPublish,
|
|
3903
4637
|
runAgenticRelease,
|
|
3904
4638
|
saveReflectionReport,
|