fix(export): fix broken template placeholders in session export HTML#41861
Conversation
Greptile SummaryThis PR fixes a critical regression introduced in The fix is minimal, targeted, and correct:
No logic changes are made to Confidence Score: 5/5
Last reviewed commit: 3f73181 |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 3f7318177d
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
8377d86 to
c25e66e
Compare
|
CI Status: The TypeScript failures in this run (missing Latest main (run #11081) shows a successful build, confirming these are unrelated. The export fix is ready to merge. 🐻 |
|
This pull request has been automatically marked as stale due to inactivity. |
|
Codex automated review: keeping this open. Keep this PR open. Current main still has the session export template/replacement mismatch, the latest release tree has the same mismatch, and the PR is paired with an open same-author bug report (#41862). The PR is a focused implementation candidate rather than obsolete cleanup. Best possible solution: Keep this PR open as a valid focused fix candidate. The best maintainer path is to land one canonical implementation that restores compact protected script placeholders, uses function replacers for injected JS content, adds a regression test against the real template/generation path, and then closes the paired bug report #41862 plus duplicate reports such as #49957 after merge. What I checked:
Remaining risk / open question:
Codex Review notes: model gpt-5.5, reasoning high; reviewed against 9bc703213bb3. |
The {{MARKED_JS}}, {{HIGHLIGHT_JS}}, and {{JS}} placeholders in the
export HTML template were split across multiple lines by a code
formatter, turning them into JS block statements instead of template
tokens. The generateHtml() function uses .replace('{{MARKED_JS}}', ...)
which requires contiguous strings, so the vendor JS and app code were
never injected — producing a 2MB HTML file that opens with styles and
session data but renders blank (no JS to parse/display the data).
Fix: collapse placeholders to single-line {{TOKEN}} format and add
prettier-ignore comments to prevent re-formatting.
Introduced in 9d403fd.
String.replace() interprets $ sequences ($&, $$, $', etc.) in replacement strings. The minified vendor libraries (highlight.min.js, marked.min.js) and the template JS contain literal $ characters that get mutated during injection — e.g. $& becomes the matched placeholder text, $$ becomes a single $. Fix: use arrow function replacers for JS content so replacement text is injected verbatim without $ interpretation. CSS and session data use string replacers since they don't contain problematic $ patterns. Flagged by Codex review (P2).
|
ProjectClownfish pushed a narrow repair to this branch so the original contributor path can stay canonical. Source PR: #41861 |
485acbd to
2256419
Compare
…penclaw#41861) * fix(export): fix broken template placeholders in session export HTML The {{MARKED_JS}}, {{HIGHLIGHT_JS}}, and {{JS}} placeholders in the export HTML template were split across multiple lines by a code formatter, turning them into JS block statements instead of template tokens. The generateHtml() function uses .replace('{{MARKED_JS}}', ...) which requires contiguous strings, so the vendor JS and app code were never injected — producing a 2MB HTML file that opens with styles and session data but renders blank (no JS to parse/display the data). Fix: collapse placeholders to single-line {{TOKEN}} format and add prettier-ignore comments to prevent re-formatting. Introduced in b8e9d67. * fix(export): use function replacers for vendor JS injection String.replace() interprets $ sequences ($&, $$, $', etc.) in replacement strings. The minified vendor libraries (highlight.min.js, marked.min.js) and the template JS contain literal $ characters that get mutated during injection — e.g. $& becomes the matched placeholder text, $$ becomes a single $. Fix: use arrow function replacers for JS content so replacement text is injected verbatim without $ interpretation. CSS and session data use string replacers since they don't contain problematic $ patterns. Flagged by Codex review (P2). * ci: retrigger checks * fix(export-session): restore inline export scripts --------- Co-authored-by: vincentkoc <25068+vincentkoc@users.noreply.github.com>
…penclaw#41861) * fix(export): fix broken template placeholders in session export HTML The {{MARKED_JS}}, {{HIGHLIGHT_JS}}, and {{JS}} placeholders in the export HTML template were split across multiple lines by a code formatter, turning them into JS block statements instead of template tokens. The generateHtml() function uses .replace('{{MARKED_JS}}', ...) which requires contiguous strings, so the vendor JS and app code were never injected — producing a 2MB HTML file that opens with styles and session data but renders blank (no JS to parse/display the data). Fix: collapse placeholders to single-line {{TOKEN}} format and add prettier-ignore comments to prevent re-formatting. Introduced in 44b1f63. * fix(export): use function replacers for vendor JS injection String.replace() interprets $ sequences ($&, $$, $', etc.) in replacement strings. The minified vendor libraries (highlight.min.js, marked.min.js) and the template JS contain literal $ characters that get mutated during injection — e.g. $& becomes the matched placeholder text, $$ becomes a single $. Fix: use arrow function replacers for JS content so replacement text is injected verbatim without $ interpretation. CSS and session data use string replacers since they don't contain problematic $ patterns. Flagged by Codex review (P2). * ci: retrigger checks * fix(export-session): restore inline export scripts --------- Co-authored-by: vincentkoc <25068+vincentkoc@users.noreply.github.com>
…penclaw#41861) * fix(export): fix broken template placeholders in session export HTML The {{MARKED_JS}}, {{HIGHLIGHT_JS}}, and {{JS}} placeholders in the export HTML template were split across multiple lines by a code formatter, turning them into JS block statements instead of template tokens. The generateHtml() function uses .replace('{{MARKED_JS}}', ...) which requires contiguous strings, so the vendor JS and app code were never injected — producing a 2MB HTML file that opens with styles and session data but renders blank (no JS to parse/display the data). Fix: collapse placeholders to single-line {{TOKEN}} format and add prettier-ignore comments to prevent re-formatting. Introduced in 6bf62fb. * fix(export): use function replacers for vendor JS injection String.replace() interprets $ sequences ($&, $$, $', etc.) in replacement strings. The minified vendor libraries (highlight.min.js, marked.min.js) and the template JS contain literal $ characters that get mutated during injection — e.g. $& becomes the matched placeholder text, $$ becomes a single $. Fix: use arrow function replacers for JS content so replacement text is injected verbatim without $ interpretation. CSS and session data use string replacers since they don't contain problematic $ patterns. Flagged by Codex review (P2). * ci: retrigger checks * fix(export-session): restore inline export scripts --------- Co-authored-by: vincentkoc <25068+vincentkoc@users.noreply.github.com>
…penclaw#41861) * fix(export): fix broken template placeholders in session export HTML The {{MARKED_JS}}, {{HIGHLIGHT_JS}}, and {{JS}} placeholders in the export HTML template were split across multiple lines by a code formatter, turning them into JS block statements instead of template tokens. The generateHtml() function uses .replace('{{MARKED_JS}}', ...) which requires contiguous strings, so the vendor JS and app code were never injected — producing a 2MB HTML file that opens with styles and session data but renders blank (no JS to parse/display the data). Fix: collapse placeholders to single-line {{TOKEN}} format and add prettier-ignore comments to prevent re-formatting. Introduced in 3582d5b. * fix(export): use function replacers for vendor JS injection String.replace() interprets $ sequences ($&, $$, $', etc.) in replacement strings. The minified vendor libraries (highlight.min.js, marked.min.js) and the template JS contain literal $ characters that get mutated during injection — e.g. $& becomes the matched placeholder text, $$ becomes a single $. Fix: use arrow function replacers for JS content so replacement text is injected verbatim without $ interpretation. CSS and session data use string replacers since they don't contain problematic $ patterns. Flagged by Codex review (P2). * ci: retrigger checks * fix(export-session): restore inline export scripts --------- Co-authored-by: vincentkoc <25068+vincentkoc@users.noreply.github.com>
…penclaw#41861) * fix(export): fix broken template placeholders in session export HTML The {{MARKED_JS}}, {{HIGHLIGHT_JS}}, and {{JS}} placeholders in the export HTML template were split across multiple lines by a code formatter, turning them into JS block statements instead of template tokens. The generateHtml() function uses .replace('{{MARKED_JS}}', ...) which requires contiguous strings, so the vendor JS and app code were never injected — producing a 2MB HTML file that opens with styles and session data but renders blank (no JS to parse/display the data). Fix: collapse placeholders to single-line {{TOKEN}} format and add prettier-ignore comments to prevent re-formatting. Introduced in 90dc2e5. * fix(export): use function replacers for vendor JS injection String.replace() interprets $ sequences ($&, $$, $', etc.) in replacement strings. The minified vendor libraries (highlight.min.js, marked.min.js) and the template JS contain literal $ characters that get mutated during injection — e.g. $& becomes the matched placeholder text, $$ becomes a single $. Fix: use arrow function replacers for JS content so replacement text is injected verbatim without $ interpretation. CSS and session data use string replacers since they don't contain problematic $ patterns. Flagged by Codex review (P2). * ci: retrigger checks * fix(export-session): restore inline export scripts --------- Co-authored-by: vincentkoc <25068+vincentkoc@users.noreply.github.com>
…penclaw#41861) * fix(export): fix broken template placeholders in session export HTML The {{MARKED_JS}}, {{HIGHLIGHT_JS}}, and {{JS}} placeholders in the export HTML template were split across multiple lines by a code formatter, turning them into JS block statements instead of template tokens. The generateHtml() function uses .replace('{{MARKED_JS}}', ...) which requires contiguous strings, so the vendor JS and app code were never injected — producing a 2MB HTML file that opens with styles and session data but renders blank (no JS to parse/display the data). Fix: collapse placeholders to single-line {{TOKEN}} format and add prettier-ignore comments to prevent re-formatting. Introduced in c9bcee7. * fix(export): use function replacers for vendor JS injection String.replace() interprets $ sequences ($&, $$, $', etc.) in replacement strings. The minified vendor libraries (highlight.min.js, marked.min.js) and the template JS contain literal $ characters that get mutated during injection — e.g. $& becomes the matched placeholder text, $$ becomes a single $. Fix: use arrow function replacers for JS content so replacement text is injected verbatim without $ interpretation. CSS and session data use string replacers since they don't contain problematic $ patterns. Flagged by Codex review (P2). * ci: retrigger checks * fix(export-session): restore inline export scripts --------- Co-authored-by: vincentkoc <25068+vincentkoc@users.noreply.github.com>
Problem
The
/export-sessioncommand produces an HTML file that opens but renders completely blank — no messages, no sidebar, nothing. The file is ~2MB (session data is present) but the viewer JS never loads.Root Cause
The
{{MARKED_JS}},{{HIGHLIGHT_JS}}, and{{JS}}placeholders intemplate.htmlwere reformatted by Prettier into multi-line JS block statements:The
generateHtml()function incommands-export-session.tsuses.replace('{{MARKED_JS}}', markedJs)which requires contiguous{{MARKED_JS}}strings. The prettified version doesn't match, so the vendor libraries (marked.js, highlight.js) and the main app JS are never injected.Introduced in 9d403fd.
Fix
Collapse placeholders back to single-line
{{TOKEN}}format and add<!-- prettier-ignore -->comments to prevent re-formatting.Testing
Before:
/export-session→ 2MB HTML file, opens with dark theme background but blank contentAfter: template placeholders match the
.replace()calls, JS gets injected, session renders