@@ -86,6 +86,7 @@ class LaunchCommandImpl extends BaseCommandImpl implements CmdLaunch.LaunchComma
8686 String revision
8787 String repository
8888 String trackingUrl
89+ String commitUrl
8990 }
9091
9192 // ===== Main Entry Point =====
@@ -104,9 +105,9 @@ class LaunchCommandImpl extends BaseCommandImpl implements CmdLaunch.LaunchComma
104105 final result = submitWorkflowLaunch(options, context, resolvedPipelineUrl)
105106
106107 // Display launch information
107- printLaunchInfo(result. repository, result. runName, result. commitId, result. revision,
108- context. workDir, context. computeEnvName, context. userName,
109- context. orgName, context. workspaceName, options)
108+ printLaunchInfo(result. repository, result. runName, result. commitId, result. revision, result . commitUrl,
109+ context. workDir, context. computeEnvId, context . computeEnvName, context. userName,
110+ context. orgName, context. workspaceName, context . apiEndpoint, options)
110111 printSuccessMessage(result. workflowId, result. trackingUrl, options)
111112
112113 // Poll for workflow logs
@@ -269,13 +270,17 @@ class LaunchCommandImpl extends BaseCommandImpl implements CmdLaunch.LaunchComma
269270 }
270271 }
271272
273+ // Get commit browse URL from SCM provider
274+ final commitUrl = getCommitBrowseUrl(pipelineUrl, commitId)
275+
272276 return new WorkflowLaunchResult (
273277 workflowId : response. workflowId as String,
274278 runName : runName,
275279 commitId : commitId,
276280 revision : revision,
277281 repository : pipelineUrl,
278- trackingUrl : trackingUrl
282+ trackingUrl : trackingUrl,
283+ commitUrl : commitUrl
279284 )
280285 }
281286
@@ -334,7 +339,8 @@ class LaunchCommandImpl extends BaseCommandImpl implements CmdLaunch.LaunchComma
334339
335340 // Show Nextflow version and launch context
336341 print (ColorUtil . colorize(" ~ " , " dim" , true ))
337- println (" version " + BuildInfo . version)
342+ final versionUrl = " https://github.com/nextflow-io/nextflow/releases/tag/v${ BuildInfo.version} "
343+ println (ColorUtil . hyperlink(" version " + BuildInfo . version, versionUrl))
338344 println (" Launching workflow in Seqera Platform" )
339345 println " "
340346 } else {
@@ -344,10 +350,26 @@ class LaunchCommandImpl extends BaseCommandImpl implements CmdLaunch.LaunchComma
344350 }
345351 }
346352
347- protected void printLaunchInfo (String repo , String runName , String commitId , String revision , String workDir , String computeEnvName , String userName , String orgName , String workspaceName , CmdLaunch.LaunchOptions options ) {
353+ protected void printLaunchInfo (String repo , String runName , String commitId , String revision , String commitUrl , String workDir , String computeEnvId , String computeEnvName , String userName , String orgName , String workspaceName , String apiEndpoint , CmdLaunch.LaunchOptions options ) {
348354 def showRevision = commitId && commitId != ' unknown'
349355 def showRevisionBrackets = revision && revision != ' unknown'
350356
357+ // Build web URLs for workspace and compute environment
358+ final webUrl = getWebUrlFromApiEndpoint(apiEndpoint)
359+ String workspaceUrl = null
360+ String computeEnvUrl = null
361+ if (orgName && workspaceName) {
362+ workspaceUrl = " ${ webUrl} /orgs/${ orgName} /workspaces/${ workspaceName} /launchpad"
363+ if (computeEnvId) {
364+ computeEnvUrl = " ${ webUrl} /orgs/${ orgName} /workspaces/${ workspaceName} /compute-envs/${ computeEnvId} "
365+ }
366+ } else if (userName) {
367+ workspaceUrl = " ${ webUrl} /user/${ userName} /launchpad"
368+ if (computeEnvId) {
369+ computeEnvUrl = " ${ webUrl} /user/${ userName} /compute-envs/${ computeEnvId} "
370+ }
371+ }
372+
351373 if (ColorUtil . isAnsiEnabled()) {
352374 def debugMsg = " Launched `${ repo} ` [${ runName} ]"
353375 if (showRevision) {
@@ -365,7 +387,7 @@ class LaunchCommandImpl extends BaseCommandImpl implements CmdLaunch.LaunchComma
365387 print (ColorUtil . colorize(" ]" , " dim" , true ))
366388 if (showRevision) {
367389 print (" - " )
368- print (ColorUtil . colorize(" revision: $commitId " , " cyan" , true ))
390+ print (ColorUtil . colorize(ColorUtil . hyperlink( " revision: $commitId " , commitUrl) , " cyan" , true ))
369391 }
370392 if (showRevisionBrackets) {
371393 print (ColorUtil . colorize(" [" , " dim" , true ))
@@ -381,16 +403,19 @@ class LaunchCommandImpl extends BaseCommandImpl implements CmdLaunch.LaunchComma
381403
382404 // Print workspace
383405 if (orgName && workspaceName) {
384- println (" 🏢 workspace: ${ ColorUtil.colorize(orgName + ' / ' + workspaceName, 'cyan', true)} " )
406+ final workspaceText = ColorUtil . hyperlink(orgName + ' / ' + workspaceName, workspaceUrl)
407+ println (" 🏢 workspace: ${ ColorUtil.colorize(workspaceText, 'cyan', true)} " )
385408 } else {
386- println (" 🏢 workspace: ${ ColorUtil.colorize("Personal workspace", 'cyan', true)} " )
409+ final personalText = ColorUtil . hyperlink(" Personal workspace" , workspaceUrl)
410+ println (" 🏢 workspace: ${ ColorUtil.colorize(personalText, 'cyan', true)} " )
387411 }
388412
389413 // Print work directory
390414 println (" 📁 workdir: ${ ColorUtil.colorize(workDir, 'cyan', true)} " )
391415
392416 // Print compute environment
393- println (" ☁️ compute: ${ ColorUtil.colorize(computeEnvName, 'cyan', true)} \n " )
417+ final computeEnvText = ColorUtil . hyperlink(computeEnvName, computeEnvUrl)
418+ println (" ☁️ compute: ${ ColorUtil.colorize(computeEnvText, 'cyan', true)} \n " )
394419 } else {
395420 def plainMsg = " Launched `${ repo} ` [${ runName} ]"
396421 if (showRevision) {
@@ -945,6 +970,21 @@ class LaunchCommandImpl extends BaseCommandImpl implements CmdLaunch.LaunchComma
945970 }
946971 }
947972
973+ /**
974+ * Construct a browse URL for the given repository and commit ID using the SCM provider
975+ */
976+ protected String getCommitBrowseUrl (String pipelineName , String commitId ) {
977+ if (! pipelineName || ! commitId || commitId == ' unknown' )
978+ return null
979+ try {
980+ def assetManager = new AssetManager (pipelineName)
981+ return assetManager. getProvider()?. getBrowseUrl(commitId)
982+ } catch (Exception e) {
983+ log. debug " Failed to get commit browse URL: ${ e.message} "
984+ return null
985+ }
986+ }
987+
948988 // ===== API Helper Methods =====
949989
950990 protected Map apiGet (String path , Map queryParams = [:], String accessToken , String apiEndpoint ) {
0 commit comments