unsloth/studio
Daniel Han 71232f749a
studio/frontend: fix onboarding CSP violations (#5658)
* studio/frontend: fix onboarding CSP violations

Two onboarding-only CSP violations were showing up in the browser
console on a default install:

* `WizardSidebar` rendered the brand sticker from
  `https://unsloth.ai/cgi/image/unsloth_sticker_no_shadow_*.png`,
  which is not in the Studio CSP `img-src` allowlist. The sticker
  rendered as a broken image.
* `Confetti` defaulted `globalOptions.useWorker` to `true`, so
  `canvas-confetti` tried to spawn an OffscreenCanvas worker from
  a `blob:` URL. CSP `script-src 'self'` blocks it; three blocked-
  worker errors fired on the final wizard step.

Use the bundled `/sticker.png` for the brand image, and default
the Confetti wrapper to the main-thread fallback. CSP stays tight.

Resolves #5657.

* studio/frontend: harden CSP confetti fix + BASE_URL sticker

Address review feedback on #5658:

1. confetti.tsx
   - Hoist the default globalOptions to a module-scope constant so the
     prop default has a stable identity across renders (canvasRef's
     dependency array no longer churns every render).
   - Always force useWorker:false at the confetti.create site, regardless
     of what the caller passed in globalOptions. Previously a caller that
     set `{ resize: true }` would silently re-enable the worker and trip
     the CSP block again.
   - Add a lazily-mounted, module-scoped CSP-safe instance and route
     ConfettiButton through it instead of the global confetti() (which
     defaults to useWorker:true and would otherwise violate CSP).

2. confetti-fireworks.ts
   - Replace the direct confetti(...) calls (global instance, default
     worker on) with calls to a shared confetti.create instance with
     useWorker:false. The guided-tour completion confetti no longer
     trips the CSP block.

3. wizard-sidebar.tsx
   - Use import.meta.env.BASE_URL prefix on the sticker src so the asset
     still resolves when Studio is deployed under a subpath (e.g.
     /studio/). Defaults to "/" so single-host installs are unchanged.

tsc clean, bun run build clean, bundle confirms the changes
(`{resize:!0,useWorker:!1}` appears in every relevant call site).

* studio/tour: preserve opts.zIndex on shared confetti fireworks canvas

Address chatgpt-codex-connector inline review on #5658 follow-up:

When canvas-confetti runs against a caller-provided canvas (which is
what we need for the CSP fix), the per-fire `zIndex` option is ignored
for stacking purposes -- the canvas element's own CSS `z-index` is what
the browser uses. The previous follow-up hard-coded the shared canvas
to `z-index:99999`, so callers that pass `opts.zIndex` (or expect the
old global-confetti behavior of being able to lower fireworks under an
overlay) silently lost that knob.

Apply `opts.zIndex` to the shared canvas's `style.zIndex` on each call
(default 99999 still used when omitted). Same default; behavior is now
restored for the lower/raise case.

The current only caller (`guided-tour.tsx` invoking
`fireConfettiFireworks()` with no args) is unaffected since it never
provided `opts.zIndex`. Public API contract is preserved.

* studio/frontend: drop dead ConfettiButton + BASE_URL onboarding mascots

- confetti.tsx: remove unused ConfettiButton + getSharedConfettiFire singleton (0 callsites)
- splash-screen.tsx, wizard-content.tsx: prefix sloth mascot paths with import.meta.env.BASE_URL so onboarding works under non-root subpaths
- confetti-fireworks.ts: drop dead per-fire zIndex from defaults (caller-provided canvas ignores it; we already drive stacking via canvas style)

* studio/frontend: BASE_URL on HF icon + race-safe shared fireworks init

- dataset-step.tsx: prefix the Hugging Face dataset-source icon with import.meta.env.BASE_URL so it resolves correctly under non-root deployments. Last onboarding asset that was still root-relative after the earlier BASE_URL sweep.
- confetti-fireworks.ts: cache the in-flight init promise in getSharedFire so two same-tick callers share the dynamic import and the appended overlay canvas. Previously two concurrent fireConfettiFireworks() calls each appended a fixed full-screen canvas and orphaned the first one.

* studio/frontend: tighten confetti CSP comments

---------

Co-authored-by: danielhanchen <michaelhan2050@gmail.com>
2026-05-22 05:02:19 -07:00
..
backend chore(deps): bump the npm-oxc-validator group across 1 directory with 2 updates (#5667) 2026-05-22 04:46:20 -07:00
frontend studio/frontend: fix onboarding CSP violations (#5658) 2026-05-22 05:02:19 -07:00
src-tauri studio: regenerate desktop launcher on unsloth studio update (macOS + Linux + Windows) (#5577) 2026-05-19 05:49:10 -07:00
__init__.py Final cleanup 2026-03-12 18:28:04 +00:00
install_llama_prebuilt.py tests/studio: lock in Windows GPU detection fix (#5106) with a synthetic CI test (#5376) 2026-05-18 00:06:01 -07:00
install_python_stack.py studio: skip flash-attn install on Blackwell GPUs (sm_100+) (#5420) 2026-05-14 18:13:50 +04:00
LICENSE.AGPL-3.0 Add AGPL-3.0 license to studio folder 2026-03-09 19:36:25 +00:00
package-lock.json ci: advisory lockfile supply-chain audit (no install-script changes) (#5604) 2026-05-19 05:56:56 -07:00
package.json ci: advisory lockfile supply-chain audit (no install-script changes) (#5604) 2026-05-19 05:56:56 -07:00
setup.bat Final cleanup 2026-03-12 18:28:04 +00:00
setup.ps1 studio: regenerate desktop launcher on unsloth studio update (macOS + Linux + Windows) (#5577) 2026-05-19 05:49:10 -07:00
setup.sh Route CPU-only Linux x86_64 to ggml-org/llama.cpp prebuilts (#5302) 2026-05-05 23:22:22 -07:00
Unsloth_Studio_Colab.ipynb studio: add --local to setup.sh + overlay unsloth-zoo from git main (#5252) 2026-05-02 08:51:56 +04:00