Editor/Drivers/PackagePublishDriver.cs

Editor utility that drives package publishing for a project. It validates the requested action (inspect_manifest, preflight, publish), prepares a ProjectPublisher, reports files to upload, and triggers publish with change details.

File AccessNetworking
#nullable enable
using System;
using System.Linq;
using System.Threading.Tasks;
using Sandbox;

namespace Editor.Mcp
{
	internal static class PackagePublishDriver
	{
		public static async Task<ToolOutcome<object>> PublishAsync( string action = "inspect_manifest", string? changeTitle = null, string? changeDetail = null )
		{
			var project = Project.Current;
			if ( project == null )
			{
				return ToolOutcome<object>.Failure( null, ToolStatus.Unavailable, "publish.no_project", "No active project loaded." );
			}

			var normAction = (action ?? "").ToLowerInvariant().Trim();
			if ( normAction == "status" || string.IsNullOrWhiteSpace( normAction ) )
			{
				normAction = "inspect_manifest";
			}

			if ( normAction != "inspect_manifest" && normAction != "preflight" && normAction != "publish" )
			{
				return ToolOutcome<object>.Failure( null, ToolStatus.Failed, "publish.invalid_action", $"Unsupported action '{action}'. Use inspect_manifest, preflight, or publish." );
			}

			ProjectPublisher? publisher = null;
			try
			{
				publisher = await ProjectPublisher.FromProject( project );
				if ( publisher != null )
				{
					await publisher.PrePublish();
				}
			}
			catch ( Exception ex )
			{
				return ToolOutcome<object>.Degraded( new
				{
					Project = project.Config.Ident,
					FullIdent = $"{project.Config.Org}.{project.Config.Ident}",
					Action = normAction,
					Notice = "Facepunch Cloud publisher pre-flight degraded or offline."
				}, "publish.cloud_auth_or_network", "Could not query Facepunch Cloud package status: network or authentication unavailable.", ex.Message );
			}

			if ( publisher == null )
			{
				return ToolOutcome<object>.Failure( null, ToolStatus.Unavailable, "publish.publisher_unavailable", "Could not initialize ProjectPublisher for current project." );
			}

			var files = publisher.Files.Select( f => new
			{
				Name = f.Name,
				Size = f.Size,
				Skip = f.Skip
			} ).ToArray();

			if ( normAction == "inspect_manifest" || normAction == "preflight" )
			{
				return ToolOutcome<object>.Ready( new
				{
					Action = normAction,
					Project = project.Config.Ident,
					FullIdent = $"{project.Config.Org}.{project.Config.Ident}",
					TotalFiles = files.Length,
					FilesToUpload = files.Count( f => !f.Skip ),
					SampleFiles = files.Take( 20 ).ToArray(),
					ReadyToPublish = true
				} );
			}

			if ( normAction == "publish" )
			{
				var title = string.IsNullOrWhiteSpace( changeTitle ) ? $"Changes on {DateTime.UtcNow:yyyy-MM-dd}" : changeTitle;
				publisher.SetChangeDetails( title, changeDetail ?? "" );
				await publisher.Publish();

				return ToolOutcome<object>.Ready( new
				{
					Action = "publish",
					Project = project.Config.Ident,
					ChangeTitle = title,
					Published = true
				} );
			}

			return ToolOutcome<object>.Failure( null, ToolStatus.Failed, "publish.invalid_action", $"Unsupported action '{action}'. Use inspect_manifest, preflight, or publish." );
		}
	}
}