mirror of
https://github.com/github/spec-kit.git
synced 2026-07-07 22:56:57 +08:00
fix(yaml): pin goose recipe prompt block-scalar indentation (#3343)
the goose recipe renderer emitted the prompt body under a bare '|' block scalar. yaml infers a plain block scalar's indentation from its first non-empty line, so a command body whose first line is itself indented (a markdown code block, a nested list item) made the parser expect that deeper indent for the whole block and reject the later, shallower lines - the generated .goose recipe then failed to parse. use an explicit '|2' indentation indicator so the block is always read at 2 spaces regardless of the body. added a regression test that round-trips an indented-first-line body through the yaml parser.
This commit is contained in:
@@ -1178,12 +1178,18 @@ class YamlIntegration(IntegrationBase):
|
||||
default_flow_style=False,
|
||||
).strip()
|
||||
|
||||
# Indent the body for YAML block scalar
|
||||
# Indent the body for YAML block scalar. Use an explicit indentation
|
||||
# indicator ("|2") rather than a bare "|": YAML infers a plain block
|
||||
# scalar's indentation from its first non-empty line, so a body whose
|
||||
# first line is itself indented (e.g. a markdown code block or a nested
|
||||
# list item) would make the parser expect that deeper indent for the
|
||||
# whole block and reject the later, less-indented lines. Pinning the
|
||||
# indent to 2 keeps the recipe parseable whatever the body looks like.
|
||||
indented = "\n".join(f" {line}" for line in body.split("\n"))
|
||||
|
||||
lines = [
|
||||
header_yaml,
|
||||
"prompt: |",
|
||||
"prompt: |2",
|
||||
indented,
|
||||
"",
|
||||
f"# Source: {source_id}",
|
||||
|
||||
@@ -184,6 +184,23 @@ class YamlIntegrationTests:
|
||||
assert "scripts:" not in parsed["prompt"]
|
||||
assert "---" not in parsed["prompt"]
|
||||
|
||||
def test_yaml_prompt_with_indented_first_line_stays_valid(self):
|
||||
"""A body whose first line is indented must still parse.
|
||||
|
||||
A bare ``|`` block scalar infers its indentation from the first
|
||||
non-empty line, so a body starting with an indented line (e.g. a
|
||||
markdown code block or nested list item) made the parser expect that
|
||||
deeper indent for the whole block and reject the later, shallower
|
||||
lines. The explicit ``|2`` indicator pins the indent so it parses."""
|
||||
body = " indented first line\nback to normal\n indented again"
|
||||
rendered = YamlIntegration._render_yaml("Title", "Desc", body, "src")
|
||||
|
||||
yaml_lines = [
|
||||
ln for ln in rendered.split("\n") if not ln.startswith("# Source:")
|
||||
]
|
||||
parsed = yaml.safe_load("\n".join(yaml_lines))
|
||||
assert parsed["prompt"].rstrip("\n") == body
|
||||
|
||||
def test_plan_command_has_no_context_placeholder(self, tmp_path):
|
||||
"""The generated plan command must not carry a context-file placeholder.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user