Skip to content

fix(export): prevent nested code fences from breaking markdown exports - #1358

Open
soumojit-D48 wants to merge 1 commit into
Nano-Collective:mainfrom
soumojit-D48:fix/export-dynamic-markdown-fence
Open

soumojit-D48 wants to merge 1 commit into
Nano-Collective:mainfrom
soumojit-D48:fix/export-dynamic-markdown-fence

Conversation

@soumojit-D48

Copy link
Copy Markdown
Contributor

Description

Fixes #1347 by making the Markdown fences around exported tool output dynamic.

Previously, /export always wrapped tool output in a three-backtick code fence. If the tool output itself contained a Markdown code block, the inner three backticks prematurely closed the outer fence and corrupted the exported conversation. This commonly affected read_file, search results, diffs, and other tools that return Markdown or source code.

The export formatter now finds the longest consecutive run of backticks in the tool output and uses a fence that is one character longer, with a minimum length of three. Normal tool output keeps the existing format, while nested code blocks remain intact in the generated Markdown file.

This change is limited to Markdown export formatting and does not change tool execution, message contents, or provider behavior.

Type of Change

  • Bug fix
  • New feature
  • Breaking change
  • Documentation update

Changeset

  • Added a changeset (pnpm changeset) describing this change for the changelog

Docs-only or internal chores need no changeset.

Testing

Automated Tests

  • New features include passing tests in .spec.ts/tsx files
  • All existing tests pass (pnpm test:all completes successfully)
  • Regression test added for nested code fences in source/commands/export.spec.tsx
  • Focused export test suite passes: 29 tests
  • TypeScript type checks pass
  • Biome lint and formatting checks pass

Manual Testing

  • Tested with Ollama
  • Tested with OpenRouter
  • Tested with OpenAI-compatible API
  • Tested MCP integration (if applicable)

Checklist

  • If this was for an open issue, I was assigned to it
  • Code follows project style guidelines
  • Self-review completed
  • Documentation updated (if needed)
  • No breaking changes
  • Appropriate logging added using structured logging (not applicable)

@github-actions

Copy link
Copy Markdown
Contributor

No changeset found

This PR does not add a changeset, so it will not appear in the changelog or trigger a release.

If the change is user-facing, add one:

pnpm changeset

Pick a bump (patch / minor / major) and write the changelog entry in our usual voice ("Added X... Thanks to @you. Closes #123."), then commit the generated .changeset/*.md file.

If this PR is docs-only or a chore that needs no release note, you can ignore this — or run pnpm changeset --empty to record that intentionally.

@github-actions

Copy link
Copy Markdown
Contributor

nc-review: comments — 2 important, 1 nit

@soumojit-D48 — a few things worth a look, none blocking.

The fix correctly addresses issue #1347: a new fenceFor helper computes a backtick fence one longer than the longest run in the tool output (with a minimum of three), and a regression test verifies that nested fences stay intact. The functional change is sound, but the PR is missing a changeset for a user-facing bug fix and the diff carries drive-by reformatting of the spec file that contradicts the project's Biome config (bracketSpacing: false).

🟠 important · changeset · source/commands/export.tsx

This is a user-facing bug fix (/export corrupts exported Markdown for any session that read a file containing backtick fences), but no .changeset/*.md file is included in the PR and the author unchecked the changeset box in the template. CONTRIBUTING and the project rubric both require a changeset for user-facing changes; without one the fix will not appear in the changelog and release-prepare will not record it. Add one, e.g. under .changeset/:

---
'@nanocollective/nanocoder': patch
---

`/export` now sizes its Markdown code fences to survive nested backtick fences in tool output, instead of breaking at the first inner triple-backtick run.

🟠 important · scope · source/commands/export.spec.tsx

The diff reformats dozens of unrelated lines in the spec file ({children} -> { children }, ({recursive: true}) -> ({ recursive: true }), etc.) even though .spec.tsx is excluded from Biome (biome.json -> files.includes) and the project's Biome config explicitly sets "bracketSpacing": false. None of these reformats are required by tooling, none are related to the fence fix, and they all conflict with the rest of the codebase's house style. Drop the unrelated whitespace churn from the diff so the fix stands alone and is easy to review / revert.

⚪ nit · tests · source/commands/export.spec.tsx

The new regression test only covers the case where the longest run is exactly three backticks (output fence is four). A second case with a longer inner run (e.g. content containing ```` would yield a five-backtick fence) would lock in the longest + 1 behaviour rather than just 4 for any input. Optional but cheap and would prevent a future regression that accidentally drops the dynamic sizing.


🔴 blocking · 🟠 a reviewer would ask for a change · ⚪ optional

Automated code review — correctness, security, design, tests, plus duplicates and scope. A human still decides; this is not a substitute for review and is not exhaustive. The required status checks separately cover lint, formatting, types, unused dependencies, the test suite and the build. This bot never merges. Maintainers can rerun with /re-review.

@github-actions github-actions Bot added the agent:comments nc-review left non-blocking findings label Sep 16, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agent:comments nc-review left non-blocking findings

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] /export markdown fence breaks on tool output content containing triple backticks

1 participant