## Summary
Resolves all 66 SonarCloud **typescript:S9383** findings ("Promises must
be awaited, end with a call to .catch, end with a call to .then with a
rejection handler or be explicitly marked as ignored with the `void`
operator") in `frontend/libs/components`, across 41 files:
| Library | Findings |
|------------------------|----------|
| `upload-modal` | 14 |
| `promptbox` | 11 |
| `settings-modal` | 11 |
| `pagescene` | 10 |
| `video-editor` | 7 |
| `lightbox-modal` | 3 |
| `pagedraw` | 3 |
| `generation-list` | 2 |
| `help-menu` | 2 |
| `gallery-modal` | 1 |
| `pricing-modal` | 1 |
| `provider-setup-modal` | 1 |
The flagged expressions include settings and session loaders
(`fetchData()`, `fetchSession()`) called from effects, upload starts and
retries in the upload modals, enqueue handlers in the prompt boxes,
`audio.play()` and `el.play()` previews, scene render and load calls in
`pagescene`, bookmark actions in `video-editor`, and async IIFEs.
This is part 3 of 3 for artcraft's 157 S9383 findings. Part 1 (Tauri
libraries) is #2805, and part 2 (`apps/artcraft/app`) is #2806.
Some of these files are also changed by open PRs for unrelated reasons,
for example #2615 (settings panes), #2519, #2520 and #2083. Each change
here inserts one word at the start of a statement, so a rebase either
way is trivial.
## Approach
This ports the approach of storytold/artcraft-services#179, which fixes
the same rule in artcraft-services. **#179 is still open and unmerged.**
This PR follows its approach and does not depend on it.
- Each flagged expression is a fire-and-forget promise: a listener
`setup()`, an `unlisten.then(f => f())` cleanup, a loader called from an
effect, an upload kicked off from a handler, or an async IIFE. Prefixing
it with `void` marks the ignored promise explicitly, which is the fix
the rule documents.
- It deliberately does not add `.catch()` everywhere. These call sites
already handle failures inside the async function or surface them
through their own state, and empty handlers would hide errors.
- Async IIFEs become `void (async () => …)()`. `if (cond) call()`
becomes `if (cond) void call()`.
- There is no behaviour change. `void` only discards the promise value,
which was already being discarded.
Each insertion is placed at the exact `textRange` start offset of the
SonarCloud finding, with no other edits.
## Testing
- Each changed file parses with `esbuild <file>`, using the same check
as #179.
- I parsed each changed file with the TypeScript 5.9 compiler API
(`createSourceFile`). That found no parse errors, and every inserted
`void` is either a whole expression statement or an arrow-function body
applied to a call, never part of a larger expression.
- `frontend/.eslintrc.json` has no `no-void` rule.
- I did not run the full Nx type-check, lint or test targets, because
`frontend/node_modules` is not installed in my environment. Please rely
on CI.
- No tests are added. Discarding an already-discarded promise value is
not observable, so no test can fail before this change and pass after
it.
**Added by @dylanmtaylor, to clear the new-code duplication gate.** The
`void` lines sat inside copy-pasted code:
- `ProviderAccountBlock` replaces the identical `GrokAccountBlock` and
`MidjourneyAccountBlock`.
- `UploadFilesPanels` (file list, resize handle, previous/next; each
modal passes its preview) replaces the layout the 3D, Image and Splat
upload modals repeated.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
<!-- coderabbit-ai-generated:v1 -->
## Summary by CodeRabbit
* **New Features**
* Multi-file uploads across image, 3D, and splat workflows now share a
two-panel layout with file statuses, preview selection, removal, retry,
and previous/next navigation.
* Grok and Midjourney account controls now use a shared interface that
displays login status and provides available connect or disconnect
actions. Failed credential checks clear the displayed session, and
account controls show a loading state while checking.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Co-authored-by: Dylan M. Taylor <dylan@dylanmtaylor.com>
ArtCraft
The IDE for artists.
https://github.com/user-attachments/assets/7339bd09-3e0d-44a7-a024-af9de64e4c11
Watch the two-minute ArtCraft demo on YouTube
Download ArtCraft · GitHub releases · Build from source
ArtCraft is the IDE for interactive AI image and video creation. Compose in 2D, stage scenes in 3D, and choose the models that fit your work. Turn prompting into crafting with visual tools for precise, repeatable results.
Show, Don't Tell: Advanced Crafting Features
Artists need control over composition, character identity, and camera placement. Build the scene before you generate it. Click any preview to view it at full size.
More previews are coming for scene blocking, canvas editing, and scene relighting.
Quick and Easy Prompting
Start with a prompt when you want to explore an idea quickly, then use the canvas and scene tools to refine it.
More previews are coming for image inpainting and image ingredients.
Models and Providers Supported within ArtCraft
| Provider | Models and workflows |
|---|---|
| ArtCraft | Images, video, music and sound, 3D meshes, and worlds. Browse the complete model catalog below. |
| Grok | Grok Imagine and Grok Video. |
| Midjourney | Midjourney image generation. |
| Sora | Sora 1, Sora 2, and GPT Image 1. |
| World Labs | Marble world generation with Gaussian splats. |
ArtCraft: the full 62-model catalog
† Currently disabled. ‡ Restricted model; not currently available in the desktop app.
Images (16)
| Family | Models |
|---|---|
| Nano Banana | Nano Banana; Nano Banana 2; Nano Banana Pro |
| GPT Image | GPT Image 1.5; GPT Image 2; GPT Image 2.5 Flare; GPT Image 2.5 Sunburst |
| FLUX | FLUX.1 [dev]; FLUX.1 [schnell]; FLUX 1.1 [pro]; FLUX 1.1 [pro] ultra |
| Seedream | Seedream 4; Seedream 4.5; Seedream 5 Lite; Seedream 5.0 Pro; Seedream 5.0 Pro Ultra |
Video (25)
| Family | Models |
|---|---|
| Seedance | Seedance 1.0 Lite †; Seedance 1.5 Pro; Seedance 2.0 |
| Kling | Kling 1.6 Pro; Kling 2.1 Pro †; Kling 2.1 Master †; Kling 2.5 Turbo Pro; Kling 2.6 Pro; Kling 3.0 Pro †; Kling 3.0 Standard † |
| Veo | Veo 2 †; Veo 3 †; Veo 3 Fast; Veo 3.1; Veo 3.1 Fast; Veo 3.1 Lite |
| Sora | Sora 2 †; Sora 2 Pro † |
| Vidu | Vidu Q3; Vidu Q3 Turbo |
| MiniMax | MiniMax H3; MiniMax H3 Turbo ‡; MiniMax H3 Ultra ‡ |
| Flux | Flux 3; Flux 3 Draft |
Music and sound (5)
| Family | Models |
|---|---|
| Suno | Suno Music; Suno Remix; Suno Sounds; Suno Sample |
| Seed Audio | Seed Audio 1.0 |
3D meshes (11)
| Family | Models |
|---|---|
| Hunyuan 3D | Hunyuan 3D 2.0; Hunyuan 3D 2.1; Hunyuan 3D 3; Hunyuan 3D 3 Sketch; Hunyuan 3D 3.1 Pro; Hunyuan 3D 3.1 Rapid; Hunyuan 3D 3.1 Part; Hunyuan 3D 3.1 Smart Topology |
| Tripo3D | Tripo3D H3.1 |
| Meshy | Meshy 6 |
| Rodin | Rodin 2.5 Fast |
Worlds and Gaussian splats (5)
| Family | Models |
|---|---|
| Marble | Marble 1.0; Marble 1.0 Draft; Marble 1.1; Marble 1.1 Plus |
| TripoSplat | TripoSplat |
Additional provider integrations are planned for Kling, Google, Runway, and Luma. We're also interested in supporting existing subscriptions with aggregators such as OpenArt and Freepik.
Downloads
- Stable releases for Windows, macOS, and Linux
- Latest builds on GitHub (including AppImage, DEB, RPM, Arch, and Flatpak packages)
- Linux packaging notes
- Build from source, including Linux
Documentation
- Development setup
- Linux packaging
- Developer documentation
- Desktop build and development scripts
- Roadmap
- License
License
ArtCraft is dual-licensed under MIT or Apache-2.0, at your option. Copyright (c) 2026 ArtCraft Team and the ArtCraft contributors. Required notices, including third-party material not covered by this license, are in NOTICE.

