@rushstack/mcp-server 0.3.14 → 0.4.1
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/CHANGELOG.json +52 -0
- package/CHANGELOG.md +15 -1
- package/bin/mcp-server +1 -1
- package/dist/tsdoc-metadata.json +1 -1
- package/lib-esm/index.js +5 -0
- package/lib-esm/index.js.map +1 -0
- package/lib-esm/pluginFramework/IRushMcpPlugin.js +4 -0
- package/lib-esm/pluginFramework/IRushMcpPlugin.js.map +1 -0
- package/lib-esm/pluginFramework/IRushMcpTool.js +4 -0
- package/lib-esm/pluginFramework/IRushMcpTool.js.map +1 -0
- package/lib-esm/pluginFramework/RushMcpPluginLoader.js +97 -0
- package/lib-esm/pluginFramework/RushMcpPluginLoader.js.map +1 -0
- package/lib-esm/pluginFramework/RushMcpPluginSession.js +28 -0
- package/lib-esm/pluginFramework/RushMcpPluginSession.js.map +1 -0
- package/lib-esm/pluginFramework/zodTypes.js +5 -0
- package/lib-esm/pluginFramework/zodTypes.js.map +1 -0
- package/lib-esm/schemas/rush-mcp-plugin.schema.json +21 -0
- package/lib-esm/schemas/rush-mcp.schema.json +28 -0
- package/lib-esm/server.js +35 -0
- package/lib-esm/server.js.map +1 -0
- package/lib-esm/start.js +33 -0
- package/lib-esm/start.js.map +1 -0
- package/lib-esm/tools/base.tool.js +29 -0
- package/lib-esm/tools/base.tool.js.map +1 -0
- package/lib-esm/tools/conflict-resolver.tool.js +48 -0
- package/lib-esm/tools/conflict-resolver.tool.js.map +1 -0
- package/lib-esm/tools/index.js +9 -0
- package/lib-esm/tools/index.js.map +1 -0
- package/lib-esm/tools/migrate-project.tool.js +93 -0
- package/lib-esm/tools/migrate-project.tool.js.map +1 -0
- package/lib-esm/tools/project-details.tool.js +50 -0
- package/lib-esm/tools/project-details.tool.js.map +1 -0
- package/lib-esm/tools/rush-command-validator.tool.js +81 -0
- package/lib-esm/tools/rush-command-validator.tool.js.map +1 -0
- package/lib-esm/tools/workspace-details.js +103 -0
- package/lib-esm/tools/workspace-details.js.map +1 -0
- package/lib-esm/utilities/command-runner.js +69 -0
- package/lib-esm/utilities/command-runner.js.map +1 -0
- package/lib-esm/utilities/common.js +10 -0
- package/lib-esm/utilities/common.js.map +1 -0
- package/lib-esm/utilities/log.js +8 -0
- package/lib-esm/utilities/log.js.map +1 -0
- package/package.json +36 -8
- /package/{lib → lib-commonjs}/index.js +0 -0
- /package/{lib → lib-commonjs}/index.js.map +0 -0
- /package/{lib → lib-commonjs}/pluginFramework/IRushMcpPlugin.js +0 -0
- /package/{lib → lib-commonjs}/pluginFramework/IRushMcpPlugin.js.map +0 -0
- /package/{lib → lib-commonjs}/pluginFramework/IRushMcpTool.js +0 -0
- /package/{lib → lib-commonjs}/pluginFramework/IRushMcpTool.js.map +0 -0
- /package/{lib → lib-commonjs}/pluginFramework/RushMcpPluginLoader.js +0 -0
- /package/{lib → lib-commonjs}/pluginFramework/RushMcpPluginLoader.js.map +0 -0
- /package/{lib → lib-commonjs}/pluginFramework/RushMcpPluginSession.js +0 -0
- /package/{lib → lib-commonjs}/pluginFramework/RushMcpPluginSession.js.map +0 -0
- /package/{lib → lib-commonjs}/pluginFramework/zodTypes.js +0 -0
- /package/{lib → lib-commonjs}/pluginFramework/zodTypes.js.map +0 -0
- /package/{lib → lib-commonjs}/schemas/rush-mcp-plugin.schema.json +0 -0
- /package/{lib → lib-commonjs}/schemas/rush-mcp.schema.json +0 -0
- /package/{lib → lib-commonjs}/server.js +0 -0
- /package/{lib → lib-commonjs}/server.js.map +0 -0
- /package/{lib → lib-commonjs}/start.js +0 -0
- /package/{lib → lib-commonjs}/start.js.map +0 -0
- /package/{lib → lib-commonjs}/tools/base.tool.js +0 -0
- /package/{lib → lib-commonjs}/tools/base.tool.js.map +0 -0
- /package/{lib → lib-commonjs}/tools/conflict-resolver.tool.js +0 -0
- /package/{lib → lib-commonjs}/tools/conflict-resolver.tool.js.map +0 -0
- /package/{lib → lib-commonjs}/tools/index.js +0 -0
- /package/{lib → lib-commonjs}/tools/index.js.map +0 -0
- /package/{lib → lib-commonjs}/tools/migrate-project.tool.js +0 -0
- /package/{lib → lib-commonjs}/tools/migrate-project.tool.js.map +0 -0
- /package/{lib → lib-commonjs}/tools/project-details.tool.js +0 -0
- /package/{lib → lib-commonjs}/tools/project-details.tool.js.map +0 -0
- /package/{lib → lib-commonjs}/tools/rush-command-validator.tool.js +0 -0
- /package/{lib → lib-commonjs}/tools/rush-command-validator.tool.js.map +0 -0
- /package/{lib → lib-commonjs}/tools/workspace-details.js +0 -0
- /package/{lib → lib-commonjs}/tools/workspace-details.js.map +0 -0
- /package/{lib → lib-commonjs}/utilities/command-runner.js +0 -0
- /package/{lib → lib-commonjs}/utilities/command-runner.js.map +0 -0
- /package/{lib → lib-commonjs}/utilities/common.js +0 -0
- /package/{lib → lib-commonjs}/utilities/common.js.map +0 -0
- /package/{lib → lib-commonjs}/utilities/log.js +0 -0
- /package/{lib → lib-commonjs}/utilities/log.js.map +0 -0
- /package/{lib → lib-dts}/index.d.ts +0 -0
- /package/{lib → lib-dts}/index.d.ts.map +0 -0
- /package/{lib → lib-dts}/pluginFramework/IRushMcpPlugin.d.ts +0 -0
- /package/{lib → lib-dts}/pluginFramework/IRushMcpPlugin.d.ts.map +0 -0
- /package/{lib → lib-dts}/pluginFramework/IRushMcpTool.d.ts +0 -0
- /package/{lib → lib-dts}/pluginFramework/IRushMcpTool.d.ts.map +0 -0
- /package/{lib → lib-dts}/pluginFramework/RushMcpPluginLoader.d.ts +0 -0
- /package/{lib → lib-dts}/pluginFramework/RushMcpPluginLoader.d.ts.map +0 -0
- /package/{lib → lib-dts}/pluginFramework/RushMcpPluginSession.d.ts +0 -0
- /package/{lib → lib-dts}/pluginFramework/RushMcpPluginSession.d.ts.map +0 -0
- /package/{lib → lib-dts}/pluginFramework/zodTypes.d.ts +0 -0
- /package/{lib → lib-dts}/pluginFramework/zodTypes.d.ts.map +0 -0
- /package/{lib → lib-dts}/server.d.ts +0 -0
- /package/{lib → lib-dts}/server.d.ts.map +0 -0
- /package/{lib → lib-dts}/start.d.ts +0 -0
- /package/{lib → lib-dts}/start.d.ts.map +0 -0
- /package/{lib → lib-dts}/tools/base.tool.d.ts +0 -0
- /package/{lib → lib-dts}/tools/base.tool.d.ts.map +0 -0
- /package/{lib → lib-dts}/tools/conflict-resolver.tool.d.ts +0 -0
- /package/{lib → lib-dts}/tools/conflict-resolver.tool.d.ts.map +0 -0
- /package/{lib → lib-dts}/tools/index.d.ts +0 -0
- /package/{lib → lib-dts}/tools/index.d.ts.map +0 -0
- /package/{lib → lib-dts}/tools/migrate-project.tool.d.ts +0 -0
- /package/{lib → lib-dts}/tools/migrate-project.tool.d.ts.map +0 -0
- /package/{lib → lib-dts}/tools/project-details.tool.d.ts +0 -0
- /package/{lib → lib-dts}/tools/project-details.tool.d.ts.map +0 -0
- /package/{lib → lib-dts}/tools/rush-command-validator.tool.d.ts +0 -0
- /package/{lib → lib-dts}/tools/rush-command-validator.tool.d.ts.map +0 -0
- /package/{lib → lib-dts}/tools/workspace-details.d.ts +0 -0
- /package/{lib → lib-dts}/tools/workspace-details.d.ts.map +0 -0
- /package/{lib → lib-dts}/utilities/command-runner.d.ts +0 -0
- /package/{lib → lib-dts}/utilities/command-runner.d.ts.map +0 -0
- /package/{lib → lib-dts}/utilities/common.d.ts +0 -0
- /package/{lib → lib-dts}/utilities/common.d.ts.map +0 -0
- /package/{lib → lib-dts}/utilities/log.d.ts +0 -0
- /package/{lib → lib-dts}/utilities/log.d.ts.map +0 -0
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
|
|
2
|
+
// See LICENSE in the project root for license information.
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import { z } from 'zod';
|
|
5
|
+
import { FileSystem, JsonFile } from '@rushstack/node-core-library';
|
|
6
|
+
import { BaseTool } from './base.tool';
|
|
7
|
+
import { getRushConfiguration } from '../utilities/common';
|
|
8
|
+
export class RushMigrateProjectTool extends BaseTool {
|
|
9
|
+
constructor(rushWorkspacePath) {
|
|
10
|
+
super({
|
|
11
|
+
name: 'rush_migrate_project',
|
|
12
|
+
description: 'Migrate a project to a different location or subspace within the Rush monorepo.',
|
|
13
|
+
schema: {
|
|
14
|
+
projectName: z.string().describe('The name of the project to be migrated'),
|
|
15
|
+
targetProjectPath: z.string().optional().describe('The target path to migrate the project to'),
|
|
16
|
+
targetSubspaceName: z.string().optional().describe('The target subspace to migrate the project to')
|
|
17
|
+
}
|
|
18
|
+
});
|
|
19
|
+
this._rushWorkspacePath = rushWorkspacePath;
|
|
20
|
+
}
|
|
21
|
+
async _modifyAndSaveSubspaceJsonFileAsync(rushConfiguration, cb) {
|
|
22
|
+
const subspacesFolderPath = path.resolve(rushConfiguration.commonRushConfigFolder, 'subspaces.json');
|
|
23
|
+
const subspacesConfiguration = await JsonFile.loadAsync(subspacesFolderPath);
|
|
24
|
+
const newSubspaceNames = await cb(subspacesConfiguration.subspaceNames);
|
|
25
|
+
subspacesConfiguration.subspaceNames = newSubspaceNames;
|
|
26
|
+
await JsonFile.saveAsync(subspacesConfiguration, subspacesFolderPath, {
|
|
27
|
+
updateExistingFile: true
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
async _modifyAndSaveRushConfigurationAsync(rushConfiguration, cb) {
|
|
31
|
+
const rushConfigurationJson = rushConfiguration.rushConfigurationJson;
|
|
32
|
+
const rushConfigurationFile = rushConfiguration.rushJsonFile;
|
|
33
|
+
const newRushConfigurationProjectJson = await cb(rushConfigurationJson.projects);
|
|
34
|
+
rushConfigurationJson.projects = newRushConfigurationProjectJson;
|
|
35
|
+
await JsonFile.saveAsync(rushConfigurationJson, rushConfigurationFile, { updateExistingFile: true });
|
|
36
|
+
}
|
|
37
|
+
async executeAsync({ projectName, targetSubspaceName, targetProjectPath }) {
|
|
38
|
+
const rushConfiguration = await getRushConfiguration();
|
|
39
|
+
const project = rushConfiguration.getProjectByName(projectName);
|
|
40
|
+
if (!project) {
|
|
41
|
+
return {
|
|
42
|
+
isError: true,
|
|
43
|
+
content: [{ type: 'text', text: `Project "${projectName}" not found` }]
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
const rootPath = this._rushWorkspacePath;
|
|
47
|
+
const sourceProjectSubspaceName = project.subspace.subspaceName;
|
|
48
|
+
const sourceProjectPath = project.projectFolder;
|
|
49
|
+
const destinationPath = path.resolve(rootPath, targetProjectPath);
|
|
50
|
+
const subspacehasOnlyOneProject = project.subspace.getProjects().length === 1;
|
|
51
|
+
// 1. Remove source subspace folder
|
|
52
|
+
if (subspacehasOnlyOneProject) {
|
|
53
|
+
const subspaceConfigFolderPath = project.subspace.getSubspaceConfigFolderPath();
|
|
54
|
+
await FileSystem.deleteFolderAsync(subspaceConfigFolderPath);
|
|
55
|
+
}
|
|
56
|
+
// 2. Move project to target subspace
|
|
57
|
+
await FileSystem.moveAsync({
|
|
58
|
+
sourcePath: sourceProjectPath,
|
|
59
|
+
destinationPath
|
|
60
|
+
});
|
|
61
|
+
// 3. Update rush configuration
|
|
62
|
+
await this._modifyAndSaveRushConfigurationAsync(rushConfiguration, (projects) => {
|
|
63
|
+
const projectIndex = projects.findIndex(({ packageName }) => packageName === projectName);
|
|
64
|
+
projects[projectIndex] = {
|
|
65
|
+
...projects[projectIndex],
|
|
66
|
+
subspaceName: targetSubspaceName,
|
|
67
|
+
projectFolder: path.relative(rootPath, destinationPath)
|
|
68
|
+
};
|
|
69
|
+
return projects;
|
|
70
|
+
});
|
|
71
|
+
// 4. Update `subspaces.json`
|
|
72
|
+
await this._modifyAndSaveSubspaceJsonFileAsync(rushConfiguration, (subspaceNames) => {
|
|
73
|
+
if (subspacehasOnlyOneProject) {
|
|
74
|
+
subspaceNames.splice(subspaceNames.indexOf(sourceProjectSubspaceName), 1);
|
|
75
|
+
}
|
|
76
|
+
if (!subspaceNames.includes(targetSubspaceName)) {
|
|
77
|
+
subspaceNames.push(targetSubspaceName);
|
|
78
|
+
}
|
|
79
|
+
return subspaceNames;
|
|
80
|
+
});
|
|
81
|
+
return {
|
|
82
|
+
content: [
|
|
83
|
+
{
|
|
84
|
+
type: 'text',
|
|
85
|
+
text: `Project "${projectName}" migrated to subspace "${targetSubspaceName}" successfully. ` +
|
|
86
|
+
`You can ask whether the user wants to run "rush update --subspace ${targetSubspaceName}" to update the project. ` +
|
|
87
|
+
`If the user says "yes", you can run "rush update --subspace ${targetSubspaceName}" directly for them.`
|
|
88
|
+
}
|
|
89
|
+
]
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
//# sourceMappingURL=migrate-project.tool.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"migrate-project.tool.js","sourceRoot":"","sources":["../../src/tools/migrate-project.tool.ts"],"names":[],"mappings":"AAAA,4FAA4F;AAC5F,2DAA2D;AAE3D,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,8BAA8B,CAAC;AAMpE,OAAO,EAAE,QAAQ,EAAuB,MAAM,aAAa,CAAC;AAC5D,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAE3D,MAAM,OAAO,sBAAuB,SAAQ,QAAQ;IAGlD,YAAmB,iBAAyB;QAC1C,KAAK,CAAC;YACJ,IAAI,EAAE,sBAAsB;YAC5B,WAAW,EAAE,iFAAiF;YAC9F,MAAM,EAAE;gBACN,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,wCAAwC,CAAC;gBAC1E,iBAAiB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,2CAA2C,CAAC;gBAC9F,kBAAkB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,+CAA+C,CAAC;aACpG;SACF,CAAC,CAAC;QAEH,IAAI,CAAC,kBAAkB,GAAG,iBAAiB,CAAC;IAC9C,CAAC;IAEO,KAAK,CAAC,mCAAmC,CAC/C,iBAAoC,EACpC,EAA6D;QAE7D,MAAM,mBAAmB,GAAW,IAAI,CAAC,OAAO,CAC9C,iBAAiB,CAAC,sBAAsB,EACxC,gBAAgB,CACjB,CAAC;QACF,MAAM,sBAAsB,GAAgC,MAAM,QAAQ,CAAC,SAAS,CAAC,mBAAmB,CAAC,CAAC;QAC1G,MAAM,gBAAgB,GAAa,MAAM,EAAE,CAAC,sBAAsB,CAAC,aAAa,CAAC,CAAC;QAClF,sBAAsB,CAAC,aAAa,GAAG,gBAAgB,CAAC;QACxD,MAAM,QAAQ,CAAC,SAAS,CAAC,sBAAsB,EAAE,mBAAmB,EAAE;YACpE,kBAAkB,EAAE,IAAI;SACzB,CAAC,CAAC;IACL,CAAC;IAEO,KAAK,CAAC,oCAAoC,CAChD,iBAAoC,EACpC,EAE+E;QAE/E,MAAM,qBAAqB,GAA2B,iBAAiB,CAAC,qBAAqB,CAAC;QAC9F,MAAM,qBAAqB,GAAW,iBAAiB,CAAC,YAAY,CAAC;QACrE,MAAM,+BAA+B,GAAoC,MAAM,EAAE,CAC/E,qBAAqB,CAAC,QAAQ,CAC/B,CAAC;QACF,qBAAqB,CAAC,QAAQ,GAAG,+BAA+B,CAAC;QACjE,MAAM,QAAQ,CAAC,SAAS,CAAC,qBAAqB,EAAE,qBAAqB,EAAE,EAAE,kBAAkB,EAAE,IAAI,EAAE,CAAC,CAAC;IACvG,CAAC;IAEM,KAAK,CAAC,YAAY,CAAC,EACxB,WAAW,EACX,kBAAkB,EAClB,iBAAiB,EAKlB;QACC,MAAM,iBAAiB,GAAsB,MAAM,oBAAoB,EAAE,CAAC;QAC1E,MAAM,OAAO,GAAyC,iBAAiB,CAAC,gBAAgB,CAAC,WAAW,CAAC,CAAC;QAEtG,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,OAAO;gBACL,OAAO,EAAE,IAAI;gBACb,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,YAAY,WAAW,aAAa,EAAE,CAAC;aACxE,CAAC;QACJ,CAAC;QAED,MAAM,QAAQ,GAAW,IAAI,CAAC,kBAAkB,CAAC;QACjD,MAAM,yBAAyB,GAAW,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAC;QACxE,MAAM,iBAAiB,GAAW,OAAO,CAAC,aAAa,CAAC;QACxD,MAAM,eAAe,GAAW,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,iBAAiB,CAAC,CAAC;QAC1E,MAAM,yBAAyB,GAAY,OAAO,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC,MAAM,KAAK,CAAC,CAAC;QAEvF,mCAAmC;QACnC,IAAI,yBAAyB,EAAE,CAAC;YAC9B,MAAM,wBAAwB,GAAW,OAAO,CAAC,QAAQ,CAAC,2BAA2B,EAAE,CAAC;YACxF,MAAM,UAAU,CAAC,iBAAiB,CAAC,wBAAwB,CAAC,CAAC;QAC/D,CAAC;QAED,qCAAqC;QACrC,MAAM,UAAU,CAAC,SAAS,CAAC;YACzB,UAAU,EAAE,iBAAiB;YAC7B,eAAe;SAChB,CAAC,CAAC;QAEH,+BAA+B;QAC/B,MAAM,IAAI,CAAC,oCAAoC,CAAC,iBAAiB,EAAE,CAAC,QAAQ,EAAE,EAAE;YAC9E,MAAM,YAAY,GAAW,QAAQ,CAAC,SAAS,CAAC,CAAC,EAAE,WAAW,EAAE,EAAE,EAAE,CAAC,WAAW,KAAK,WAAW,CAAC,CAAC;YAClG,QAAQ,CAAC,YAAY,CAAC,GAAG;gBACvB,GAAG,QAAQ,CAAC,YAAY,CAAC;gBACzB,YAAY,EAAE,kBAAkB;gBAChC,aAAa,EAAE,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,eAAe,CAAC;aACxD,CAAC;YACF,OAAO,QAAQ,CAAC;QAClB,CAAC,CAAC,CAAC;QAEH,6BAA6B;QAC7B,MAAM,IAAI,CAAC,mCAAmC,CAAC,iBAAiB,EAAE,CAAC,aAAa,EAAE,EAAE;YAClF,IAAI,yBAAyB,EAAE,CAAC;gBAC9B,aAAa,CAAC,MAAM,CAAC,aAAa,CAAC,OAAO,CAAC,yBAAyB,CAAC,EAAE,CAAC,CAAC,CAAC;YAC5E,CAAC;YACD,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,kBAAkB,CAAC,EAAE,CAAC;gBAChD,aAAa,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;YACzC,CAAC;YACD,OAAO,aAAa,CAAC;QACvB,CAAC,CAAC,CAAC;QAEH,OAAO;YACL,OAAO,EAAE;gBACP;oBACE,IAAI,EAAE,MAAM;oBACZ,IAAI,EACF,YAAY,WAAW,2BAA2B,kBAAkB,kBAAkB;wBACtF,qEAAqE,kBAAkB,2BAA2B;wBAClH,+DAA+D,kBAAkB,sBAAsB;iBAC1G;aACF;SACF,CAAC;IACJ,CAAC;CACF","sourcesContent":["// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.\n// See LICENSE in the project root for license information.\n\nimport path from 'node:path';\n\nimport { z } from 'zod';\n\nimport { FileSystem, JsonFile } from '@rushstack/node-core-library';\nimport type { ISubspacesConfigurationJson } from '@rushstack/rush-sdk/lib/api/SubspacesConfiguration';\nimport type { RushConfiguration, RushConfigurationProject } from '@rushstack/rush-sdk';\nimport type { IRushConfigurationProjectJson } from '@rushstack/rush-sdk/lib/api/RushConfigurationProject';\nimport type { IRushConfigurationJson } from '@rushstack/rush-sdk/lib/api/RushConfiguration';\n\nimport { BaseTool, type CallToolResult } from './base.tool';\nimport { getRushConfiguration } from '../utilities/common';\n\nexport class RushMigrateProjectTool extends BaseTool {\n private _rushWorkspacePath: string;\n\n public constructor(rushWorkspacePath: string) {\n super({\n name: 'rush_migrate_project',\n description: 'Migrate a project to a different location or subspace within the Rush monorepo.',\n schema: {\n projectName: z.string().describe('The name of the project to be migrated'),\n targetProjectPath: z.string().optional().describe('The target path to migrate the project to'),\n targetSubspaceName: z.string().optional().describe('The target subspace to migrate the project to')\n }\n });\n\n this._rushWorkspacePath = rushWorkspacePath;\n }\n\n private async _modifyAndSaveSubspaceJsonFileAsync(\n rushConfiguration: RushConfiguration,\n cb: (subspaceNames: string[]) => Promise<string[]> | string[]\n ): Promise<void> {\n const subspacesFolderPath: string = path.resolve(\n rushConfiguration.commonRushConfigFolder,\n 'subspaces.json'\n );\n const subspacesConfiguration: ISubspacesConfigurationJson = await JsonFile.loadAsync(subspacesFolderPath);\n const newSubspaceNames: string[] = await cb(subspacesConfiguration.subspaceNames);\n subspacesConfiguration.subspaceNames = newSubspaceNames;\n await JsonFile.saveAsync(subspacesConfiguration, subspacesFolderPath, {\n updateExistingFile: true\n });\n }\n\n private async _modifyAndSaveRushConfigurationAsync(\n rushConfiguration: RushConfiguration,\n cb: (\n projects: IRushConfigurationProjectJson[]\n ) => Promise<IRushConfigurationProjectJson[]> | IRushConfigurationProjectJson[]\n ): Promise<void> {\n const rushConfigurationJson: IRushConfigurationJson = rushConfiguration.rushConfigurationJson;\n const rushConfigurationFile: string = rushConfiguration.rushJsonFile;\n const newRushConfigurationProjectJson: IRushConfigurationProjectJson[] = await cb(\n rushConfigurationJson.projects\n );\n rushConfigurationJson.projects = newRushConfigurationProjectJson;\n await JsonFile.saveAsync(rushConfigurationJson, rushConfigurationFile, { updateExistingFile: true });\n }\n\n public async executeAsync({\n projectName,\n targetSubspaceName,\n targetProjectPath\n }: {\n projectName: string;\n targetProjectPath: string;\n targetSubspaceName: string;\n }): Promise<CallToolResult> {\n const rushConfiguration: RushConfiguration = await getRushConfiguration();\n const project: RushConfigurationProject | undefined = rushConfiguration.getProjectByName(projectName);\n\n if (!project) {\n return {\n isError: true,\n content: [{ type: 'text', text: `Project \"${projectName}\" not found` }]\n };\n }\n\n const rootPath: string = this._rushWorkspacePath;\n const sourceProjectSubspaceName: string = project.subspace.subspaceName;\n const sourceProjectPath: string = project.projectFolder;\n const destinationPath: string = path.resolve(rootPath, targetProjectPath);\n const subspacehasOnlyOneProject: boolean = project.subspace.getProjects().length === 1;\n\n // 1. Remove source subspace folder\n if (subspacehasOnlyOneProject) {\n const subspaceConfigFolderPath: string = project.subspace.getSubspaceConfigFolderPath();\n await FileSystem.deleteFolderAsync(subspaceConfigFolderPath);\n }\n\n // 2. Move project to target subspace\n await FileSystem.moveAsync({\n sourcePath: sourceProjectPath,\n destinationPath\n });\n\n // 3. Update rush configuration\n await this._modifyAndSaveRushConfigurationAsync(rushConfiguration, (projects) => {\n const projectIndex: number = projects.findIndex(({ packageName }) => packageName === projectName);\n projects[projectIndex] = {\n ...projects[projectIndex],\n subspaceName: targetSubspaceName,\n projectFolder: path.relative(rootPath, destinationPath)\n };\n return projects;\n });\n\n // 4. Update `subspaces.json`\n await this._modifyAndSaveSubspaceJsonFileAsync(rushConfiguration, (subspaceNames) => {\n if (subspacehasOnlyOneProject) {\n subspaceNames.splice(subspaceNames.indexOf(sourceProjectSubspaceName), 1);\n }\n if (!subspaceNames.includes(targetSubspaceName)) {\n subspaceNames.push(targetSubspaceName);\n }\n return subspaceNames;\n });\n\n return {\n content: [\n {\n type: 'text',\n text:\n `Project \"${projectName}\" migrated to subspace \"${targetSubspaceName}\" successfully. ` +\n `You can ask whether the user wants to run \"rush update --subspace ${targetSubspaceName}\" to update the project. ` +\n `If the user says \"yes\", you can run \"rush update --subspace ${targetSubspaceName}\" directly for them.`\n }\n ]\n };\n }\n}\n"]}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
|
|
2
|
+
// See LICENSE in the project root for license information.
|
|
3
|
+
import { z } from 'zod';
|
|
4
|
+
import { getRushConfiguration } from '../utilities/common';
|
|
5
|
+
import { BaseTool } from './base.tool';
|
|
6
|
+
export class RushProjectDetailsTool extends BaseTool {
|
|
7
|
+
constructor() {
|
|
8
|
+
super({
|
|
9
|
+
name: 'rush_project_details',
|
|
10
|
+
description: 'Returns the complete project details in JSON format for a given rush project.',
|
|
11
|
+
schema: {
|
|
12
|
+
projectName: z.string().describe('The name of the project to get details for')
|
|
13
|
+
}
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
async executeAsync({ projectName }) {
|
|
17
|
+
const rushConfiguration = await getRushConfiguration();
|
|
18
|
+
const project = rushConfiguration.getProjectByName(projectName);
|
|
19
|
+
if (!project) {
|
|
20
|
+
throw new Error(`Project ${projectName} not found`);
|
|
21
|
+
}
|
|
22
|
+
return {
|
|
23
|
+
content: [
|
|
24
|
+
{
|
|
25
|
+
type: 'text',
|
|
26
|
+
text: JSON.stringify({
|
|
27
|
+
packageJson: project.packageJson,
|
|
28
|
+
/**
|
|
29
|
+
* Example: `C:\MyRepo\libraries\my-project`
|
|
30
|
+
*/
|
|
31
|
+
projectFolder: project.projectFolder,
|
|
32
|
+
/**
|
|
33
|
+
* Example: `libraries/my-project`
|
|
34
|
+
*/
|
|
35
|
+
projectRelativeFolder: project.projectRelativeFolder,
|
|
36
|
+
/**
|
|
37
|
+
* Example: `C:\MyRepo\libraries\my-project\config\rush`
|
|
38
|
+
*/
|
|
39
|
+
projectRushConfigFolder: project.projectRushConfigFolder,
|
|
40
|
+
/**
|
|
41
|
+
* Example: `my-subspace`
|
|
42
|
+
*/
|
|
43
|
+
projectSubspaceName: project.subspace.subspaceName
|
|
44
|
+
}, null, 2)
|
|
45
|
+
}
|
|
46
|
+
]
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=project-details.tool.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"project-details.tool.js","sourceRoot":"","sources":["../../src/tools/project-details.tool.ts"],"names":[],"mappings":"AAAA,4FAA4F;AAC5F,2DAA2D;AAE3D,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,EAAE,QAAQ,EAAuB,MAAM,aAAa,CAAC;AAE5D,MAAM,OAAO,sBAAuB,SAAQ,QAAQ;IAClD;QACE,KAAK,CAAC;YACJ,IAAI,EAAE,sBAAsB;YAC5B,WAAW,EAAE,+EAA+E;YAC5F,MAAM,EAAE;gBACN,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,4CAA4C,CAAC;aAC/E;SACF,CAAC,CAAC;IACL,CAAC;IAEM,KAAK,CAAC,YAAY,CAAC,EAAE,WAAW,EAA2B;QAChE,MAAM,iBAAiB,GAAsB,MAAM,oBAAoB,EAAE,CAAC;QAC1E,MAAM,OAAO,GAAyC,iBAAiB,CAAC,gBAAgB,CAAC,WAAW,CAAC,CAAC;QAEtG,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,MAAM,IAAI,KAAK,CAAC,WAAW,WAAW,YAAY,CAAC,CAAC;QACtD,CAAC;QAED,OAAO;YACL,OAAO,EAAE;gBACP;oBACE,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE,IAAI,CAAC,SAAS,CAClB;wBACE,WAAW,EAAE,OAAO,CAAC,WAAW;wBAChC;;2BAEG;wBACH,aAAa,EAAE,OAAO,CAAC,aAAa;wBACpC;;2BAEG;wBACH,qBAAqB,EAAE,OAAO,CAAC,qBAAqB;wBACpD;;2BAEG;wBACH,uBAAuB,EAAE,OAAO,CAAC,uBAAuB;wBACxD;;2BAEG;wBACH,mBAAmB,EAAE,OAAO,CAAC,QAAQ,CAAC,YAAY;qBACnD,EACD,IAAI,EACJ,CAAC,CACF;iBACF;aACF;SACF,CAAC;IACJ,CAAC;CACF","sourcesContent":["// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.\n// See LICENSE in the project root for license information.\n\nimport { z } from 'zod';\n\nimport type { RushConfiguration, RushConfigurationProject } from '@rushstack/rush-sdk';\n\nimport { getRushConfiguration } from '../utilities/common';\nimport { BaseTool, type CallToolResult } from './base.tool';\n\nexport class RushProjectDetailsTool extends BaseTool {\n public constructor() {\n super({\n name: 'rush_project_details',\n description: 'Returns the complete project details in JSON format for a given rush project.',\n schema: {\n projectName: z.string().describe('The name of the project to get details for')\n }\n });\n }\n\n public async executeAsync({ projectName }: { projectName: string }): Promise<CallToolResult> {\n const rushConfiguration: RushConfiguration = await getRushConfiguration();\n const project: RushConfigurationProject | undefined = rushConfiguration.getProjectByName(projectName);\n\n if (!project) {\n throw new Error(`Project ${projectName} not found`);\n }\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(\n {\n packageJson: project.packageJson,\n /**\n * Example: `C:\\MyRepo\\libraries\\my-project`\n */\n projectFolder: project.projectFolder,\n /**\n * Example: `libraries/my-project`\n */\n projectRelativeFolder: project.projectRelativeFolder,\n /**\n * Example: `C:\\MyRepo\\libraries\\my-project\\config\\rush`\n */\n projectRushConfigFolder: project.projectRushConfigFolder,\n /**\n * Example: `my-subspace`\n */\n projectSubspaceName: project.subspace.subspaceName\n },\n null,\n 2\n )\n }\n ]\n };\n }\n}\n"]}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
|
|
2
|
+
// See LICENSE in the project root for license information.
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import { z } from 'zod';
|
|
5
|
+
import { JsonFile } from '@rushstack/node-core-library';
|
|
6
|
+
import { getRushConfiguration } from '../utilities/common';
|
|
7
|
+
import { BaseTool } from './base.tool';
|
|
8
|
+
export const selectionParamsSet = new Set([
|
|
9
|
+
'-t',
|
|
10
|
+
'--to',
|
|
11
|
+
'--to-except',
|
|
12
|
+
'-T',
|
|
13
|
+
'--from',
|
|
14
|
+
'-f',
|
|
15
|
+
'--only',
|
|
16
|
+
'-o',
|
|
17
|
+
'--impacted-by',
|
|
18
|
+
'-i',
|
|
19
|
+
'--impacted-by-except',
|
|
20
|
+
'-I'
|
|
21
|
+
]);
|
|
22
|
+
export class RushCommandValidatorTool extends BaseTool {
|
|
23
|
+
constructor() {
|
|
24
|
+
super({
|
|
25
|
+
name: 'rush_command_validator',
|
|
26
|
+
description: 'Validates Rush commands before execution by checking command format and ensuring compliance with Rush command standards. This tool helps prevent invalid command usage and provides guidance on proper parameter selection.',
|
|
27
|
+
schema: {
|
|
28
|
+
commandName: z.enum(['rush', 'rushx']).describe('The main command to execute (rush or rushx)'),
|
|
29
|
+
subCommandName: z
|
|
30
|
+
.string()
|
|
31
|
+
.describe('The Rush subcommand to validate (install, update, add, remove, purge, list, build, etc.)'),
|
|
32
|
+
args: z.array(z.string()).describe('The arguments to validate for the subcommand')
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
async executeAsync({ commandName, subCommandName, args }) {
|
|
37
|
+
var _a;
|
|
38
|
+
const rushConfiguration = await getRushConfiguration();
|
|
39
|
+
const commandLineJson = await JsonFile.loadAsync(path.resolve(rushConfiguration.commonFolder, 'config', 'rush', 'command-line.json'));
|
|
40
|
+
const conditionSubCommandNames = new Set((_a = commandLineJson.commands) === null || _a === void 0 ? void 0 : _a.filter((command) => command.commandKind !== 'global').map((command) => command.name));
|
|
41
|
+
if (conditionSubCommandNames.has(subCommandName) && !args.some((arg) => selectionParamsSet.has(arg))) {
|
|
42
|
+
return {
|
|
43
|
+
isError: true,
|
|
44
|
+
content: [
|
|
45
|
+
{
|
|
46
|
+
type: 'text',
|
|
47
|
+
text: `Please add selection parameters like ${Array.from(selectionParamsSet).join(', ')} to the command and re-validate. The package name should be retrieved from the package.json file in your project folder.`
|
|
48
|
+
}
|
|
49
|
+
]
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
for (const [index, arg] of args.entries()) {
|
|
53
|
+
if (selectionParamsSet.has(arg)) {
|
|
54
|
+
const packageName = args[index + 1];
|
|
55
|
+
const isValidPackage = packageName === '.' || rushConfiguration.projects.some((p) => p.packageName === packageName);
|
|
56
|
+
if (!isValidPackage) {
|
|
57
|
+
return {
|
|
58
|
+
isError: true,
|
|
59
|
+
content: [
|
|
60
|
+
{
|
|
61
|
+
type: 'text',
|
|
62
|
+
text: `The package "${packageName}" does not exist in the Rush workspace. You can retrieve the package name from the 'package.json' file in the project folder.`
|
|
63
|
+
}
|
|
64
|
+
]
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
const commandStr = `${commandName} ${subCommandName} ${args.join(' ')}`;
|
|
70
|
+
const text = `Command "${commandStr}" validated successfully, you can ${commandName === 'rushx' || subCommandName === 'add' ? 'enter the project folder and ' : ''}execute it now.`;
|
|
71
|
+
return {
|
|
72
|
+
content: [
|
|
73
|
+
{
|
|
74
|
+
type: 'text',
|
|
75
|
+
text
|
|
76
|
+
}
|
|
77
|
+
]
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
//# sourceMappingURL=rush-command-validator.tool.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rush-command-validator.tool.js","sourceRoot":"","sources":["../../src/tools/rush-command-validator.tool.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.\n// See LICENSE in the project root for license information.\n\nimport path from 'node:path';\n\nimport { z } from 'zod';\n\nimport { JsonFile } from '@rushstack/node-core-library';\nimport type { ICommandLineJson } from '@rushstack/rush-sdk/lib/api/CommandLineJson';\nimport type { RushConfiguration } from '@rushstack/rush-sdk';\n\nimport { getRushConfiguration } from '../utilities/common';\nimport { BaseTool, type CallToolResult } from './base.tool';\n\nexport const selectionParamsSet: ReadonlySet<string> = new Set([\n '-t',\n '--to',\n '--to-except',\n '-T',\n '--from',\n '-f',\n '--only',\n '-o',\n '--impacted-by',\n '-i',\n '--impacted-by-except',\n '-I'\n]);\n\nexport class RushCommandValidatorTool extends BaseTool {\n public constructor() {\n super({\n name: 'rush_command_validator',\n description:\n 'Validates Rush commands before execution by checking command format and ensuring compliance with Rush command standards. This tool helps prevent invalid command usage and provides guidance on proper parameter selection.',\n schema: {\n commandName: z.enum(['rush', 'rushx']).describe('The main command to execute (rush or rushx)'),\n subCommandName: z\n .string()\n .describe(\n 'The Rush subcommand to validate (install, update, add, remove, purge, list, build, etc.)'\n ),\n args: z.array(z.string()).describe('The arguments to validate for the subcommand')\n }\n });\n }\n\n public async executeAsync({\n commandName,\n subCommandName,\n args\n }: {\n commandName: string;\n subCommandName: string;\n args: string[];\n }): Promise<CallToolResult> {\n const rushConfiguration: RushConfiguration = await getRushConfiguration();\n const commandLineJson: ICommandLineJson = await JsonFile.loadAsync(\n path.resolve(rushConfiguration.commonFolder, 'config', 'rush', 'command-line.json')\n );\n const conditionSubCommandNames: Set<string> = new Set(\n commandLineJson.commands\n ?.filter((command) => command.commandKind !== 'global')\n .map((command) => command.name)\n );\n\n if (conditionSubCommandNames.has(subCommandName) && !args.some((arg) => selectionParamsSet.has(arg))) {\n return {\n isError: true,\n content: [\n {\n type: 'text',\n text: `Please add selection parameters like ${Array.from(selectionParamsSet).join(\n ', '\n )} to the command and re-validate. The package name should be retrieved from the package.json file in your project folder.`\n }\n ]\n };\n }\n\n for (const [index, arg] of args.entries()) {\n if (selectionParamsSet.has(arg)) {\n const packageName: string = args[index + 1];\n const isValidPackage: boolean =\n packageName === '.' || rushConfiguration.projects.some((p) => p.packageName === packageName);\n\n if (!isValidPackage) {\n return {\n isError: true,\n content: [\n {\n type: 'text',\n text: `The package \"${packageName}\" does not exist in the Rush workspace. You can retrieve the package name from the 'package.json' file in the project folder.`\n }\n ]\n };\n }\n }\n }\n\n const commandStr: string = `${commandName} ${subCommandName} ${args.join(' ')}`;\n const text: string = `Command \"${commandStr}\" validated successfully, you can ${\n commandName === 'rushx' || subCommandName === 'add' ? 'enter the project folder and ' : ''\n }execute it now.`;\n\n return {\n content: [\n {\n type: 'text',\n text\n }\n ]\n };\n }\n}\n"]}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
|
|
2
|
+
// See LICENSE in the project root for license information.
|
|
3
|
+
import { getRushConfiguration } from '../utilities/common';
|
|
4
|
+
import { BaseTool } from './base.tool';
|
|
5
|
+
export class RushWorkspaceDetailsTool extends BaseTool {
|
|
6
|
+
constructor() {
|
|
7
|
+
super({
|
|
8
|
+
name: 'rush_workspace_details',
|
|
9
|
+
description: 'Retrieves a comprehensive overview of the Rush monorepo project graph in an LLM-friendly format. Use it to answer questions about the current Rush workspace and architecture.',
|
|
10
|
+
schema: {}
|
|
11
|
+
});
|
|
12
|
+
}
|
|
13
|
+
async executeAsync() {
|
|
14
|
+
const rushConfiguration = await getRushConfiguration();
|
|
15
|
+
const projects = rushConfiguration.projects;
|
|
16
|
+
return {
|
|
17
|
+
content: [
|
|
18
|
+
{
|
|
19
|
+
type: 'text',
|
|
20
|
+
text: this._getWorkspaceDetailsPrompt(rushConfiguration, projects)
|
|
21
|
+
}
|
|
22
|
+
]
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
_getWorkspaceDetailsPrompt(rushConfiguration, projects) {
|
|
26
|
+
return `
|
|
27
|
+
The following is a comprehensive representation of the Rush monorepo workspace. The information is organized into two sections:
|
|
28
|
+
|
|
29
|
+
1. WORKSPACE LEVEL: Contains global configuration information about the Rush workspace itself.
|
|
30
|
+
2. PROJECT LEVEL: Lists all projects in the monorepo with their detailed information.
|
|
31
|
+
|
|
32
|
+
WORKSPACE LEVEL information includes Rush version, pnpm version, and overall project count.
|
|
33
|
+
|
|
34
|
+
PROJECT LEVEL information is separated by <project_name></project_name> tags. Each project contains:
|
|
35
|
+
- its direct workspace dependencies package names, marked by "deps: [...]"
|
|
36
|
+
- its package name, marked by "packageName: [...]"
|
|
37
|
+
- its project type/category, marked by "projectType: [...]"
|
|
38
|
+
- its source file location, marked by "projectFolder: [...]"
|
|
39
|
+
- its scripts/commands, marked by "scripts: [...]"
|
|
40
|
+
- its version, marked by "version: [...]"
|
|
41
|
+
- additional metadata if available
|
|
42
|
+
|
|
43
|
+
This data is very important. Use it to analyze the workspace and understand the project graph. The user cannot see this data, so don't reference it directly. It is read-only information to help you understand the workspace.
|
|
44
|
+
|
|
45
|
+
${this._getRobotReadableWorkspaceDetails(rushConfiguration.rushConfigurationJson, projects)}
|
|
46
|
+
`.trim();
|
|
47
|
+
}
|
|
48
|
+
_getRobotReadableWorkspaceDetails(rushConfiguration, projects) {
|
|
49
|
+
let serializedWorkspace = '';
|
|
50
|
+
// Add workspace-level information with clearer section marking
|
|
51
|
+
serializedWorkspace += `======== WORKSPACE LEVEL INFORMATION ========\n`;
|
|
52
|
+
serializedWorkspace += `<RUSH_WORKSPACE>\n`;
|
|
53
|
+
serializedWorkspace += ` rushVersion: [${rushConfiguration.rushVersion}]\n`;
|
|
54
|
+
serializedWorkspace += ` pnpmVersion: [${rushConfiguration.pnpmVersion}]\n`;
|
|
55
|
+
serializedWorkspace += ` projectCount: [${projects.length}]\n`;
|
|
56
|
+
serializedWorkspace += `</RUSH_WORKSPACE>\n\n`;
|
|
57
|
+
serializedWorkspace += `======== PROJECT LEVEL INFORMATION ========\n`;
|
|
58
|
+
projects.forEach((project) => {
|
|
59
|
+
serializedWorkspace += `<${project.packageName}>\n`;
|
|
60
|
+
serializedWorkspace += ` packageName: [${project.packageName}]\n`;
|
|
61
|
+
serializedWorkspace += ` version: [${project.packageJson.version}]\n`;
|
|
62
|
+
serializedWorkspace += ` projectFolder: [${project.projectFolder}]\n`;
|
|
63
|
+
serializedWorkspace += ` subspaceName: [${project.subspace.subspaceName}]\n`;
|
|
64
|
+
const projectType = project.shouldPublish ? 'publishable' : 'local';
|
|
65
|
+
serializedWorkspace += ` projectType: [${projectType}]\n`;
|
|
66
|
+
const dependencies = project.dependencyProjects;
|
|
67
|
+
const depNames = Array.from(dependencies, (dep) => dep.packageName);
|
|
68
|
+
if (depNames.length === 0) {
|
|
69
|
+
serializedWorkspace += ` deps: []\n`;
|
|
70
|
+
}
|
|
71
|
+
else if (depNames.length <= 5) {
|
|
72
|
+
serializedWorkspace += ` deps: [${depNames.join(', ')}]\n`;
|
|
73
|
+
}
|
|
74
|
+
else {
|
|
75
|
+
serializedWorkspace += ` deps: [\n ${depNames.join(',\n ')}\n ]\n`;
|
|
76
|
+
}
|
|
77
|
+
if (project.packageJson.scripts) {
|
|
78
|
+
const scripts = Object.keys(project.packageJson.scripts);
|
|
79
|
+
if (scripts.length === 0) {
|
|
80
|
+
serializedWorkspace += ` scripts: []\n`;
|
|
81
|
+
}
|
|
82
|
+
else if (scripts.length <= 5) {
|
|
83
|
+
serializedWorkspace += ` scripts: [${scripts.join(', ')}]\n`;
|
|
84
|
+
}
|
|
85
|
+
else {
|
|
86
|
+
serializedWorkspace += ` scripts: [\n ${scripts.join(',\n ')}\n ]\n`;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
else {
|
|
90
|
+
serializedWorkspace += ` scripts: []\n`;
|
|
91
|
+
}
|
|
92
|
+
if (project.versionPolicyName) {
|
|
93
|
+
serializedWorkspace += ` versionPolicy: [${project.versionPolicyName}]\n`;
|
|
94
|
+
}
|
|
95
|
+
if (project.reviewCategory) {
|
|
96
|
+
serializedWorkspace += ` reviewCategory: [${project.reviewCategory}]\n`;
|
|
97
|
+
}
|
|
98
|
+
serializedWorkspace += `</${project.packageName}>\n\n`;
|
|
99
|
+
});
|
|
100
|
+
return serializedWorkspace;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
//# sourceMappingURL=workspace-details.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workspace-details.js","sourceRoot":"","sources":["../../src/tools/workspace-details.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.\n// See LICENSE in the project root for license information.\n\nimport type { RushConfiguration, RushConfigurationProject } from '@rushstack/rush-sdk';\nimport type { IRushConfigurationJson } from '@rushstack/rush-sdk/lib/api/RushConfiguration';\n\nimport { getRushConfiguration } from '../utilities/common';\nimport { BaseTool, type CallToolResult } from './base.tool';\n\nexport class RushWorkspaceDetailsTool extends BaseTool {\n public constructor() {\n super({\n name: 'rush_workspace_details',\n description:\n 'Retrieves a comprehensive overview of the Rush monorepo project graph in an LLM-friendly format. Use it to answer questions about the current Rush workspace and architecture.',\n schema: {}\n });\n }\n\n public async executeAsync(): Promise<CallToolResult> {\n const rushConfiguration: RushConfiguration = await getRushConfiguration();\n const projects: RushConfigurationProject[] = rushConfiguration.projects;\n\n return {\n content: [\n {\n type: 'text',\n text: this._getWorkspaceDetailsPrompt(rushConfiguration, projects)\n }\n ]\n };\n }\n\n private _getWorkspaceDetailsPrompt(\n rushConfiguration: RushConfiguration,\n projects: RushConfigurationProject[]\n ): string {\n return `\nThe following is a comprehensive representation of the Rush monorepo workspace. The information is organized into two sections:\n\n1. WORKSPACE LEVEL: Contains global configuration information about the Rush workspace itself.\n2. PROJECT LEVEL: Lists all projects in the monorepo with their detailed information.\n\nWORKSPACE LEVEL information includes Rush version, pnpm version, and overall project count.\n\nPROJECT LEVEL information is separated by <project_name></project_name> tags. Each project contains:\n- its direct workspace dependencies package names, marked by \"deps: [...]\"\n- its package name, marked by \"packageName: [...]\"\n- its project type/category, marked by \"projectType: [...]\"\n- its source file location, marked by \"projectFolder: [...]\"\n- its scripts/commands, marked by \"scripts: [...]\"\n- its version, marked by \"version: [...]\"\n- additional metadata if available\n\nThis data is very important. Use it to analyze the workspace and understand the project graph. The user cannot see this data, so don't reference it directly. It is read-only information to help you understand the workspace.\n\n${this._getRobotReadableWorkspaceDetails(rushConfiguration.rushConfigurationJson, projects)}\n`.trim();\n }\n\n private _getRobotReadableWorkspaceDetails(\n rushConfiguration: IRushConfigurationJson,\n projects: RushConfigurationProject[]\n ): string {\n let serializedWorkspace: string = '';\n\n // Add workspace-level information with clearer section marking\n serializedWorkspace += `======== WORKSPACE LEVEL INFORMATION ========\\n`;\n serializedWorkspace += `<RUSH_WORKSPACE>\\n`;\n serializedWorkspace += ` rushVersion: [${rushConfiguration.rushVersion}]\\n`;\n serializedWorkspace += ` pnpmVersion: [${rushConfiguration.pnpmVersion}]\\n`;\n serializedWorkspace += ` projectCount: [${projects.length}]\\n`;\n serializedWorkspace += `</RUSH_WORKSPACE>\\n\\n`;\n serializedWorkspace += `======== PROJECT LEVEL INFORMATION ========\\n`;\n\n projects.forEach((project) => {\n serializedWorkspace += `<${project.packageName}>\\n`;\n\n serializedWorkspace += ` packageName: [${project.packageName}]\\n`;\n serializedWorkspace += ` version: [${project.packageJson.version}]\\n`;\n serializedWorkspace += ` projectFolder: [${project.projectFolder}]\\n`;\n serializedWorkspace += ` subspaceName: [${project.subspace.subspaceName}]\\n`;\n\n const projectType: string = project.shouldPublish ? 'publishable' : 'local';\n serializedWorkspace += ` projectType: [${projectType}]\\n`;\n\n const dependencies: ReadonlySet<RushConfigurationProject> = project.dependencyProjects;\n const depNames: string[] = Array.from(dependencies, (dep) => dep.packageName);\n\n if (depNames.length === 0) {\n serializedWorkspace += ` deps: []\\n`;\n } else if (depNames.length <= 5) {\n serializedWorkspace += ` deps: [${depNames.join(', ')}]\\n`;\n } else {\n serializedWorkspace += ` deps: [\\n ${depNames.join(',\\n ')}\\n ]\\n`;\n }\n\n if (project.packageJson.scripts) {\n const scripts: string[] = Object.keys(project.packageJson.scripts);\n if (scripts.length === 0) {\n serializedWorkspace += ` scripts: []\\n`;\n } else if (scripts.length <= 5) {\n serializedWorkspace += ` scripts: [${scripts.join(', ')}]\\n`;\n } else {\n serializedWorkspace += ` scripts: [\\n ${scripts.join(',\\n ')}\\n ]\\n`;\n }\n } else {\n serializedWorkspace += ` scripts: []\\n`;\n }\n\n if (project.versionPolicyName) {\n serializedWorkspace += ` versionPolicy: [${project.versionPolicyName}]\\n`;\n }\n\n if (project.reviewCategory) {\n serializedWorkspace += ` reviewCategory: [${project.reviewCategory}]\\n`;\n }\n\n serializedWorkspace += `</${project.packageName}>\\n\\n`;\n });\n\n return serializedWorkspace;\n }\n}\n"]}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
|
|
2
|
+
// See LICENSE in the project root for license information.
|
|
3
|
+
import { Executable } from '@rushstack/node-core-library';
|
|
4
|
+
export class CommandExecutionError extends Error {
|
|
5
|
+
constructor(command, args, stderr, status) {
|
|
6
|
+
super(`Command "${command} ${args.join(' ')}" failed with status ${status}:\n${stderr}`);
|
|
7
|
+
this.name = 'CommandExecutionError';
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
export class CommandRunner {
|
|
11
|
+
static _resolveCommand(command) {
|
|
12
|
+
var _a;
|
|
13
|
+
const cachedPath = this._commandCache.get(command);
|
|
14
|
+
if (cachedPath === null) {
|
|
15
|
+
throw new Error(`Command "${command}" not found in system PATH`);
|
|
16
|
+
}
|
|
17
|
+
if (cachedPath) {
|
|
18
|
+
return cachedPath;
|
|
19
|
+
}
|
|
20
|
+
const resolvedPath = (_a = Executable.tryResolve(command)) !== null && _a !== void 0 ? _a : null;
|
|
21
|
+
this._commandCache.set(command, resolvedPath);
|
|
22
|
+
if (!resolvedPath) {
|
|
23
|
+
throw new Error(`Command "${command}" not found in system PATH`);
|
|
24
|
+
}
|
|
25
|
+
return resolvedPath;
|
|
26
|
+
}
|
|
27
|
+
static async _executeCommandAsync(command, args, options) {
|
|
28
|
+
const commandPath = this._resolveCommand(command);
|
|
29
|
+
return new Promise((resolve, reject) => {
|
|
30
|
+
var _a, _b;
|
|
31
|
+
const childProcess = Executable.spawn(commandPath, args, options);
|
|
32
|
+
let stdout = '';
|
|
33
|
+
let stderr = '';
|
|
34
|
+
(_a = childProcess.stdout) === null || _a === void 0 ? void 0 : _a.on('data', (data) => {
|
|
35
|
+
stdout += data.toString();
|
|
36
|
+
});
|
|
37
|
+
(_b = childProcess.stderr) === null || _b === void 0 ? void 0 : _b.on('data', (data) => {
|
|
38
|
+
stderr += data.toString();
|
|
39
|
+
});
|
|
40
|
+
childProcess.on('close', (status) => {
|
|
41
|
+
if (status !== 0) {
|
|
42
|
+
reject(new CommandExecutionError(command, args, stderr, status !== null && status !== void 0 ? status : 1));
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
resolve({
|
|
46
|
+
status: status !== null && status !== void 0 ? status : 0,
|
|
47
|
+
stdout,
|
|
48
|
+
stderr,
|
|
49
|
+
command,
|
|
50
|
+
args
|
|
51
|
+
});
|
|
52
|
+
});
|
|
53
|
+
childProcess.on('error', (error) => {
|
|
54
|
+
reject(error);
|
|
55
|
+
});
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
static async runRushCommandAsync(args, options) {
|
|
59
|
+
return this._executeCommandAsync('rush', args, options);
|
|
60
|
+
}
|
|
61
|
+
static async runRushXCommandAsync(args, options) {
|
|
62
|
+
return this._executeCommandAsync('rushx', args, options);
|
|
63
|
+
}
|
|
64
|
+
static async runGitCommandAsync(args, options) {
|
|
65
|
+
return this._executeCommandAsync('git', args, options);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
CommandRunner._commandCache = new Map();
|
|
69
|
+
//# sourceMappingURL=command-runner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"command-runner.js","sourceRoot":"","sources":["../../src/utilities/command-runner.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.\n// See LICENSE in the project root for license information.\n\nimport type { ChildProcess } from 'node:child_process';\n\nimport { Executable, type IExecutableSpawnSyncOptions } from '@rushstack/node-core-library';\n\ninterface ICommandResult {\n status: number;\n stdout: string;\n stderr: string;\n command: string;\n args: string[];\n}\n\nexport class CommandExecutionError extends Error {\n public constructor(command: string, args: string[], stderr: string, status: number) {\n super(`Command \"${command} ${args.join(' ')}\" failed with status ${status}:\\n${stderr}`);\n this.name = 'CommandExecutionError';\n }\n}\n\nexport class CommandRunner {\n private static readonly _commandCache: Map<string, string | null> = new Map();\n\n private static _resolveCommand(command: string): string {\n const cachedPath: string | null | undefined = this._commandCache.get(command);\n if (cachedPath === null) {\n throw new Error(`Command \"${command}\" not found in system PATH`);\n }\n\n if (cachedPath) {\n return cachedPath;\n }\n\n const resolvedPath: string | null = Executable.tryResolve(command) ?? null;\n this._commandCache.set(command, resolvedPath);\n\n if (!resolvedPath) {\n throw new Error(`Command \"${command}\" not found in system PATH`);\n }\n\n return resolvedPath;\n }\n\n private static async _executeCommandAsync(\n command: string,\n args: string[],\n options?: IExecutableSpawnSyncOptions\n ): Promise<ICommandResult> {\n const commandPath: string = this._resolveCommand(command);\n\n return new Promise((resolve, reject) => {\n const childProcess: ChildProcess = Executable.spawn(commandPath, args, options);\n let stdout: string = '';\n let stderr: string = '';\n\n childProcess.stdout?.on('data', (data) => {\n stdout += data.toString();\n });\n\n childProcess.stderr?.on('data', (data) => {\n stderr += data.toString();\n });\n\n childProcess.on('close', (status) => {\n if (status !== 0) {\n reject(new CommandExecutionError(command, args, stderr, status ?? 1));\n return;\n }\n\n resolve({\n status: status ?? 0,\n stdout,\n stderr,\n command,\n args\n });\n });\n\n childProcess.on('error', (error) => {\n reject(error);\n });\n });\n }\n\n public static async runRushCommandAsync(\n args: string[],\n options?: IExecutableSpawnSyncOptions\n ): Promise<ICommandResult> {\n return this._executeCommandAsync('rush', args, options);\n }\n\n public static async runRushXCommandAsync(\n args: string[],\n options?: IExecutableSpawnSyncOptions\n ): Promise<ICommandResult> {\n return this._executeCommandAsync('rushx', args, options);\n }\n\n public static async runGitCommandAsync(\n args: string[],\n options?: IExecutableSpawnSyncOptions\n ): Promise<ICommandResult> {\n return this._executeCommandAsync('git', args, options);\n }\n}\n"]}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
|
|
2
|
+
// See LICENSE in the project root for license information.
|
|
3
|
+
export const getRushConfiguration = async () => {
|
|
4
|
+
// Since the MCP server is not always started from the directory of the Rush monorepo,
|
|
5
|
+
// it’s necessary to use dynamic import to load the Rush SDK.
|
|
6
|
+
const Rush = await import('@rushstack/rush-sdk');
|
|
7
|
+
const rushConfiguration = Rush.RushConfiguration.loadFromDefaultLocation();
|
|
8
|
+
return rushConfiguration;
|
|
9
|
+
};
|
|
10
|
+
//# sourceMappingURL=common.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"common.js","sourceRoot":"","sources":["../../src/utilities/common.ts"],"names":[],"mappings":"AAAA,4FAA4F;AAC5F,2DAA2D;AAI3D,MAAM,CAAC,MAAM,oBAAoB,GAAG,KAAK,IAAgC,EAAE;IACzE,sFAAsF;IACtF,6DAA6D;IAC7D,MAAM,IAAI,GAAyC,MAAM,MAAM,CAAC,qBAAqB,CAAC,CAAC;IACvF,MAAM,iBAAiB,GAAsB,IAAI,CAAC,iBAAiB,CAAC,uBAAuB,EAAE,CAAC;IAC9F,OAAO,iBAAiB,CAAC;AAC3B,CAAC,CAAC","sourcesContent":["// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.\n// See LICENSE in the project root for license information.\n\nimport type { RushConfiguration } from '@rushstack/rush-sdk';\n\nexport const getRushConfiguration = async (): Promise<RushConfiguration> => {\n // Since the MCP server is not always started from the directory of the Rush monorepo,\n // it’s necessary to use dynamic import to load the Rush SDK.\n const Rush: typeof import('@rushstack/rush-sdk') = await import('@rushstack/rush-sdk');\n const rushConfiguration: RushConfiguration = Rush.RushConfiguration.loadFromDefaultLocation();\n return rushConfiguration;\n};\n"]}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
|
|
2
|
+
// See LICENSE in the project root for license information.
|
|
3
|
+
import { Terminal, ConsoleTerminalProvider } from '@rushstack/terminal';
|
|
4
|
+
export const terminal = new Terminal(new ConsoleTerminalProvider({ verboseEnabled: true }));
|
|
5
|
+
export function log(...messageParts) {
|
|
6
|
+
terminal.writeErrorLine(...messageParts);
|
|
7
|
+
}
|
|
8
|
+
//# sourceMappingURL=log.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"log.js","sourceRoot":"","sources":["../../src/utilities/log.ts"],"names":[],"mappings":"AAAA,4FAA4F;AAC5F,2DAA2D;AAE3D,OAAO,EAAE,QAAQ,EAAE,uBAAuB,EAAgC,MAAM,qBAAqB,CAAC;AAEtG,MAAM,CAAC,MAAM,QAAQ,GAAa,IAAI,QAAQ,CAAC,IAAI,uBAAuB,CAAC,EAAE,cAAc,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;AAEtG,MAAM,UAAU,GAAG,CAAC,GAAG,YAAqC;IAC1D,QAAQ,CAAC,cAAc,CAAC,GAAG,YAAY,CAAC,CAAC;AAC3C,CAAC","sourcesContent":["// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.\n// See LICENSE in the project root for license information.\n\nimport { Terminal, ConsoleTerminalProvider, type TerminalWriteParameters } from '@rushstack/terminal';\n\nexport const terminal: Terminal = new Terminal(new ConsoleTerminalProvider({ verboseEnabled: true }));\n\nexport function log(...messageParts: TerminalWriteParameters): void {\n terminal.writeErrorLine(...messageParts);\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rushstack/mcp-server",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.1",
|
|
4
4
|
"description": "A Model Context Protocol server implementation for Rush",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"rush",
|
|
@@ -9,8 +9,32 @@
|
|
|
9
9
|
"monorepo",
|
|
10
10
|
"server"
|
|
11
11
|
],
|
|
12
|
-
"main": "lib/index.js",
|
|
13
|
-
"
|
|
12
|
+
"main": "./lib-commonjs/index.js",
|
|
13
|
+
"module": "./lib-esm/index.js",
|
|
14
|
+
"types": "./dist/mcp-server.d.ts",
|
|
15
|
+
"exports": {
|
|
16
|
+
".": {
|
|
17
|
+
"types": "./dist/mcp-server.d.ts",
|
|
18
|
+
"node": "./lib-commonjs/index.js",
|
|
19
|
+
"import": "./lib-esm/index.js",
|
|
20
|
+
"require": "./lib-commonjs/index.js"
|
|
21
|
+
},
|
|
22
|
+
"./lib/*.schema.json": "./lib-commonjs/*.schema.json",
|
|
23
|
+
"./lib/*": {
|
|
24
|
+
"types": "./lib-dts/*.d.ts",
|
|
25
|
+
"node": "./lib-commonjs/*.js",
|
|
26
|
+
"import": "./lib-esm/*.js",
|
|
27
|
+
"require": "./lib-commonjs/*.js"
|
|
28
|
+
},
|
|
29
|
+
"./package.json": "./package.json"
|
|
30
|
+
},
|
|
31
|
+
"typesVersions": {
|
|
32
|
+
"*": {
|
|
33
|
+
"lib/*": [
|
|
34
|
+
"lib-dts/*"
|
|
35
|
+
]
|
|
36
|
+
}
|
|
37
|
+
},
|
|
14
38
|
"repository": {
|
|
15
39
|
"type": "git",
|
|
16
40
|
"url": "https://github.com/microsoft/rushstack.git",
|
|
@@ -28,18 +52,22 @@
|
|
|
28
52
|
"dependencies": {
|
|
29
53
|
"@modelcontextprotocol/sdk": "~1.10.2",
|
|
30
54
|
"zod": "~3.25.76",
|
|
31
|
-
"@rushstack/node-core-library": "5.
|
|
32
|
-
"@rushstack/terminal": "0.
|
|
33
|
-
"@rushstack/ts-command-line": "5.
|
|
34
|
-
"@rushstack/rush-sdk": "5.
|
|
55
|
+
"@rushstack/node-core-library": "5.20.1",
|
|
56
|
+
"@rushstack/terminal": "0.22.1",
|
|
57
|
+
"@rushstack/ts-command-line": "5.3.1",
|
|
58
|
+
"@rushstack/rush-sdk": "5.169.2"
|
|
35
59
|
},
|
|
36
60
|
"devDependencies": {
|
|
37
61
|
"eslint": "~9.37.0",
|
|
38
62
|
"typescript": "~5.8.2",
|
|
39
63
|
"@types/node": "20.17.19",
|
|
40
|
-
"@rushstack/heft": "1.1
|
|
64
|
+
"@rushstack/heft": "1.2.1",
|
|
41
65
|
"local-node-rig": "1.0.0"
|
|
42
66
|
},
|
|
67
|
+
"sideEffects": [
|
|
68
|
+
"lib-commonjs/start.js",
|
|
69
|
+
"lib-esm/start.js"
|
|
70
|
+
],
|
|
43
71
|
"scripts": {
|
|
44
72
|
"build": "heft build --clean",
|
|
45
73
|
"_phase:build": "heft run --only build -- --clean"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|