Skip to content

fix: keep long frontmatter values on a single line - #3989

Merged
mnriem merged 1 commit into
github:mainfrom
deborre:fix/frontmatter-long-description-wrap
Aug 5, 2026
Merged

fix: keep long frontmatter values on a single line#3989
mnriem merged 1 commit into
github:mainfrom
deborre:fix/frontmatter-long-description-wrap

Conversation

@deborre

@deborre deborre commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

CommandRegistrar.render_frontmatter (src/specify_cli/agents.py) calls yaml.dump() without width=, so PyYAML applies its default ~80-column wrap and folds long scalars onto a continuation line.

A description longer than roughly 80 characters renders as:

---
name: speckit-implement
description: Execute the implementation plan by processing and executing all tasks
  defined in tasks.md
---

Why this is worth fixing

The YAML stays valid and round-trips faithfully through yaml.safe_load, so this is not data loss — I want to be accurate about the severity. It is a shape inconsistency, with real consequences:

  • Hand-written core command templates always keep description on a single line, so preset- and extension-rendered commands don't match the files sitting beside them in the same directory.
  • Consumers that read frontmatter line-wise rather than with a YAML parser see the description truncated at the fold, followed by a stray line. Spec Kit itself hand-builds SKILL.md frontmatter in the skills path (SKILL.md frontmatter corrupts multiline descriptions and breaks on control characters #3391), so that's not a hypothetical class of consumer.
  • speckit.implement's own description is 89 characters, so any preset overriding it hits this immediately.

The change

width=float("inf") disables line-wrapping only. Escaping, quoting, and the handling of genuinely multi-line values are unchanged — PyYAML selects the scalar style before applying width.

Verification

  • Added a regression test that fails without the change (asserts the description survives on one line and still parses).
  • Full suite: 6354 passed. Four failures in tests/integrations/test_integration_subcommand.py reproduce on a clean checkout of main as well (ANSI escapes in captured output) and are unrelated to this change.

Reproduction

specify preset add --dev <preset with an 89-char command description>
cat .claude/skills/speckit-<name>/SKILL.md   # description folded across two lines

`CommandRegistrar.render_frontmatter` calls `yaml.dump()` without `width=`,
so PyYAML applies its default ~80-column wrap and folds any long scalar onto
a continuation line.

A `description` longer than roughly 80 characters is therefore rendered as:

    ---
    name: speckit-implement
    description: Execute the implementation plan by processing and executing all tasks
      defined in tasks.md
    ---

The YAML remains valid and round-trips faithfully through `yaml.safe_load`,
so this is not data loss. It is a shape inconsistency with real consequences:

- Hand-written core command templates always keep `description` on one line,
  so preset- and extension-rendered commands do not match the files they sit
  beside in the same directory.
- Consumers that read frontmatter line-wise rather than with a YAML parser
  see the description truncated at the fold, followed by a stray line. Spec
  Kit itself hand-builds SKILL.md frontmatter in the skills path (see github#3391),
  so this is not a hypothetical class of consumer.
- `speckit.implement`'s own description is 89 characters, so a preset that
  overrides it hits this immediately.

`width=float("inf")` disables the line-wrapping only; escaping, quoting and
the handling of genuinely multi-line values are unchanged, since PyYAML
selects the scalar style before applying width.

Adds a regression test that fails without the change.

Verified against the repo's own suite: 6354 passed. Four failures in
tests/integrations/test_integration_subcommand.py are present on a clean
checkout too (ANSI escapes in captured output) and are unrelated.
@deborre
deborre requested a review from mnriem as a code owner August 4, 2026 23:16
@mnriem
mnriem requested a balanced review from Copilot August 5, 2026 13:27

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Ready to approve

The focused implementation correctly addresses the reported formatting inconsistency with regression coverage.

This review doesn't count toward merge requirements. Sign up for the private preview to control whether Copilot approvals count.

Pull request overview

Prevents PyYAML from wrapping long frontmatter values, preserving compatibility with line-oriented consumers.

Changes:

  • Disables YAML width-based wrapping.
  • Adds a round-trip regression test for long descriptions.
File summaries
File Description
src/specify_cli/agents.py Disables frontmatter scalar wrapping.
tests/test_extensions.py Tests single-line output and YAML parsing.
Review details
  • Files reviewed: 2/2 changed files
  • Comments generated: 0
  • Review effort level: Balanced

We're testing this review assessment. Please use 👍 or 👎 to tell us if it's correct.

@mnriem
mnriem merged commit 4d5458c into github:main Aug 5, 2026
14 checks passed
@mnriem

mnriem commented Aug 5, 2026

Copy link
Copy Markdown
Collaborator

Thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants