Fix Alquimia argument hints after folded descriptions (#4063)

Co-authored-by: root <kinsonnee@gmail.com>
This commit is contained in:
WOLIKIMCHENG
2026-08-13 00:13:02 +08:00
committed by GitHub
parent c1bceb625c
commit b77ca572ca
2 changed files with 121 additions and 2 deletions
@@ -65,7 +65,16 @@ class AlquimiaAIIntegration(SkillsIntegration):
@staticmethod
def inject_argument_hint(content: str, hint: str) -> str:
"""Insert ``argument-hint`` after the first ``description:`` in YAML frontmatter.
"""Insert ``argument-hint`` after the ``description:`` scalar in YAML frontmatter.
A long ``description`` gets folded by the YAML dumper across
indented continuation lines (plain or quoted), and an embedded
paragraph break can add unindented blank lines inside a quoted
scalar. Inserting the new line right after the *first* line of
that scalar — instead of after the whole scalar — either produces
invalid YAML or gets silently absorbed into the description
string (#4044), so every continuation line (indented, or blank)
is skipped first.
Skips injection if ``argument-hint:`` already exists in the
frontmatter to avoid duplicate keys.
@@ -88,15 +97,29 @@ class AlquimiaAIIntegration(SkillsIntegration):
in_fm = False
dash_count = 0
injected = False
for line in lines:
i = 0
n = len(lines)
while i < n:
line = lines[i]
stripped = line.rstrip("\n\r")
if stripped == "---":
dash_count += 1
in_fm = dash_count == 1
out.append(line)
i += 1
continue
if in_fm and not injected and stripped.startswith("description:"):
out.append(line)
i += 1
# Skip folded/quoted continuation lines before inserting
# so the new key lands after the description scalar ends.
# Blank lines count too: PyYAML emits unindented blank
# lines for embedded "\n\n" inside a quoted scalar.
while i < n and (
lines[i][:1] in (" ", "\t") or lines[i].rstrip("\r\n") == ""
):
out.append(lines[i])
i += 1
# Preserve the exact line-ending style (\r\n vs \n)
if line.endswith("\r\n"):
eol = "\r\n"
@@ -109,6 +132,7 @@ class AlquimiaAIIntegration(SkillsIntegration):
injected = True
continue
out.append(line)
i += 1
return "".join(out)
@staticmethod
@@ -471,6 +471,101 @@ class TestAlquimiaArgumentHints:
hint_count = sum(1 for ln in lines if ln.startswith("argument-hint:"))
assert hint_count == 1
def test_inject_argument_hint_survives_folded_description(self):
"""A long description folded across lines must not corrupt the YAML (#4044).
A description long enough for the YAML dumper to fold it into a
multi-line plain scalar previously had ``argument-hint:`` spliced
into the *middle* of that scalar, producing invalid YAML.
"""
from specify_cli.integrations.alquimia import AlquimiaAIIntegration
frontmatter = {
"name": "speckit-specify",
"description": (
"Create or update the feature specification from a natural "
"language feature description. Also accepts an issue URL "
"resolved via gh CLI (demo customization)."
),
"compatibility": "Requires spec-kit project structure with .specify/ directory",
}
frontmatter_text = yaml.safe_dump(
frontmatter, sort_keys=False, allow_unicode=True
).strip()
content = f"---\n{frontmatter_text}\n---\n\nBody text\n"
assert "\n " in content, "fixture description must actually fold across lines"
result = AlquimiaAIIntegration.inject_argument_hint(
content, "Describe the feature"
)
parsed = yaml.safe_load(result.split("---")[1])
assert parsed["argument-hint"] == "Describe the feature"
assert parsed["description"] == frontmatter["description"]
def test_inject_argument_hint_survives_quoted_folded_description(self):
"""A folded description forced into quotes must not absorb the hint (#4044)."""
from specify_cli.integrations.alquimia import AlquimiaAIIntegration
frontmatter = {
"name": "speckit-specify",
"description": (
"Create or update the feature specification from a natural "
"language feature description. Also accepts a GitHub "
"issue/PR URL or #N reference resolved via gh CLI (demo)."
),
"compatibility": "Requires spec-kit project structure with .specify/ directory",
}
frontmatter_text = yaml.safe_dump(
frontmatter, sort_keys=False, allow_unicode=True
).strip()
content = f"---\n{frontmatter_text}\n---\n\nBody text\n"
assert "\n " in content, "fixture description must actually fold across lines"
result = AlquimiaAIIntegration.inject_argument_hint(
content, "Describe the feature"
)
parsed = yaml.safe_load(result.split("---")[1])
assert parsed["argument-hint"] == "Describe the feature"
assert parsed["description"] == frontmatter["description"]
def test_inject_argument_hint_survives_multi_paragraph_description(self):
"""A description with an embedded blank line must not absorb the hint.
PyYAML serializes an embedded ``\\n\\n`` inside a quoted scalar as
unindented blank lines, not indented ones, so a fix that only skips
indented continuation lines still fails on this case.
"""
from specify_cli.integrations.alquimia import AlquimiaAIIntegration
frontmatter = {
"name": "speckit-specify",
"description": (
"First paragraph of a fairly long description that will "
"need to wrap across multiple lines when dumped by PyYAML."
"\n\n"
"Second paragraph continues the description after a blank "
"line separator to force embedded newlines in the scalar."
),
"compatibility": "Requires spec-kit project structure with .specify/ directory",
}
frontmatter_text = yaml.safe_dump(
frontmatter, sort_keys=False, allow_unicode=True
).strip()
content = f"---\n{frontmatter_text}\n---\n\nBody text\n"
assert "\n\n" in frontmatter_text, (
"fixture must produce a blank continuation line"
)
result = AlquimiaAIIntegration.inject_argument_hint(
content, "Describe the feature"
)
parsed = yaml.safe_load(result.split("---")[1])
assert parsed["argument-hint"] == "Describe the feature"
assert parsed["description"] == frontmatter["description"]
class TestAlquimiaDisableModelInvocation:
"""Verify disable-model-invocation is false for Alquimia skills."""