/*
┌──────────────────────────────────────────────────────────────────┐
│ Author: Ivan Murzak (https://github.com/IvanMurzak) │
│ Repository: GitHub (https://github.com/IvanMurzak/Unity-MCP) │
│ Copyright (c) 2025 Ivan Murzak │
│ Licensed under the Apache License, Version 2.0. │
│ See the LICENSE file in the project root for more information. │
└──────────────────────────────────────────────────────────────────┘
*/
#nullable enable
using System.Text;
using com.IvanMurzak.McpPlugin;
using com.IvanMurzak.McpPlugin.Skills;
using com.IvanMurzak.Unity.MCP.Editor.API;
using Microsoft.Extensions.Logging;
namespace com.IvanMurzak.Unity.MCP.Editor.Utils
{
///
/// Unity-specific skill file generator that emits unity-mcp-cli run-tool
/// commands instead of curl HTTP API calls in the "How to Call" section.
/// Authorization is handled automatically by the CLI (reads config file),
/// so the authorization example block is omitted.
///
public class UnitySkillFileGenerator : SkillFileGenerator
{
public UnitySkillFileGenerator() : base()
{
}
public UnitySkillFileGenerator(ILogger? logger = null) : base(logger)
{
}
///
/// Authorization is handled automatically by the CLI from the project config file.
/// No need to show a separate authorization example in SKILL.md.
///
public override bool IncludeAuthorizationExample => false;
///
/// Description is already in the YAML front-matter — skip the duplicate paragraph
/// after the title to save tokens.
///
public override bool IncludeDescriptionBody => false;
///
/// Descriptions are already shown in the parameter table — strip them from the
/// Input JSON Schema to save tokens.
///
public override bool IncludeInputSchemaPropertyDescriptions => false;
///
protected override void BuildHowToCallHeading(StringBuilder sb)
{
// sb.AppendLine("## Use command line");
// sb.AppendLine();
}
///
protected override void BuildToolCommand(StringBuilder sb, IRunTool tool, string host, string inputExample)
{
var command = tool.ToolType == McpToolType.System
? "run-system-tool"
: "run-tool";
sb.AppendLine("```bash");
sb.AppendLine($"unity-mcp-cli {command} {tool.Name} --input '{inputExample}'");
sb.AppendLine("```");
sb.AppendLine();
AppendInputFileHint(sb, tool, host, inputExample);
sb.AppendLine();
sb.AppendLine("### Troubleshooting");
sb.AppendLine();
sb.AppendLine("If `unity-mcp-cli` is not found, either install it globally (`npm install -g unity-mcp-cli`) or use `npx unity-mcp-cli` instead.");
sb.AppendLine($"Read the /{Skill_InitialSetup.SkillId} skill for detailed installation instructions.");
sb.AppendLine();
}
///
protected override void AppendInputFileHint(StringBuilder sb, IRunTool tool, string host, string inputExample)
{
if (inputExample == "{}")
return;
var command = tool.ToolType == McpToolType.System
? "run-system-tool"
: "run-tool";
sb.AppendLine($"> For complex input (multi-line strings, code), save the JSON to a file and use:");
sb.AppendLine("> ```bash");
sb.AppendLine($"> unity-mcp-cli {command} {tool.Name} --input-file args.json");
sb.AppendLine("> ```");
sb.AppendLine(">");
sb.AppendLine("> Or pipe via stdin (recommended):");
sb.AppendLine("> ```bash");
sb.AppendLine($"> unity-mcp-cli {command} {tool.Name} --input-file - <<'EOF'");
sb.AppendLine("> {\"param\": \"value\"}");
sb.AppendLine("> EOF");
sb.AppendLine("> ```");
sb.AppendLine();
}
}
}