diff --git a/scripts/powershell/setup-plan.ps1 b/scripts/powershell/setup-plan.ps1 index e179f0d160..0ebd591c87 100644 --- a/scripts/powershell/setup-plan.ps1 +++ b/scripts/powershell/setup-plan.ps1 @@ -48,7 +48,14 @@ if (Test-Path $paths.IMPL_PLAN -PathType Leaf) { Write-Output "Copied plan template to $($paths.IMPL_PLAN)" } } else { - Write-Warning "Plan template not found" + # Match the bash twin's wording and stream routing (stderr in -Json so + # stdout stays pure JSON, stdout otherwise), consistent with the sibling + # "Copied plan template" message above. + if ($Json) { + [Console]::Error.WriteLine("Warning: Plan template not found") + } else { + Write-Output "Warning: Plan template not found" + } # Create a basic plan file if template doesn't exist New-Item -ItemType File -Path $paths.IMPL_PLAN -Force | Out-Null } diff --git a/tests/test_setup_plan_no_overwrite.py b/tests/test_setup_plan_no_overwrite.py index ff19b1a0ac..b965551f2d 100644 --- a/tests/test_setup_plan_no_overwrite.py +++ b/tests/test_setup_plan_no_overwrite.py @@ -246,3 +246,27 @@ def test_ps_setup_plan_copied_message_on_stderr_in_json_mode(plan_repo: Path) -> data = json.loads(result.stdout) assert "IMPL_PLAN" in data assert "Copied plan template" in result.stderr + + +@pytest.mark.skipif(not (HAS_PWSH or _WINDOWS_POWERSHELL), reason="no PowerShell available") +def test_ps_setup_plan_template_not_found_warning_matches_bash(plan_repo: Path) -> None: + """When no plan template resolves, -Json mode must emit 'Warning: Plan template + not found' on stderr (matching the bash twin's wording and stream routing) while + keeping stdout pure JSON. Before the fix the PowerShell script used Write-Warning, + producing a different 'WARNING:' prefix on the warning stream instead.""" + # Remove the template the fixture installs so resolution finds nothing. + (plan_repo / ".specify" / "templates" / "plan-template.md").unlink() + script = plan_repo / ".specify" / "scripts" / "powershell" / "setup-plan.ps1" + exe = "pwsh" if HAS_PWSH else _WINDOWS_POWERSHELL + result = subprocess.run( + [exe, "-NoProfile", "-File", str(script), "-Json"], + cwd=plan_repo, + capture_output=True, + text=True, + check=False, + env=_clean_env(), + ) + assert result.returncode == 0, result.stderr + data = json.loads(result.stdout) + assert "IMPL_PLAN" in data + assert "Warning: Plan template not found" in result.stderr