version: '3' # Tasks operate from the workspace root (frontend/). Editor commands pass # `editor` as the vite project root (positional after `build` / before the # mode flag) or use `--project editor/...` for tsc — so the editor lives # under frontend/editor/ without each task needing a cd. tasks: install: desc: "Install dependencies" run: once cmds: - '{{ if eq .CI "true" }}npm ci{{ else }}npm install{{ end }}' sources: - package-lock.json - package.json status: - test -d node_modules env: CI: '{{ .CI | default "false" }}' prepare:env: internal: true run: when_changed deps: [install] vars: MODE: '{{.MODE | default ""}}' cmds: - npx tsx editor/scripts/setup-env.mts{{if .MODE}} --{{.MODE}}{{end}} sources: - editor/scripts/setup-env.mts generates: - editor/.env.local - editor/.env{{if .MODE}}.{{.MODE}}{{end}}.local prepare:icons: internal: true run: once deps: [install] cmds: - node editor/scripts/generate-icons.js prepare: desc: "Set up dev environment" run: when_changed vars: MODE: '{{.MODE | default ""}}' deps: - task: prepare:env vars: { MODE: '{{.MODE}}' } - prepare:icons # ============================================================ # Development # ============================================================ dev:_run: internal: true ignore_error: true vars: MODE: '{{.MODE}}' PORT: '{{.PORT | default "5173"}}' BACKEND_URL: '{{.BACKEND_URL | default "http://localhost:8080"}}' OPEN: '{{.OPEN | default ""}}' env: BACKEND_URL: '{{.BACKEND_URL}}' cmds: - npx vite editor --mode {{.MODE}} --port {{.PORT}}{{if .OPEN}} --open{{end}} dev: desc: "Start frontend dev server" cmds: - task: dev:proprietary vars: { PORT: '{{.PORT}}', BACKEND_URL: '{{.BACKEND_URL}}', OPEN: '{{.OPEN}}' } dev:core: desc: "Start frontend dev server in core mode" deps: [prepare] cmds: - task: dev:_run vars: { MODE: core, PORT: '{{.PORT}}', BACKEND_URL: '{{.BACKEND_URL}}', OPEN: '{{.OPEN}}' } dev:proprietary: desc: "Start frontend dev server in proprietary mode" deps: [prepare] cmds: - task: dev:_run vars: { MODE: proprietary, PORT: '{{.PORT}}', BACKEND_URL: '{{.BACKEND_URL}}', OPEN: '{{.OPEN}}' } dev:saas: desc: "Start frontend dev server in SaaS mode" deps: - task: prepare vars: { MODE: saas } cmds: - task: dev:_run vars: { MODE: saas, PORT: '{{.PORT}}', BACKEND_URL: '{{.BACKEND_URL}}', OPEN: '{{.OPEN}}' } dev:desktop: desc: "Start frontend dev server in desktop mode" deps: - task: prepare vars: { MODE: desktop } cmds: - task: dev:_run vars: { MODE: desktop, PORT: '{{.PORT}}', BACKEND_URL: '{{.BACKEND_URL}}', OPEN: '{{.OPEN}}' } dev:prototypes: desc: "Start frontend dev server in prototypes mode" deps: [prepare] cmds: - task: dev:_run vars: { MODE: prototypes, PORT: '{{.PORT}}', BACKEND_URL: '{{.BACKEND_URL}}', OPEN: '{{.OPEN}}' } dev:portal: desc: "Start developer portal dev server" deps: [install] cmds: - npx vite portal --port {{.PORT | default "5173"}}{{if .OPEN}} --open{{end}} # ============================================================ # Build # ============================================================ build: desc: "Production build (default mode)" deps: [prepare] cmds: - npx vite build editor build:core: desc: "Build for core mode" deps: [prepare] cmds: - npx vite build editor --mode core build:proprietary: desc: "Build for proprietary mode" deps: [prepare] cmds: - npx vite build editor --mode proprietary build:saas: desc: "Build for SaaS mode" deps: - task: prepare vars: { MODE: saas } cmds: - npx vite build editor --mode saas build:desktop: desc: "Build for desktop mode" deps: - task: prepare vars: { MODE: desktop } cmds: - npx vite build editor --mode desktop build:prototypes: desc: "Build for prototypes mode" deps: [prepare] cmds: - npx vite build editor --mode prototypes build:portal: desc: "Build developer portal" deps: [install] cmds: - npx vite build portal storybook: desc: "Start Storybook dev server" deps: [install] cmds: - npx storybook dev -p 6006 {{.CLI_ARGS}} storybook:build: desc: "Build static Storybook" deps: [install] cmds: - npx storybook build {{.CLI_ARGS}} # ============================================================ # Code quality # ============================================================ lint: desc: "Run linting" deps: [install] cmds: - task: lint:eslint - task: lint:dpdm lint:eslint: desc: "Run ESLint linting" deps: [install] cmds: - npx eslint --max-warnings=0 lint:dpdm: desc: "Run circular import linting" deps: [install] cmds: # Globs so dpdm walks the whole tree. dpdm expands the braces itself, so this is # shell-agnostic. Covers editor, portal, and the shared design system. - npx dpdm "editor/src/**/*.{ts,tsx}" "portal/src/**/*.{ts,tsx}" "shared/**/*.{ts,tsx}" --circular --no-warning --no-tree --exit-code circular:1 lint:fix: desc: "Auto-fix lint issues" deps: [install] cmds: - npx eslint --fix format: desc: "Auto-fix code formatting" deps: [install] cmds: - npx prettier --write . format:check: desc: "Check code formatting" deps: [install] cmds: - npx prettier --check . fix: desc: "Auto-fix lint and format" cmds: - task: format - task: lint:fix typecheck: desc: "Typecheck default build of the app" cmds: - task: typecheck:proprietary typecheck:core: desc: "Typecheck core build variant" deps: [prepare] cmds: - npx tsc --noEmit --project editor/src/core/tsconfig.json typecheck:proprietary: desc: "Typecheck proprietary build variant" deps: [prepare] cmds: - npx tsc --noEmit --project editor/src/proprietary/tsconfig.json typecheck:saas: desc: "Typecheck SaaS build variant" deps: - task: prepare vars: { MODE: saas } cmds: - npx tsc --noEmit --project editor/src/saas/tsconfig.json typecheck:desktop: desc: "Typecheck desktop build variant" deps: - task: prepare vars: { MODE: desktop } cmds: - npx tsc --noEmit --project editor/src/desktop/tsconfig.json typecheck:cloud: desc: "Typecheck cloud shared layer (standalone)" deps: [prepare] cmds: - npx tsc --noEmit --project editor/src/cloud/tsconfig.json typecheck:scripts: desc: "Typecheck scripts" deps: [prepare] cmds: - npx tsc --noEmit --project editor/scripts/tsconfig.json typecheck:prototypes: desc: "Typecheck prototypes build variant" deps: [prepare] cmds: - npx tsc --noEmit --project editor/src/prototypes/tsconfig.json typecheck:portal: desc: "Typecheck developer portal build variant" deps: [install] cmds: - npx tsc --noEmit --project portal/tsconfig.json typecheck:shared: desc: "Typecheck the shared design system" deps: [install] cmds: - npx tsc --noEmit --project shared/tsconfig.json typecheck:all: desc: "Typecheck all build variants" cmds: - task: typecheck:core - task: typecheck:proprietary - task: typecheck:saas - task: typecheck:desktop - task: typecheck:cloud - task: typecheck:scripts - task: typecheck:prototypes - task: typecheck:portal - task: typecheck:shared # ============================================================ # Quality Gate # ============================================================ check: desc: "Quick quality gate for local development" cmds: - task: typecheck - task: lint - task: format:check - task: test check:all: desc: "Full CI quality gate" cmds: - task: typecheck:all - task: lint - task: format:check - task: build - task: build:portal - task: test - task: storybook:build # ============================================================ # Test # ============================================================ test: desc: "Run tests" deps: [prepare] cmds: - npx vitest run --root editor test:watch: desc: "Run tests in watch mode" deps: [prepare] cmds: - npx vitest --watch --root editor test:coverage: desc: "Run tests with coverage (one-shot; CI-friendly)." deps: [prepare] cmds: # `vitest run` makes this CI-safe (the bare `vitest` form enters watch # mode). Explicit reporter list because v8 + json-summary is what the # coverage-summary.py helper consumes; html/text are kept for humans. # # reportsDirectory is pinned to ./coverage relative to vitest's root # (--root editor), so output lands at frontend/editor/coverage/. The # CI upload step reads from that path. An earlier attempt with # `./editor/coverage` double-nested into frontend/editor/editor/coverage; # pinning future-proofs against vitest changing the default. - > npx vitest run --root editor --coverage --coverage.provider=v8 --coverage.reporter=text-summary --coverage.reporter=json-summary --coverage.reporter=html --coverage.reportsDirectory=./coverage # ============================================================ # Code Generation # ============================================================ licenses:generate: desc: "Generate frontend license report" deps: [install] cmds: - node editor/scripts/generate-licenses.js