Initial commit to new repository

This commit is contained in:
2026-04-03 18:22:19 +09:00
commit 4458bb0f52
7672 changed files with 452440 additions and 0 deletions

View File

@@ -0,0 +1,165 @@
using AxCopilot.Services.Agent;
using FluentAssertions;
using Xunit;
using System;
using System.IO;
using System.Reflection;
using System.Text;
namespace AxCopilot.Tests.Services;
public class SkillServiceRuntimePolicyTests
{
[Fact]
public void BuildRuntimeDirective_ReturnsEmpty_WhenNoRuntimeMetadata()
{
var skill = new SkillDefinition
{
Name = "plain-skill",
SystemPrompt = "do work"
};
var directive = SkillService.BuildRuntimeDirective(skill);
directive.Should().BeEmpty();
}
[Fact]
public void BuildRuntimeDirective_ContainsForkAgentEffortAndModelHints()
{
var skill = new SkillDefinition
{
Name = "advanced-skill",
ExecutionContext = "fork",
Agent = "worker",
Effort = "high",
Model = "gpt-5.4",
DisableModelInvocation = true,
AllowedTools = "Read, process, WebFetch",
Hooks = "lint-pre, verify-post",
HookFilters = "lint-pre@pre@file_edit, verify-post@post@*"
};
var directive = SkillService.BuildRuntimeDirective(skill);
directive.Should().Contain("[Skill Runtime Policy]");
directive.Should().Contain("execution_context: fork");
directive.Should().Contain("preferred_agent: worker");
directive.Should().Contain("reasoning_effort: high");
directive.Should().Contain("preferred_model: gpt-5.4");
directive.Should().Contain("allowed_tools: file_read, http_tool, process");
directive.Should().Contain("hook_names: lint-pre, verify-post");
directive.Should().Contain("hook_filters: lint-pre@pre@file_edit, verify-post@post@*");
directive.Should().Contain("disable_model_invocation");
}
[Fact]
public void ParseSkillFile_HooksMapAndList_AreNormalizedIntoHooksField()
{
var tempDir = Path.Combine(Path.GetTempPath(), "axcopilot-skill-hooks-" + Guid.NewGuid().ToString("N"));
Directory.CreateDirectory(tempDir);
var skillPath = Path.Combine(tempDir, "SKILL.md");
try
{
var content = """
---
name: hook-skill
hooks:
pre: lint-pre, verify-pre
post:
- verify-post
- report-post
---
body
""";
File.WriteAllText(skillPath, content, Encoding.UTF8);
var method = typeof(SkillService).GetMethod("ParseSkillFile", BindingFlags.NonPublic | BindingFlags.Static);
method.Should().NotBeNull();
var parsed = method!.Invoke(null, [skillPath]) as SkillDefinition;
parsed.Should().NotBeNull();
parsed!.Hooks.Should().Contain("lint-pre");
parsed.Hooks.Should().Contain("verify-pre");
parsed.Hooks.Should().Contain("verify-post");
parsed.Hooks.Should().Contain("report-post");
parsed.HookFilters.Should().Contain("lint-pre@pre@*");
parsed.HookFilters.Should().Contain("verify-pre@pre@*");
parsed.HookFilters.Should().Contain("*@post@*");
}
finally
{
try { if (Directory.Exists(tempDir)) Directory.Delete(tempDir, true); } catch { }
}
}
[Fact]
public void ParseSkillFile_NestedHooksMap_PreservesToolTimingFilters()
{
var tempDir = Path.Combine(Path.GetTempPath(), "axcopilot-skill-hooks-nested-" + Guid.NewGuid().ToString("N"));
Directory.CreateDirectory(tempDir);
var skillPath = Path.Combine(tempDir, "SKILL.md");
try
{
var content = """
---
name: nested-hook-skill
hooks:
file_edit:
pre:
- lint-pre
post: verify-post
---
body
""";
File.WriteAllText(skillPath, content, Encoding.UTF8);
var method = typeof(SkillService).GetMethod("ParseSkillFile", BindingFlags.NonPublic | BindingFlags.Static);
method.Should().NotBeNull();
var parsed = method!.Invoke(null, [skillPath]) as SkillDefinition;
parsed.Should().NotBeNull();
parsed!.Hooks.Should().Contain("lint-pre");
parsed.Hooks.Should().Contain("verify-post");
parsed.HookFilters.Should().Contain("lint-pre@pre@file_edit");
parsed.HookFilters.Should().Contain("verify-post@post@file_edit");
}
finally
{
try { if (Directory.Exists(tempDir)) Directory.Delete(tempDir, true); } catch { }
}
}
[Fact]
public void ParseSkillFile_SampleFlag_SetsIsSample()
{
var tempDir = Path.Combine(Path.GetTempPath(), "axcopilot-skill-sample-" + Guid.NewGuid().ToString("N"));
Directory.CreateDirectory(tempDir);
var skillPath = Path.Combine(tempDir, "SKILL.md");
try
{
var content = """
---
name: sample-skill
sample: true
---
body
""";
File.WriteAllText(skillPath, content, Encoding.UTF8);
var method = typeof(SkillService).GetMethod("ParseSkillFile", BindingFlags.NonPublic | BindingFlags.Static);
method.Should().NotBeNull();
var parsed = method!.Invoke(null, [skillPath]) as SkillDefinition;
parsed.Should().NotBeNull();
parsed!.IsSample.Should().BeTrue();
}
finally
{
try { if (Directory.Exists(tempDir)) Directory.Delete(tempDir, true); } catch { }
}
}
}