Commit Graph
148 Commits
Author SHA1 Message Date
amitwh 7a396f64a6 feat(renderer): setup React, Vite, Tailwind CSS and Zustand state management 2026-06-03 23:23:59 +05:30
amitwh 88e9a5290d fix(renderer): add ensureEditor fallback and fix pandoc export path
1. Source editor blank: Added ensureEditor() method with try-catch that
   lazily creates the CodeMirror editor when setEditorContent is called
   if the initial DOMContentLoaded creation failed or was skipped.
   Replaced inline createEditor calls in createTabElements and
   DOMContentLoaded with ensureEditor().

2. Export via pandoc failing: runPandocCmd parsed the full path
   /bin/linux/pandoc as the command, then prepended it to args because
   parsed.command !== 'pandoc'. This caused pandoc to receive its own
   binary path as the first input file. Fix: use path.basename() to
   check if the command ends with 'pandoc' (or 'pandoc.exe').

Amit Haridas
2026-06-03 20:44:00 +05:30
amitwh fff15d8d3e fix(renderer): add window.electronAPI shim and update CSP for KaTeX
The main window uses nodeIntegration without preload, so window.electronAPI
was undefined. This caused the DOMContentLoaded handler to crash at:
  await window.electronAPI.getAppVersion()
which prevented the CodeMirror editor from being created (blank source
window) and stopped renderer-ready from being sent (broken menu/options).

Fixes:
1. Add window.electronAPI shim at top of renderer.js wrapping ipcRenderer.
2. Update CSP meta tag to allow KaTeX CDN (style-src, script-src, font-src).

Amit Haridas
2026-06-03 15:37:20 +05:30
amitwh c574d77c20 fix(renderer): remove let ModalManager to prevent SyntaxError on load
ModalManager.js is loaded via <script> tag in index.html, which
declares class ModalManager in the global script scope. renderer.js
was then doing 'let ModalManager;' which caused:
  SyntaxError: Identifier 'ModalManager' has already been declared

This prevented renderer.js from executing at all, breaking tabs,
editor, file open, and preview rendering.

Fix: conditionally require ModalManager only if undefined, without
re-declaring. In sloppy mode this safely assigns to the existing global.

Amit Haridas
2026-06-03 15:25:22 +05:30
amitwh 272215f9af fix(renderer): prevent welcome screen from overwriting opened markdown files
The welcome tab setup awaited getAppVersion() inside DOMContentLoaded.
While yielding, the renderer-ready timeout fired, file-opened was processed,
and openFile rendered the markdown. When the welcome setup resumed, it
overwrote tab.content and preview.innerHTML with the welcome screen,
leaving the preview blank.

Fix: only show the welcome screen if the tab is still empty (no filePath
and no content) when the async setup resumes.

Amit Haridas
2026-06-03 15:14:41 +05:30
amitwh 0192590567 fix(renderer): add missing closing brace for redo IPC handler
The ipcRenderer.on('redo') callback was missing its closing });
introduced in a9e05d2, causing SyntaxError: Unexpected end of input.

Amit Haridas
2026-06-03 14:36:59 +05:30
amitwh 96df5652d6 fix: resolve list-directory IPC handler closing brace syntax error 2026-05-26 11:39:57 +05:30
amitwh a9e05d2c0f feat: implement Custom Preview CSS, Reveal.js options, Large File Mode, and Interactive PDF Thumbnail Sidebar 2026-05-25 23:11:47 +05:30
amitwh c982b3e90f chore(diagnostics): add logging to _renderPreview to trace markdown rendering
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
2026-05-25 00:32:27 +05:30
amitwh cfaafc07b2 chore(deps): update vulnerable packages to patched versions
Updated packages:
- simple-git 3.32.3 → 3.36.0 (RCE vulnerability)
- fast-uri 3.1.0 → 3.1.2 (host confusion, path traversal)
- dompurify 3.3.1 → 3.4.5 (XSS bypasses)
- mermaid 11.13.0 → 11.15.0 (CSS injection, DoS)
- uuid 11.1.0 → 11.1.1 (buffer bounds check)
- ws 8.20.0 → 8.20.0 (uninitialized memory)
- ip-address 10.1.0 → 10.2.0 (XSS)
- @xmldom/xmldom 0.8.11 → 0.9.10 (XML injection, DoS)
- docx4js 3.3.0 → 2.0.1 (breaks xml2js dep chain)
- brace-expansion (transitive update)

Also applied lint:fix autofix (const correctness).

Amit Haridas
2026-05-25 00:00:28 +05:30
amitwh 94ad99dc4d fix(renderer): ensure tab content visibility after file open
- 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
2026-05-24 23:54:31 +05:30
amitwh baf644d62b fix(modal): prevent duplicate ModalManager declaration
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
2026-05-22 22:08:06 +05:30
amitwh f9a5420ad2 4.4.1: update version everywhere, fix DOMPurify initialization
- Bump version to 4.4.1
- DOMPurify now initialized with window context (fixes markdown rendering)
- Add 'it' to eslint globals

Amit Haridas
2026-05-22 21:54:05 +05:30
amitwh f8361174f2 chore: add it to eslint globals, add debug logging to createEditor
Amit Haridas
2026-05-22 21:42:34 +05:30
amitwh 64df0660c8 fix(renderer): initialize DOMPurify with window context
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
2026-05-03 16:38:47 +05:30
amitwhandCopilot bbfa2a38e9 security: add permission request handler for security isolation
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>
2026-04-24 17:19:52 +05:30
amitwhandCopilot 94ec3f45ce fix: show dynamic app version everywhere in UI
- 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>
2026-04-23 23:31:18 +05:30
amitwhandCopilot 5ee986fab8 fix: bundle pandoc+ffmpeg, fix CI pipeline and Windows GitHub build
- Remove package-lock.json from .gitignore so npm ci works in CI
- Refactor main.js: delegate PDF ops to src/main/PDFOperations.js,
  git ops to src/main/GitOperations.js
- getPandocPath(): use bundled binary from resources/bin/ when packaged,
  fall back to dev bin/ or system pandoc in development
- getFFmpegPath(): use ffmpeg-static (asarUnpack) when packaged
- Install ffmpeg-static (v5.3.0, bundled 76MB binary)
- Add scripts/download-tools.js to fetch pandoc binary at build time
  (idempotent, runs on CI before electron-builder)
- electron-builder: add asarUnpack for ffmpeg-static, extraFiles for
  pandoc binary per platform (linux + win32)
- release.yml: switch build-windows to windows-latest runner with native
  NSIS support; add cert decode step; add download-tools step for both
  linux and windows jobs
- Fix lint error: hoist outlinePanelContainer to module scope so
  TabManager methods can reference it without no-undef errors

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-04-23 22:56:41 +05:30
amitwh c1573dba08 feat(writing-studio): add four sidebar panels (goals, snapshots, manuscript, proofread)
Amit Haridas
2026-04-23 22:55:12 +05:30
amitwh 9576abc979 feat(writing-studio): add plugin manifest and entry point
Amit Haridas
2026-04-23 22:55:12 +05:30
amitwh caa3f3d35a feat(writing-studio): add project manager with compile and stats
Amit Haridas
2026-04-23 22:55:12 +05:30
amitwh 2a6f0fc302 feat(writing-studio): add snapshot manager with diff and prune
Amit Haridas
2026-04-23 22:55:12 +05:30
amitwh 4da5b7b9c4 feat(writing-studio): add goal tracker with streaks and history
Amit Haridas
2026-04-23 22:55:12 +05:30
amitwh 1ba42592d7 feat(writing-studio): add sprint engine with WPM tracking
Amit Haridas
2026-04-23 22:55:12 +05:30
amitwh 539502d7ff feat(plugins): wire plugin system into app initialization
- Add plugin system bootstrap in renderer.js after sidebar/commands init
- Wire status bar DOM insertion, editor API, and IPC adapters
- Add plugin-settings:get/set IPC channels to preload allowlist
- Add IPC handlers in main process using existing settings store
- Fix eqeqeq warning in EventBus.hasHandler

Amit Haridas
2026-04-23 22:55:12 +05:30
amitwh b5771dd914 feat(plugins): add sample plugin demonstrating the system
Amit Haridas
2026-04-23 22:55:12 +05:30
amitwh a816b6ec32 feat(plugins): add PluginContext, PluginRegistry, and SettingsStore
- PluginContext: scoped API with crash-safe command wrappers
- PluginRegistry: lifecycle management with graceful init failure
- SettingsStore: plugin-scoped key/value via IPC backend
- Export hooks: pre/post hooks on registry for cross-plugin integration

Amit Haridas
2026-04-23 22:55:12 +05:30
amitwh 54c9484cb5 feat(plugins): add PluginLoader with manifest discovery and validation
Amit Haridas
2026-04-23 22:55:12 +05:30
amitwh 36e26318cd feat(plugins): add PluginAPI base class with no-op lifecycle
Amit Haridas
2026-04-23 22:55:12 +05:30
amitwh 8abd580295 feat(plugins): add EventBus with typed events and crash-safe handlers
Amit Haridas
2026-04-23 22:55:12 +05:30
amitwh 4426b75c6f fix: improve tab safety and app feedback 2026-04-14 22:30:46 +05:30
amitwh f0ab54cd60 chore: bump to v4.2.0 — Writer's Studio Feature Pack
Amit Haridas
2026-04-06 11:44:29 +05:30
amitwh 72a7a854d0 feat(analytics): add writing analytics with readability scores and vocabulary analysis
Amit Haridas
2026-04-06 11:42:22 +05:30
amitwh 50d0638c5c feat(zen): add distraction-free writing mode with typewriter scrolling
Zen mode hides all chrome and centers the editor with typewriter
scrolling, line dimming, and a floating word count HUD.
Toggle with F11, exit with Escape.

Amit Haridas
2026-04-06 11:37:51 +05:30
amitwh 7a3493e54f fix(outline): add tab-switch refresh and dark mode styles
Amit Haridas
2026-04-06 11:05:54 +05:30
amitwh b1a5784bcc feat(outline): add document outline sidebar panel with heading navigation
Amit Haridas
2026-04-06 10:40:29 +05:30
amitwh ed4279f4df feat: bump to v4.1.0 and add CI/CD release pipeline
- Bump version to 4.1.0 in package.json and index.html
- Add build:local script for combined Linux + Windows local builds
- Add CI workflow: runs tests on push/PR to master
- Add Release workflow: tag-triggered (v*), parallel Linux + Windows
  builds, publishes all packages to GitHub Releases

Amit Haridas
2026-03-25 22:20:53 +05:30
amitwh adc8dabda1 fix: resolve modal stacking, animation, and close cleanup bugs
- Set backdrop z-index:0 and content z-index:1 to fix backdrop covering
  modal content within the stacking context
- Force reflow between removing hidden and adding open class so CSS
  opacity transition fires correctly
- Add transitionend listener + setTimeout fallback to restore hidden
  class after close animation completes
- Override flex:1 on modal footer buttons to prevent full-width stretch
- Add min-width to modal size variants for consistent sizing
- Add 23 tests covering open/close lifecycle, keyboard, and destroy

Amit Haridas
2026-03-25 22:20:34 +05:30
amitwh 5911a7501b fix: guard window assignment for CommonJS compatibility 2026-03-24 22:37:40 +05:30
amitwh d998b03ca1 fix: remove ES6 export keyword for browser compatibility 2026-03-24 19:08:14 +05:30
amitwh 31468e77c5 refactor: remove old dialog CSS in favor of unified modal system
Amit Haridas
2026-03-24 16:50:09 +05:30
amitwh 2022352ed1 refactor: update renderer.js to use ModalManager for all dialogs
- Import ModalManager and create instances for all 10 dialogs
- Replace classList.add/remove('hidden') with modal.open()/close()
- Remove duplicate backdrop click and escape key handlers (now handled by ModalManager)
- Update print-preview.js to use ModalManager when available
- Add CommonJS export to ModalManager for renderer compatibility

Dialogs updated:
- find-dialog (findModal)
- export-dialog (exportModal)
- print-preview-overlay (printPreviewModal)
- table-generator-dialog (tableModal)
- ascii-art-dialog (asciiModal)
- universal-converter-dialog (converterModal)
- batch-dialog (batchModal)
- pdf-editor-dialog (pdfEditorModal)
- header-footer-dialog (headerFooterModal)
- field-picker-dialog (fieldPickerModal)

Amit Haridas
2026-03-24 16:44:20 +05:30
amitwh 6bac18d270 feat: convert all dialogs to unified modal structure
Convert 10 dialogs from old classes (.export-dialog, .batch-dialog, .find-dialog)
to the new unified .modal structure with proper accessibility attributes.

Changes:
- find-dialog: small modal with find/replace controls
- export-dialog: large modal with export options
- print-preview-overlay: full-size modal for print preview
- table-generator-dialog: default modal for table creation
- ascii-art-dialog: large modal for ASCII art generation
- universal-converter-dialog: large modal for file conversion
- batch-dialog: large modal for batch processing
- pdf-editor-dialog: full-size modal for PDF editing
- header-footer-dialog: default modal for header/footer config
- field-picker-dialog: small modal for field selection

All dialogs now include:
- role="dialog" and aria-modal="true" for accessibility
- aria-labelledby pointing to title element
- .modal-backdrop with data-close attribute
- .modal-content with appropriate size class
- .modal-header with title and close button
- .modal-body for content
- .modal-footer with action buttons

Amit Haridas
2026-03-24 16:30:52 +05:30
amitwh fdfd778d94 feat: include modal.css and ModalManager in index.html
Amit Haridas
2026-03-24 16:23:59 +05:30
amitwh 30f6198f1d feat: add modal CSS with glassmorphism and animations
Amit Haridas
2026-03-24 16:22:41 +05:30
amitwh 253608e17f feat: add ModalManager class for unified modal system
Amit Haridas
2026-03-24 16:20:03 +05:30
amitwh fe4d634163 feat: add Shadcn/ui design tokens and accessibility improvements
- Add src/styles/tokens.css with comprehensive design tokens
- Define color tokens (primary, secondary, accent, destructive, etc.)
- Add spacing, typography, shadow, and transition tokens
- Include dark mode token overrides
- Add utility classes (btn, badge, input variants)
- Add skip-link for keyboard navigation
- Update index.html to include tokens.css

This enables consistent theming and easier future UI updates.

Amit Haridas
2026-03-24 09:55:18 +05:30
amitwh 3bc703d8dc feat: add platform adapter structure for V4
- Create adapters/types.js with comprehensive type definitions
- Create adapters/electron/fs.js for file system operations
- Prepare structure for future migration to Tauri/Flutter

This abstraction layer makes future platform migration easier
and enables better testing with mock adapters.

Amit Haridas
2026-03-24 09:06:21 +05:30
amitwh 78200b8d6a perf: add debounced preview rendering for better typing performance
- Add previewDebounceTimers map to track debounce timers per tab
- Add updatePreview(tabId, immediate) with optional immediate flag
- Debounce preview updates during typing (300ms delay)
- Use immediate=true for tab switches and file loads
- Refactor _renderPreview as internal method

This significantly improves editor responsiveness when typing
in large markdown files.

Amit Haridas
2026-03-24 08:59:49 +05:30
amitwh 0987058aa2 fix: integrate PDF viewer into tab system for multitab support
- Add tab type system ('markdown' and 'pdf')
- Create PDF tabs with their own state (page, zoom, rotation)
- Update closeTab to properly clean up PDF resources
- Update updateUI to handle PDF tabs (hide toolbar, etc.)
- Add visual indicators for PDF tabs in tab bar
- Add CSS styles for PDF tab containers

Fixes: PDF and markdown multitab function not working

Amit Haridas
2026-03-24 08:55:39 +05:30