Repository navigation
Launch directory for runs and exports; Molden file check - #56
Merged
Merged
Conversation
…minal Every run used a mkdtemp work dir under the OS temp dir that was deleted when the run finished, so exported files (orbitals.molden from an Export step, xtbopt.xyz, ...) vanished silently. When jlmol is started from a terminal (stdin is a TTY), main registers process.cwd() as a work-dir token that is never removed, and the ElemCo and xtb runners use it: calculation.jl, coord.xyz and everything the calculation writes stay there. Launches without a terminal keep the temp dir. The output panel prints which directory is used. xtb removes a stale xtbopt.xyz before a run, since success is detected from that file. New bridge calls: launchDir(), removeFile(). The bridge probe checks the removal and that removeWorkDir on the launch dir is a no-op. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Browser-style downloads (image export, XYZ export) landed silently in the download folder. They now go through Electron's save dialog via setSaveDialogOptions on the download item. The default is the launch directory when started from a terminal, the download folder otherwise. Main reports the outcome to the renderer (jlmol-download-done) and the status line shows the saved path or that the export was cancelled. In --bridge-probe mode the file is written to the default path without a dialog (a native dialog cannot be driven headless); the probe checks the default location and the done message under a pty. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
`npm start` chdirs to the package root before running the script, so process.cwd() was ~/projects/jlmol whatever directory the command was typed in. npm exports the original directory as INIT_CWD; use it when set. Terminal detection now accepts a TTY on stdin, stdout or stderr, so a redirected stdin alone no longer disables the launch dir. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…ripts Under WSL `npm start` may run the Windows Electron binary, which gets neither a TTY (WSL interop hands it pipes) nor npm's INIT_CWD (not in WSLENV), so the terminal heuristic never fires and exports defaulted to Downloads. The start scripts now pass --workdir="$INIT_CWD" (the directory the command was typed in) and --wsl-distro="$WSL_DISTRO_NAME". launchdir.js resolves it: on win32 a POSIX path is mapped to C:\... for /mnt/c/... or to \\wsl.localhost\<distro>\... (then \\wsl$\...), the first that exists wins; an invalid value is logged and ignored. Without --workdir the terminal heuristic (INIT_CWD, else cwd) remains. The module is pure and carries a self-test (`node launchdir.js`). Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
… for WSL Julia Daniel's log from WSL: "Launch directory: /home/kats/projects/jlmol [--workdir]" and the dialog got "\home\kats\projects\jlmol\molecule.png". On win32 Node calls a slash-rooted path absolute, and stat() resolved it against the current drive, the \\wsl.localhost share, so it even existed. The save dialog then fell back to the home directory. A POSIX --workdir on win32 now only yields its mapped spellings (C:\ for /mnt/c, \\wsl.localhost\<distro>\..., \\wsl$\...). Self-test covers the trap. The Julia runner's WSL path translation now also maps \\wsl.localhost\<distro>\rest to /rest, so calculation.jl in a launch dir on the distro's own tree reaches `wsl julia` as a valid path. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The browser file picker behind <input type="file"> cannot be pointed at
a directory. In the desktop app the input's click now opens
dialog.showOpenDialog with defaultPath = launch dir (when there is one;
otherwise the OS picks its usual folder), main reads the file and hands
{name, content} to the renderer. handleFileSelect's loading body is
extracted into loadStructureContent(name, content) and shared with the
browser build, which keeps the input.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The file input's "No file chosen" label never learns about files opened through the native dialog. The desktop app now hides the input and shows a button plus a label with the loaded file's name; the browser build keeps the input. The #structureFile id rule (display: block) beat the hidden attribute, hence the explicit [hidden] rule. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
tblite (the g-xTB binary's molden writer) puts the valence electron count in the atomic-number column of [Atoms]: N 5, C 4, O 6. JSmol trusts that column over the label and draws boron, beryllium and carbon with garbled bonds. Daniel's caffeine file loads cleanly once the column is corrected. js/molden-check.js compares the column with the element label and builds a corrected text; it also reports, without fixing, an MO coefficient count that does not match the basis size (missing [5D]). loadStructureContent runs the check for .molden files and shows a dialog: "Fix and load", "Fix, load and save…" (a <name>-fixed.molden copy through the save dialog) or "Load as is". Command-line files go through loadStructureContent too, so they get the same check. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
Five unresolved findings remain, including two critical concurrency issues.
Get a fresh assessment by requesting another Copilot review.
Review effort: Lite
Findings: 2
Open (5)
Concurrent Julia runs overwrite shared scripts and outputs · New Concurrent xtb runs overwrite shared inputs and optimization outputs · New Spherical f/g shells are ignored when validating basis sizes · New Unnormalized workdir paths are incorrectly rejected · New Windows npm scripts pass unexpanded environment variables · New
What changed in this PR
Adds persistent launch-directory handling, native file dialogs, export status reporting, and Molden validation.
Changes:
- Routes Julia and xTB outputs to launch directories.
- Adds native open/save dialogs and WSL path support.
- Validates Molden atomic numbers and basis sizes.
| File | Summary |
|---|---|
README.md |
Documents launch-directory behavior. |
preload.js |
Exposes file, download, and launch-directory APIs. |
package.json |
Updates startup scripts; native Windows expansion remains problematic (moderate, 3 votes). |
main.js |
Implements directory handling, dialogs, downloads, and probes. |
launchdir.js |
Resolves launch directories; unnormalized paths can be rejected incorrectly (moderate, 2 votes). |
js/xtb.js |
Uses persistent xTB directories; concurrent runs can collide on shared files (critical, 3 votes). |
js/search.js |
Adds native file opening and Molden loading. |
js/molden-check.js |
Validates Molden files; [7F] and [9G] shells are ignored (moderate, 3 votes). |
js/image-export.js |
Reports export outcomes. |
js/elemco.js |
Runs Julia calculations in launch directories; concurrent runs can overwrite shared files (critical, 3 votes). |
index.html |
Adds native file-open controls and Molden integration. |
css/styles.css |
Styles new controls and dialogs. |
CHANGELOG.md |
Documents the new functionality. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Comment on lines
+1281
to
+1286
| const launch = await native.launchDir(); | ||
| if (launch) { | ||
| workDir = launch.token; | ||
| } else { | ||
| workDir = await native.mkWorkDir('jlmol_julia_'); | ||
| ownsWorkDir = true; |
Comment on lines
+150
to
+152
| const launch = await native.launchDir(); | ||
| const workDir = launch ? launch.token : await native.mkWorkDir('jlmol_xtb_'); | ||
| const ownsWorkDir = !launch; |
Comment on lines
+95
to
+96
| const useSph = flags['5d']; | ||
| const expected = useSph ? sph : cart; |
Comment on lines
+45
to
+53
| for (const c of candidates) { | ||
| if (P.isAbsolute(c) && isDir(c)) return { dir: c, source: '--workdir' }; | ||
| } | ||
| return { dir: null, source: `--workdir rejected (${explicit})` }; | ||
| } | ||
| if (!isTTY()) return { dir: null, source: 'no terminal' }; | ||
| const init = env.INIT_CWD; | ||
| if (init && P.isAbsolute(init) && isDir(init)) return { dir: init, source: 'terminal, INIT_CWD' }; | ||
| return { dir: cwd(), source: 'terminal, cwd' }; |
Comment on lines
+7
to
+8
| "start": "electron . --workdir=\"$INIT_CWD\" --wsl-distro=\"$WSL_DISTRO_NAME\"", | ||
| "start-verbose": "electron . --verbose --workdir=\"$INIT_CWD\" --wsl-distro=\"$WSL_DISTRO_NAME\"", |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.


Summary
--workdirfrom the npm start scripts, or a terminal's current directory), so exported files (orbitals.molden,xtbopt.xyz, ...) stay there instead of vanishing with a temp dir. Works from WSL running the Windows binary (POSIX path mapped to\\wsl.localhost\<distro>\...).Test plan
npm run smokeand--bridge-probegreen locally (Linux, Xvfb), the probe also under a pty (launch dir detected, download lands there).node launchdir.jsself-test.🤖 Generated with Claude Code