feat: add "Open in OrcaSlicer" export action - #347
Merged
lightningpixel merged 10 commits intoSep 19, 2026
Merged
Conversation
Modly had no SECURITY.md and no private channel for vulnerability reports, which left email as the only route for researchers. Private vulnerability reporting is now enabled on the repository; this points people at it and sets expectations around it. The policy leads with a threat model and lets the scope follow from it, so that an excluded report comes with the reason it was excluded. Two assumptions are deliberate: workflow files are untrusted input because sharing them is normal, and any web page the user has open is an untrusted caller of the loopback API. The second is why the network-exposure exclusion is narrowed to deliberate exposure only -- a page in the user's own browser needs none. Every claim was checked against the code. The policy does not call the installer signed (no platform signs it), says nothing about PyTorch (we do not ship it), and does not excuse social engineering on the strength of UI warnings that do not exist.
…curity docs: add a security policy with a private reporting route
Lets external contributors claim an issue without repo write access. Commenting /assign self-assigns via a github-script Action (GITHUB_TOKEN has the write permission the commenter doesn't); /unassign releases it. CONTRIBUTING.md documents the full flow: claim -> fork -> PR with `Closes #N` -> board moves through In progress / Ready to review / Ready to test / Done. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SDMd7LzfFJ7TXav5etBjRi
…buting-assign-command-to-main docs: add CONTRIBUTING.md and /assign command bot
The /assign bot moved GitHub assignees but never touched the Project v2 board itself, so the "In progress" column stayed empty. Same for PRs: opening one with `Closes #N` closed the issue on merge but never moved the card to "Ready to review". - assign-command.yml: on /assign, move the linked board item to "In progress"; on /unassign, move it back to "Backlog". Uses PROJECT_TOKEN since the default GITHUB_TOKEN has no Projects v2 scope. - pr-board-sync.yml (new): on PR opened/edited/ready_for_review, parse closing keywords (Closes/Fixes/Resolves #N) from the description and move each linked issue's card to "Ready to review". Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YTLv6fJFA5MotMqWgStGrf
…status-automation-main feat: sync project board status with /assign and linked PRs
One-click hand-off from a generated model to OrcaSlicer via its
orcaslicer://open?file=<url> deeplink, in the Export dropdown.
- Backend: GET /export/slicer/{fmt}/{token}/model.{fmt} converts the
workspace GLB to STL on the fly — bakes scene-graph transforms,
reorients Y-up->Z-up, normalizes print size. Path-only URL ending in
the filename (no query string), since OrcaSlicer derives the import
format from the URL's final segment; ancestry-based path containment.
- Electron: slicer:open IPC opens the deeplink and reports failure so the
UI can fall back when OrcaSlicer isn't installed.
- Frontend: "Open in OrcaSlicer" item in the Export dropdown, shown for
sliceable workspace meshes; pure deeplink builder with unit tests.
Tests: api/tests/test_export_router.py and orcaSlicerLink.test.ts.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…lindly The slicer route assumed every source was a unit-sized, Y-up glTF straight from a generator, but the Export action is reachable for any mesh in the viewer. - Imported meshes (served through /optimize/serve-file) were excluded outright, so the most direct "I have a model, slice it" path offered no action at all and gave no hint why. They are now sliceable via an exact-membership registry of the files the user picked themselves this session, which keeps the route closed to arbitrary absolute paths rather than widening its path guard. - The Y->Z rotation now applies only to glTF sources. STL/OBJ/PLY are already Z-up, and import converts them to GLB without touching the axes, so the original extension decides -- not the container's. - Normalising to 50 mm now happens only for unit-sized meshes. A mesh that already carries a real-world size is the user's own, and silently shrinking a 180 mm part would waste a print. - slicer:open no longer claims it can detect a missing OrcaSlicer: on Windows an unregistered scheme still makes ShellExecuteEx succeed, so that error branch could never run. test_normalizes_longest_edge_to_default_print_size encoded the unconditional rescale, so its fixture becomes a unit-sized mesh, matching real generator output.
Owner
|
Thanks for this — the path containment in the slicer route is solid, and the tests covering the I pushed a commit on your branch. It changes three things:
I also dropped the "make sure it is installed" error: on Windows an unregistered scheme still makes Worth flagging: I changed |
lightningpixel
approved these changes
Sep 19, 2026
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.
One-click hand-off from a generated model to OrcaSlicer via its
orcaslicer://open?file=<url>deeplink, available in the Export dropdown.let me know if this is alright or there might be some better place for this button.
What
GET /export/slicer/{fmt}/{token}/model.{fmt}route that converts the workspace GLB to STL on the fly: bakes scene-graph transforms, reorients Y-up → Z-up, and normalizes the longest edge to a sane print size. The URL is intentionally path-only and ends inmodel.stl(no query string), because OrcaSlicer derives the import filename/format from the URL's final path segment. Uses ancestry-based path containment (not string-prefix).slicer:openIPC that fires the deeplink and reports success/failure so the UI can fall back when OrcaSlicer isn't installed.Why STL + deeplink
OrcaSlicer registers
orcaslicer://open?file=<url>, downloads the URL, and imports it — and it cannot import GLB. So we convert to STL (which OrcaSlicer auto-repairs) and serve it at a deeplink-shaped URL.Testing
api/tests/test_export_router.py— conversion, Y→Z reorientation, print-size normalization, and guards (unsupported format, extension mismatch, malformed token, path traversal, sibling-prefix escape, 404).src/areas/generate/orcaSlicerLink.test.ts— exact deeplink string, no query string, url-safe base64 round-trip.npm run lintclean;npm run test:nodegreen. Manual E2E verified on macOS (imports upright, ~50 mm).Notes / follow-ups
Closes #346