fix: prevent ambiguous TOML closing quotes when body ends with " (#2113)#2115
Conversation
…ithub#2113) _render_toml_string placed the closing `"""` inline with content, so a body ending with `"` produced `""""` (four consecutive quotes). While technically valid TOML 1.0, this breaks stricter parsers such as Gemini CLI v0.27.2. Insert a newline before the closing delimiter when the body ends with a quote character. Same treatment for the single-quote (`'''`) fallback. Adds both a positive test (body ending with `"` must not produce `""""`) and a negative test (safe bodies keep the inline delimiter).
There was a problem hiding this comment.
Pull request overview
Fixes TOML generation for TomlIntegration so multiline string closing delimiters don’t become ambiguous when the prompt body ends with a quote character (addressing Gemini CLI’s stricter TOML parsing from #2113).
Changes:
- Adjust
_render_toml_string()to insert a separator before closing"""/'''delimiters when content ends with the matching quote. - Add regression tests asserting the generated TOML does not contain ambiguous closing-quote sequences and keeps the inline delimiter when safe.
Show a summary per file
| File | Description |
|---|---|
src/specify_cli/integrations/base.py |
Updates TOML multiline string rendering logic to avoid ambiguous closing delimiters when content ends with quotes. |
tests/integrations/test_integration_base_toml.py |
Adds regression tests intended to cover the ambiguous-closing-quotes scenario and a “safe inline delimiter” case. |
Copilot's findings
Tip
Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- Files reviewed: 2/2 changed files
- Comments generated: 2
…limiters
Address PR review feedback:
- Replace sep=newline with TOML line-ending backslash so the parsed
value does not gain a trailing newline when body ends with a quote.
- For literal string (''') fallback, skip to escaped basic string when
value ends with single quote instead of inserting a newline.
- Make test body multiline so it exercises the """ rendering path,
and assert no trailing newline in parsed value.
There was a problem hiding this comment.
Pull request overview
Fixes TOML generation in TomlIntegration so multiline strings whose body ends with a quote don’t produce an ambiguous closing delimiter sequence (e.g., """"), addressing stricter TOML parsers like Gemini CLI (issue #2113).
Changes:
- Update
_render_toml_string()to avoid inline"""closing when the escaped multiline body ends with"(by moving the delimiter to the next line without changing the parsed value). - Add regression tests for the ambiguous-quote case and for keeping the closing delimiter inline when it’s safe.
Show a summary per file
| File | Description |
|---|---|
src/specify_cli/integrations/base.py |
Adjusts TOML multiline string rendering to prevent ambiguous closing quotes. |
tests/integrations/test_integration_base_toml.py |
Adds tests covering the reported failure case and a safe inline-delimiter regression check. |
Copilot's findings
Tip
Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- Files reviewed: 2/2 changed files
- Comments generated: 1
… and ends with single-quote Addresses review feedback from PR github#2115: adds test for the branch where the body contains '"""' and ends with "'", which forces _render_toml_string() through the escaped basic-string fallback instead of the '''...''' literal-string path (since '''' would produce the same ambiguous-closing-delimiter problem).
There was a problem hiding this comment.
Pull request overview
Fixes TOML rendering in TomlIntegration to avoid generating ambiguous closing delimiters when a multiline prompt ends with a quote character, which breaks stricter TOML parsers (e.g., Gemini CLI; issue #2113).
Changes:
- Adjust
_render_toml_string()to avoid""""(and analogous'''') ambiguity at the end of multiline strings. - Add regression tests covering: the bug case (body ends with
"), a fallback case (contains"""and ends with'), and a safe-case where the delimiter should remain inline.
Show a summary per file
| File | Description |
|---|---|
src/specify_cli/integrations/base.py |
Updates TOML string serialization logic to prevent ambiguous closing delimiters in multiline output. |
tests/integrations/test_integration_base_toml.py |
Adds targeted tests to reproduce #2113 and verify delimiter placement remains unchanged when safe. |
Copilot's findings
Tip
Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- Files reviewed: 2/2 changed files
- Comments generated: 0 new
Summary
Fixes #2113 — Gemini CLI fails to parse
speckit.checklist.tomldue to 4 consecutive double-quote characters at the end of the file.Root Cause
_render_toml_stringinTomlIntegrationplaces the closing"""delimiter inline with the body content. When the body ends with a"character (e.g.- Correct: "Is X clearly specified?"), the output becomes""""— four consecutive double quotes.While TOML 1.0 technically allows up to two extra quotes before the closing
""", stricter parsers like Gemini CLI v0.27.2 reject this as a syntax error.The checklist template ended with
- Correct: "Is X clearly specified?"(prior to commit 1a9e4d1 which added extension hooks and changed the ending). This triggered the bug for every Gemini project initialized before that commit, and the underlying vulnerability remained for any future template ending with".Fix
Insert a
\nbefore the closing"""when the escaped body ends with". Same treatment for the'''fallback path when the body ends with'.Tests
test_toml_no_ambiguous_closing_quotes— body ending with"must not produce""""(positive/bug case)test_toml_closing_delimiter_inline_when_safe— body NOT ending with"keeps the inline closing delimiter (negative/regression case)All 62 TOML integration tests pass (Gemini + Tabnine).