mlgym-deploy 2.6.0 → 2.7.0

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.
Files changed (2) hide show
  1. package/index.js +135 -2
  2. package/package.json +1 -1
package/index.js CHANGED
@@ -16,8 +16,8 @@ import crypto from 'crypto';
16
16
 
17
17
  const execAsync = promisify(exec);
18
18
 
19
- // Current version of this MCP server - INCREMENT FOR PROJECT ANALYSIS
20
- const CURRENT_VERSION = '2.6.0';
19
+ // Current version of this MCP server - INCREMENT FOR WORKFLOW FIXES
20
+ const CURRENT_VERSION = '2.7.0';
21
21
  const PACKAGE_NAME = 'mlgym-deploy';
22
22
 
23
23
  // Version check state
@@ -777,6 +777,122 @@ async function checkAuthStatus() {
777
777
  };
778
778
  }
779
779
 
780
+ // Smart deployment initialization that follows the correct workflow
781
+ async function smartDeploy(args) {
782
+ const { local_path = '.' } = args;
783
+ const absolutePath = path.resolve(local_path);
784
+
785
+ const steps = [];
786
+
787
+ try {
788
+ // Step 1: Check authentication
789
+ steps.push({ step: 'auth_check', status: 'running' });
790
+ const auth = await loadAuth();
791
+ if (!auth.token) {
792
+ steps[steps.length - 1].status = 'failed';
793
+ return {
794
+ content: [{
795
+ type: 'text',
796
+ text: JSON.stringify({
797
+ status: 'error',
798
+ message: 'Not authenticated. Please use mlgym_authenticate first',
799
+ workflow_steps: steps
800
+ }, null, 2)
801
+ }]
802
+ };
803
+ }
804
+ steps[steps.length - 1].status = 'completed';
805
+
806
+ // Step 2: Analyze project
807
+ steps.push({ step: 'project_analysis', status: 'running' });
808
+ const analysis = await analyzeProject(local_path);
809
+ steps[steps.length - 1].status = 'completed';
810
+ steps[steps.length - 1].result = {
811
+ type: analysis.project_type,
812
+ framework: analysis.framework,
813
+ suggested_name: analysis.suggested_name
814
+ };
815
+
816
+ // Step 3: Check existing project
817
+ steps.push({ step: 'check_existing', status: 'running' });
818
+ const projectStatus = await checkExistingProject(local_path);
819
+ steps[steps.length - 1].status = 'completed';
820
+
821
+ if (projectStatus.configured) {
822
+ return {
823
+ content: [{
824
+ type: 'text',
825
+ text: JSON.stringify({
826
+ status: 'info',
827
+ message: projectStatus.message,
828
+ project_name: projectStatus.name,
829
+ git_remote: `git@git.mlgym.io:${projectStatus.namespace}/${projectStatus.name}.git`,
830
+ next_steps: [
831
+ 'Project already configured',
832
+ 'Run: git push mlgym main'
833
+ ],
834
+ workflow_steps: steps
835
+ }, null, 2)
836
+ }]
837
+ };
838
+ }
839
+
840
+ // Step 4: Prepare project (generate Dockerfile if needed)
841
+ steps.push({ step: 'prepare_project', status: 'running' });
842
+ if (!analysis.has_dockerfile && analysis.project_type !== 'unknown') {
843
+ const prepResult = await prepareProject({
844
+ local_path,
845
+ project_type: analysis.project_type,
846
+ framework: analysis.framework,
847
+ package_manager: analysis.package_manager
848
+ });
849
+ steps[steps.length - 1].status = 'completed';
850
+ steps[steps.length - 1].result = prepResult.actions;
851
+ } else {
852
+ steps[steps.length - 1].status = 'skipped';
853
+ steps[steps.length - 1].result = 'Dockerfile already exists or project type unknown';
854
+ }
855
+
856
+ // Return analysis and next steps
857
+ return {
858
+ content: [{
859
+ type: 'text',
860
+ text: JSON.stringify({
861
+ status: 'ready',
862
+ message: 'Project analyzed and prepared. Ready for MLGym initialization.',
863
+ analysis: {
864
+ project_type: analysis.project_type,
865
+ framework: analysis.framework,
866
+ suggested_name: analysis.suggested_name,
867
+ has_dockerfile: analysis.has_dockerfile || true
868
+ },
869
+ next_step: 'Use mlgym_project_init with project details to create MLGym project',
870
+ suggested_params: {
871
+ name: analysis.suggested_name,
872
+ description: `${analysis.framework || analysis.project_type} application`,
873
+ enable_deployment: true,
874
+ hostname: analysis.suggested_name
875
+ },
876
+ workflow_steps: steps
877
+ }, null, 2)
878
+ }]
879
+ };
880
+
881
+ } catch (error) {
882
+ return {
883
+ content: [{
884
+ type: 'text',
885
+ text: JSON.stringify({
886
+ status: 'error',
887
+ message: 'Smart deploy failed',
888
+ error: error.message,
889
+ workflow_steps: steps
890
+ }, null, 2)
891
+ }]
892
+ };
893
+ }
894
+ }
895
+
780
896
  // Initialize Project (requires authentication)
781
897
  async function initProject(args) {
782
898
  let { name, description, enable_deployment = true, hostname, local_path = '.' } = args;
@@ -1057,6 +1173,20 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
1057
1173
  }
1058
1174
  }
1059
1175
  }
1176
+ },
1177
+ {
1178
+ name: 'mlgym_smart_deploy',
1179
+ description: 'RECOMMENDED: Smart deployment workflow that automatically analyzes, prepares, and guides you through the entire deployment process. Use this for new projects!',
1180
+ inputSchema: {
1181
+ type: 'object',
1182
+ properties: {
1183
+ local_path: {
1184
+ type: 'string',
1185
+ description: 'Local directory path (defaults to current directory)',
1186
+ default: '.'
1187
+ }
1188
+ }
1189
+ }
1060
1190
  }
1061
1191
  ]
1062
1192
  };
@@ -1106,6 +1236,9 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
1106
1236
  }]
1107
1237
  };
1108
1238
 
1239
+ case 'mlgym_smart_deploy':
1240
+ return await smartDeploy(args);
1241
+
1109
1242
  default:
1110
1243
  throw new Error(`Unknown tool: ${name}`);
1111
1244
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mlgym-deploy",
3
- "version": "2.6.0",
3
+ "version": "2.7.0",
4
4
  "description": "MCP server for GitLab Backend - User creation and project deployment",
5
5
  "main": "index.js",
6
6
  "type": "module",