250 Commits
Author SHA1 Message Date
Tautvydas Derzinskas 88949d9d8c feat: let users choose what their API token can read over the REST API
The API token read every GET endpoint. It now reads only the scopes its user allows
(search, models, dashboard, activity, collections, tags, categories, authors, images,
model files, imports, everything else), set beside the MCP tools in a sectioned Token
permissions dialog. Existing and new tokens get every scope, so integrations such as
Homarr and holm keep working; a refused request names the scope it needs.
2026-10-21 17:57:28 +02:00
Tautvydas Derzinskas 0d0eeaf7a8 Merge pull request #111 from Ruivalim/feat/mcp-endpoint
feat: MCP endpoint for AI assistants, with tools chosen per API token
2026-10-21 16:57:17 +02:00
Tautvydas Derzinskas 8b4653e415 fix: harden mesh check against bad indices and tidy review follow-ups
- Reject triangle indices outside the vertex list instead of stalling the queue
- Leave degenerate triangles out of body bounding boxes
- Skip the quality fetch without a print id and never show a previous print's result
- Disable the per-check switches while a save is in flight
2026-10-21 08:55:58 +02:00
Tautvydas Derzinskas dec1b0dbe3 feat: admin MCP access, token permissions dialog, and review fixes
Follow-up to the review of the MCP endpoint, after merging develop.

Backend
- Instance-wide MCP access an admin sets (Off / Read only / Read and
  change, default Read and change), at GET/POST /settings/mcp and logged
  as mcp_access_changed. Off turns every token away at /api/mcp; Read
  only offers and answers only the tools that read, refuses turning a
  write tool on, and keeps a token's earlier write choices so they come
  back with Read and change. GET /profile/api-token carries mcp_access
  and only the tools it offers.
- Model links come from the public URL an admin saved, not the
  PUBLIC_URL env var it's only seeded from.
- An import refuses a category that isn't the user's own, for POST
  /import and import_model alike.
- add_to_collection inserts and logs only the models it actually adds.
- get_import_status refuses a task the web app started instead of
  failing on its result.
- The migration is now 20261030120000_api_token_mcp_tools, after every
  migration on develop and on open branches.
- Tests for each access level, the category check, a web app task id
  and the logged count.

Frontend
- The token's MCP tools move off the profile into a Token permissions
  dialog behind a cog beside the token, with MCP as its first section
  so the REST API's permissions can join it later.
- Each tool is a row: a small CSS tile picturing what it does (moving
  only while its row is hovered or focused, still for reduced motion,
  greyed when denied), its name and description, and a Deny / Allow
  Segmented control. Tools are grouped by whether they read or change
  the library.
- Admin Auth page: an AI assistants (MCP) section to set the access.
- The connect command gets a copy button and is hidden while MCP is off.
- Regenerating says the token's tools go back to the read-only ones.
- Save errors go through toasts.
- Spanish and French strings for every MCP key, and the new keys in all
  four languages.

Docs
- mcp.md and api-token.md: the Token permissions dialog, the admin
  setting, the regenerate reset, and what an assistant reading scraped
  descriptions could be talked into.
2026-10-21 08:47:49 +02:00
Tautvydas Derzinskas 12a6375832 Merge branch 'develop' into feat/mcp-endpoint 2026-10-21 08:47:09 +02:00
Tautvydas Derzinskas f913710cc4 feat: check models for print problems when they are opened
Closes #37. The first time a model is opened, each of its STL, OBJ and 3MF
files is checked in the render worker for holes, non-manifold edges, flipped
or inside-out faces, loose fragments, missing 3MF parts, damaged files and an
unlikely size. The rules follow ADMesh and Blender's 3D Print Toolbox.

The model page shows a scan overlay while it runs, then a tick or a
severity-coloured warning beside 3D Preview that opens a report with an
animated tile per problem. Results are saved per plate and rechecked only
when QUALITY_CHECK_VERSION changes.

Admins can switch checks off as a whole or per problem under Rendering;
severity and switched-off problems apply when results are read, so neither
needs a recheck. Checks are on by default.
2026-10-21 07:41:24 +02:00
Tautvydas Derzinskas 8db1c02f07 Merge pull request #108 from TautvydasDerzinskas/feat/reset-to-defaults
Feat/reset to defaults
2026-10-20 20:39:57 +02:00
Tautvydas Derzinskas d5cd155794 fix: roll a failed theme save back to the last saved theme 2026-10-20 20:33:39 +02:00
Tautvydas Derzinskas ef14f54221 fix: guard tag rewrites against concurrent edits, pluralise merge count, fix lt wording 2026-10-20 20:12:31 +02:00
Rui Valim 04e97197d7 fix(mcp): rank list_tags by use and let it narrow, instead of every tag at once
A real library of 488 models has 4,306 tags: the whole list came to 63 KB,
more of an assistant's context than one answer should take. It now
returns the most used 200 by default, with how many models have each,
and takes a query to narrow them.
2026-10-20 15:00:20 -03:00
Tautvydas Derzinskas 1a44b87cdc fix: count suffixed renames, roll back failed theme saves, keep reset dialog open on error 2026-10-20 19:58:08 +02:00
Rui Valim 699fa8a1c5 feat(frontend): offer the MCP tools that change the library, with a confirm
They're marked as changing the library, and turning one on asks first.
2026-10-20 14:54:42 -03:00
Tautvydas Derzinskas a0dbba8058 feat: sort, bulk actions and merge for collections and tags
Collections sort by newest, name or most models; tags gain a newest sort. Both pages get select mode with merge, bookmark and delete. Merging asks which one to keep and previews the result: the kept one's new model count, what is deleted, a bookmark moving over and syncs that stop. Built-in collections sit select mode out.
2026-10-20 19:50:56 +02:00
Tautvydas Derzinskas 825e8395d8 refactor: share the selection hook, toolbar and tick across grids 2026-10-20 19:50:42 +02:00
Rui Valim ccb588361e feat(frontend): choose an API token's MCP tools on the profile
The API token section lists the MCP tools with a box each, saved as it's
ticked, and shows the command to connect Claude Code with the new token
and this instance's address. Changing the tools is logged.
2026-10-20 14:23:38 -03:00
Tautvydas Derzinskas f8424dcb23 feat: reset categories to the starter tree, previewing what changes 2026-10-20 19:22:56 +02:00
Tautvydas Derzinskas 3c3d19a3b7 feat: reset appearance settings to their defaults 2026-10-20 19:22:30 +02:00
Tautvydas Derzinskas 0d505b716a feat: keep a model's pictures and supporting files beside its model files
Gallery and description images, plate thumbnails and renders now live in an
Images folder next to the model's files (Print.assetsPath), and supporting and
prepared files sit beside the plates, named through the storage template. They
move with the model when the storage structure changes, and the storage browser
lists them by kind.

Models from before keep working: reads fall back to the old shared folders, and
the first start runs the storage move to bring their files over, then clears
what's left in those folders.
2026-10-20 15:09:19 +02:00
Tautvydas Derzinskas 401cc38461 fix: retry a dashboard row's render when its url changes 2026-10-20 14:19:36 +02:00
Tautvydas Derzinskas 74ca5cbc0e refactor: read tag mosaic pictures once for both kinds 2026-10-20 14:07:44 +02:00
Tautvydas Derzinskas 6dac5555e7 fix: order theme saves, reset hover slideshow per account, address review 2026-10-20 13:51:54 +02:00
Tautvydas Derzinskas 4e3699ed45 feat: show provider logos and names in the dashboard's top providers 2026-10-20 13:36:00 +02:00
Tautvydas Derzinskas 926c5d345b feat: add render colour, graphite accent and hover slideshow toggle
Appearance gains a render colour that tints generated renders, the dashboard lists, tag tiles and the 3D preview.
It follows the accent until picked apart, and offers the accents plus an untinted light grey. A graphite accent
joins the palette, light grey in the dark theme so it stays visible. The hover slideshow on model cards can be
turned off, and the language picker moves to the top.

The dashboard's own Thumbnails option is gone: its lists and the tag tiles now lead with pictures or renders as
the model cards do, tags from a mosaic of the models' renders. The one-colour dashboard icon is no longer made.
2026-10-20 13:32:53 +02:00
Tautvydas Derzinskas 81bc40ab70 fix(i18n): pluralise the selection count and fix French wording 2026-10-20 12:27:12 +02:00
Tautvydas Derzinskas c1aa6e6237 fix(i18n): add missing Spanish and French strings
Fill the 232 keys es and fr lacked, model card toggle included, and drop
16 keys English no longer has.
2026-10-20 12:19:17 +02:00
Tautvydas Derzinskas 959233ece9 Merge pull request #103 from ldbl1/develop
feat(i18n): add Spanish and French translation files
2026-10-20 12:10:33 +02:00
Tautvydas Derzinskas 5dc3086e77 fix: reset model render state when its url changes
Start retries over for a new render and drop a status check that returns
for a render no longer shown.
2026-10-20 12:03:26 +02:00
Tautvydas Derzinskas e76666e291 fix: ignore stale card preview saves and render checks
Queue card-preview saves so the last pick sticks, drop failures from
superseded picks or a previous account, and ignore a render check that
returns after its ModelRender is gone.
2026-10-20 11:54:19 +02:00
Tautvydas Derzinskas ddfe33a4bd Merge remote-tracking branch 'origin/develop' into feat/card-preview-renders
# Conflicts:
#	frontend/src/App.tsx
#	frontend/src/components/Layout/ConfigurationDialog/AppearancePanel.tsx
2026-10-20 11:39:24 +02:00
Tautvydas Derzinskas 678c4802d7 fix: address card preview review comments
Retry thumbnail adoption for a cached render, reset card and model-page
render state per print, scope the card-preview choice to the signed-in
account and put it back when saving fails.
2026-10-20 11:37:44 +02:00
Tautvydas Derzinskas 14126dee8c fix: keep accent per account and readable in light mode
Ignores a theme answer for a token that's since changed, resets the accent to the default on sign-out or when none is saved, only lets the latest accent pick revert on a failed save, and gives amber a darker selected-menu text in light mode.
2026-10-20 11:08:19 +02:00
Tautvydas Derzinskas 908ae80b5b feat: tint generated model renders with the accent
Model cards can lead with the model's own pictures (default) or with our render, a choice saved per user in Appearance. The server draws each model once in grey shading on transparent, from the first file it can draw, simplifying oversized meshes and viewing flat models from above; the browser tints it with the accent, so every theme and accent shows at once. The model page's 3D preview offers the accent palette and opens in the chosen accent.
2026-10-20 11:03:54 +02:00
Lorodo 11b2bd7b5b fix(i18n): format translation files with prettier 2026-10-20 11:03:52 +02:00
Lorodo 205a4cf7f1 feat(i18n): add Spanish and French translation files 2026-10-20 10:53:58 +02:00
Tautvydas Derzinskas d26f730bee feat: let users pick an accent color
Appearance gains an accent picker: Thingport green plus colors from provider brands (Thingiverse, Printables, Thangs, MyMiniFactory, Cults3D). The choice is stored per user beside the theme and recolors the app, the logo and its seasonal overlays at once.
2026-10-20 10:16:55 +02:00
Tautvydas Derzinskas 3b8319e603 Merge pull request #97 from TautvydasDerzinskas/feat/multi-select-models
feat: multi-select models in grids with bulk actions
2026-10-20 08:18:25 +02:00
Tautvydas Derzinskas 43463d0268 fix: split bulk requests over 500, cancel on confirm dismissal, passive badge in select mode 2026-10-20 08:12:57 +02:00
Tautvydas Derzinskas 96300510b4 fix(i18n): require each locale's plural forms in i18n:check
Lithuanian lacked _few forms, so counts like 2 fell back to English.
Add them, fix _other wording for 10+, and update stale docs and comments.
2026-10-20 07:57:22 +02:00
Tautvydas Derzinskas fe5dbecdc5 feat: multi-select models in grids with bulk actions
A select toggle above each model grid (models, collections, tags, search,
author) switches clicks from opening a card to selecting it. The selected
models can then be added to or removed from a collection, favourited or
unfavourited, downloaded as one zip, deleted, or sent to AI categorization
or description improvement.

The AI actions start a single library run limited to the selected models,
so they get the run's progress bar and one summary notification instead
of one provider call and notification per model.

Closes #91
2026-10-20 07:53:55 +02:00
Tautvydas Derzinskas 10451a9f11 feat(i18n): add a language by dropping in its locale file
Languages come from the locale files, named in themselves via Intl.DisplayNames, with missing keys falling back to English. The week start follows the locale, the Appearance picker switches to a Select past four languages, and docs/TRANSLATING.md plus an i18n:check script guide translators.
2026-10-20 07:25:46 +02:00
Tautvydas Derzinskas c8b9fa753f fix: fetch every day the widest heatmap card can show 2026-10-20 07:23:08 +02:00
Tautvydas Derzinskas c65e712a31 feat: preview dashboard panels as tiles and add an activity heatmap panel 2026-10-20 07:01:16 +02:00
Tautvydas Derzinskas e76fbf3b58 feat: add an About view for each provider
A dialog with the provider's description, dependencies, imports and setup
steps, an animation of its import path in the provider's colour, and a table
comparing all providers. Opens from Configuration > Providers (About), the
logo or name in Administration > Providers, the dashboard's provider chips and
model provider badges.
2026-10-20 05:57:41 +02:00
Tautvydas Derzinskas 37094b56db refactor: add Cults3D error handling and enhance sync provider picker with logos 2026-10-20 05:34:53 +02:00
Tautvydas Derzinskas 930b9b48db feat: add Cults3D provider
Imports Cults3D models, anyone's likes and the user's own printlists, and
syncs them. Metadata comes from Cults3D's GraphQL API with each user's own
nickname and API key. The API never hands out files, and the site's pages are
behind a Cloudflare check only a browser passes, so Thingport Grab sends the
browser's _session_id and cf_clearance cookies with its User-Agent; with
them the server orders a free model for nothing, as its Download button
does, and follows the download page to the signed file link (CloudFront, or
Cults3D's Scaleway bucket for older models). Paid models download once
bought. A Cloudflare block defers a sync until the next visit with Grab.
2026-10-20 05:08:08 +02:00
Tautvydas Derzinskas 27c42fe790 feat: show collection descriptions in the category banner style
A collection's description sits in the same tinted box as a category's, between the sort options and the grid. The box is now a shared InfoBanner.
2026-10-20 00:09:22 +02:00
Tautvydas Derzinskas 87db3f0ff0 feat: pick mapped provider categories by name
Each provider gets a Manage button that opens its categories as chips, by name, instead of a field of ids. The names come from a catalog checked in with the app, refreshed by backend/scripts/syncProviderCategories.ts. Stored values keep their shape.
2026-10-20 00:01:04 +02:00
Tautvydas Derzinskas 0aff9e9a9e feat: show model sources as provider badges
Cards and the model page show the provider's logo on a round badge instead of a text chip; the chip shows in its tooltip.
2026-10-19 23:44:03 +02:00
Tautvydas Derzinskas 70e3821e1a refactor: remove bookmarklet from provider settings
The bookmarklet stays in Add > Import, its one place now.
2026-10-19 23:36:40 +02:00
Tautvydas Derzinskas 2591714c0c feat: add Thangs provider
Imports Thangs models, likes and collections, and syncs them. Metadata is
public; files need the user's own sign-in, which Thingport Grab sends and
Thingport renews from the refresh token. Paid models download once owned;
print-only ones are refused before any download. Free accounts' daily
download limit stops a batch and defers the rest of a sync to its next check.
2026-10-19 23:36:07 +02:00