Skip to content

fix(cli): generate a v2 markdown table and honors escaped pipes#100

Closed
area73 wants to merge 1 commit into
DirectedEdges:mainfrom
rerades:bug-fix/manifest-v2-support
Closed

fix(cli): generate a v2 markdown table and honors escaped pipes#100
area73 wants to merge 1 commit into
DirectedEdges:mainfrom
rerades:bug-fix/manifest-v2-support

Conversation

@area73
Copy link
Copy Markdown

@area73 area73 commented May 19, 2026

Summary

specs scan writes a v2 markdown-table manifest, but specs generate only detected the legacy v1 checkbox-list format (- [) and failed the documented scan && generate round-trip with Error: Unrecognized source format. This PR wires the existing ManifestParserV2 into GenerateCommand and fixes a parser bug where escaped pipes (\|) emitted by ScanCommand's escapeCell were not honored on the read side — the backslash was leaking literally into the parsed component name.

Changes

  • GenerateCommand — detect v2 manifests via ManifestParserV2.isV2, v1 via isV1Manifest, JSON unchanged. Parse dispatch now picks the right parser. Error message and exit code are preserved.
  • ManifestParserV2 — replaced the combined ROW_REGEX with a recognition regex plus an escape-aware splitRow walker. Public ManifestResultV2 shape is unchanged.
  • Tests — v1 / v2 / JSON / unrecognized detection regressions, plus a v2 escaped-pipe fixture: Toggle \| On/Off parses to Toggle | On/Off.
  • OpenSpec — change generate-v2-manifest-support (proposal, design, tasks, spec delta) and adds openspec/config.yaml.

Why

The scan && generate round-trip is part of the documented CLI workflow. Without v2 support in generate, any manifest produced by current scan was unusable downstream. The escaped-pipe fix ensures component names containing | survive the round-trip intact.

Files touched

  • packages/cli/src/commands/GenerateCommand.ts
  • packages/cli/src/utilities/ManifestParserV2.ts
  • packages/cli/tests/unit/commands/GenerateCommand.test.ts
  • packages/cli/tests/unit/utilities/ManifestParserV2.test.ts
  • openspec/config.yaml
  • openspec/changes/generate-v2-manifest-support/ (proposal, design, tasks, spec delta)

Test plan

  • npm test --workspace=packages/cli passes
  • npm run build passes
  • Manual round-trip: specs scan ... then specs generate ... against the produced v2 manifest succeeds
  • Manifest containing a component name with an escaped pipe (e.g. Toggle \| On/Off) round-trips to Toggle | On/Off
  • v1 checkbox-list manifests still parse (no regression)
  • JSON manifests still parse (no regression)
  • Unrecognized input still errors with the documented message and exit code

@area73
Copy link
Copy Markdown
Author

area73 commented May 19, 2026

@nathanacurtis, I opened this PR to address the V2 markdown-table manifest issue.

I used to work with OpenSpec for SDD, so I added the specs to give you more context on the behavior and requirements that were already in place.

I can remove them if you feel they’re not needed.

If you think the OpenSpec library could be useful, you’ll need to go through the installation steps separately. I didn’t include the commands or skills on .claude in order to keep this PR focused and clean.

I hope this PR helps, and that you find it useful.

Thanks for your work on this project. It’s really awesome.

@nathanacurtis
Copy link
Copy Markdown
Member

Thank you so much for this, @area73 — genuinely. You spotted a real, user-facing break in the scan → generate round-trip, diagnosed the root cause precisely (v1-only detection in GenerateCommand plus the escaped-pipe leak), and backed it with tests. That diagnosis is exactly right and it directly shaped the fix we're shipping.

We're going to land an intentionally minimal version in #104 (releasing as specs-cli@0.15.1): wire ManifestParserV2.isV2 into generate's detection and unescape \| in the parser — no new dependencies and no OpenSpec change set, to keep the patch surface as small as possible. So I'm closing this PR as superseded, not rejected — the credit for catching and pinpointing the bug is yours, and the fix exists because of it. 🙏

Closes #100 in favor of #104. Thank you again for taking the time to report and fix this.

@area73
Copy link
Copy Markdown
Author

area73 commented May 20, 2026

I'm glad I could help, thanks for the credits 🙌

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.

2 participants