diff options
Diffstat (limited to 'scripts')
| -rw-r--r-- | scripts/E2EClient/Program.cs | 2 | ||||
| -rw-r--r-- | scripts/Operational-E2E.ps1 | 34 | ||||
| -rw-r--r-- | scripts/Publish-Release.ps1 | 4 | ||||
| -rw-r--r-- | scripts/Restart-PublishedServer.ps1 | 2 | ||||
| -rw-r--r-- | scripts/Run-Final-ElevatedVerification.ps1 | 4 | ||||
| -rw-r--r-- | scripts/Verify-PublishedHttp.ps1 | 15 | ||||
| -rw-r--r-- | scripts/Verify-Readme.ps1 | 261 |
7 files changed, 98 insertions, 224 deletions
diff --git a/scripts/E2EClient/Program.cs b/scripts/E2EClient/Program.cs index ee7bb75..8733cdf 100644 --- a/scripts/E2EClient/Program.cs +++ b/scripts/E2EClient/Program.cs @@ -13,7 +13,7 @@ IClientTransport transport = args[0] == "stdio" { Name = "agent-mcp-operational-e2e", Command = Path.GetFullPath(args[1]), - Arguments = ["serve", "--config", Path.GetFullPath(args[2]), "--lang", "ja", "--transport", "stdio"], + Arguments = [Path.GetFullPath(args[2])], WorkingDirectory = Path.GetDirectoryName(Path.GetFullPath(args[1]))! }) : new HttpClientTransport(new HttpClientTransportOptions diff --git a/scripts/Operational-E2E.ps1 b/scripts/Operational-E2E.ps1 index b253198..cea1c75 100644 --- a/scripts/Operational-E2E.ps1 +++ b/scripts/Operational-E2E.ps1 @@ -17,8 +17,7 @@ $bundleRoot = Join-Path $root 'bundle' $fixture = Join-Path $root 'fixture' $alias = 'python-e2e-' + [Guid]::NewGuid().ToString('N').Substring(0, 12) $passed = $false -$approved = $false -$resolutionStorePath = $null +$appliedStorePath = $null $server = $null New-Item -ItemType Directory -Path $bundleRoot,$fixture | Out-Null $fixtureAclBefore = (Get-Acl -LiteralPath $fixture).Sddl @@ -40,6 +39,8 @@ try { $pythonVersion = (& $python --version 2>&1 | Out-String).Trim() if ($pythonVersion -notmatch '^Python 3\.14\.') { throw "Operational E2E requires Python 3.14; resolved '$pythonVersion'." } $runtimeRoot = Split-Path $python + $pythonYaml = $pythonLogical.Replace('\','/') + $runtimeYaml = $runtimeRoot.Replace('\','/') Set-Content -LiteralPath (Join-Path $fixture 'README.md') -Encoding utf8NoBOM -Value @' # Graph metrics fixture @@ -50,7 +51,7 @@ produce a deterministic topological order, detect cycles, and calculate the weig $fixtureYaml = $fixture.Replace('\','/') $config = @" -schema_version: 1 +schema_version: 2 application: language: ja mcp: @@ -83,9 +84,10 @@ sandbox: - $fixtureYaml mounts: [] execution: - executables: - - $alias - shells: [] + entries: + - alias: $alias + path: $pythonYaml + runtime_root: $runtimeYaml network: access: none local_endpoints: [] @@ -112,15 +114,12 @@ logging: "@ Set-Content -LiteralPath $configPath -Value $config -Encoding utf8NoBOM - & $agent executable approve $alias --path $pythonLogical --runtime-root $runtimeRoot --yes --config $configPath --lang en - if ($LASTEXITCODE -ne 0) { throw 'Executable approval failed.' } - $approved = $true - & $agent sandbox confirm --yes --config $configPath --lang en - if ($LASTEXITCODE -ne 0) { throw 'Sandbox Environment Resolution confirmation failed.' } + & $agent apply $configPath --yes + if ($LASTEXITCODE -ne 0) { throw 'Applied Configuration failed.' } $normalizedConfig = [IO.Path]::GetFullPath($configPath).ToUpperInvariant() $hash = [Convert]::ToHexString([Security.Cryptography.SHA256]::HashData([Text.Encoding]::UTF8.GetBytes($normalizedConfig))) - $resolutionStorePath = Join-Path $env:LOCALAPPDATA "AgentSandboxMcp\environment-resolutions\$hash.json" - & $agent sandbox show --format json --config $configPath --lang en | Out-Null + $appliedStorePath = Join-Path $env:LOCALAPPDATA "AgentSandboxMcp\applied-configurations\$hash.json" + & $agent show $configPath | Out-Null if ($LASTEXITCODE -ne 0) { throw 'Effective Sandbox Policy show failed.' } $request = @" @@ -138,7 +137,7 @@ README.md の読取後、2ファイルの作成、最初のテスト実行、失 if ($LASTEXITCODE -ne 0) { throw 'E2E stdio client failed.' } } else { - $server = Start-Process -FilePath $agent -ArgumentList @('serve','--config',$configPath,'--lang','ja','--transport','http') -WorkingDirectory $bundle -WindowStyle Hidden -PassThru + $server = Start-Process -FilePath $agent -ArgumentList @($configPath) -WorkingDirectory $bundle -WindowStyle Hidden -PassThru $httpAuthority = if ($HttpHost -eq '::1') { '[::1]' } else { $HttpHost } $endpoint = "http://${httpAuthority}:18080/mcp" $ready = $false @@ -183,11 +182,8 @@ catch { } finally { if ($server -and -not $server.HasExited) { $server.Kill($true); $server.WaitForExit() } - if ($approved -and (Test-Path -LiteralPath $agent)) { - & $agent executable revoke $alias --yes --config $configPath --lang en | Out-Null - } - if ($resolutionStorePath -and (Test-Path -LiteralPath $resolutionStorePath)) { - Remove-Item -LiteralPath $resolutionStorePath -Force + if ($appliedStorePath -and (Test-Path -LiteralPath $appliedStorePath)) { + Remove-Item -LiteralPath $appliedStorePath -Force } if ($passed -and (Test-Path -LiteralPath $root)) { Remove-Item -LiteralPath $root -Recurse -Force } } diff --git a/scripts/Publish-Release.ps1 b/scripts/Publish-Release.ps1 index d794bb5..41bdfa3 100644 --- a/scripts/Publish-Release.ps1 +++ b/scripts/Publish-Release.ps1 @@ -66,8 +66,8 @@ try { if (-not $SkipRuntimeCheck) { Push-Location $freshBundle try { - & .\agent-mcp.exe sandbox resolve --config .\agent.yaml --lang en - if ($LASTEXITCODE -ne 0) { throw "Bundle resolution check failed with exit code $LASTEXITCODE." } + & .\agent-mcp.exe show .\agent.yaml + if ($LASTEXITCODE -ne 0) { throw "Bundle configuration check failed with exit code $LASTEXITCODE." } } finally { Pop-Location } } diff --git a/scripts/Restart-PublishedServer.ps1 b/scripts/Restart-PublishedServer.ps1 index 58dd928..d4386f4 100644 --- a/scripts/Restart-PublishedServer.ps1 +++ b/scripts/Restart-PublishedServer.ps1 @@ -26,5 +26,5 @@ if ($StopOnly) { exit 0 } if (-not (Test-Path -LiteralPath $agent) -or -not (Test-Path -LiteralPath $configuration)) { throw 'Published agent-mcp executable or configuration is missing.' } -$started = Start-Process -FilePath $agent -ArgumentList @('serve', '--config', $configuration) -WorkingDirectory $bundle -WindowStyle Hidden -PassThru +$started = Start-Process -FilePath $agent -ArgumentList @($configuration) -WorkingDirectory $bundle -WindowStyle Hidden -PassThru Write-Output "Started published agent-mcp PID $($started.Id)." diff --git a/scripts/Run-Final-ElevatedVerification.ps1 b/scripts/Run-Final-ElevatedVerification.ps1 index 627bd65..71135c2 100644 --- a/scripts/Run-Final-ElevatedVerification.ps1 +++ b/scripts/Run-Final-ElevatedVerification.ps1 @@ -47,8 +47,8 @@ $windowsTests = Join-Path $repository 'build\Release\Agent.Windows.Tests\net10.0 $coreTests = Join-Path $repository 'build\Release\Agent.Core.Tests\net10.0-windows10.0.26100.0\Agent.Core.Tests.exe' $plannerTests = Join-Path $repository 'build\Release\Agent.Planner.Tests\net10.0\Agent.Planner.Tests.exe' -Invoke-VerificationStep 'bundle-check' { - & (Join-Path $bundle 'agent-mcp.exe') check --config (Join-Path $bundle 'agent.yaml') --lang en +Invoke-VerificationStep 'bundle-show' { + & (Join-Path $bundle 'agent-mcp.exe') show (Join-Path $bundle 'agent.yaml') } Invoke-VerificationStep 'windows-security-tests' { & $windowsTests } Invoke-VerificationStep 'core-unit-integration-tests' { & $coreTests } diff --git a/scripts/Verify-PublishedHttp.ps1 b/scripts/Verify-PublishedHttp.ps1 index a02a28b..7dd5fe2 100644 --- a/scripts/Verify-PublishedHttp.ps1 +++ b/scripts/Verify-PublishedHttp.ps1 @@ -29,6 +29,8 @@ $runRoot = Join-Path $testRootPath ('agent-mcp-http-cmd-' + [Guid]::NewGuid().To $runRootForward = $runRoot.Replace('\', '/') $endpoint = 'http://127.0.0.1:8080/mcp' $log = Join-Path $evidence 'verification.log' +$serverOut = Join-Path $evidence 'server.stdout.log' +$serverErr = Join-Path $evidence 'server.stderr.log' $server = $null New-Item -ItemType Directory -Force -Path $evidence | Out-Null New-Item -ItemType Directory -Path $runRoot | Out-Null @@ -47,14 +49,17 @@ run-probe.cmdは次を順番に実行し、どれかが失敗したら非0で終 "@ try { - & $agent check --config $config --lang ja 2>&1 | Tee-Object -FilePath $log - if ($LASTEXITCODE -ne 0) { throw "Published check failed with exit code $LASTEXITCODE." } + & $agent show $config 2>&1 | Tee-Object -FilePath $log + if ($LASTEXITCODE -ne 0) { throw "Published configuration show failed with exit code $LASTEXITCODE." } - $server = Start-Process -FilePath $agent -ArgumentList @('serve','--config',$config,'--lang','ja','--transport','http') ` - -WorkingDirectory $bundle -WindowStyle Hidden -PassThru + $server = Start-Process -FilePath $agent -ArgumentList @($config) -WorkingDirectory $bundle ` + -WindowStyle Hidden -RedirectStandardOutput $serverOut -RedirectStandardError $serverErr -PassThru $ready = $false for ($attempt = 0; $attempt -lt 100; $attempt++) { - if ($server.HasExited) { throw "Published server exited before readiness: $($server.ExitCode)" } + if ($server.HasExited) { + $diagnostic = if (Test-Path -LiteralPath $serverErr) { Get-Content -LiteralPath $serverErr -Raw } else { '' } + throw "Published server exited before readiness: $($server.ExitCode) $diagnostic" + } try { $response = Invoke-WebRequest -Uri $endpoint -Method Get -SkipHttpErrorCheck if ($response.StatusCode -eq 405) { $ready = $true; break } diff --git a/scripts/Verify-Readme.ps1 b/scripts/Verify-Readme.ps1 index f67f640..42c8b8f 100644 --- a/scripts/Verify-Readme.ps1 +++ b/scripts/Verify-Readme.ps1 @@ -1,255 +1,128 @@ param( - [Parameter(Mandatory)] - [string]$TestRoot, - [Parameter(Mandatory)] - [string]$VenvPython, + [Parameter(Mandatory)][string]$TestRoot, + [Parameter(Mandatory)][string]$VenvPython, [string]$EvidenceRoot = 'artifacts\evidence\readme-verification', [switch]$CliOnly ) $ErrorActionPreference = 'Stop' -$OutputEncoding = [Text.UTF8Encoding]::new($false) -[Console]::OutputEncoding = $OutputEncoding $repository = (Resolve-Path (Join-Path $PSScriptRoot '..')).Path $testRootPath = (Resolve-Path -LiteralPath $TestRoot).Path $venvPythonPath = (Resolve-Path -LiteralPath $VenvPython).Path $evidence = [IO.Path]::GetFullPath((Join-Path $repository $EvidenceRoot)) -if (-not $evidence.StartsWith($repository + [IO.Path]::DirectorySeparatorChar, [StringComparison]::OrdinalIgnoreCase)) { - throw 'Evidence output must remain inside the repository.' -} -$administrator = ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole( - [Security.Principal.WindowsBuiltInRole]::Administrator) -if (-not $administrator -and -not $CliOnly) { throw 'README verification must run as Windows Administrator unless -CliOnly is specified.' } -if (-not (Test-Path -LiteralPath $venvPythonPath -PathType Leaf)) { throw 'VenvPython must be an existing file.' } +if (-not $evidence.StartsWith($repository + [IO.Path]::DirectorySeparatorChar, [StringComparison]::OrdinalIgnoreCase)) { throw 'Evidence output must remain inside the repository.' } +$administrator = ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator) +if (-not $administrator -and -not $CliOnly) { throw 'README operational verification must run as Windows Administrator.' } $pwshPath = (Get-Command pwsh.exe -ErrorAction Stop).Source -$pwshRuntime = Split-Path $pwshPath $cmdPath = $env:ComSpec $venvRoot = Split-Path (Split-Path $venvPythonPath) -$pyvenv = Get-Content -LiteralPath (Join-Path $venvRoot 'pyvenv.cfg') -$pythonRuntime = (($pyvenv | Where-Object { $_ -match '^home\s*=' }) -split '=', 2)[1].Trim() -if (-not (Test-Path -LiteralPath $pythonRuntime -PathType Container)) { throw "Python Runtime Root does not exist: $pythonRuntime" } +$pythonRuntime = (((Get-Content -LiteralPath (Join-Path $venvRoot 'pyvenv.cfg')) | Where-Object { $_ -match '^home\s*=' }) -split '=', 2)[1].Trim() $basePythonPath = Join-Path $pythonRuntime 'python.exe' if (-not (Test-Path -LiteralPath $basePythonPath -PathType Leaf)) { throw "Base Python does not exist: $basePythonPath" } New-Item -ItemType Directory -Force -Path $evidence | Out-Null -$runRoot = Join-Path $testRootPath ('agent-mcp-readme-cli-' + [Guid]::NewGuid().ToString('N')) +$runRoot = Join-Path $testRootPath ('agent-mcp-readme-' + [Guid]::NewGuid().ToString('N')) New-Item -ItemType Directory -Path $runRoot | Out-Null $agent = Join-Path $repository 'build\Release\Agent.App\net10.0-windows10.0.26100.0\agent-mcp.exe' $windowsTests = Join-Path $repository 'build\Release\Agent.Windows.Tests\net10.0-windows10.0.26100.0\Agent.Windows.Tests.exe' $configPath = Join-Path $runRoot 'agent.yaml' $logPath = Join-Path $evidence 'verification.log' -$failed = $false -$aliases = @( - ('readme-python-' + [Guid]::NewGuid().ToString('N').Substring(0, 8)) - ('readme-powershell-' + [Guid]::NewGuid().ToString('N').Substring(0, 8)) - ('readme-cmd-' + [Guid]::NewGuid().ToString('N').Substring(0, 8)) -) -$pythonAlias, $powershellAlias, $cmdAlias = $aliases -$listener = [Net.Sockets.TcpListener]::new([Net.IPAddress]::Loopback, 0) -$listener.Start() -$httpPort = ([Net.IPEndPoint]$listener.LocalEndpoint).Port -$listener.Stop() -$resolutionStorePath = $null $server = $null +$failed = $false -function Invoke-Step { - param([string]$Name, [scriptblock]$Action) +function Invoke-Step([string]$Name, [scriptblock]$Action) { "START $Name $(Get-Date -Format o)" | Tee-Object -FilePath $logPath -Append try { $global:LASTEXITCODE = 0 & $Action *>&1 | Tee-Object -FilePath $logPath -Append if ($LASTEXITCODE -ne 0) { throw "$Name exited with $LASTEXITCODE" } - "PASS $Name $(Get-Date -Format o)" | Tee-Object -FilePath $logPath -Append - } - catch { - $_ | Out-String | Tee-Object -FilePath $logPath -Append - $script:failed = $true - "FAIL $Name $(Get-Date -Format o)" | Tee-Object -FilePath $logPath -Append - } + "PASS $Name" | Tee-Object -FilePath $logPath -Append + } catch { $script:failed = $true; "FAIL $Name $($_.Exception.Message)" | Tee-Object -FilePath $logPath -Append } } -function Invoke-ExpectedFailure { - param([string]$Name, [string[]]$Arguments) - "START $Name $(Get-Date -Format o)" | Tee-Object -FilePath $logPath -Append +function Invoke-ExpectedFailure([string]$Name, [string[]]$Arguments) { & $agent @Arguments *>&1 | Tee-Object -FilePath $logPath -Append - if ($LASTEXITCODE -ne 2) { - $script:failed = $true - "FAIL $Name expected_exit=2 actual_exit=$LASTEXITCODE" | Tee-Object -FilePath $logPath -Append - } - else { "PASS $Name expected_exit=2" | Tee-Object -FilePath $logPath -Append } -} - -function Start-And-ProbeServer { - param([bool]$ExplicitServe) - $arguments = if ($ExplicitServe) { - @('serve', '--config', $configPath, '--lang', 'ja', '--transport', 'http') - } else { - @('--config', $configPath, '--lang', 'ja', '--transport', 'http') - } - $script:server = Start-Process -FilePath $agent -ArgumentList $arguments -WorkingDirectory (Split-Path $agent) -WindowStyle Hidden -PassThru - $endpoint = "http://127.0.0.1:$httpPort/mcp" - for ($attempt = 0; $attempt -lt 100; $attempt++) { - if ($script:server.HasExited) { throw "Server exited before becoming ready: $($script:server.ExitCode)" } - try { - $response = Invoke-WebRequest -Uri $endpoint -Method Get -SkipHttpErrorCheck - if ($response.StatusCode -eq 405) { return } - } catch { } - Start-Sleep -Milliseconds 100 - } - throw 'Server did not become ready.' + if ($LASTEXITCODE -ne 2) { $script:failed = $true; "FAIL $Name expected=2 actual=$LASTEXITCODE" | Tee-Object -FilePath $logPath -Append } + else { "PASS $Name" | Tee-Object -FilePath $logPath -Append } } try { - $forwardRoot = $testRootPath.Replace('\', '/') - $forwardPrompt = (Join-Path $repository 'prompts\user-system.md').Replace('\', '/') - $forwardSkills = (Join-Path $repository 'skills').Replace('\', '/') - $forwardLocales = (Join-Path $repository 'config\locales').Replace('\', '/') - $forwardLogs = (Join-Path $runRoot 'logs').Replace('\', '/') + $listener = [Net.Sockets.TcpListener]::new([Net.IPAddress]::Loopback, 0); $listener.Start() + $httpPort = ([Net.IPEndPoint]$listener.LocalEndpoint).Port; $listener.Stop() + $forwardRoot = $testRootPath.Replace('\','/') + $forwardPrompt = (Join-Path $repository 'prompts\user-system.md').Replace('\','/') + $forwardSkills = (Join-Path $repository 'skills').Replace('\','/') + $forwardLocales = (Join-Path $repository 'config\locales').Replace('\','/') + $forwardLogs = (Join-Path $runRoot 'logs').Replace('\','/') + $pythonYaml = $basePythonPath.Replace('\','/'); $runtimeYaml = $pythonRuntime.Replace('\','/') + $pwshYaml = $pwshPath.Replace('\','/'); $cmdYaml = $cmdPath.Replace('\','/') @" -schema_version: 1 -application: - language: en +schema_version: 2 +application: { language: en } mcp: transport: http - http: - host: 127.0.0.1 - port: $httpPort - images: - max_count: 4 - max_bytes_each: 10485760 - max_total_bytes: 20971520 - tasks: - time_to_live_hours: 24 - poll_interval_ms: 1000 -agent: - user_system_prompt: $forwardPrompt - max_iterations: 8 - same_failure_limit: 2 -ollama: - endpoint: http://127.0.0.1:11434 - model: deepseek-v4-flash:cloud - think: true - keep_alive: 5m - options: - num_ctx: 32768 - temperature: 0 - extra_options: {} -planner: - max_tasks: 8 + http: { host: 127.0.0.1, port: $httpPort } +agent: { user_system_prompt: $forwardPrompt, max_iterations: 8, same_failure_limit: 2 } +ollama: { endpoint: 'http://127.0.0.1:11434', model: 'deepseek-v4-flash:cloud', think: true } +planner: { max_tasks: 8 } sandbox: profile: development - workspaces: - - $forwardRoot + workspaces: [$forwardRoot] mounts: [] execution: - executables: - - $pythonAlias - shells: - - $powershellAlias - - $cmdAlias - network: - access: none - local_endpoints: [] - restricted_endpoints: [] - resources: - profile: constrained -file_edit: - memory_backup_limit_mb: 16 -limits: - whole_read_bytes: 1048576 - search_max_results: 1000 - tail_max_lines: 10000 - context_summary_ratio: 0.8 -localization: - directory: $forwardLocales - fallback: en -skills: - directory: $forwardSkills -logging: - directory: $forwardLogs - level: information - http_requests: true - max_file_bytes: 10485760 - retained_files: 5 + entries: + - { alias: python, path: $pythonYaml, runtime_root: $runtimeYaml } + - { alias: powershell, path: '$pwshYaml' } + - { alias: cmd, path: $cmdYaml } + network: { access: none, local_endpoints: [], restricted_endpoints: [] } + resources: { profile: constrained } +localization: { directory: $forwardLocales, fallback: en } +skills: { directory: $forwardSkills } +logging: { directory: $forwardLogs, level: information, max_file_bytes: 10485760, retained_files: 5 } "@ | Set-Content -LiteralPath $configPath -Encoding utf8NoBOM - @( - "timestamp=$(Get-Date -Format o)", - "commit=$(git -C $repository rev-parse HEAD)", - "administrator=$administrator", - "os=$([Environment]::OSVersion.VersionString)", - "venv_python=$venvPythonPath", - "venv_version=$(& $venvPythonPath --version)", - "powershell=$pwshPath", - "cmd=$cmdPath" - ) | Set-Content -LiteralPath (Join-Path $evidence 'metadata.txt') -Encoding utf8NoBOM - - Invoke-Step 'cli-sandbox-resolve' { & $agent sandbox resolve --config $configPath --lang ja } - Invoke-Step 'cli-sandbox-confirm-yes' { & $agent sandbox confirm --yes --config $configPath --lang ja } $normalizedConfig = [IO.Path]::GetFullPath($configPath).ToUpperInvariant() $hash = [Convert]::ToHexString([Security.Cryptography.SHA256]::HashData([Text.Encoding]::UTF8.GetBytes($normalizedConfig))) - $resolutionStorePath = Join-Path $env:LOCALAPPDATA "AgentSandboxMcp\environment-resolutions\$hash.json" - Invoke-Step 'cli-executable-resolve-path' { & $agent executable resolve $pythonAlias --path $basePythonPath --config $configPath --lang ja } - Invoke-Step 'cli-executable-approve-runtime-root-yes' { & $agent executable approve $pythonAlias --path $basePythonPath --runtime-root $pythonRuntime --yes --config $configPath --lang ja } - Invoke-Step 'cli-shell-resolve-powershell' { & $agent executable resolve $powershellAlias --path $pwshPath --config $configPath --lang en } - Invoke-Step 'cli-shell-approve-runtime-root-yes' { & $agent executable approve $powershellAlias --path $pwshPath --runtime-root $pwshRuntime --yes --config $configPath --lang en } - Invoke-Step 'cli-shell-resolve-cmd' { & $agent executable resolve $cmdAlias --path $cmdPath --config $configPath --lang en } - Invoke-Step 'cli-shell-approve-cmd-no-runtime' { & $agent executable approve $cmdAlias --path $cmdPath --no-runtime --yes --config $configPath --lang en } - Invoke-Step 'cli-executable-list' { & $agent executable list --config $configPath --lang ja } - Invoke-Step 'cli-sandbox-show-text-default-format' { & $agent sandbox show --config $configPath --lang en } - Invoke-Step 'cli-sandbox-show-json' { & $agent sandbox show --format json --config $configPath --lang ja } - if ($CliOnly) { - Invoke-ExpectedFailure 'cli-check-detects-non-admin' @('check', '--config', $configPath, '--lang', 'ja') - } - else { - Invoke-Step 'cli-check' { & $agent check --config $configPath --lang ja } - } + $appliedStorePath = Join-Path $env:LOCALAPPDATA "AgentSandboxMcp\applied-configurations\$hash.json" - Invoke-ExpectedFailure 'cli-invalid-transport' @('serve', '--config', $configPath, '--transport', 'invalid') - Invoke-ExpectedFailure 'cli-invalid-format' @('sandbox', 'show', '--format', 'xml', '--config', $configPath) - Invoke-ExpectedFailure 'cli-management-missing-config' @('sandbox', 'resolve') - Invoke-ExpectedFailure 'cli-mutually-exclusive-runtime-options' @('executable', 'approve', $pythonAlias, '--path', $basePythonPath, '--runtime-root', $pythonRuntime, '--no-runtime', '--config', $configPath) + Invoke-Step 'cli-show-before-apply' { & $agent show $configPath } + Invoke-Step 'cli-apply-yes' { & $agent apply $configPath --yes } + Invoke-Step 'cli-show-applied' { & $agent show $configPath } + Invoke-ExpectedFailure 'removed-serve' @('serve') + Invoke-ExpectedFailure 'removed-check' @('check') + Invoke-ExpectedFailure 'removed-config-option' @('--config', $configPath) + Invoke-ExpectedFailure 'removed-language-option' @('--lang', 'ja') + Invoke-ExpectedFailure 'removed-transport-option' @('--transport', 'http') + Invoke-ExpectedFailure 'removed-executable-command' @('executable', 'list') + Invoke-ExpectedFailure 'removed-sandbox-command' @('sandbox', 'show') if (-not $CliOnly) { - Invoke-Step 'cli-serve-explicit-http' { - Start-And-ProbeServer $true - $script:server.Kill($true) - $script:server.WaitForExit() - $script:server = $null - } - Invoke-Step 'cli-serve-implicit-option-first' { - Start-And-ProbeServer $false - $script:server.Kill($true) - $script:server.WaitForExit() - $script:server = $null + Invoke-Step 'implicit-http-start' { + $script:server = Start-Process -FilePath $agent -ArgumentList @($configPath) -WorkingDirectory (Split-Path $agent) -WindowStyle Hidden -PassThru + $endpoint = "http://127.0.0.1:$httpPort/mcp" + for ($attempt=0; $attempt -lt 100; $attempt++) { + if ($script:server.HasExited) { throw "Server exited: $($script:server.ExitCode)" } + try { $response = Invoke-WebRequest -Uri $endpoint -Method Get -SkipHttpErrorCheck; if ($response.StatusCode -eq 405) { break } } catch { } + Start-Sleep -Milliseconds 100 + } + if ($attempt -eq 100) { throw 'Server did not become ready.' } + $script:server.Kill($true); $script:server.WaitForExit(); $script:server = $null } - $env:AGENT_MCP_MONKEY_ROOT = $testRootPath $env:AGENT_MCP_TEST_VENV_PYTHON = $venvPythonPath $env:AGENT_MCP_TEST_POWERSHELL = $pwshPath - $env:AGENT_MCP_TEST_POWERSHELL_RUNTIME = $pwshRuntime + $env:AGENT_MCP_TEST_POWERSHELL_RUNTIME = Split-Path $pwshPath $env:AGENT_MCP_TEST_CMD = $cmdPath - Invoke-Step 'readme-operational-windows-tests' { - & $windowsTests -class Agent.Windows.Tests.ReadmeOperationalTests -parallel none -failSkips - } + Invoke-Step 'readme-operational-windows-tests' { & $windowsTests -class Agent.Windows.Tests.ReadmeOperationalTests -parallel none -failSkips } } - Invoke-Step 'cli-executable-revoke-python' { & $agent executable revoke $pythonAlias --yes --config $configPath --lang ja } - Invoke-Step 'cli-executable-revoke-powershell' { & $agent executable revoke $powershellAlias --yes --config $configPath --lang en } - Invoke-Step 'cli-executable-revoke-cmd' { & $agent executable revoke $cmdAlias --yes --config $configPath --lang en } -} -finally { +} finally { if ($server -and -not $server.HasExited) { $server.Kill($true); $server.WaitForExit() } - foreach ($alias in $aliases) { - & $agent executable revoke $alias --yes --config $configPath --lang en 2>$null | Out-Null - } - if ($resolutionStorePath -and (Test-Path -LiteralPath $resolutionStorePath)) { Remove-Item -LiteralPath $resolutionStorePath -Force } + if ($appliedStorePath -and (Test-Path -LiteralPath $appliedStorePath)) { Remove-Item -LiteralPath $appliedStorePath -Force } if (Test-Path -LiteralPath $runRoot) { - $resolvedRunRoot = (Resolve-Path -LiteralPath $runRoot).Path - if (-not $resolvedRunRoot.StartsWith($testRootPath.TrimEnd('\') + '\', [StringComparison]::OrdinalIgnoreCase)) { - throw 'Refusing to clean a test directory outside TestRoot.' - } - Remove-Item -LiteralPath $resolvedRunRoot -Recurse -Force + $resolved = (Resolve-Path -LiteralPath $runRoot).Path + if (-not $resolved.StartsWith($testRootPath.TrimEnd('\') + '\', [StringComparison]::OrdinalIgnoreCase)) { throw 'Refusing to clean outside TestRoot.' } + Remove-Item -LiteralPath $resolved -Recurse -Force } Remove-Item Env:AGENT_MCP_MONKEY_ROOT,Env:AGENT_MCP_TEST_VENV_PYTHON,Env:AGENT_MCP_TEST_POWERSHELL,Env:AGENT_MCP_TEST_POWERSHELL_RUNTIME,Env:AGENT_MCP_TEST_CMD -ErrorAction SilentlyContinue } |
