diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..165cfa6 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,25 @@ +# Repository Guidelines + +## Project Structure & Module Organization +Core application code lives in `src/`. Use `src/main.js` for the Electron main process, `src/preload.js` for the preload bridge, and `src/renderer.js` plus `src/editor/`, `src/sidebar/`, `src/repl/`, and `src/utils/` for renderer-side features. Electron adapter code is in `src/adapters/electron/`. Reusable markdown/document templates live in `src/templates/`. Static assets and icons are in `assets/`. Tests are in `tests/`, and build output goes to `dist/`. + +## Build, Test, and Development Commands +- `npm start`: launch the Electron app locally. +- `npm test`: run the Jest suite once. +- `npm run test:watch`: rerun tests during local development. +- `npm run test:coverage`: generate coverage output. +- `npm run lint` / `npm run lint:fix`: check or fix ESLint issues in `src` and `tests`. +- `npm run format` / `npm run format:check`: apply or verify Prettier formatting. +- `npm run build:linux`, `npm run build:win`, `npm run build:mac`: create platform packages with `electron-builder`. + +## Coding Style & Naming Conventions +This repo uses Prettier and ESLint. Follow `.prettierrc`: 2-space indentation, single quotes, semicolons, trailing commas where valid in ES5, and a 100-character line width. Prefer `camelCase` for variables/functions, `PascalCase` for classes, and kebab-case for file names only when already established. Keep module boundaries clear: UI logic in renderer modules, OS/file-system work behind Electron IPC and adapters. + +## Testing Guidelines +Tests use Jest with `jest-environment-jsdom`. Add new tests under `tests/` with `*.test.js` names, mirroring the feature area when possible, for example `tests/sidebar.test.js` or `tests/print-preview.test.js`. Update or add regression tests for renderer behavior, preload APIs, and utility helpers when fixing bugs. Run `npm test` before opening a PR; use `npm run test:coverage` for larger refactors. + +## Commit & Pull Request Guidelines +Recent history follows Conventional Commit prefixes such as `feat:`, `fix:`, and `refactor:`. Keep subjects short and imperative, for example `fix: guard modal cleanup on close`. PRs should describe the user-visible change, note test coverage, link any related issue, and include screenshots or GIFs for UI changes. + +## Security & Configuration Tips +Do not bypass preload boundaries or introduce direct `eval`/dynamic code paths; ESLint already treats these as errors. Export and conversion features depend on external tools such as Pandoc, FFmpeg, ImageMagick, and LibreOffice, so document any new runtime dependency in `README.md` and packaging config. diff --git a/README.md b/README.md index cca5841..19eae7e 100644 --- a/README.md +++ b/README.md @@ -162,4 +162,4 @@ Amit Haridas (amit.wh@gmail.com) ## Version -v3.0.0 +v4.1.0 diff --git a/docs/THREAT_MODEL.md b/docs/THREAT_MODEL.md index b903379..d80ae46 100644 --- a/docs/THREAT_MODEL.md +++ b/docs/THREAT_MODEL.md @@ -1,6 +1,6 @@ # MarkdownConverter - STRIDE Threat Model Analysis -**Version:** 4.0.0 +**Version:** 4.1.0 **Date:** 2026-03-15 **Methodology:** STRIDE + MITRE ATT&CK Mapping **Analyst:** Security Assessment Team diff --git a/src/adapters/electron/fs.js b/src/adapters/electron/fs.js index c865d09..955d09f 100644 --- a/src/adapters/electron/fs.js +++ b/src/adapters/electron/fs.js @@ -18,7 +18,7 @@ const electronFsAdapter = { * @returns {Promise} File content */ async readFile(path) { - return await window.electronAPI.readFile(path); + return await window.electronAPI.file.read(path); }, /** @@ -28,7 +28,7 @@ const electronFsAdapter = { * @returns {Promise} */ async writeFile(path, content) { - return await window.electronAPI.writeFile(path, content); + return await window.electronAPI.file.write(path, content); }, /** @@ -37,8 +37,7 @@ const electronFsAdapter = { * @returns {Promise} */ async deleteFile(path) { - // TODO: Add IPC channel for delete - throw new Error('deleteFile not implemented'); + return await window.electronAPI.file.delete(path); }, /** @@ -47,8 +46,7 @@ const electronFsAdapter = { * @returns {Promise} */ async ensureDir(path) { - // TODO: Add IPC channel for ensureDir - throw new Error('ensureDir not implemented'); + return await window.electronAPI.file.ensureDir(path); }, /** @@ -57,8 +55,18 @@ const electronFsAdapter = { * @returns {Promise>} */ async listDirectory(path) { - // TODO: Add IPC channel for listDirectory - throw new Error('listDirectory not implemented'); + const result = await window.electronAPI.invoke('list-directory', path); + if (!result?.entries) { + return []; + } + + return result.entries.map((entry) => ({ + name: entry.name, + isDir: entry.isDirectory, + size: entry.size ?? 0, + modified: entry.modified ?? 0, + path: entry.path + })); }, /** @@ -67,8 +75,7 @@ const electronFsAdapter = { * @returns {Promise} */ async exists(path) { - // TODO: Add IPC channel for exists - throw new Error('exists not implemented'); + return await window.electronAPI.file.exists(path); }, /** @@ -77,8 +84,7 @@ const electronFsAdapter = { * @returns {Promise} */ async isDirectory(path) { - // TODO: Add IPC channel for isDirectory - throw new Error('isDirectory not implemented'); + return await window.electronAPI.file.isDirectory(path); }, /** @@ -88,8 +94,7 @@ const electronFsAdapter = { * @returns {Promise} */ async copy(source, dest) { - // TODO: Add IPC channel for copy - throw new Error('copy not implemented'); + return await window.electronAPI.file.copy(source, dest); }, /** @@ -99,8 +104,7 @@ const electronFsAdapter = { * @returns {Promise} */ async move(source, dest) { - // TODO: Add IPC channel for move - throw new Error('move not implemented'); + return await window.electronAPI.file.move(source, dest); } }; diff --git a/src/index.html b/src/index.html index 6d40554..b8a717e 100644 --- a/src/index.html +++ b/src/index.html @@ -1275,6 +1275,8 @@ + +