## Summary Pushes ArtCraft Launcher ([storytold/craft-launcher](https://github.com/storytold/craft-launcher)) as the recommended way to install the Crafting Apps. One install covers every app and keeps them up to date. Each app keeps its own installers. - **`/apps` header:** the main button is now **Download ArtCraft Launcher**. It detects the visitor's OS and links straight to the right installer, with a small line naming the file (e.g. "For macOS · Disk image (Universal)"). Below the buttons, one line says it's the recommended option and that each app also has its own installers. - **`/apps/<slug>` Get-it section:** split into two numbered options. **Option 1 · Recommended** is the launcher block: the pitch on the left, and on the right a sunken panel with the version, a full-width download button and an About link. **Option 2 · Standalone** ("Just <App>? Download it standalone.") comes next, followed by the app's existing per-platform installers, unchanged. - **Fallback:** when the OS can't be detected (phones, tablets), the launcher buttons go to the launcher's GitHub release page. ## Implementation - `CRAFT_LAUNCHER_RELEASE` in `crafting-app-releases.ts` holds the launcher's version (v0.1.0). It reuses the shared asset list minus the macOS CLI zip, and its files are named `artcraft-launcher-*`. Setting it to `null` hides every launcher button. - `src/lib/craft-launcher.ts` holds the name, repo, download list and release-page URL. `src/components/apps/launcher-callout.tsx` holds the app-page block. - `craftReleaseDownloads` now delegates to a new repo-based `releaseDownloads` helper, which the launcher also uses. - `LauncherDownloadButton` in `app-downloads.tsx` reuses the existing OS and CPU detection. - Download clicks are already tracked as `app_download` (`app_name: craft-launcher`) by the link classifier in `analytics.ts`. - Small fix: the platform cards get `min-w-0`, so long filenames no longer push the page wider than the screen on narrow phones. ## Testing - `npm run typecheck` and `npm run build` pass. - All 20 launcher release URLs on the page return 200 on GitHub. - Checked in Chromium with a macOS user agent: `/apps` and app pages in light and dark mode, and at 1440px, 390px and 360px. Nothing overflows the page horizontally. This needs a deploy of `artcraft-website-next` before getartcraft.com changes. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude <noreply@anthropic.com>
Frontend
This is the Nx workspace for ArtCraft web apps and shared libraries. The desktop frontend is maintained in storytold/artcraft.
All commands to run these projects are performed from this directory (except the repo-root launcher scripts noted below).
Requirements
- Node.js 20+ (Nx 21 / Vite 6 requirement). Install via nvm,
nodejs.org, or
brew install node. - npm (ships with Node).
We use npm, not pnpm. pnpm was briefly adopted ("add pnpm to solve build issues") and later removed ("fix(frontend): consume video-editor libs via nx path aliases, drop pnpm"). If you have leftovers from that era — a
pnpm-lock.yaml,pnpm-workspace.yaml, or anode_modules/.pnpmdirectory — npm installs will fail (typically withENOTEMPTYrename errors). See Troubleshooting below.
Install dependencies
npm install
Running the apps in dev mode
From the repository root, the launcher scripts (these preflight your environment, install dependencies, and free the dev port first):
./script/website/unix_frontend_website_dev.sh # artcraft-website-next (marketing site), port 3000
./script/website/unix_frontend_webapp_dev.sh # artcraft-webapp (user dashboard), port 4201
Run the webapp from artcraft-services, not the separate artcraft desktop
checkout. The webapp launcher also works from another directory when invoked
by its full or relative path:
../artcraft-services/script/website/unix_frontend_webapp_dev.sh
Or directly from this directory:
npx nx dev @frontend/artcraft-webapp
Building
npx nx build artcraft-webapp
Netlify deploys run apps/<app>/script/netlify_build.sh (see each app's
netlify.toml).
Troubleshooting
npm install fails with ENOTEMPTY: directory not empty, rename ...
Your node_modules tree is corrupted — usually an interrupted install, or a
tree written by pnpm back when the repo briefly used it. Fix:
./clean_modules.sh
npm install
Or the manual minimum:
rm -rf node_modules .nx pnpm-lock.yaml pnpm-workspace.yaml
npm install
Stale build state after switching branches
Call this when starting on main or a new branch:
./clean_modules.sh
It removes all dist/ outputs, resets the nx cache, and removes
node_modules.
Import aliases
The names for @frontend and @storyteller come from the package.json file
in the libs folder:
import { Login } from "@frontend/login";
import { api } from "@storyteller/api";
For shared UI components, import from @storyteller/ui-[componentname]:
import { Button } from "@storyteller/ui-button";
import { Modal } from "@storyteller/ui-modal";
Generating a new component library
# 1. Generate the library
npx nx g @nx/react:library libs/components/toaster --import-path=@storyteller/ui-toaster --bundler=vite
npm install
# 2. Import it somewhere in code
# 3. Sync and build
nx sync
nx build