Extract the sidebar Templates panel's inline load-into-new-tab callback into
a shared loadTemplateIntoNewTab() function, and add the missing
ipcRenderer.on('load-template-menu', ...) listener so the File > New from
Template submenu (which already sends this IPC event, already whitelisted in
preload.js) actually loads the selected template.
Amit Haridas
Extract the recent-files.json deletion logic into a standalone
clearRecentFilesOnDisk() function and call it from both the menu
click handler and the ipcMain.on handler. Previously the menu sent
the message in the wrong direction (main→renderer instead of
renderer→main), causing the feature to silently no-op. Both paths now
use the same function and send the correct 'recent-files-cleared'
notification to keep the renderer in sync.
Amit Haridas
Monospace font embedding feature release. Adds bundled JetBrains Mono +
Fira Code TTFs (asarUnpack), preview/print font picker with ligatures
toggle, and embedded fonts in PDF (xelatex fontspec), DOCX (OOXML
surgery), EPUB (--epub-embed-font + OPF manifest), and HTML (sidecar
CSS with base64 data URI).
Exercises the real export pipeline against the bundled JetBrains Mono TTFs:
- PdfFontHeader emits valid xelatex fontspec with correct family + Ligatures=NoCommon
- ExportCss.build emits @font-face with base64 data URI
- DocxFontEmbedder injects TTFs into pandoc-produced DOCX (word/fontTable.xml + word/fonts/)
- EpubFontEmbedder.patchManifest adds TTF entry to OPF <manifest>
- HTML export links the sidecar CSS which embeds the font
Run with: node tests/smoke-e2e-monospace.js
Renderer already calls window.electronAPI.invoke('get-monospace-settings')
to apply body classes; this wires up the channel allowlist and main-process
handlers so the IPC actually returns the active monospace settings and
persists updates.
Embeds regular + bold TTF of the active monospace family into pandoc's
DOCX output. ODT uses pandoc's built-in font handling; RTF has no font
embedding capability (documented limitation).
Replaces -V monofont=Consolas with a generated xelatex/lualatex header
that fontspec-loads the bundled JetBrains Mono or Fira Code TTF. Adds
a cached settings reader with proper invalidation on store.set, and
reorders fallback engines to prefer lualatex (fontspec-capable) before
pdflatex.
Inlines @font-face as base64 data URI so the iframe srcdoc can render
JetBrains Mono / Fira Code without depending on the parent window's
loaded @font-face sets. Reads family + ligature state from the
renderer-wide cache populated by applyMonospaceClasses().
Amit Haridas
Bundles JetBrains Mono + Fira Code TTFs in assets/fonts/. Embeds them into
DOCX (jszip), passes path via xelatex fontspec for PDF, base64-injects
@font-face for HTML/EPUB. Replaces Consolas (Windows-only) and Google Fonts
CDN load in the ASCII generator window.
Adds user-pickable monospace family + ligature toggle (default JBM, no
ligatures) for ASCII column alignment.
Closes: N/A
Refs: docs/superpowers/specs/2026-06-30-monospace-font-embedding-design.md
Amit Haridas
- Make the HTML preprocessor code-block and inline-code aware so code
examples containing <style> / <div> / comments are preserved.
- Strip all raw <div> tags (not just alignment attributes) to avoid
malformed output from unmatched closing tags.
- Handle uppercase tags and single/unquoted attributes.
- Create temporary DOCX input files inside private mkdtemp directories
instead of predictable names in the shared temp directory.
- Wrap batch DOCX preprocessing in try/catch so one unreadable file
does not abort the entire batch.
- Add regression tests for the edge cases above.
Pre-process markdown before Word/DOCX export to remove raw HTML artifacts
(<style> blocks, HTML comments, and <div align=...> tags) that were
visible in the generated document. Applies to single and batch DOCX exports
via both Pandoc and WordTemplateExporter paths.
- Normalize pandoc command parsing with path.basename() to support bundled binary paths
- Use bundled pandoc binary in convertWithPandoc instead of relying on PATH
- Forward includeSubfolders checkbox state from renderer to main process
- Add pandoc availability check before batch conversion
- Re-enable Start button when batch conversion completes
- Clean up obsolete dist build artifact causing test snapshot warning
- Bump version to 4.4.4
Documents project architecture, Pandoc dependency resolution, build
pipeline (electron-builder, no bundler), security model notes
(contextIsolation: false on this branch), and development commands
extracted from actual package.json and source.
Amit Haridas
This will help identify whether the issue is:
1. marked.parse returning a Promise instead of string
2. DOMPurify.sanitize failing
3. The preview element not existing
4. Libraries not being loaded
Amit Haridas
- Add missing updateUI() call at end of openFile() to set .active class
on tab content. Without this, the CSS rule .tab-content:not(.active)
{ display: none } kept newly opened files invisible.
- Add diagnostic logging to file-opened IPC handler and openFile()
to trace future file loading issues.
- Add diagnostic logging to openFileFromPath() in main process.
Amit Haridas
window.ModalManager was set unconditionally, causing "Identifier
'ModalManager' has already been declared" when script tag in HTML
also loaded ModalManager before renderer.js required it.
Now checks !window.ModalManager before setting.
Amit Haridas
require('dompurify') returns a factory function, not a sanitizer
instance. Calling .sanitize() on the factory threw a TypeError,
which was caught by the preview renderer's try-catch and displayed
a generic "Error rendering preview" message. Fix by invoking the
factory with the renderer's window object.
Amit Haridas
Restrict Electron permission requests to only clipboard operations.
Deny: camera, microphone, geolocation, notifications, and all other
permissions by default.
Implements setPermissionRequestHandler on web-contents-created event
to enforce security policy early in the app lifecycle.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Add get-app-version IPC handler in main.js (returns app.getVersion())
- Expose electronAPI.getAppVersion() in preload.js
- index.html: replace hardcoded v4.2.0 span with dynamic population
from getAppVersion() in DOMContentLoaded
- welcome.js: accept appVersion param instead of hardcoded 4.1.0
- renderer.js: pass live version to createWelcomeContent()
- main.js about screen: use app.getVersion() instead of hardcoded 4.1.0
- Update stale @version 4.1.0 JSDoc comments to 4.3.0
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
electron-builder detects git tags in CI and tries to auto-publish to
GitHub, failing with 'GH_TOKEN not set'. We handle the release
separately via softprops/action-gh-release, so suppress auto-publish.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Add build:linux-ci script (deb + AppImage, no snap — snapcraft not
available on ubuntu-latest runners without extra setup)
- Switch release.yml linux build to npm run build:linux-ci
- release job: if: always() so Windows artifacts still get released
even if linux build fails
- Download artifact steps: continue-on-error so missing platform
doesn't block GitHub Release creation
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Remove rpm from linux build targets (rpmbuild not available locally)
CI can add it back with apt-get if needed, but pandoc/ffmpeg are now
bundled so the rpm depends were incorrect anyway
- Remove rpmbuild apt install step from release.yml (not needed)
- Remove pandoc/ffmpeg from deb depends — they are now bundled binaries
- Keep imagemagick and libreoffice-common in deb depends (not bundled)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>