mirror of
https://github.com/github/spec-kit.git
synced 2026-08-15 14:02:04 +02:00
fix(workflows): keep the init step's documented ignore_agent_tools default on an explicit null (#3889)
The step documents the default twice:
class docstring: "Because workflows run unattended, the step defaults to
``--ignore-agent-tools``"
field docs: "Skip checks for the coding agent CLI (defaults to ``true``)"
It implements that with `config.get("ignore_agent_tools", True)`, which
applies the default only when the key is ABSENT. A bare
`ignore_agent_tools:` in YAML parses to None, and `_resolve_bool(None)`
returns False:
key ABSENT -> True flag emitted: YES
bare ignore_agent_tools: -> False flag emitted: NO <-- bug
explicit true -> True flag emitted: YES
explicit false -> False flag emitted: NO
So the flag is dropped, `specify init` re-runs the agent-CLI presence
check, and an unattended run fails with "Agent Detection Error" for any
integration whose CLI is not installed on the runner.
Normalize an explicit null to the default, mirroring the while/do-while
`max_iterations` handling.
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
b69147c841
commit
84a2114338
@@ -95,9 +95,17 @@ class InitStep(StepBase):
|
||||
|
||||
force = self._resolve_bool(config.get("force"), context)
|
||||
# Workflows run unattended; skip the agent CLI presence check by default.
|
||||
ignore_agent_tools = self._resolve_bool(
|
||||
config.get("ignore_agent_tools", True), context
|
||||
)
|
||||
# ``config.get(key, True)`` applies that default only when the key is
|
||||
# ABSENT: a bare ``ignore_agent_tools:`` in YAML parses to None, which
|
||||
# ``_resolve_bool`` then turns into False -- flipping the documented
|
||||
# default and re-enabling the agent-CLI presence check this step promises
|
||||
# to skip, so an unattended run fails with "Agent Detection Error" for
|
||||
# any integration whose CLI is not installed. Normalize an explicit null
|
||||
# to the default, mirroring the while/do-while ``max_iterations`` handling.
|
||||
raw_ignore_agent_tools = config.get("ignore_agent_tools")
|
||||
if raw_ignore_agent_tools is None:
|
||||
raw_ignore_agent_tools = True
|
||||
ignore_agent_tools = self._resolve_bool(raw_ignore_agent_tools, context)
|
||||
|
||||
argv: list[str] = ["init"]
|
||||
if here:
|
||||
|
||||
@@ -2176,6 +2176,59 @@ class TestInitStep:
|
||||
assert "--ignore-agent-tools" in argv
|
||||
assert (tmp_path / ".specify").is_dir()
|
||||
|
||||
def test_explicit_null_ignore_agent_tools_keeps_documented_default(
|
||||
self, tmp_path
|
||||
):
|
||||
"""A bare ``ignore_agent_tools:`` must keep the documented default.
|
||||
|
||||
The class docstring says "Because workflows run unattended, the step
|
||||
defaults to ``--ignore-agent-tools``" and the field docs say "defaults to
|
||||
``true``". But ``config.get(key, True)`` applies the default only when the
|
||||
key is ABSENT — a bare ``ignore_agent_tools:`` in YAML parses to None,
|
||||
which ``_resolve_bool`` turned into False, dropping the flag and
|
||||
re-enabling the agent-CLI presence check for an unattended run.
|
||||
"""
|
||||
from specify_cli.workflows.steps.init import InitStep
|
||||
from specify_cli.workflows.base import StepContext, StepStatus
|
||||
|
||||
step = InitStep()
|
||||
ctx = StepContext(
|
||||
project_root=str(tmp_path), default_integration="copilot"
|
||||
)
|
||||
result = step.execute(
|
||||
{
|
||||
"id": "bootstrap",
|
||||
"here": True,
|
||||
"script": "sh",
|
||||
"ignore_agent_tools": None,
|
||||
},
|
||||
ctx,
|
||||
)
|
||||
|
||||
assert result.status == StepStatus.COMPLETED
|
||||
assert "--ignore-agent-tools" in result.output["argv"]
|
||||
|
||||
def test_explicit_false_ignore_agent_tools_is_honoured(self, tmp_path):
|
||||
"""An explicit ``false`` must still opt in to the agent-CLI check."""
|
||||
from specify_cli.workflows.steps.init import InitStep
|
||||
from specify_cli.workflows.base import StepContext
|
||||
|
||||
step = InitStep()
|
||||
ctx = StepContext(
|
||||
project_root=str(tmp_path), default_integration="copilot"
|
||||
)
|
||||
result = step.execute(
|
||||
{
|
||||
"id": "bootstrap",
|
||||
"here": True,
|
||||
"script": "sh",
|
||||
"ignore_agent_tools": False,
|
||||
},
|
||||
ctx,
|
||||
)
|
||||
|
||||
assert "--ignore-agent-tools" not in result.output["argv"]
|
||||
|
||||
def test_default_integration_falls_back_to_workflow_default(self, tmp_path):
|
||||
from specify_cli.workflows.steps.init import InitStep
|
||||
from specify_cli.workflows.base import StepContext, StepStatus
|
||||
|
||||
Reference in New Issue
Block a user