diff --git a/.github/workflows/deploy-landing.yml b/.github/workflows/deploy-landing.yml new file mode 100644 index 0000000..2399f14 --- /dev/null +++ b/.github/workflows/deploy-landing.yml @@ -0,0 +1,70 @@ +name: Deploy landing + +# Publishes the landing + docs site (apps/landing) to GitHub Pages. +# - push to main -> build + deploy the live site (mx.rousanali.com) +# - pull_request -> build only (a check that the site still compiles) +# The custom domain is carried by apps/landing/public/CNAME, which Vite copies +# into dist/ so the Pages artifact always declares mx.rousanali.com. +# Only runs when the site or its build inputs actually change. + +on: + push: + branches: [main] + paths: + - 'apps/landing/**' + - '.github/workflows/deploy-landing.yml' + - 'pnpm-lock.yaml' + - 'package.json' + pull_request: + paths: + - 'apps/landing/**' + - '.github/workflows/deploy-landing.yml' + - 'pnpm-lock.yaml' + - 'package.json' + workflow_dispatch: + +# GitHub Pages deployment needs these; id-token lets deploy-pages authenticate. +permissions: + contents: read + pages: write + id-token: write + +# Allow one in-flight Pages deployment at a time; don't cancel a running one. +concurrency: + group: pages + cancel-in-progress: false + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - uses: pnpm/action-setup@v4 + + - uses: actions/setup-node@v4 + with: + node-version: 22 + cache: pnpm + + - run: pnpm install + + # Produces the static site (incl. the CNAME) at apps/landing/dist. + - run: pnpm landing:build + + # Package dist/ as the Pages artifact for the deploy job to consume. + - uses: actions/upload-pages-artifact@v3 + with: + path: apps/landing/dist + + deploy: + # Only publish from main; on PRs the build job above is just a check. + if: github.ref == 'refs/heads/main' && github.event_name != 'pull_request' + needs: build + runs-on: ubuntu-latest + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + steps: + - id: deployment + uses: actions/deploy-pages@v4 diff --git a/.gitignore b/.gitignore index 2bc6744..e228891 100644 --- a/.gitignore +++ b/.gitignore @@ -14,6 +14,13 @@ npm/LICENSE # dependencies node_modules/ +# VitePress docs-site build output + cache +docs/.vitepress/dist/ +docs/.vitepress/cache/ + +# landing + docs site build output +apps/landing/dist/ + # playwright screenshot/console artifacts .playwright-mcp/ diff --git a/CLAUDE.md b/CLAUDE.md index 65439e6..9c7a6e3 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -1,6 +1,6 @@ # mx — source & control panel for the mx system -This repo is the **source of truth** for **mx** ("multiplexer"), a system for running several features in parallel across shared repos using git worktrees. You are working on mx *itself* here — the CLI, the core library, the templates, the docs — not on any feature. The published CLI lives on npm as `@roulabs/mx` (command `mx`); the source is hosted at `github.com/roulabs/mx`. +This repo is the **source of truth** for **mx** ("multiplexer"), a system for running several features in parallel across shared repos using git worktrees. You are working on mx *itself* here — the CLI, the core library, the templates, the docs — not on any feature. The published CLI lives on npm as `@rousan/mx` (command `mx`); the source is hosted at `github.com/rousan/mx`. mx produces a **runtime**: an `mx/` folder somewhere on the device, containing `repos/`, `works/`, and a `CLAUDE.md` stamped from the templates shipped inside the CLI. The source repo and any runtime are fully **decoupled** — this repo is never tied to a particular runtime. @@ -14,7 +14,7 @@ A TypeScript pnpm monorepo. **Source code and publishable npm package live in se - **`packages/core` (`@mx/core`)** — pure, typed, unit-tested domain logic. Functions take inputs, return plain data, and `throw MxError`; they never `console.log` or `process.exit`, and never assume an on-disk layout (paths like the templates dir are passed in). - **`apps/cli` (`@mx/cli`, private)** — CLI source over `@mx/core`: arg parsing, cwd→`-n` inference, output formatting (`--porcelain` vs human), exit codes. Bundled by tsup into a single dependency-free entry. The package itself is private and never published; it exists only as a workspace member so pnpm can wire `@mx/core` in. -- **`npm/` (`@roulabs/mx`)** — the publishable package. `package.json` and `README.md` are committed (public metadata + user docs). `bin/mx.js`, `templates/`, and `LICENSE` are produced by `pnpm build` (gitignored). `npm publish` runs from this folder. +- **`npm/` (`@rousan/mx`)** — the publishable package. `package.json` and `README.md` are committed (public metadata + user docs). `bin/mx.js`, `templates/`, and `LICENSE` are produced by `pnpm build` (gitignored). `npm publish` runs from this folder. New behavior is normally a core function plus thin CLI wiring. @@ -33,9 +33,11 @@ This CLAUDE.md is the entry point. For deeper material on any topic, see `/docs/ When working on a specific area (release flow, command behaviour, etc.), open the matching doc — they have detail that didn't fit in this CLAUDE.md. +These `docs/*.md` files are **also the source of the public docs site** at [mx.rousanali.com](https://mx.rousanali.com) — a VitePress site built directly from this folder (config in `docs/.vitepress/config.mts`, landing in `docs/index.md`). Run it with `pnpm docs:dev` / build with `pnpm docs:build`; it deploys on Cloudflare Pages (prod on `main`, preview per PR). Editing a doc updates both the repo and the site, so keep them accurate. See [docs/development.md § Documentation site](docs/development.md#documentation-site-mx-rousanali-com). + ## Running the CLI (dev vs global) -There is **no global PATH coupling to this repo**. The global `mx` exists only when you install a build: `npm i -g @roulabs/mx` (npm owns that bin). +There is **no global PATH coupling to this repo**. The global `mx` exists only when you install a build: `npm i -g @rousan/mx` (npm owns that bin). For development, run the local build via the workspace: @@ -81,7 +83,7 @@ These three are distinct — don't confuse them: It does **not** modify `work.json` contents, `.code-workspace` files, worktree code, session body files, context body files, user-edited hook bodies, or anything under `repos//git/`. Its output header is "Synced runtime at …"; every reported path is either a re-stamped template or a newly-created empty directory. -**`mx update`** is now a *different* command: it **self-updates the CLI** within its current major (`npm i -g @roulabs/mx@^`), detects whether a newer major exists and suggests the deliberate upgrade (`npm i -g @roulabs/mx@` then `mx migrate`), and is **not** version-gated. It falls back to printing the manual command if npm is missing or the install fails. **After a successful in-major update it automatically runs `mx sync`** — by shelling out to the freshly-installed global `mx` (this process is still the old code), so the new version's templates are what get stamped; in `--porcelain` mode the sync runs silently to keep stdout a single JSON object. +**`mx update`** is now a *different* command: it **self-updates the CLI** within its current major (`npm i -g @rousan/mx@^`), detects whether a newer major exists and suggests the deliberate upgrade (`npm i -g @rousan/mx@` then `mx migrate`), and is **not** version-gated. It falls back to printing the manual command if npm is missing or the install fails. **After a successful in-major update it automatically runs `mx sync`** — by shelling out to the freshly-installed global `mx` (this process is still the old code), so the new version's templates are what get stamped; in `--porcelain` mode the sync runs silently to keep stdout a single JSON object. **`mx migrate`** upgrades an older-version runtime up to the version this CLI supports — the only runtime command allowed on a version mismatch. It validates the full migration chain before mutating (`NO_MIGRATION` on a gap, `CLI_TOO_OLD` if the runtime is newer), and reports per-step `warnings`. The **v1 → v2** step moves each clone into `repos//git/` and each work's flat worktrees into `wt/`. The **v2 → v3** step centralizes hooks: it stamps the `/hooks/` hub, writes each repo's `repo.json`, and **retires the old per-repo `hydrate.sh`/`health.sh` and per-work `hooks/`** — deleting them when they're unchanged from the mx default, but **keeping them with a warning** when customized (so you can fold the logic into the central hooks). `--dry-run` previews the whole plan (and warnings) without mutating. @@ -106,7 +108,7 @@ You may dogfood mx by treating its source as just another repo in an mx runtime ```bash # One-time, on your productive runtime: -mx repo add git@github.com:roulabs/mx.git +mx repo add git@github.com:rousan/mx.git # Per feature (repeatable for as many parallel mx features as you want): mx work new improve-mx-status-ui @@ -122,7 +124,7 @@ There are two `mx` binaries available inside a self-hosted worktree, and they mu | binary | what it runs | use for | |---|---|---| -| `mx` (on `$PATH`) | the **globally installed** `@roulabs/mx` — published version | productive runtime operations: `mx i`, `mx work archive feat`, etc. **Safe** against the productive runtime. | +| `mx` (on `$PATH`) | the **globally installed** `@rousan/mx` — published version | productive runtime operations: `mx i`, `mx work archive feat`, etc. **Safe** against the productive runtime. | | `pnpm mx ...` or `node npm/bin/mx.js ...` | the **locally-built** CLI from your in-progress code | **testing only** — must always be pointed at a sandbox runtime, never the productive one. | The hard rule: **the locally-built CLI never sees the productive runtime.** Before any test, set `$MX_RUNTIME` to a sandbox: @@ -148,7 +150,7 @@ Each `works//wt/mx/` is fully independent: its own branch, its own `.mx ## Layout ``` -mx/ # pnpm workspace (TypeScript); repo = github.com/roulabs/mx +mx/ # pnpm workspace (TypeScript); repo = github.com/rousan/mx ├── package.json # root scripts: build / dev / mx / typecheck / lint / test ├── pnpm-workspace.yaml ├── tsconfig.base.json · eslint.config.js · .prettierrc.json · .nvmrc · LICENSE @@ -169,7 +171,7 @@ mx/ # pnpm workspace (TypeScript); repo = githu │ ├── src/ # args, output, help, paths, selfupdate, setup, main, │ │ # commands/{global,repo,work} │ └── tsup.config.ts # bundles src/bin/mx.ts -> ../../npm/bin/mx.js, copies assets -└── npm/ # @roulabs/mx — publishable package +└── npm/ # @rousan/mx — publishable package ├── package.json # committed (public metadata) ├── README.md # committed (consumer docs) ├── bin/mx.js # built by `pnpm build` (gitignored) @@ -218,7 +220,7 @@ Implemented in `apps/cli` over `@mx/core`. Each command resolves the runtime via - **`mx init [path]`** — scaffold/adopt a runtime (target = path arg, else `$MX_RUNTIME`, else `~/mx`): create `repos/`, `works/`, `files/` (empty operational-values store), `.mx-root`; stamp `mx.json`, `CLAUDE.md`; stamp `context/INDEX.json` (only if missing — context is user data). Refuses to adopt a runtime whose `mx.json` differs (→ `mx migrate`, or upgrade the CLI). Idempotent; no clone; no pointer written. - **`mx info [--all] [--porcelain]`** — runtime path, repos + branches, works + worktrees + ports. Active works only by default; `--all` includes archived. Alias: `mx i`. - **`mx sync`** — (formerly `mx update`) re-stamp the runtime `CLAUDE.md`; stamp `context/INDEX.json` only if missing; backfill the central `hooks/` hub (stamp-if-missing), the runtime `bin/` + shipped utility bins, the runtime `files/` store, each repo's `repo.json`, the per-work dirs (`wt/`, `scripts/`, `files/`, `tmp/`, `sessions/`), and the per-work `CLAUDE.md`. Never modifies user data. Version-gated. -- **`mx update`** — self-update the CLI within its major (`npm i -g @roulabs/mx@^`); suggests a deliberate major upgrade if one exists. Not version-gated. After a successful update it auto-runs `mx sync` (via the freshly-installed global) to refresh the runtime. +- **`mx update`** — self-update the CLI within its major (`npm i -g @rousan/mx@^`); suggests a deliberate major upgrade if one exists. Not version-gated. After a successful update it auto-runs `mx sync` (via the freshly-installed global) to refresh the runtime. - **`mx migrate [--dry-run]`** — upgrade an older runtime to the supported version (the only runtime command allowed on a version mismatch); validates the chain first (`NO_MIGRATION` / `CLI_TOO_OLD`). v1→v2 moves clones into `git/` + worktrees into `wt/`; v2→v3 stamps the central `hooks/` hub, writes `repo.json`, and retires old per-repo/per-work scripts (default → removed, customized → kept + warned). `--dry-run` validates and prints the full plan + warnings without mutating; porcelain adds `dryRun: true`, `warnings`. - **`mx health [--all]`** — whole-runtime health overview: every repo's health block (as `mx repo health`) followed by every active work's health block (as `mx work health`); `--all` includes archived works. Porcelain returns `{repos, works}`. - **`mx mission-control [--port ] [-o]`** (alias `mx mc`) — start a local, read-only **live web dashboard** for the runtime: a calm monochrome overview of every repo's and work's health plus a consolidated ports board (port → service → worktree → work → `localhost` URL). Served by a zero-dependency `node:http` server that streams updates over SSE; the UI is a single self-contained HTML page (built from `apps/mission-control/`, bundled into the package). Blocks until Ctrl-C; `-o` opens the browser. @@ -248,7 +250,7 @@ Key properties: ## Conventions -- **TypeScript pnpm monorepo, zero runtime dependencies.** Both source packages (`@mx/core`, `@mx/cli`) use only `node:` builtins; tsup bundles `@mx/core` into the CLI so the published `@roulabs/mx` package installs no deps. Tooling (tsup, eslint, vitest, prettier) is devDeps only. `@mx/cli` is private; the published thing is the `npm/` folder. +- **TypeScript pnpm monorepo, zero runtime dependencies.** Both source packages (`@mx/core`, `@mx/cli`) use only `node:` builtins; tsup bundles `@mx/core` into the CLI so the published `@rousan/mx` package installs no deps. Tooling (tsup, eslint, vitest, prettier) is devDeps only. `@mx/cli` is private; the published thing is the `npm/` folder. - **Workflow:** `pnpm typecheck` · `pnpm lint` · `pnpm test` · `pnpm build` (and `pnpm dev` to watch). Add a Vitest test in `packages/core/test` for new core logic. - **Runtime is env-addressed** (`$MX_RUNTIME` / `--runtime` / `~/mx`); never persist a runtime path in this repo. Dev uses the gitignored `.mx/` runtime. - **Release:** CI-driven via `.github/workflows/release.yml`. **Every merge to `main` must produce a new release** — the PR bumps `"version"` in `npm/package.json`, and on push to `main` the workflow runs typecheck/lint/test/build, `npm publish`es from `npm/` (auth via the `NPM_TOKEN` automation-token secret), tags `vX.Y.Z`, and creates a GitHub Release. If the version still matches an existing tag, the run **fails** demanding a bump (a merge without a bump is treated as a mistake). One-time setup: add an npm automation token as the `NPM_TOKEN` repo secret (see `docs/release.md`). The local `pnpm release` (`scripts/release.sh`) remains as a **manual fallback** — it verifies npm auth + clean tree + fresh tag + unpublished version, prompts to confirm, then `npm publish --auth-type=web` (browser confirm for 2FA) and pushes the tag. **Gotchas** (npm name similarity rejection on unscoped names; CDN propagation lag on first publish of a new scope; npm has no `org create` CLI command — orgs must be created at https://www.npmjs.com/org/create) are documented in `README.md` § Release. @@ -258,8 +260,8 @@ Key properties: For a fresh session / new machine: -- **Done and verified:** the full TS pnpm monorepo (`@mx/core` source + `@mx/cli` source + `npm/` publishable package), all commands (`init`, `info`, `sync`, `update`, `migrate`, `repo`, `work` incl. `worktree`/`port`/`path`/`open`), runtime versioning + container repo layout + central hook hub (v3), env-based runtime discovery, templates copied into `npm/templates/` at build time, CI workflow for PR checks, `scripts/release.sh` for local publishing, MIT license, and a consumer README at `npm/README.md`. `pnpm typecheck/lint/test/build` are green; the packed tarball installs via `npm i -g` and runs self-contained from outside the repo. Hosted at `github.com/roulabs/mx`, branch `main`. -- **Shipped:** `@roulabs/mx` is live on npm at https://www.npmjs.com/package/@roulabs/mx (first release `v1.0.0` on 2026-06-04). For the currently-published version, run `git describe --tags --abbrev=0` or check the npm page. End-user install: `npm i -g @roulabs/mx` → `mx` command. +- **Done and verified:** the full TS pnpm monorepo (`@mx/core` source + `@mx/cli` source + `npm/` publishable package), all commands (`init`, `info`, `sync`, `update`, `migrate`, `repo`, `work` incl. `worktree`/`port`/`path`/`open`), runtime versioning + container repo layout + central hook hub (v3), env-based runtime discovery, templates copied into `npm/templates/` at build time, CI workflow for PR checks, `scripts/release.sh` for local publishing, MIT license, and a consumer README at `npm/README.md`. `pnpm typecheck/lint/test/build` are green; the packed tarball installs via `npm i -g` and runs self-contained from outside the repo. Hosted at `github.com/rousan/mx`, branch `main`. +- **Shipped:** `@rousan/mx` is live on npm at https://www.npmjs.com/package/@rousan/mx (first release `v1.0.0` on 2026-06-04). For the currently-published version, run `git describe --tags --abbrev=0` or check the npm page. End-user install: `npm i -g @rousan/mx` → `mx` command. - **Start working:** `pnpm install && pnpm build`, then `export MX_RUNTIME="$PWD/.mx"` and `pnpm mx init`. Iterate with `pnpm dev` (watch) + `pnpm mx ...`; run `pnpm typecheck && pnpm lint && pnpm test` before committing. - **Next release:** bump `npm/package.json` version in your PR, then merge to `main` — `.github/workflows/release.yml` publishes, tags, and creates the GitHub Release automatically (auth via the `NPM_TOKEN` secret). Forgetting the bump fails the run. `pnpm release` remains a local fallback. - **Not done yet:** per-runtime support for non-Claude agents (`AGENTS.md` for Codex, `.cursorrules` for Cursor). Optional next idea: isolated per-env state (separate DB schema / container) for safe parallel runs. (`mx open`-style terminal layout shipped in 2.0.0 as `mx work new -o`.) diff --git a/README.md b/README.md index 37bb310..5ad3f6a 100644 --- a/README.md +++ b/README.md @@ -4,13 +4,13 @@ Source and tooling for **mx** ("multiplexer") — a system for working on severa This repo is the **source** for mx: a TypeScript pnpm monorepo with the core library, the CLI, the runtime templates, and the docs. The thing it produces — a single `mx/` **runtime** with your cloned repos and live feature environments — lives wherever `$MX_RUNTIME` points (default `~/mx`), fully decoupled from this repo. -Published on npm as **`@roulabs/mx`** (command `mx`). For end-user install/usage, see [`npm/README.md`](npm/README.md). The `npm/` folder is the publishable package — `pnpm build` populates it; `npm publish` ships it. +Published on npm as **`@rousan/mx`** (command `mx`). For end-user install/usage, see [`npm/README.md`](npm/README.md). The `npm/` folder is the publishable package — `pnpm build` populates it; `npm publish` ships it. ## Runtime vs. source | | what it is | where | |-------------|--------------------------------------|-------------------------------| -| **source** | the core lib, CLI, templates, docs | this repo (`github.com/roulabs/mx`) | +| **source** | the core lib, CLI, templates, docs | this repo (`github.com/rousan/mx`) | | **runtime** | clones + live feature environments | `$MX_RUNTIME` (default `~/mx`) | The runtime's `CLAUDE.md` is **generated** from `templates/CLAUDE.md` at the repo root (run `pnpm build` then `mx sync` to re-stamp). The per-work `work.json` and `.code-workspace` are **owned and generated by the CLI** — feature sessions read/mutate them only through `mx` commands. The runtime is **versioned** via `/mx.json` (CLI major ⇄ runtime version); a mismatched runtime is gated until `mx migrate`. See `CLAUDE.md` for the source-of-truth and ownership rules. @@ -43,7 +43,7 @@ mx/ # pnpm workspace │ └── cli/ # @mx/cli (private) — CLI source │ ├── src/ # tsup -> ../../npm/bin/mx.js │ └── tsup.config.ts # bundles into npm/ and copies assets on success -└── npm/ # @roulabs/mx — publishable package +└── npm/ # @rousan/mx — publishable package ├── package.json · README.md # committed (public metadata + consumer docs) └── bin/, templates/, LICENSE # built by `pnpm build` (gitignored) ``` @@ -57,7 +57,7 @@ mx/ # pnpm workspace ## Develop (including on a fresh machine) ```bash -git clone git@github.com:roulabs/mx.git && cd mx +git clone git@github.com:rousan/mx.git && cd mx pnpm install pnpm build # populates npm/ (bin/mx.js + templates/ + LICENSE) export MX_RUNTIME="$PWD/.mx" # gitignored dev runtime in this repo @@ -67,7 +67,7 @@ pnpm mx work new my-feature pnpm mx info ``` -`mx` runs the **built** output, so re-run `pnpm build` (or keep `pnpm dev` watching) after changing CLI/core code. Templates live at `/templates` (no code, just content) and are copied into `npm/templates/` at build — edits take effect on the next build. There is no global PATH coupling to this repo — the global `mx` comes only from installing a build (`npm i -g @roulabs/mx`). +`mx` runs the **built** output, so re-run `pnpm build` (or keep `pnpm dev` watching) after changing CLI/core code. Templates live at `/templates` (no code, just content) and are copied into `npm/templates/` at build — edits take effect on the next build. There is no global PATH coupling to this repo — the global `mx` comes only from installing a build (`npm i -g @rousan/mx`). ## Scripts @@ -131,5 +131,5 @@ See **[docs/release.md](docs/release.md)** for the full runbook, the `NPM_TOKEN` - [x] Env-based runtime discovery (`--runtime` / `$MX_RUNTIME` / default `~/mx`) - [x] Per-service free-port allocation across all works (no fixed blocks) - [x] TypeScript pnpm monorepo (`@mx/core` + `apps/cli`), lint/test/build tooling -- [x] npm distribution (`@roulabs/mx`) — CI-driven release on merge to `main`, CI for PR checks +- [x] npm distribution (`@rousan/mx`) — CI-driven release on merge to `main`, CI for PR checks - [ ] Optional: isolated per-env state (separate DB schema / container) for safe parallel runs diff --git a/apps/cli/package.json b/apps/cli/package.json index e14c9f6..716b836 100644 --- a/apps/cli/package.json +++ b/apps/cli/package.json @@ -3,7 +3,7 @@ "version": "0.0.0", "private": true, "type": "module", - "description": "Source for the @roulabs/mx npm package. Published artifacts live in /npm.", + "description": "Source for the @rousan/mx npm package. Published artifacts live in /npm.", "scripts": { "build": "tsup", "dev": "tsup --watch", diff --git a/apps/cli/src/selfupdate.ts b/apps/cli/src/selfupdate.ts index b5cfa64..91efdf1 100644 --- a/apps/cli/src/selfupdate.ts +++ b/apps/cli/src/selfupdate.ts @@ -3,7 +3,7 @@ import { compareVersions, maxVersion } from '@mx/core'; import { cliVersion } from './paths'; /** The published package name self-update targets. */ -const PKG = '@roulabs/mx'; +const PKG = '@rousan/mx'; /** * Major version number from a semver string (`"2.3.1"` → `2`). @@ -92,7 +92,7 @@ export interface SelfUpdateInfo { /** * Self-update the CLI to the newest release **within its current major** - * (`npm i -g @roulabs/mx@^`), and detect whether a newer major exists. + * (`npm i -g @rousan/mx@^`), and detect whether a newer major exists. * Crossing a major is intentionally left to the user (it requires `mx migrate` * afterwards), so this only ever reports a newer major as a suggestion. * diff --git a/apps/landing/index.html b/apps/landing/index.html new file mode 100644 index 0000000..a9571b5 --- /dev/null +++ b/apps/landing/index.html @@ -0,0 +1,23 @@ + + + + + + mx — work on parallel features using coding agents + + + + + + + +
+ + + diff --git a/apps/landing/package.json b/apps/landing/package.json new file mode 100644 index 0000000..7965e66 --- /dev/null +++ b/apps/landing/package.json @@ -0,0 +1,25 @@ +{ + "name": "@mx/landing", + "version": "0.0.0", + "private": true, + "type": "module", + "description": "mx landing + docs site — the beginner-friendly public website published at https://mx.rousanali.com. A standalone React/Vite/Tailwind static site (built to apps/landing/dist and deployed to GitHub Pages). It teaches mx from zero; the deep reference lives in docs/.", + "scripts": { + "build": "vite build", + "dev": "vite", + "preview": "vite preview", + "typecheck": "tsc --noEmit -p tsconfig.json" + }, + "dependencies": { + "react": "^19.0.0", + "react-dom": "^19.0.0" + }, + "devDependencies": { + "@tailwindcss/vite": "^4.0.0", + "@types/react": "^19.0.0", + "@types/react-dom": "^19.0.0", + "@vitejs/plugin-react": "^4.3.0", + "tailwindcss": "^4.0.0", + "vite": "^6.0.0" + } +} diff --git a/apps/landing/public/CNAME b/apps/landing/public/CNAME new file mode 100644 index 0000000..6ec694e --- /dev/null +++ b/apps/landing/public/CNAME @@ -0,0 +1 @@ +mx.rousanali.com diff --git a/apps/landing/public/favicon.svg b/apps/landing/public/favicon.svg new file mode 100644 index 0000000..6daedc1 --- /dev/null +++ b/apps/landing/public/favicon.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/apps/landing/src/App.tsx b/apps/landing/src/App.tsx new file mode 100644 index 0000000..20b6071 --- /dev/null +++ b/apps/landing/src/App.tsx @@ -0,0 +1,41 @@ +import { useTheme } from './theme'; +import { Nav } from './sections/Nav'; +import { Hero } from './sections/Hero'; +import { Why } from './sections/Why'; +import { Agents } from './sections/Agents'; +import { Concepts } from './sections/Concepts'; +import { Quickstart } from './sections/Quickstart'; +import { Workflow } from './sections/Workflow'; +import { Features } from './sections/Features'; +import { Commands } from './sections/Commands'; +import { Faq } from './sections/Faq'; +import { Footer } from './sections/Footer'; + +/** + * The mx landing + docs site: a single scrolling page that teaches mx from zero + * — hook (Hero), problem (Why), the core agent pitch (Agents), vocabulary + * (Concepts), hands-on (Quickstart), capabilities (Features), reference + * (Commands), objections (Faq), then a closing CTA (Footer). Ordered so each + * section builds on the last. Workflow (after Quickstart) shows one concrete + * end-to-end setup for using it day to day. + */ +export function App() { + const { theme, toggle } = useTheme(); + return ( +
+
+ ); +} diff --git a/apps/landing/src/content.ts b/apps/landing/src/content.ts new file mode 100644 index 0000000..1e83ec8 --- /dev/null +++ b/apps/landing/src/content.ts @@ -0,0 +1,367 @@ +import type { IconName } from './ui'; + +/** + * The npm package name and the canonical repo URL, referenced from several + * sections. Kept here so a rename touches one place. + */ +export const PKG = '@rousan/mx'; +export const REPO_URL = 'https://github.com/rousan/mx'; +export const NPM_URL = 'https://www.npmjs.com/package/@rousan/mx'; + +/** + * One capability card in the "What you get" grid. `title` is the headline, + * `body` explains it in plain language, `icon` picks a shared glyph. + */ +export interface Feature { + icon: IconName; + title: string; + body: string; +} + +/** + * The headline capabilities, written for someone who has never heard of mx. + * These deliberately avoid jargon; the Concepts section defines the terms. The + * parallel-agents card leads, since that is mx's reason for existing. + */ +export const FEATURES: Feature[] = [ + { + icon: 'sparkles', + title: 'A coding agent per feature', + body: 'Open a feature in a fullscreen terminal that resumes or starts its own Claude Code session, pre-seeded with context. Run several agents at once, one per feature, without them tripping over each other.', + }, + { + icon: 'layers', + title: 'A separate desk per feature', + body: 'Every feature gets its own folder, branch, and running app. Switching between two features is just switching folders — nothing to stash, nothing to rebuild.', + }, + { + icon: 'branch', + title: 'Built on git worktrees', + body: 'mx uses a native git feature: multiple branches checked out at once, in separate folders, sharing one clone. You get the isolation without a second copy of the repo on disk.', + }, + { + icon: 'box', + title: 'One runtime, many repos', + body: 'Clone each repo once. Every feature forks lightweight worktrees from that clone — so a full-stack change spanning frontend and backend lives together under one feature.', + }, + { + icon: 'switch', + title: 'Ports that never collide', + body: 'mx hands each feature its own set of ports and remembers them, so you can run two copies of the same app side by side without editing config or fighting "port already in use".', + }, + { + icon: 'plug', + title: 'Hooks for the boring setup', + body: 'A new worktree can auto-copy your .env, install dependencies, or seed a database. One script per lifecycle event, in any language — so a fresh feature is ready the moment it exists.', + }, + { + icon: 'activity', + title: 'Live mission control', + body: 'A local, read-only web dashboard streams the health of every repo and feature plus a consolidated ports board — so you can see your whole fleet at a glance.', + }, +]; + +/** + * One point in the "Built for coding agents" section — the workflow details + * that make mx a fit for running many agent sessions in parallel. + */ +export interface AgentPoint { + icon: IconName; + title: string; + body: string; +} + +/** + * How mx supports a fleet of coding agents, concretely. These map to real + * commands and hooks (mx work open, the session-prompt hook, per-feature ports, + * --porcelain output), so the section stays truthful rather than aspirational. + */ +export const AGENT_POINTS: AgentPoint[] = [ + { + icon: 'sparkles', + title: 'One session per feature', + body: 'mx work open drops you into a fullscreen terminal that resumes — or starts — that feature’s Claude Code session. Each feature keeps its own conversation, history, and context.', + }, + { + icon: 'plug', + title: 'Seed every session automatically', + body: 'A session-prompt hook generates each new session’s opening prompt — global, per-repo, or per-feature — so an agent starts with the right context instead of a blank slate.', + }, + { + icon: 'switch', + title: 'No agents stepping on each other', + body: 'Every agent works in its own worktree, branch, and ports. Point a fleet at ten features at once; none share a checkout or fight over a port.', + }, + { + icon: 'terminal', + title: 'Agent-friendly by design', + body: 'Every read command emits stable JSON with --porcelain, and mx infers the feature from the working directory — so an agent can drive mx as reliably as a person can.', + }, +]; + +/** + * A core concept, explained twice: a one-line "plain English" gloss and a + * slightly deeper paragraph. This is the teaching heart of the site. + */ +export interface Concept { + icon: IconName; + term: string; + plain: string; + detail: string; +} + +/** + * The four nouns you need to hold in your head to use mx. Ordered outside-in: + * runtime contains repos and works; a work contains worktrees. + */ +export const CONCEPTS: Concept[] = [ + { + icon: 'folder', + term: 'Runtime', + plain: 'One folder on your machine where mx keeps everything.', + detail: + 'Think of it as mx’s home base (default ~/mx). It holds your cloned repos and one folder per feature you’re working on. You can have several runtimes and switch with an environment variable.', + }, + { + icon: 'box', + term: 'Repo', + plain: 'A pristine clone of a repository, cloned once.', + detail: + 'mx clones each repo a single time into the runtime and treats that clone as read-only reference. You never edit it directly — features branch off it instead, sharing its git history to save disk and time.', + }, + { + icon: 'layers', + term: 'Work', + plain: 'One feature you’re building — the unit you switch between.', + detail: + 'A "work" bundles everything for one feature: which repos it touches, the branches, the ports, and an editor workspace. Starting a second feature is one command, and the two stay completely isolated.', + }, + { + icon: 'branch', + term: 'Worktree', + plain: 'A repo checked out on a feature’s branch, in its own folder.', + detail: + 'Each work has one worktree per repo it touches (under wt/), each on its own branch. This is the folder you actually code in — a normal git checkout you can build, run, commit, and push.', + }, +]; + +/** + * One step in the quickstart. `cmd` is the shell command, `comment` an optional + * inline note, and `body` the plain-language "what this does / why". + */ +export interface Step { + n: number; + title: string; + cmd: string; + comment?: string; + body: string; +} + +/** + * The minimal path from zero to coding in a worktree. Each step reads on its + * own so a newcomer can follow without cross-referencing the reference docs. + */ +export const STEPS: Step[] = [ + { + n: 1, + title: 'Install mx', + cmd: `npm i -g ${PKG}`, + body: 'A single global install gives you the mx command. You need Node 22+ and git. That’s the only thing that ever gets installed globally.', + }, + { + n: 2, + title: 'Create your runtime', + cmd: 'mx init', + comment: 'scaffolds ~/mx', + body: 'This sets up mx’s home folder — the one place all its state lives. Run it once. Everything after this happens through mx commands.', + }, + { + n: 3, + title: 'Add a repo (once)', + cmd: 'mx repo add git@github.com:you/app.git', + body: 'mx clones the repo into the runtime as read-only reference. You do this once per repo, no matter how many features you build from it.', + }, + { + n: 4, + title: 'Start a feature and dive in', + cmd: 'mx work new my-feature app', + comment: 'creates a worktree of "app" on branch my-feature', + body: 'This creates a feature and a git worktree for it. cd into works/my-feature/wt/app and you’re in a normal checkout on your feature branch — build, run, commit, push as usual. Start a second feature the same way; both stay isolated.', + }, +]; + +/** + * One step in the example end-to-end workflow. `body` explains the step; `cmds` + * are the optional literal commands for it. + */ +export interface WorkflowStep { + n: number; + title: string; + body: string; + cmds?: string[]; +} + +/** + * A concrete, opinionated way to work day to day with mx — one fullscreen macOS + * Space per feature (terminal split with the editor), the coding agent in the + * first terminal tab, and a swipe to switch features. mx doesn't require any of + * this; it's one workflow that works well, offered so a newcomer has a starting + * shape to copy rather than a blank page. + */ +export const WORKFLOW_STEPS: WorkflowStep[] = [ + { + n: 1, + title: 'One fullscreen Space per feature', + body: 'Open a fullscreen terminal and create the work. Then jump into its folder and open the editor workspace mx generated for you — every repo’s worktree shows up as a folder in one window (code for VS Code, cursor for Cursor).', + cmds: [ + 'mx work new checkout-redesign app api', + 'cd "$(mx work -n checkout-redesign path)"', + 'code checkout-redesign.code-workspace', + ], + }, + { + n: 2, + title: 'Split the terminal and editor side by side', + body: 'Put the terminal and the editor into a macOS split view — terminal on the left, editor on the right. That single fullscreen pane is one feature. Build the next feature the same way, in its own Space.', + }, + { + n: 3, + title: 'Agent in tab 1, everything else in more tabs', + body: 'Run the feature’s Claude Code session in the first terminal tab. Use a second tab — or tmux panes — for the dev server, logs, and git, so each concern for that feature has its place.', + cmds: ['mx work open -n checkout-redesign'], + }, + { + n: 4, + title: 'Hand the feature to the agent', + body: 'Once the session is up, ask it to create the worktrees for the repos the feature touches (through mx), give it the feature description to work from, and switch the session to auto mode for the best hands-off results.', + }, + { + n: 5, + title: 'Switch features with a three-finger swipe', + body: 'Because each feature is its own fullscreen Space, a three-finger left/right swipe on the trackpad jumps you between features instantly — no windows to hunt for, nothing torn down behind you.', + }, + { + n: 6, + title: 'Group your Spaces with labeled dividers', + body: 'Open Mission Control (a three-finger swipe up) to see every Space at once, and slot in labeled separators with mx divider so features cluster by stage — MAIN, IN PROGRESS, IN REVIEWS, PR REVIEWS. Each divider is just a Space filled with big block text, so the groups are easy to spot as you swipe.', + cmds: ['mx divider "IN PROGRESS" -o'], + }, + { + n: 7, + title: 'Wrap up when it’s merged', + body: 'When the feature ships, ask the agent to write a session summary (per mx’s session rules), then archive the work — that frees its ports and worktrees while keeping the branches and summaries — and close the terminal and editor.', + cmds: ['mx work archive -n checkout-redesign'], + }, +]; + +/** + * A group of related CLI commands for the reference section, so the full + * surface is scannable by intent rather than as one long flat list. + */ +export interface CommandGroup { + title: string; + blurb: string; + commands: { cmd: string; desc: string }[]; +} + +/** + * The command reference, grouped by what you're trying to do. This is a curated + * teaching subset with plain descriptions; the exhaustive flag-level reference + * lives in the repo's docs/commands.md. + */ +export const COMMAND_GROUPS: CommandGroup[] = [ + { + title: 'Set up', + blurb: 'Create the runtime and bring repos in. You run these rarely.', + commands: [ + { cmd: 'mx init', desc: 'Scaffold the runtime (the ~/mx home folder).' }, + { cmd: 'mx repo add ', desc: 'Clone a repo into the runtime as read-only reference.' }, + { cmd: 'mx repo new ', desc: 'Create a fresh local repo with no remote (for experiments).' }, + { cmd: 'mx repo ls', desc: 'List the repos mx knows about.' }, + ], + }, + { + title: 'Daily work', + blurb: 'Start features, look around, jump into a worktree. Your bread and butter.', + commands: [ + { cmd: 'mx work new ', desc: 'Create a feature plus an initial worktree for it.' }, + { cmd: 'mx info', desc: 'See every repo, feature, worktree, and allocated port at a glance.' }, + { cmd: 'mx work -n path', desc: 'Print a feature’s folder (handy for cd).' }, + { cmd: 'mx work -n worktree add ', desc: 'Add another repo’s worktree to a feature.' }, + { cmd: 'mx work -n worktree set-branch ', desc: 'Record the branch after you git checkout inside a worktree.' }, + ], + }, + { + title: 'Ports & sessions', + blurb: 'Give a feature its own ports, and open it in a terminal or editor.', + commands: [ + { cmd: 'mx work -n port set ', desc: 'Allocate a free port, unique across all features.' }, + { cmd: 'mx work -n open', desc: 'Open a fullscreen terminal that resumes or starts the feature’s Claude session (macOS).' }, + { cmd: 'mx mission-control', desc: 'Launch a live web dashboard of health and ports (alias: mx mc).' }, + { cmd: 'mx divider ', desc: 'Fill a terminal with big block text — a visual separator for macOS Spaces.' }, + ], + }, + { + title: 'Maintenance', + blurb: 'Health checks, cleanup, and keeping mx itself up to date.', + commands: [ + { cmd: 'mx health', desc: 'Whole-runtime overview: every repo and active feature’s health.' }, + { cmd: 'mx work -n archive', desc: 'Remove worktrees but keep the feature and its branches (recoverable).' }, + { cmd: 'mx work -n destroy', desc: 'Permanently delete a feature’s folder; branches are kept.' }, + { cmd: 'mx update', desc: 'Self-update the CLI and refresh the runtime.' }, + { cmd: 'mx sync', desc: 'Re-stamp runtime files to match the current mx version.' }, + ], + }, +]; + +/** + * One frequently-asked question, answered for someone still deciding whether mx + * is for them. + */ +export interface Faq { + q: string; + a: string; +} + +/** + * The objections and clarifications a newcomer typically has. Answers stay + * short and reassuring, pointing at the mental model rather than internals. + */ +export const FAQS: Faq[] = [ + { + q: 'Do I need to understand git worktrees first?', + a: 'No. mx creates and manages worktrees for you — you interact with plain folders and normal git inside them. Worktrees are the engine; you rarely touch them directly. If you’re curious, they’re a built-in git feature for checking out several branches at once.', + }, + { + q: 'Does mx replace git or my editor?', + a: 'Neither. Inside a worktree you use git exactly as you always have — branch, commit, push, open PRs. mx only orchestrates the folders, branches, ports, and workspaces around your repos. It generates a VS Code workspace file, but you edit however you like.', + }, + { + q: 'Do I have to use it with AI coding agents?', + a: 'No. mx grew out of running many Claude Code sessions in parallel, and that’s its sweet spot — but the same isolation is just as useful for plain human work: juggling several features, reviewing a PR while building another, or a full-stack change across repos. The agent-session support sits on top; you can ignore it and still get all the worktree, branch, and port management.', + }, + { + q: 'Where does my actual code live?', + a: 'In worktrees, under works//wt/. That’s a normal git checkout on your feature branch — build it, run it, commit, push. The pristine clone mx keeps is only read-only reference that worktrees fork from.', + }, + { + q: 'Do I have to hand-edit any config files?', + a: 'No — and you shouldn’t. mx owns its state files (the work manifest and the editor workspace). You change them only through mx commands; every read command has a --porcelain flag that emits stable JSON for scripts and agents.', + }, + { + q: 'Which platforms does it run on?', + a: 'mx is cross-platform (Node 22+ and git). A couple of convenience helpers that open a fullscreen Terminal window — mx work open -o and mx divider -o — are macOS-only; everything else works everywhere.', + }, +]; + +/** + * The in-page nav links. `href` is an anchor to a section id on this page. + */ +export const NAV_LINKS: { label: string; href: string }[] = [ + { label: 'Why mx', href: '#why' }, + { label: 'Agents', href: '#agents' }, + { label: 'Concepts', href: '#concepts' }, + { label: 'Quickstart', href: '#quickstart' }, + { label: 'Workflow', href: '#workflow' }, + { label: 'Commands', href: '#commands' }, +]; diff --git a/apps/landing/src/index.css b/apps/landing/src/index.css new file mode 100644 index 0000000..c986f80 --- /dev/null +++ b/apps/landing/src/index.css @@ -0,0 +1,153 @@ +@import 'tailwindcss'; + +/* + * Dark mode is driven by a `data-theme` attribute on (stamped by the + * theme hook in theme.ts), NOT by the media query alone. This lets the manual + * light/dark toggle win deterministically while still defaulting to the OS + * preference on first load. Every `dark:` utility keys off this variant. + */ +@custom-variant dark (&:where([data-theme='dark'], [data-theme='dark'] *)); + +/* + * Semantic design tokens — a calm, mostly-monochrome grayscale system with a + * single warm terra-cotta accent, in the spirit of a documentation site (and + * the sibling `ccal` project). Emphasis comes from ink weight and gray steps; + * the accent is used sparingly for the logo, one hero phrase, prompts, links, + * icon chips, and the primary button. Light values are the base; the dark + * override block below swaps them when . Exposing them + * through `@theme inline` lets us use them as Tailwind color utilities + * (e.g. `bg-surface`, `text-muted`, `border-line`, `text-accent`). + * + * Token roles: `--accent` the terra-cotta accent (prompts, icons, dots); + * `--accent-ink` a readable accent for links; `--accent-soft` a faint accent + * tint for icon chips; `--cta`/`--on-cta` the orange primary-button fill and its + * text; `--accent-strong`/`--on-accent` the neutral ink fill used for step + * markers (near-black in light, inverted to near-white in dark). + */ +:root { + --bg: #ffffff; + --bg-soft: #f7f7f8; + --surface: #ffffff; + --surface-2: #f4f4f5; + --line: #e4e4e7; + --line-strong: #d4d4d8; + --text: #18181b; + --text-soft: #3f3f46; + --muted: #71717a; + --faint: #a1a1aa; + --accent: #c0562f; + --accent-ink: #b04a26; + --accent-2: #c0562f; + --accent-soft: rgba(192, 86, 47, 0.1); + --accent-strong: #18181b; + --on-accent: #ffffff; + --cta: #c0562f; + --on-cta: #ffffff; + --amber: #71717a; + --code-bg: #f6f6f7; +} + +[data-theme='dark'] { + --bg: #09090b; + --bg-soft: #0c0c0f; + --surface: #111113; + --surface-2: #18181b; + --line: #26262b; + --line-strong: #3a3a42; + --text: #e7e7ea; + --text-soft: #c8c8ce; + --muted: #9a9aa4; + --faint: #63636d; + --accent: #e0793f; + --accent-ink: #ea8a5a; + --accent-2: #e0793f; + --accent-soft: rgba(224, 121, 63, 0.15); + --accent-strong: #fafafa; + --on-accent: #18181b; + --cta: #c0562f; + --on-cta: #ffffff; + --amber: #a1a1aa; + --code-bg: #0d0d11; +} + +@theme inline { + --color-bg: var(--bg); + --color-bg-soft: var(--bg-soft); + --color-surface: var(--surface); + --color-surface-2: var(--surface-2); + --color-line: var(--line); + --color-line-strong: var(--line-strong); + --color-ink: var(--text); + --color-ink-soft: var(--text-soft); + --color-muted: var(--muted); + --color-faint: var(--faint); + --color-accent: var(--accent); + --color-accent-ink: var(--accent-ink); + --color-accent-2: var(--accent-2); + --color-amber: var(--amber); + --font-mono: + ui-monospace, 'SF Mono', 'JetBrains Mono', 'Fira Code', Menlo, Consolas, monospace; +} + +html { + scroll-behavior: smooth; + /* Offset in-page anchor jumps so the sticky nav doesn't cover section headings. */ + scroll-padding-top: 5.5rem; + background: var(--bg); +} + +body { + margin: 0; + background: var(--bg); + color: var(--text); + font-family: + ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif; + -webkit-font-smoothing: antialiased; + text-rendering: optimizeLegibility; +} + +/* Neutral "ink fill" used for step markers: near-black in light, inverted to + * near-white in dark. `--on-accent` is the readable text color on top. */ +.mx-grad { + background-color: var(--accent-strong); + color: var(--on-accent); +} +/* The wordmark is strong ink — emphasis comes from weight, not hue. */ +.mx-grad-text { + color: var(--text); +} +/* The primary call-to-action button: the terra-cotta accent fill with white + * text (the one place the accent is used as a solid fill). */ +.mx-cta { + background-color: var(--cta); + color: var(--on-cta); +} +/* Inline accent emphasis — the single highlighted phrase in the hero headline. */ +.mx-accent-text { + color: var(--accent); +} + +/* Faint parallel-lanes backdrop for the hero — a nod to worktrees running side by side. */ +.mx-lanes { + background-image: repeating-linear-gradient( + 90deg, + color-mix(in srgb, var(--line) 55%, transparent) 0px, + color-mix(in srgb, var(--line) 55%, transparent) 1px, + transparent 1px, + transparent 132px + ); + mask-image: radial-gradient(ellipse 80% 60% at 50% 30%, #000 30%, transparent 78%); +} + +/* Respect users who prefer reduced motion — kill smooth scroll + animations. */ +@media (prefers-reduced-motion: reduce) { + html { + scroll-behavior: auto; + } + *, + *::before, + *::after { + animation-duration: 0.001ms !important; + transition-duration: 0.001ms !important; + } +} diff --git a/apps/landing/src/main.tsx b/apps/landing/src/main.tsx new file mode 100644 index 0000000..8910946 --- /dev/null +++ b/apps/landing/src/main.tsx @@ -0,0 +1,13 @@ +import { StrictMode } from 'react'; +import { createRoot } from 'react-dom/client'; +import { App } from './App'; +import './index.css'; + +const root = document.getElementById('root'); +if (root) { + createRoot(root).render( + + + , + ); +} diff --git a/apps/landing/src/sections/Agents.tsx b/apps/landing/src/sections/Agents.tsx new file mode 100644 index 0000000..d913727 --- /dev/null +++ b/apps/landing/src/sections/Agents.tsx @@ -0,0 +1,134 @@ +import { Section, Icon, Terminal, Line, Mono } from '../ui'; +import { AGENT_POINTS } from '../content'; + +/** + * The "Built for coding agents" section — mx's origin story and core pitch: + * combine a coding agent's ability to run many sessions with git worktrees' + * isolation, and manage everything around them. It leads with the one-line + * "equation", shows the actual open command, then the concrete workflow points. + */ +export function Agents() { + return ( +
+ + +
+ + start (or resume) this feature’s agent session + mx work open -n checkout-redesign + → fullscreen terminal, Claude Code session “checkout-redesign” + → seeded by the session-prompt hook +   + meanwhile, other agents run in their own worktrees + mx work open -n search-filters + mx work open -n api-rate-limits + three agents, three features, zero collisions + + +
+

+ A coding agent can hold many sessions — but they all share one checkout, so they clobber + each other’s branches, files, and ports. Worktrees fix the isolation;{' '} + mx makes running a session per worktree a + single command and keeps the whole fleet organized. +

+

+ It’s not Claude-only, either: the same model works for any coding agent, and the{' '} + --porcelain JSON output plus cwd-based inference mean an agent can drive mx + itself just as cleanly as you do. +

+
+
+ +
+ {AGENT_POINTS.map((p) => ( +
+ + + +
+

{p.title}

+

{p.body}

+
+
+ ))} +
+
+ ); +} + +/** + * The one-line "equation" that captures mx's core idea visually: a coding + * agent's parallel sessions, plus git worktrees, equals isolated agents — one + * per feature. Stacks vertically on small screens. + */ +function Equation() { + return ( +
+ + + + + +
+ ); +} + +/** + * A single term in the equation. + * + * @param icon - Glyph for the term. + * @param title - The term's name. + * @param sub - A short clarifying line. + * @param emphasized - When true, style as the result (stronger border/fill). + */ +function EqBox({ + icon, + title, + sub, + emphasized, +}: { + icon: 'sparkles' | 'branch' | 'layers'; + title: string; + sub: string; + emphasized?: boolean; +}) { + return ( +
+ + + +
+
{title}
+
{sub}
+
+
+ ); +} + +/** + * The `+` / `=` operator glyph between equation terms, centered and dimmed. + * + * @param symbol - The operator character to show. + */ +function EqOp({ symbol }: { symbol: string }) { + return ( +
+ {symbol} +
+ ); +} diff --git a/apps/landing/src/sections/Commands.tsx b/apps/landing/src/sections/Commands.tsx new file mode 100644 index 0000000..60c8282 --- /dev/null +++ b/apps/landing/src/sections/Commands.tsx @@ -0,0 +1,50 @@ +import { Section, Mono } from '../ui'; +import { COMMAND_GROUPS, REPO_URL } from '../content'; + +/** + * The command reference, grouped by intent (set up, daily work, ports & + * sessions, maintenance) rather than as one flat list — so a newcomer scans by + * what they want to do. It's a curated teaching subset; the exhaustive + * flag-level reference lives in the repo docs, linked at the end. + */ +export function Commands() { + return ( +
+
+ {COMMAND_GROUPS.map((group) => ( +
+

{group.title}

+

{group.blurb}

+
    + {group.commands.map((c) => ( +
  • + {c.cmd} + {c.desc} +
  • + ))} +
+
+ ))} +
+ +

+ Tip: inside a feature folder you can drop the -n <name> — mx infers the + feature (and repo) from your current directory. For the full reference with every flag, see{' '} + + docs/commands.md + + . +

+
+ ); +} diff --git a/apps/landing/src/sections/Concepts.tsx b/apps/landing/src/sections/Concepts.tsx new file mode 100644 index 0000000..d783919 --- /dev/null +++ b/apps/landing/src/sections/Concepts.tsx @@ -0,0 +1,155 @@ +import { Section, Icon } from '../ui'; +import { CONCEPTS } from '../content'; + +/** + * The Concepts section teaches the four nouns behind mx (runtime, repo, work, + * worktree) two ways: a labeled diagram of how they nest on disk, then a card + * per term with a plain-English gloss and a short detail. After this a reader + * should be able to parse any mx command. + */ +export function Concepts() { + return ( +
+ + +
+ {CONCEPTS.map((c) => ( +
+
+ + + +

{c.term}

+
+

{c.plain}

+

{c.detail}

+
+ ))} +
+
+ ); +} + +/** + * A labeled, responsive diagram of the on-disk nesting: the runtime contains + * cloned repos (read-only) and one folder per feature; each feature holds + * worktrees that fork from those repos, each on its own branch and ports. Built + * from styled divs rather than an SVG so text reflows on small screens. + */ +function ModelDiagram() { + return ( +
+ {/* Outer frame: the runtime. */} +
+ + + {/* Repos row: cloned once, read-only. */} +
+
+ Repos · cloned once, read-only +
+
+ {['app', 'api'].map((r) => ( +
+ + {r} +
+ ))} +
+
+ + {/* Works row: one card per feature, each holding its worktrees. */} +
+
+ Works · one per feature — the thing you switch between +
+
+ + +
+
+
+ +

+ Two features live side by side. Each wt/<repo>{' '} + is a real git checkout you code in — forked from the shared clone, on its own branch and + ports. +

+
+ ); +} + +/** + * A small labeled header row used inside the diagram frame. + * + * @param icon - Glyph for the entity. + * @param text - The entity name. + * @param hint - A dimmed clarifying note. + */ +function DiagramLabel({ icon, text, hint }: { icon: 'folder'; text: string; hint: string }) { + return ( +
+ + + {text} + + {hint} +
+ ); +} + +/** + * One feature card in the diagram, listing its worktrees with branch and port. + * + * @param name - The feature (work) name. + * @param worktrees - The per-repo worktrees this feature holds. + */ +function WorkBox({ + name, + worktrees, +}: { + name: string; + worktrees: { repo: string; branch: string; port: string }[]; +}) { + return ( +
+
+ + {name} +
+
+ {worktrees.map((wt) => ( +
+ wt/{wt.repo} + + + {wt.branch} + {wt.port} + +
+ ))} +
+
+ ); +} diff --git a/apps/landing/src/sections/Faq.tsx b/apps/landing/src/sections/Faq.tsx new file mode 100644 index 0000000..f6e32f7 --- /dev/null +++ b/apps/landing/src/sections/Faq.tsx @@ -0,0 +1,37 @@ +import { Section, Icon } from '../ui'; +import { FAQS } from '../content'; + +/** + * The FAQ: the objections and clarifications a newcomer typically has before + * committing. Rendered as native
so each answer is expandable, + * keyboard-accessible, and works without JavaScript. + */ +export function Faq() { + return ( +
+
+ {FAQS.map((item) => ( +
+ + {item.q} + + +

{item.a}

+
+ ))} +
+
+ ); +} diff --git a/apps/landing/src/sections/Features.tsx b/apps/landing/src/sections/Features.tsx new file mode 100644 index 0000000..67b0be1 --- /dev/null +++ b/apps/landing/src/sections/Features.tsx @@ -0,0 +1,34 @@ +import { Section, Icon } from '../ui'; +import { FEATURES } from '../content'; + +/** + * The "What you get" grid: six capability cards in plain language. It comes + * after the mental model and quickstart, so a reader already has the vocabulary + * to appreciate each one. + */ +export function Features() { + return ( +
+
+ {FEATURES.map((f) => ( +
+ + + +

{f.title}

+

{f.body}

+
+ ))} +
+
+ ); +} diff --git a/apps/landing/src/sections/Footer.tsx b/apps/landing/src/sections/Footer.tsx new file mode 100644 index 0000000..2b06978 --- /dev/null +++ b/apps/landing/src/sections/Footer.tsx @@ -0,0 +1,83 @@ +import { CopyButton, Icon, Logo } from '../ui'; +import { PKG, REPO_URL, NPM_URL } from '../content'; + +/** + * Closing call-to-action band plus the site footer: repeat the install line for + * readers who scrolled the whole way, then the wordmark, resource links, and + * license/attribution. + */ +export function Footer() { + return ( + <> + {/* Final CTA — a last, prominent chance to copy the install command. */} +
+
+

+ Run a coding agent on every feature +

+

+ One global install, and your next parallel feature — and its agent session — is a single + command away. +

+
+ + $ + npm i -g {PKG} + + +
+
+
+ +
+
+
+
+ + mx +
+

+ A coding agent on every feature — parallel sessions on git worktrees. +

+
+ + +
+ +
+
+ MIT License · Copyright © Rousan Ali · Made for people who ship more than one thing at a + time. +
+
+
+ + ); +} diff --git a/apps/landing/src/sections/Hero.tsx b/apps/landing/src/sections/Hero.tsx new file mode 100644 index 0000000..c11d322 --- /dev/null +++ b/apps/landing/src/sections/Hero.tsx @@ -0,0 +1,70 @@ +import { CopyButton, Icon, Logo } from '../ui'; +import { PKG, REPO_URL } from '../content'; + +/** + * The hero: the one-line promise, a subheadline that names the problem, the + * install command, and two calls to action. A faint parallel-lanes backdrop + * (see `.mx-lanes`) hints at features running side by side. + */ +export function Hero() { + return ( +
+ {/* Decorative background: faint parallel lanes only — no colored glow, to + keep the monochrome, documentation-site calm. */} +
+ +
+ + + + + Open source · MIT · for Claude Code & coding agents + + + +

+ Work on parallel features +
+ using coding agents. +

+ +

+ mx combines your coding agent’s + parallel sessions — Claude Code, Cursor, and the rest — with git worktrees. Every feature + gets its own isolated folder, branch, ports, and agent session, so a fleet of agents can + work at once without tripping over each other. +

+ + {/* Primary install line — the single most important thing to copy. */} +
+ + $ + npm i -g {PKG} + + +
+ + +
+
+ ); +} diff --git a/apps/landing/src/sections/Nav.tsx b/apps/landing/src/sections/Nav.tsx new file mode 100644 index 0000000..bbe57a4 --- /dev/null +++ b/apps/landing/src/sections/Nav.tsx @@ -0,0 +1,73 @@ +import { useEffect, useState } from 'react'; +import { Icon, Logo } from '../ui'; +import { NAV_LINKS, REPO_URL } from '../content'; +import type { Theme } from '../theme'; + +/** + * Sticky top navigation: the mx wordmark, in-page section links, a GitHub link, + * and the light/dark toggle. It gains a border and blur once the user scrolls, + * so it reads as flat over the hero and lifted over content. + * + * @param theme - The active theme, to pick the correct toggle icon. + * @param onToggleTheme - Callback that flips the theme. + */ +export function Nav({ theme, onToggleTheme }: { theme: Theme; onToggleTheme: () => void }) { + const [scrolled, setScrolled] = useState(false); + + // Track whether the page has scrolled past the hero fold so the bar can lift. + useEffect(() => { + const onScroll = () => setScrolled(window.scrollY > 12); + onScroll(); + window.addEventListener('scroll', onScroll, { passive: true }); + return () => window.removeEventListener('scroll', onScroll); + }, []); + + return ( +
+ +
+ ); +} diff --git a/apps/landing/src/sections/Quickstart.tsx b/apps/landing/src/sections/Quickstart.tsx new file mode 100644 index 0000000..5f593d3 --- /dev/null +++ b/apps/landing/src/sections/Quickstart.tsx @@ -0,0 +1,44 @@ +import { Section, Command, Mono } from '../ui'; +import { STEPS } from '../content'; + +/** + * The Quickstart: four numbered steps from an empty machine to coding inside a + * worktree. Each step pairs the exact command with a plain "what this does" + * note, so it reads top to bottom without needing the reference docs. + */ +export function Quickstart() { + return ( +
+
    + {/* Vertical connector line linking the step numbers. */} +
    + + {STEPS.map((step) => ( +
  1. + + {step.n} + +
    +

    {step.title}

    +

    {step.body}

    + +
    +
  2. + ))} +
+ +
+

+ Now cd works/my-feature/wt/app and you’re in a normal git checkout on your + feature branch. Build it, run it, commit, push, open a PR — all the usual way. Start a + second feature with another mx work new and the two stay completely isolated. +

+
+
+ ); +} diff --git a/apps/landing/src/sections/Why.tsx b/apps/landing/src/sections/Why.tsx new file mode 100644 index 0000000..23033e4 --- /dev/null +++ b/apps/landing/src/sections/Why.tsx @@ -0,0 +1,83 @@ +import { Section, Terminal, Line, Mono } from '../ui'; + +/** + * The "Why mx" section: first make the pain visceral (the stash-and-switch + * dance everyone knows), then reframe the solution with a plain analogy, then + * show the before/after side by side. This is where a newcomer decides mx is + * worth their time, so it leads with feeling, not features. + */ +export function Why() { + return ( +
+
+ {/* The pain, dramatized as the familiar terminal dance. */} +
+

+ The old way +

+ + mid-feature, then a hotfix comes in — stash your half-done work + git stash + git checkout main && git checkout -b hotfix +   + dev server died, ports freed, state gone + pnpm install + … reinstalling because the branch differs + pnpm dev + Error: port 3000 already in use +   + fix shipped — now rebuild your headspace + git checkout my-feature && git stash pop + where was I again? + +

+ Every switch tears down your running app, risks port clashes, and evicts the mental + context you’d built up. And a coding agent can only work one checkout at a time — so + running several agents in parallel is off the table entirely. +

+
+ + {/* The relief: two folders, switch instantly. */} +
+

With mx

+ + the feature you were building — still running + cd ~/mx/works/my-feature/wt/app + dev server up on :3000, exactly as you left it +   + the hotfix — its own folder, branch, and port + mx work new hotfix app + cd ~/mx/works/hotfix/wt/app + dev server up on :3002 — no clash +   + done? switch back — nothing was torn down + cd ~/mx/works/my-feature/wt/app + still running. still in context. + +

+ No stashing. No re-install. No port fight. Each feature is a separate checkout in its own + folder, on its own branch, with its own ports — so switching is just cd, and + each one can host its own coding-agent session. +

+
+
+ + {/* The one-sentence mental reframe, given room to land. */} +
+

+ The idea in one line:{' '} + + instead of one workbench you clear off for every task, give each feature its own bench + {' '} + — that stays exactly as you left it. mx builds those benches (using git worktrees under the + hood) and keeps track of the branches, ports, and editor workspace for each one. +

+
+
+ ); +} diff --git a/apps/landing/src/sections/Workflow.tsx b/apps/landing/src/sections/Workflow.tsx new file mode 100644 index 0000000..672c6cb --- /dev/null +++ b/apps/landing/src/sections/Workflow.tsx @@ -0,0 +1,228 @@ +import { Section, Command, Icon } from '../ui'; +import { WORKFLOW_STEPS } from '../content'; + +/** + * The "In practice" section: one concrete, opinionated daily workflow — a + * fullscreen macOS Space per feature (terminal split with the editor), the + * agent in the first terminal tab, and a three-finger swipe to switch. It opens + * with a visual of the split layout, then the numbered steps. The lede stresses + * that mx doesn't mandate any of this; it's a starting shape to copy. + */ +export function Workflow() { + return ( +
+ + +
    + {/* Vertical connector line linking the step numbers. */} +
    + + {WORKFLOW_STEPS.map((step) => ( +
  1. + + {step.n} + +
    +

    {step.title}

    +

    {step.body}

    + {step.cmds ? ( +
    + {step.cmds.map((cmd) => ( + + ))} +
    + ) : null} +
    +
  2. + ))} +
+ +
+

Grouped in Mission Control

+

+ Swipe up with three fingers and your whole board appears: feature Spaces clustered between{' '} + mx divider labels, so you always know what’s + in progress, in review, and merged. +

+ +
+
+ ); +} + +/** + * The ordered contents of the Mission Control Spaces strip: either a labeled + * `mx divider` Space (a group header) or one or more feature Spaces (small + * thumbnails) that belong to the preceding group. Mirrors the real layout a + * user arranges — MAIN, then in-progress features, then review stages. + */ +const STRIP: ({ divider: string } | { spaces: number })[] = [ + { divider: 'MAIN' }, + { spaces: 3 }, + { divider: 'IN PROGRESS' }, + { spaces: 4 }, + { divider: 'IN REVIEWS' }, + { spaces: 2 }, + { divider: 'PR REVIEWS' }, + { spaces: 1 }, + { divider: 'MX' }, + { spaces: 1 }, +]; + +/** + * A horizontally-scrolling mock of the macOS Mission Control Spaces bar: big + * block-text divider Spaces (from `mx divider`) act as group headers, with small + * feature-Space thumbnails clustered under each. Recreates the user's real + * board rather than a screenshot, so it stays crisp and theme-aware. + */ +function SpacesStrip() { + return ( +
+
+ {STRIP.map((item, i) => + 'divider' in item ? ( +
+ {item.divider} +
+ ) : ( + Array.from({ length: item.spaces }).map((_, j) => ) + ), + )} +
+
+ ); +} + +/** + * One feature-Space thumbnail in the Mission Control strip — a tiny split-pane + * window (terminal | editor) rendered abstractly with a few faint lines. + */ +function SpaceThumb() { + return ( +
+
+ + +
+
+
+ + + +
+
+ + + +
+
+
+ ); +} + +/** + * A stylized mock of one feature's fullscreen Space: a terminal pane on the left + * (tab 1 = the agent session, tab 2 = the dev server) and the editor on the + * right, with swipe affordances on the sides to convey "each feature is its own + * Space; swipe to switch." Purely decorative — built from styled divs. + */ +function SpaceMock() { + return ( +
+ + +
+ {/* Window title bar for the whole fullscreen Space. */} +
+ + + + + checkout-redesign — one feature, one Space + +
+ +
+ {/* Left half: the terminal, with two tabs. */} +
+
+ + +
+
+
+ $mx work open -n checkout-redesign +
+
◆ Claude Code · auto mode on
+
# create worktrees + build the feature…
+
› editing app, api…
+
+
+ + {/* Right half: the editor. */} +
+
+ + dev-mx (Workspace) +
+
+
wt/
+
app/
+
api/
+
checkout-redesign.code-workspace
+
+
+
+
+ + +
+ ); +} + +/** + * A single tab in the mock terminal's tab strip. + * + * @param label - The tab's label. + * @param active - Whether this tab reads as the focused one. + */ +function TermTab({ label, active }: { label: string; active?: boolean }) { + return ( + + {label} + + ); +} + +/** + * A dimmed swipe affordance flanking the Space mock, conveying that a + * three-finger trackpad swipe moves between per-feature Spaces. + * + * @param direction - Which way the arrow points (and sits). + */ +function SwipeArrow({ direction }: { direction: 'left' | 'right' }) { + return ( +
+ + + {direction === 'left' ? 'prev feature' : 'next feature'} + +
+ ); +} diff --git a/apps/landing/src/theme.ts b/apps/landing/src/theme.ts new file mode 100644 index 0000000..123c89e --- /dev/null +++ b/apps/landing/src/theme.ts @@ -0,0 +1,54 @@ +import { useCallback, useEffect, useState } from 'react'; + +/** + * The two concrete themes the site can render in. There is no "system" runtime + * state — on first load we resolve the OS preference to one of these and stamp + * it, so the rest of the app only ever deals with a concrete value. + */ +export type Theme = 'light' | 'dark'; + +/** + * localStorage key under which the user's explicit choice is remembered across + * visits. Absent until the user toggles at least once. + */ +const STORAGE_KEY = 'mx-theme'; + +/** + * Resolve the theme to apply on first paint: a previously-saved explicit choice + * wins, otherwise fall back to the OS `prefers-color-scheme` setting. + * + * @returns The concrete theme to stamp on the document element. + */ +function initialTheme(): Theme { + const saved = localStorage.getItem(STORAGE_KEY); + if (saved === 'light' || saved === 'dark') return saved; + return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'; +} + +/** + * Theme controller hook: stamps `data-theme` on so the CSS tokens and + * every `dark:` utility resolve, and persists the user's explicit toggle. + * + * @returns The active theme and a `toggle` callback that flips it. + */ +export function useTheme(): { theme: Theme; toggle: () => void } { + const [theme, setTheme] = useState(() => initialTheme()); + + // Reflect the current theme onto the document element on every change so the + // `[data-theme=...]` selectors in index.css take effect. + useEffect(() => { + document.documentElement.setAttribute('data-theme', theme); + }, [theme]); + + const toggle = useCallback(() => { + setTheme((prev) => { + const next: Theme = prev === 'dark' ? 'light' : 'dark'; + // Persisting marks the choice as explicit, so it survives reloads and + // overrides the OS preference from then on. + localStorage.setItem(STORAGE_KEY, next); + return next; + }); + }, []); + + return { theme, toggle }; +} diff --git a/apps/landing/src/ui.tsx b/apps/landing/src/ui.tsx new file mode 100644 index 0000000..b40e653 --- /dev/null +++ b/apps/landing/src/ui.tsx @@ -0,0 +1,327 @@ +import { useState, type ReactNode, type SVGProps } from 'react'; + +/** + * Names of the inline stroke icons the site uses. Keeping them in one keyed set + * means every icon shares the same 24x24 grid, 1.6 stroke, and currentColor + * fill, so they stay visually consistent wherever they appear. + */ +export type IconName = + | 'copy' + | 'check' + | 'github' + | 'npm' + | 'sun' + | 'moon' + | 'arrow' + | 'terminal' + | 'layers' + | 'shield' + | 'branch' + | 'plug' + | 'sparkles' + | 'activity' + | 'folder' + | 'box' + | 'switch' + | 'plus'; + +/** + * Path/element markup for each icon, drawn on a shared 24x24 viewBox with + * `currentColor` so callers control size and color via className. + */ +const ICON_PATHS: Record = { + copy: ( + <> + + + + ), + check: , + github: ( + + ), + npm: ( + + ), + sun: ( + <> + + + + ), + moon: , + arrow: , + terminal: ( + <> + + + + ), + layers: ( + <> + + + + ), + shield: ( + <> + + + + ), + branch: ( + <> + + + + + + ), + plug: ( + <> + + + + ), + sparkles: ( + <> + + + + ), + activity: , + folder: , + box: ( + <> + + + + ), + switch: ( + <> + + + + + ), + plus: , +}; + +/** + * The mx logo mark: a "multiplex" fan-out — one node branching into three + * parallel nodes — echoing mx running several features (worktrees) in parallel. + * Drawn with `currentColor` so callers set the color (the accent) via className. + * + * @param props - Standard SVG props (notably `className` for size/color). + * @returns The logo SVG, sized and colored from its className. + */ +export function Logo(props: SVGProps) { + return ( + + ); +} + +/** + * Render one of the shared inline icons. + * + * @param name - Which icon from the keyed set to draw. + * @param props - Standard SVG props (notably `className` for size/color). + * @returns The SVG element, inheriting size and color from its className. + */ +export function Icon({ name, ...props }: { name: IconName } & SVGProps) { + return ( + + ); +} + +/** + * A small copy-to-clipboard button that flips to a checkmark for ~1.5s after a + * successful copy, giving the user immediate feedback. + * + * @param value - The text written to the clipboard when clicked. + * @param label - Accessible label describing what gets copied. + */ +export function CopyButton({ value, label = 'Copy' }: { value: string; label?: string }) { + const [copied, setCopied] = useState(false); + return ( + + ); +} + +/** + * A single terminal command rendered as a copyable line: a dimmed `$` prompt, + * the command in monospace, and a copy button. The copied text excludes the + * prompt so it pastes cleanly into a shell. + * + * @param cmd - The shell command (without the leading `$`). + * @param comment - Optional trailing explanation shown dimmed after the command. + */ +export function Command({ cmd, comment }: { cmd: string; comment?: string }) { + return ( +
+ + $ + {cmd} + {comment ? # {comment} : null} + + +
+ ); +} + +/** + * A stylized terminal window frame with the three traffic-light dots and an + * optional title. Used to present multi-line command sequences and output. + * + * @param title - Small label shown in the window's title bar. + * @param children - The terminal body (typically rows). + */ +export function Terminal({ title, children }: { title?: string; children: ReactNode }) { + return ( +
+
+ {/* Monochrome window dots — the terminal chrome stays calm and grayscale. */} + + + + {title ? {title} : null} +
+
{children}
+
+ ); +} + +/** + * One line inside a . A `prompt` line shows the `$` and the command; + * an output line (no prompt) is dimmed to read as program output. + * + * @param children - The line's text content. + * @param prompt - When true, prefix with a `$` prompt and use command styling. + * @param comment - When true, render as a dim `# ...` annotation line. + */ +export function Line({ + children, + prompt, + comment, +}: { + children: ReactNode; + prompt?: boolean; + comment?: boolean; +}) { + if (comment) { + return
# {children}
; + } + if (prompt) { + return ( +
+ $ + {children} +
+ ); + } + return
{children}
; +} + +/** + * A titled top-level page section with a consistent id anchor, eyebrow label, + * heading, and optional lede paragraph. Wraps content in the shared max-width. + * + * @param id - Anchor id used by the nav's in-page links. + * @param eyebrow - Small uppercase label above the heading. + * @param title - The section heading. + * @param lede - Optional intro paragraph under the heading. + * @param children - The section body. + * @param tinted - When true, paint a soft background band (for visual rhythm). + */ +export function Section({ + id, + eyebrow, + title, + lede, + children, + tinted, +}: { + id: string; + eyebrow?: string; + title: ReactNode; + lede?: ReactNode; + children: ReactNode; + tinted?: boolean; +}) { + return ( +
+
+
+ {eyebrow ? ( +
+ {eyebrow} +
+ ) : null} +

{title}

+ {lede ?

{lede}

: null} +
+ {children} +
+
+ ); +} + +/** + * A small inline monospace token for referring to a command, flag, or path in + * running prose without the weight of a full code block. + * + * @param children - The literal text to render in monospace. + */ +export function Mono({ children }: { children: ReactNode }) { + return ( + + {children} + + ); +} diff --git a/apps/landing/tsconfig.json b/apps/landing/tsconfig.json new file mode 100644 index 0000000..94e9859 --- /dev/null +++ b/apps/landing/tsconfig.json @@ -0,0 +1,17 @@ +{ + "compilerOptions": { + "target": "ES2022", + "lib": ["ES2022", "DOM", "DOM.Iterable"], + "module": "ESNext", + "moduleResolution": "bundler", + "jsx": "react-jsx", + "strict": true, + "noEmit": true, + "skipLibCheck": true, + "esModuleInterop": true, + "isolatedModules": true, + "verbatimModuleSyntax": true, + "types": ["vite/client"] + }, + "include": ["src", "vite.config.ts"] +} diff --git a/apps/landing/vite.config.ts b/apps/landing/vite.config.ts new file mode 100644 index 0000000..1fb58b2 --- /dev/null +++ b/apps/landing/vite.config.ts @@ -0,0 +1,23 @@ +import { defineConfig } from 'vite'; +import react from '@vitejs/plugin-react'; +import tailwindcss from '@tailwindcss/vite'; + +/** + * Vite config for the mx landing + docs site. + * + * Unlike the mission-control app (which inlines everything into a single + * `index.html` so the CLI can embed it), this is a conventional multi-asset + * static site. `vite build` emits `apps/landing/dist/` with hashed JS/CSS, and + * GitHub Pages serves that folder at https://mx.rousanali.com (deployed on merge + * to the default branch by .github/workflows/deploy-landing.yml). + * + * `base: '/'` because the site is served from the domain root (a custom domain), + * not a project subpath. + */ +export default defineConfig({ + plugins: [react(), tailwindcss()], + base: '/', + build: { + outDir: 'dist', + }, +}); diff --git a/docs/.vitepress/config.mts b/docs/.vitepress/config.mts new file mode 100644 index 0000000..0f922bb --- /dev/null +++ b/docs/.vitepress/config.mts @@ -0,0 +1,84 @@ +import { defineConfig } from 'vitepress'; + +/** + * VitePress site config for the mx documentation, published at + * https://mx.rousanali.com. The site is built directly from the repo's existing + * `docs/*.md` files (this folder is the VitePress srcDir), so the docs and the + * code stay in one place and can't drift. + */ +export default defineConfig({ + title: 'mx', + description: 'Run several features in parallel across shared repos using git worktrees.', + lang: 'en-US', + cleanUrls: true, + lastUpdated: true, + // The published site is served at the domain root. + base: '/', + // Session summaries and the docs folder's own README are internal, not pages. + srcExclude: ['sessions/**', 'README.md'], + // The existing docs cross-link each other with relative paths and anchors; + // don't fail the build on a stale anchor while the site is taking shape. + ignoreDeadLinks: true, + markdown: { + // These are CLI docs full of `` / `` placeholders in prose. With + // raw-HTML passthrough on (the default), Vue's template compiler treats a + // bare `` as an unclosed tag and the build fails. Turning it off + // escapes stray angle brackets as text; code spans, fenced blocks, and + // VitePress containers (::: tip) are unaffected. + html: false, + }, + head: [ + ['meta', { name: 'theme-color', content: '#3c3c43' }], + ['meta', { property: 'og:title', content: 'mx' }], + [ + 'meta', + { + property: 'og:description', + content: 'Run several features in parallel across shared repos using git worktrees.', + }, + ], + ], + themeConfig: { + nav: [ + { text: 'Guide', link: '/getting-started' }, + { text: 'Reference', link: '/commands' }, + { text: 'Changelog', link: '/history' }, + ], + sidebar: [ + { + text: 'Guide', + items: [ + { text: 'Getting started', link: '/getting-started' }, + { text: 'Overview', link: '/overview' }, + { text: 'Self-hosting', link: '/self-hosting' }, + ], + }, + { + text: 'Reference', + items: [ + { text: 'Commands', link: '/commands' }, + { text: 'Runtime model', link: '/runtime-model' }, + { text: 'Architecture', link: '/architecture' }, + ], + }, + { + text: 'Contributing', + items: [ + { text: 'Development', link: '/development' }, + { text: 'Release', link: '/release' }, + ], + }, + { text: 'Changelog', link: '/history' }, + ], + socialLinks: [{ icon: 'github', link: 'https://github.com/rousan/mx' }], + editLink: { + pattern: 'https://github.com/rousan/mx/edit/main/docs/:path', + text: 'Edit this page on GitHub', + }, + search: { provider: 'local' }, + footer: { + message: 'Released under the MIT License.', + copyright: 'Copyright © Rousan Ali', + }, + }, +}); diff --git a/docs/architecture.md b/docs/architecture.md index 67dcdbe..e9be80a 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -5,11 +5,11 @@ mx is a TypeScript pnpm monorepo with **source code and the publishable npm pack ## The three pieces ``` -github.com/roulabs/mx +github.com/rousan/mx ├── packages/core/ → @mx/core (source; pure domain logic) ├── apps/cli/ → @mx/cli (source; CLI surface; PRIVATE — never published) ├── apps/mission-control/ → @mx/mission-control (source; React/Vite/Tailwind dashboard; PRIVATE — ships only as a prebuilt single HTML) -└── npm/ → @roulabs/mx (publishable; `pnpm build` populates it) +└── npm/ → @rousan/mx (publishable; `pnpm build` populates it) ``` ### `@mx/core` (`packages/core/`) @@ -44,7 +44,7 @@ Key files in `apps/cli/src/`: - `args.ts` — argv parser with `Flags`: `porcelain`, `help`, `version`, `force`, `yes`, `all`, `archived`, `open`, `dryRun`, `quick`, `runtime`, `name`, `description`, `branch`, `base` - `output.ts` — `emit(human, data)`, `fail(err)`, the monochrome style helpers (`dim`, `bold`), the plain glyphs (`check()` = ✓, `warn()` = ⚠), and `confirmYesNo()` (sync TTY prompt via `spawnSync('/bin/sh', ['-c', 'read REPLY'])`) - `paths.ts` — `templatesDir()` resolves `/bin/mx.js` → `/templates` -- `selfupdate.ts` — `mx update`: self-updates the CLI within its major via `npm i -g @roulabs/mx@^`, detects a newer major and prints the deliberate upgrade suggestion, falls back to printing the manual command if npm is missing or the install fails +- `selfupdate.ts` — `mx update`: self-updates the CLI within its major via `npm i -g @rousan/mx@^`, detects a newer major and prints the deliberate upgrade suggestion, falls back to printing the manual command if npm is missing or the install fails - `hooks.ts` — the single hook runner: `runHook(root, event, ctx, quiet)` executes `/hooks/` (any shebang) with `ctx.cwd` + merged `MX_*` env if present, returning `{ran, ok, missing}`; `runPreHook` throws `HOOK_FAILED` on non-zero (abort), `runPostHook` warns. `commands/{work,repo}.ts` call these around worktree create/remove, work archive/unarchive, and repo fetch. (Replaced v2's `hydrate.ts` + `workhooks.ts`.) - `open.ts` — the macOS `mx work new -o` / `mx work open` helper (fullscreen Terminal in the work folder) - `help.ts` — `mx help` text @@ -58,12 +58,12 @@ Key files in `apps/cli/src/`: ### `@mx/mission-control` (`apps/mission-control/`) -The `mx mission-control` dashboard UI: a React + Vite + Tailwind app built to a **single self-contained `dist/index.html`** (via `vite-plugin-singlefile` — all JS/CSS inlined). Private and never published as a package; only the built HTML ships, copied into `npm/mission-control/` and served by the CLI's zero-dep server. React/Vite/Tailwind are dev-only, so the published `@roulabs/mx` keeps zero runtime dependencies. `pnpm build` builds this **before** `@mx/cli` so the copy step finds `dist/`. +The `mx mission-control` dashboard UI: a React + Vite + Tailwind app built to a **single self-contained `dist/index.html`** (via `vite-plugin-singlefile` — all JS/CSS inlined). Private and never published as a package; only the built HTML ships, copied into `npm/mission-control/` and served by the CLI's zero-dep server. React/Vite/Tailwind are dev-only, so the published `@rousan/mx` keeps zero runtime dependencies. `pnpm build` builds this **before** `@mx/cli` so the copy step finds `dist/`. ### `npm/` (the publishable package) Committed: -- `npm/package.json` — public metadata (`@roulabs/mx`, version, bin → `bin/mx.js`, `publishConfig.access: public`) +- `npm/package.json` — public metadata (`@rousan/mx`, version, bin → `bin/mx.js`, `publishConfig.access: public`) - `npm/README.md` — consumer docs Built by `pnpm build` (gitignored): @@ -97,13 +97,13 @@ apps/cli/src/ ┘ │ npm/package.json (committed) │ npm/README.md (committed) │ ↓ - @roulabs/mx@X.Y.Z on npm + @rousan/mx@X.Y.Z on npm tag vX.Y.Z on GitHub ``` ## Zero runtime dependencies -`@roulabs/mx` ships with **no `dependencies`** in its `package.json`. The CLI uses only Node builtins (`node:fs`, `node:path`, `node:child_process`, `node:url`, …). `@mx/core` is `noExternal`-bundled into the CLI by tsup so it's not declared either. Tooling (tsup, eslint, vitest, prettier) is `devDependencies` only. +`@rousan/mx` ships with **no `dependencies`** in its `package.json`. The CLI uses only Node builtins (`node:fs`, `node:path`, `node:child_process`, `node:url`, …). `@mx/core` is `noExternal`-bundled into the CLI by tsup so it's not declared either. Tooling (tsup, eslint, vitest, prettier) is `devDependencies` only. ## Workflow diff --git a/docs/commands.md b/docs/commands.md index 64124de..8c1497d 100644 --- a/docs/commands.md +++ b/docs/commands.md @@ -78,13 +78,13 @@ Output enumerates every path actually written: ### `mx update` -**Self-update the CLI** — not the runtime. Re-installs `@roulabs/mx` within its current major via `npm i -g @roulabs/mx@^`, picking up the latest same-major release. +**Self-update the CLI** — not the runtime. Re-installs `@rousan/mx` within its current major via `npm i -g @rousan/mx@^`, picking up the latest same-major release. It also checks whether a newer **major** exists. If so, it prints a suggestion to cross the major deliberately: ``` -A newer major is available: @roulabs/mx@3. - npm i -g @roulabs/mx@3 +A newer major is available: @rousan/mx@3. + npm i -g @rousan/mx@3 mx migrate ``` diff --git a/docs/development.md b/docs/development.md index 5af60dc..7ad5b88 100644 --- a/docs/development.md +++ b/docs/development.md @@ -11,7 +11,7 @@ How to set up, iterate on, and test mx. ## First-time setup ```bash -git clone git@github.com:roulabs/mx.git && cd mx +git clone git@github.com:rousan/mx.git && cd mx pnpm install pnpm build # populates npm/ (bin/mx.js + templates/ + LICENSE) export MX_RUNTIME="$PWD/.mx" # gitignored dev runtime in this repo @@ -73,7 +73,7 @@ This rule is **load-bearing under self-hosting** — see [self-hosting](self-hos There is **no global PATH coupling to this repo**. The global `mx` exists only when you install a build: ```bash -npm i -g @roulabs/mx +npm i -g @rousan/mx ``` Within this repo, `pnpm mx` runs the local build via the workspace script (`node npm/bin/mx.js`). After changing CLI / core code: `pnpm build` (or keep `pnpm dev` watching) before the change takes effect. @@ -87,3 +87,39 @@ Templates live at `/templates`. tsup copies them into `npm/templates/` at build, - `confirmYesNo()` delegates to `spawnSync('/bin/sh', ['-c', "read REPLY"])` because Node's `fs.readSync(0, …)` returns EAGAIN immediately on macOS in non-blocking stdin mode. The shell builtin `read` blocks on TTY correctly across macOS and Linux. - The first `pnpm install` on a corp npm mirror can be slow — not stuck. - `mx init` is idempotent; re-stamping never clobbers `repos/`, `works/`, or existing `context/INDEX.json`. + +## Documentation site (mx.rousanali.com) + +There are **two** doc surfaces in this repo, on purpose: + +- **`apps/landing/`** — the **public, beginner-first site** published at mx.rousanali.com. A standalone React/Vite/Tailwind app that teaches mx from zero (the problem it solves, the four-word mental model with a diagram, a four-command quickstart, a curated command reference, and an FAQ). This is what a newcomer sees. It intentionally does **not** import from `docs/` — it is hand-written for teaching, so the two can evolve independently without drift risk. +- **`docs/*.md`** — the **deep reference** (runtime model, full command flags, architecture, release runbook, history). Optional VitePress site for reading these locally; also the source the landing page links out to for exhaustive detail. + +```bash +pnpm landing:dev # landing app dev server with hot reload +pnpm landing:build # production build -> apps/landing/dist +pnpm landing:preview # preview the production build + +pnpm docs:dev # (optional) VitePress reference site from docs/*.md +pnpm docs:build # -> docs/.vitepress/dist +``` + +The landing app lives in `apps/landing/src/`: content (features, concepts, quickstart steps, commands, FAQ) is data in `content.ts`; each page section is a component under `sections/`; `theme.ts` drives the light/dark toggle. To change copy, edit `content.ts`; to change layout, edit the relevant section. + +### Hosting: GitHub Pages (GitHub Actions) + +The public site is served at **mx.rousanali.com** from **GitHub Pages**, deployed by the **`.github/workflows/deploy-landing.yml`** workflow (the official `upload-pages-artifact` + `deploy-pages` actions): + +- **push to `main`** → build with `pnpm landing:build` and deploy `apps/landing/dist` to Pages; +- **pull request** → build only (a check that the site still compiles; Pages has no per-PR previews); +- both gated on a `paths` filter, so only changes under `apps/landing/**` (or the lockfile / root `package.json` / the workflow itself) trigger it. + +The custom domain is carried by **`apps/landing/public/CNAME`** (contents: `mx.rousanali.com`), which Vite copies into `dist/` so every deployed artifact declares the domain — GitHub Pages won't drop it. No repo secrets are needed; Pages auth uses the workflow's `id-token`. + +One-time setup: + +1. Repo **Settings → Pages → Build and deployment → Source: GitHub Actions** (enables Actions-based Pages). +2. In your DNS, add a `CNAME` record for `mx.rousanali.com` → `rousan.github.io` (apex/root would use A/AAAA records instead; this is a subdomain, so `CNAME` is correct). +3. After the first deploy, Settings → Pages should show the custom domain as `mx.rousanali.com`; tick **Enforce HTTPS** once the certificate is issued. + +The workflow surfaces the live URL on the `github-pages` environment for the deploy run. diff --git a/docs/getting-started.md b/docs/getting-started.md new file mode 100644 index 0000000..e97b163 --- /dev/null +++ b/docs/getting-started.md @@ -0,0 +1,50 @@ +# Getting started + +**mx** ("multiplexer") lets you work on several features in parallel across shared repositories. Each feature is a *work* with its own git worktrees, branches, and ports, so you switch between them instantly — no stashing, no branch-juggling. + +## Requirements + +- **Node ≥ 22** and **git** on your `PATH`. +- macOS for the optional window helpers (`mx work open -o`, `mx divider -o`); everything else is cross-platform. + +## Install + +```bash +npm install -g @rousan/mx # provides the `mx` command +``` + +## Point mx at a runtime + +mx keeps all its state in one folder — the **runtime**. It's resolved in this order: the `--runtime ` flag, then `$MX_RUNTIME`, then the default `~/mx`. Set it once: + +```bash +export MX_RUNTIME="$HOME/mx" # optional; ~/mx is the default +``` + +## Your first work + +```bash +mx init # scaffold the runtime +mx repo add git@github.com:you/app.git # clone a repo into the runtime (once) +mx work new my-feature app # create a work + an initial worktree of "app" +cd "$(mx work -n my-feature path)"/wt/app # jump into the worktree (on branch my-feature) +``` + +That's it — `wt/app` is a normal git worktree on its own branch. Do your work there, commit, push, open a PR. Start a second feature the same way and both stay fully isolated. + +## The mental model + +- **Runtime** — one folder (`$MX_RUNTIME`) holding pristine repo clones under `repos//git`, and one folder per feature under `works//`. +- **Work** — a feature. Its worktrees live in `works//wt/`, each on its own branch, sharing the pristine clone's object store. +- **mx owns the state.** The per-work `work.json` manifest and the VS Code workspace are written *only* through `mx` commands. Treat them as read-only build output; every read command takes `--porcelain` for stable JSON. + +See [Overview](/overview) for the full picture, [Runtime model](/runtime-model) for what's on disk, and [Commands](/commands) for the complete CLI reference. + +## Handy next steps + +```bash +mx info # see repos, works, worktrees, ports +mx work -n my-feature port set app web # allocate a free port (unique across all works) +mx work -n my-feature open # fullscreen Terminal + Claude session (macOS) +mx mission-control # live web dashboard of the whole runtime +``` diff --git a/docs/history.md b/docs/history.md index 54a80f7..fbd9b92 100644 --- a/docs/history.md +++ b/docs/history.md @@ -2,6 +2,12 @@ What each release brought. Reverse-chronological. Dates reflect when the corresponding tag was pushed. +## 4.0.0 — 2026-07-16 + +**Open-sourced and renamed.** The project moved to `github.com/rousan/mx` and the npm package was renamed from `@roulabs/mx` to **`@rousan/mx`** (a *new* package — the old one is deprecated with a pointer). No behavior change: the CLI, runtime layout (still v3), and every command are identical; this release only re-brands the identity and repo. Existing installs won't auto-migrate — reinstall with `npm rm -g @roulabs/mx && npm i -g @rousan/mx`, then `mx sync` to re-stamp the runtime with the new name/URLs. (Older entries below reference `@roulabs/mx`; that history is left as-is.) + +**Public site.** Introduces a beginner-first landing + docs site at **mx.rousanali.com** — a standalone React/Vite/Tailwind app under `apps/landing` (`pnpm landing:dev` / `landing:build`) that teaches mx from zero, deployed to GitHub Pages on push to `main`. The deeper reference stays in `docs/*.md` (optionally buildable as a VitePress site via `pnpm docs:build`). See [development](development.md#documentation-site-mx-rousanali-com). + ## 3.6.2 — 2026-07-09 **`mx divider` renders text literally, with caller-controlled line breaks.** Spaces are now kept verbatim (`" MAIN "` keeps its padding) instead of being collapsed, and the banner no longer auto-wraps on whitespace. Instead, **you** control stacking: a `\n` (or a real newline) starts a new line, so `mx divider "IN\nPROGRESS"` stacks the two words and fills the window like a single word, while `"IN PROGRESS"` stays one line. The CLI preserves the argument's spaces (no trim) and collapses a real newline to `\n` when re-launching under `-o` so the AppleScript stays single-line. Renderer change in `@mx/core` (`renderBanner`) + CLI arg handling. diff --git a/docs/index.md b/docs/index.md new file mode 100644 index 0000000..14376ae --- /dev/null +++ b/docs/index.md @@ -0,0 +1,32 @@ +--- +layout: home + +hero: + name: mx + text: Parallel work across shared repos + tagline: Run several features at once with isolated git worktrees, branches, and ports — switch instantly, no stashing or branch-juggling. + actions: + - theme: brand + text: Get started + link: /getting-started + - theme: alt + text: Why mx + link: /overview + - theme: alt + text: GitHub + link: https://github.com/rousan/mx + +features: + - title: Isolated per-feature environments + details: Each feature is a "work" with its own git worktrees, feature branches, and per-service ports. Nothing collides; switching is instant. + - title: mx owns the state + details: The work manifest and VS Code workspace are managed only through mx commands. Read stable JSON with --porcelain; never hand-edit runtime files. + - title: One runtime, many repos + details: Clone repos once into a single runtime; fork lightweight worktrees per feature that share the pristine clone's object store. + - title: Lifecycle hooks + details: A central hook hub fires on worktree create/remove, archive/unarchive, and fetch — hydrate deps, copy env files, allocate ports, in any language. + - title: Great for parallel AI coding sessions + details: Open a work in a fullscreen Terminal that resumes or creates its Claude Code session, seeded by a dynamic session-prompt hook. + - title: Live mission control + details: A local, read-only web dashboard streams repo/work health and a consolidated ports board over SSE. +--- diff --git a/docs/overview.md b/docs/overview.md index 78a553f..7ab614d 100644 --- a/docs/overview.md +++ b/docs/overview.md @@ -5,7 +5,7 @@ mx ("multiplexer") is a CLI for running **several features in parallel across sh End-users install it with: ```bash -npm i -g @roulabs/mx # provides the `mx` command +npm i -g @rousan/mx # provides the `mx` command ``` Requires Node ≥22 and git. @@ -59,7 +59,7 @@ The runtime is **versioned**: `mx.json` records the on-disk layout version (CLI ## Where things live in this repo -The source repo at `github.com/roulabs/mx`: +The source repo at `github.com/rousan/mx`: - `packages/core/` — `@mx/core`, pure domain logic (no I/O for stdout, no `process.exit`) - `apps/cli/` — `@mx/cli`, the CLI source wrapping `@mx/core` diff --git a/docs/release.md b/docs/release.md index 5918cd0..24d050f 100644 --- a/docs/release.md +++ b/docs/release.md @@ -1,6 +1,6 @@ # Release runbook -How to ship a new version of `@roulabs/mx`, and the gotchas caught the hard way that aren't obvious from code. +How to ship a new version of `@rousan/mx`, and the gotchas caught the hard way that aren't obvious from code. ## The flow (automated — primary) @@ -28,8 +28,8 @@ What the workflow does on each push to `main`: CI cannot use the interactive `--auth-type=web` browser flow. It needs an **npm automation token** (automation tokens bypass 2FA at publish time): -1. Sign in at as a user with publish rights on the `@roulabs` org. -2. Avatar → **Access Tokens** → **Generate New Token** → **Classic Token** → type **Automation** (or a **Granular Access Token** scoped to publish `@roulabs/mx`). Copy it — it's shown once. +1. Sign in at as a user with publish rights on the `@rousan` org. +2. Avatar → **Access Tokens** → **Generate New Token** → **Classic Token** → type **Automation** (or a **Granular Access Token** scoped to publish `@rousan/mx`). Copy it — it's shown once. 3. In GitHub: repo **Settings → Secrets and variables → Actions → New repository secret**. Name it `NPM_TOKEN`, paste the value. `GITHUB_TOKEN` (used to push the tag and create the Release) is provided automatically by Actions; the workflow requests `contents: write` permission for it. No other secret is needed. @@ -55,10 +55,10 @@ pnpm release # → scripts/release.sh 1. **Verify `npm whoami`** — must be logged in. 2. **Working tree clean** — refuses with `git status` short output if not. 3. **Tag doesn't exist** locally or on origin (with a fresh `git fetch --tags`). -4. **Version not already published** — `npm view @roulabs/mx@X.Y.Z` returns 404. +4. **Version not already published** — `npm view @rousan/mx@X.Y.Z` returns 404. 5. **Run `pnpm typecheck && pnpm lint && pnpm test && pnpm build`** — all green. 6. **Show `npm pack --dry-run` tarball preview**. -7. **Prompt: `Publish @roulabs/mx@X.Y.Z and tag vX.Y.Z? (y/N)`** — type `y`. +7. **Prompt: `Publish @rousan/mx@X.Y.Z and tag vX.Y.Z? (y/N)`** — type `y`. 8. **`npm publish --auth-type=web`** from `npm/` — opens a browser, you confirm in browser (handles 2FA cleanly). 9. **`git tag -a vX.Y.Z -m vX.Y.Z`**, **`git push origin HEAD`**, **`git push origin vX.Y.Z`**. @@ -70,13 +70,13 @@ The script fails fast on any preflight issue — safe to re-run. For a brand-new scoped package (`@org/pkg`), the org must exist on npm before you can publish. The npm CLI has `npm org set / rm / ls` but **no `create`**. Orgs are created via the web UI only: . Pick the **Free** plan (unlimited public packages, no card required). -This bit us when first publishing `@roulabs/mx@1.0.0`. The publish errored with "Scope not found" until the `@roulabs` org existed on npm. +This bit us when first publishing `@rousan/mx@1.0.0`. The publish errored with "Scope not found" until the `@rousan` org existed on npm. ### 2. `npm view ` returning 404 doesn't mean a name will publish npm has an **opaque similarity heuristic** that rejects unscoped names at publish time. `mxcli` was rejected at publish for being too similar to an existing `mx-cli` package, even though `npm view mxcli` had returned a clean 404. -**Scoped names (`@org/name`) bypass this check entirely**, which is why we settled on `@roulabs/mx` after the `mxcli` attempt failed. +**Scoped names (`@org/name`) bypass this check entirely**, which is why we settled on `@rousan/mx` after the `mxcli` attempt failed. ### 3. 2FA-protected accounts need `--auth-type=web` to publish without an OTP prompt @@ -87,7 +87,7 @@ If your npm account has 2FA enabled (most do today), a plain `npm publish` trigg After a successful publish to a brand-new scoped org, `npm view @org/pkg` may return 404 for several minutes while the npm CDN and search index catch up. The package **is** published — the version-specific endpoint shows up immediately: ```bash -curl -s https://registry.npmjs.org/@roulabs/mx/latest | head -c 200 +curl -s https://registry.npmjs.org/@rousan/mx/latest | head -c 200 ``` This isn't an error; just propagation lag. Don't try to "fix" by republishing. @@ -111,7 +111,7 @@ The publishable package layout is `npm/` (committed: `package.json`, `README.md` If a release changes `templates/CLAUDE.md`, existing runtimes won't see it until the user runs: ```bash -npm i -g @roulabs/mx@latest +npm i -g @rousan/mx@latest mx sync ``` @@ -129,5 +129,5 @@ Semver, loosely interpreted (mx is at 2.x, internal-use): - **`pnpm publish` failing** → check `npm whoami`, check the scope exists, check the name isn't similarity-rejected, check 2FA isn't blocking. - **Tag pushed but npm shows old version** → wait 5 minutes (CDN), then check the `/latest` endpoint directly. -- **`mx` from `$PATH` shows wrong version** → that's the globally installed one; might be stale. `npm i -g @roulabs/mx@latest` to refresh. +- **`mx` from `$PATH` shows wrong version** → that's the globally installed one; might be stale. `npm i -g @rousan/mx@latest` to refresh. - **`pnpm mx version` shows the version from `npm/package.json`** — the CLI reads its own version from the package.json at startup (since v1.0.1). diff --git a/docs/runtime-model.md b/docs/runtime-model.md index 62b83dd..6324425 100644 --- a/docs/runtime-model.md +++ b/docs/runtime-model.md @@ -50,7 +50,7 @@ What an mx runtime looks like on disk, the contracts mx owns, and the data shape A given CLI supports exactly one runtime version, with the mapping **CLI major ⇄ runtime version** (CLI 2.x ⇄ v2). Before any runtime-touching command, mx compares the runtime's `mx.json` against the version it supports; on a mismatch it refuses with `RUNTIME_VERSION_MISMATCH`. The only commands allowed on a mismatched runtime are `mx migrate`, `mx update` (self-update the CLI — doesn't touch the runtime), `mx help`, and `mx version`. - **Runtime older than the CLI** → run `mx migrate` to upgrade it. The **v1 → v2** step moves each clone into `repos//git/` (`git worktree repair`) and each work's flat worktrees into `wt/` (`git worktree move`), creating the per-work dirs and rewriting `.code-workspace` paths. The **v2 → v3** step centralizes hooks: it stamps the `/hooks/` hub, writes each repo's `repo.json`, and retires the old per-repo `hydrate.sh`/`health.sh` and per-work `hooks/` — removing them when unchanged from the mx default, **keeping them with a warning** when customized so you can migrate the logic by hand. `mx migrate` validates the whole chain before mutating; a missing step errors `NO_MIGRATION`. Pass `mx migrate --dry-run` to preview the whole plan and any warnings without changing anything. -- **Runtime newer than the CLI** → upgrade the CLI (`mx update`, then `npm i -g @roulabs/mx@` for a new major). `mx migrate` against a newer runtime errors `CLI_TOO_OLD`. +- **Runtime newer than the CLI** → upgrade the CLI (`mx update`, then `npm i -g @rousan/mx@` for a new major). `mx migrate` against a newer runtime errors `CLI_TOO_OLD`. `mx init` stamps `mx.json` on a fresh runtime and refuses to adopt an existing runtime whose version differs. A malformed `mx.json` errors `BAD_VERSION`. diff --git a/docs/self-hosting.md b/docs/self-hosting.md index 2db1ee6..0768439 100644 --- a/docs/self-hosting.md +++ b/docs/self-hosting.md @@ -7,7 +7,7 @@ You can dogfood mx by treating its source as just another repo in an mx runtime One-time, on your productive runtime: ```bash -mx repo add git@github.com:roulabs/mx.git +mx repo add git@github.com:rousan/mx.git ``` Per feature (repeat for as many parallel mx features as you want): @@ -28,7 +28,7 @@ There are two `mx` binaries available inside a self-hosted worktree, and they mu | binary | what it runs | use for | |---|---|---| -| `mx` (on `$PATH`) | the **globally installed** `@roulabs/mx` — published version | productive runtime operations: `mx i`, `mx work archive feat`, etc. **Safe** against the productive runtime. | +| `mx` (on `$PATH`) | the **globally installed** `@rousan/mx` — published version | productive runtime operations: `mx i`, `mx work archive feat`, etc. **Safe** against the productive runtime. | | `pnpm mx ...` or `node npm/bin/mx.js ...` | the **locally-built** CLI from your in-progress code | **testing only** — must always be pointed at a sandbox runtime, never the productive one. | ## The strict rule @@ -97,7 +97,7 @@ Both load. They describe different layers and don't conflict — the source repo 4. checks no `vX.Y.Z` tag exists locally or on origin 5. runs `pnpm typecheck && pnpm lint && pnpm test && pnpm build` 6. shows a tarball preview -7. asks `Publish @roulabs/mx@X.Y.Z and tag vX.Y.Z? (y/N)` +7. asks `Publish @rousan/mx@X.Y.Z and tag vX.Y.Z? (y/N)` 8. on `y`: `npm publish --auth-type=web` from `npm/`, `git tag -a`, `git push origin HEAD`, `git push origin ` The `--auth-type=web` step opens a browser for confirmation (handles 2FA). The push step uses the **current branch** — see the caveat above about feature-branch vs main. diff --git a/eslint.config.js b/eslint.config.js index 7a2534c..ae2b2b9 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -22,6 +22,10 @@ export default tseslint.config( // The dashboard is a React/Vite app with its own conventions; the repo's // JSDoc-on-everything TS config doesn't apply to JSX components. 'apps/mission-control/**', + // The landing + docs site is likewise a standalone React/Vite app. + 'apps/landing/**', + // VitePress docs-site config + build output; not part of the CLI/core. + 'docs/.vitepress/**', ], }, js.configs.recommended, diff --git a/npm/README.md b/npm/README.md index cc5d412..b49cef4 100644 --- a/npm/README.md +++ b/npm/README.md @@ -9,7 +9,7 @@ The runtime is **versioned** (an integer in `/mx.json`). A given CLI su ## Install ```bash -npm install -g @roulabs/mx # provides the `mx` command +npm install -g @rousan/mx # provides the `mx` command ``` Requires Node >= 22 and git. diff --git a/npm/package.json b/npm/package.json index 9112d87..0c77b36 100644 --- a/npm/package.json +++ b/npm/package.json @@ -1,6 +1,6 @@ { - "name": "@roulabs/mx", - "version": "3.6.2", + "name": "@rousan/mx", + "version": "4.0.0", "description": "mx — run several features in parallel across shared repos using git worktrees", "type": "module", "bin": { @@ -12,10 +12,10 @@ "license": "MIT", "repository": { "type": "git", - "url": "git+https://github.com/roulabs/mx.git" + "url": "git+https://github.com/rousan/mx.git" }, - "homepage": "https://github.com/roulabs/mx#readme", - "bugs": "https://github.com/roulabs/mx/issues", + "homepage": "https://mx.rousanali.com", + "bugs": "https://github.com/rousan/mx/issues", "keywords": [ "git", "worktree", diff --git a/package.json b/package.json index 2f512b9..6973bf8 100644 --- a/package.json +++ b/package.json @@ -17,6 +17,12 @@ "lint": "eslint .", "format": "prettier --write .", "test": "vitest run", + "docs:dev": "vitepress dev docs", + "docs:build": "vitepress build docs", + "docs:preview": "vitepress preview docs", + "landing:dev": "pnpm --filter @mx/landing run dev", + "landing:build": "pnpm --filter @mx/landing run build", + "landing:preview": "pnpm --filter @mx/landing run preview", "release": "bash scripts/release.sh" }, "devDependencies": { @@ -29,6 +35,7 @@ "tsup": "^8.3.0", "typescript": "^5.6.0", "typescript-eslint": "^8.10.0", + "vitepress": "^1.6.4", "vitest": "^2.1.0" } } \ No newline at end of file diff --git a/packages/core/src/migrations.ts b/packages/core/src/migrations.ts index 905b6e3..e4b4c4a 100644 --- a/packages/core/src/migrations.ts +++ b/packages/core/src/migrations.ts @@ -329,7 +329,7 @@ export function migrateRuntime( if (from > RUNTIME_VERSION) { throw new MxError( `runtime is v${from}, newer than this mx supports (v${RUNTIME_VERSION}). ` + - `Upgrade your mx CLI: \`npm i -g @roulabs/mx@latest\`.`, + `Upgrade your mx CLI: \`npm i -g @rousan/mx@latest\`.`, 'CLI_TOO_OLD', ); } diff --git a/packages/core/src/runtime.ts b/packages/core/src/runtime.ts index 23e374b..48c939c 100644 --- a/packages/core/src/runtime.ts +++ b/packages/core/src/runtime.ts @@ -344,7 +344,7 @@ export function writeRuntimeVersion(root: string, version: number): void { */ function versionMismatchMessage(actual: number): string { if (actual > RUNTIME_VERSION) { - return `runtime is v${actual}, newer than this mx supports (v${RUNTIME_VERSION}). Upgrade your mx CLI: \`npm i -g @roulabs/mx@latest\`.`; + return `runtime is v${actual}, newer than this mx supports (v${RUNTIME_VERSION}). Upgrade your mx CLI: \`npm i -g @rousan/mx@latest\`.`; } return `runtime is v${actual} but this mx supports runtime v${RUNTIME_VERSION}. Run \`mx migrate\` to upgrade the runtime.`; } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 0eb2f9b..4a2391f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -35,6 +35,9 @@ importers: typescript-eslint: specifier: ^8.10.0 version: 8.60.1(eslint@9.39.4)(typescript@5.9.3) + vitepress: + specifier: ^1.6.4 + version: 1.6.4(@algolia/client-search@5.56.0)(@types/node@22.19.19)(search-insights@2.17.3)(typescript@5.9.3) vitest: specifier: ^2.1.0 version: 2.1.9(@types/node@22.19.19) @@ -45,6 +48,34 @@ importers: specifier: workspace:* version: link:../../packages/core + apps/landing: + dependencies: + react: + specifier: ^19.0.0 + version: 19.2.7 + react-dom: + specifier: ^19.0.0 + version: 19.2.7(react@19.2.7) + devDependencies: + '@tailwindcss/vite': + specifier: ^4.0.0 + version: 4.3.2(vite@6.4.3) + '@types/react': + specifier: ^19.0.0 + version: 19.2.17 + '@types/react-dom': + specifier: ^19.0.0 + version: 19.2.3(@types/react@19.2.17) + '@vitejs/plugin-react': + specifier: ^4.3.0 + version: 4.7.0(vite@6.4.3) + tailwindcss: + specifier: ^4.0.0 + version: 4.3.2 + vite: + specifier: ^6.0.0 + version: 6.4.3(@types/node@22.19.19) + apps/mission-control: dependencies: react: @@ -80,6 +111,176 @@ importers: packages: + /@algolia/abtesting@1.22.0: + resolution: {integrity: sha512-BFR6zNowNKcY7Ou7TaJc9QWexES4YKPbmf/OTFofpdsdhz4x6q0lbxp3duO0EHnyrN7rE4ba/TSXuY+BDGu4+g==, tarball: https://registry.npmjs.org/@algolia/abtesting/-/abtesting-1.22.0.tgz} + engines: {node: '>= 14.0.0'} + dependencies: + '@algolia/client-common': 5.56.0 + '@algolia/requester-browser-xhr': 5.56.0 + '@algolia/requester-fetch': 5.56.0 + '@algolia/requester-node-http': 5.56.0 + dev: true + + /@algolia/autocomplete-core@1.17.7(@algolia/client-search@5.56.0)(algoliasearch@5.56.0)(search-insights@2.17.3): + resolution: {integrity: sha512-BjiPOW6ks90UKl7TwMv7oNQMnzU+t/wk9mgIDi6b1tXpUek7MW0lbNOUHpvam9pe3lVCf4xPFT+lK7s+e+fs7Q==, tarball: https://registry.npmjs.org/@algolia/autocomplete-core/-/autocomplete-core-1.17.7.tgz} + dependencies: + '@algolia/autocomplete-plugin-algolia-insights': 1.17.7(@algolia/client-search@5.56.0)(algoliasearch@5.56.0)(search-insights@2.17.3) + '@algolia/autocomplete-shared': 1.17.7(@algolia/client-search@5.56.0)(algoliasearch@5.56.0) + transitivePeerDependencies: + - '@algolia/client-search' + - algoliasearch + - search-insights + dev: true + + /@algolia/autocomplete-plugin-algolia-insights@1.17.7(@algolia/client-search@5.56.0)(algoliasearch@5.56.0)(search-insights@2.17.3): + resolution: {integrity: sha512-Jca5Ude6yUOuyzjnz57og7Et3aXjbwCSDf/8onLHSQgw1qW3ALl9mrMWaXb5FmPVkV3EtkD2F/+NkT6VHyPu9A==, tarball: https://registry.npmjs.org/@algolia/autocomplete-plugin-algolia-insights/-/autocomplete-plugin-algolia-insights-1.17.7.tgz} + peerDependencies: + search-insights: '>= 1 < 3' + dependencies: + '@algolia/autocomplete-shared': 1.17.7(@algolia/client-search@5.56.0)(algoliasearch@5.56.0) + search-insights: 2.17.3 + transitivePeerDependencies: + - '@algolia/client-search' + - algoliasearch + dev: true + + /@algolia/autocomplete-preset-algolia@1.17.7(@algolia/client-search@5.56.0)(algoliasearch@5.56.0): + resolution: {integrity: sha512-ggOQ950+nwbWROq2MOCIL71RE0DdQZsceqrg32UqnhDz8FlO9rL8ONHNsI2R1MH0tkgVIDKI/D0sMiUchsFdWA==, tarball: https://registry.npmjs.org/@algolia/autocomplete-preset-algolia/-/autocomplete-preset-algolia-1.17.7.tgz} + peerDependencies: + '@algolia/client-search': '>= 4.9.1 < 6' + algoliasearch: '>= 4.9.1 < 6' + dependencies: + '@algolia/autocomplete-shared': 1.17.7(@algolia/client-search@5.56.0)(algoliasearch@5.56.0) + '@algolia/client-search': 5.56.0 + algoliasearch: 5.56.0 + dev: true + + /@algolia/autocomplete-shared@1.17.7(@algolia/client-search@5.56.0)(algoliasearch@5.56.0): + resolution: {integrity: sha512-o/1Vurr42U/qskRSuhBH+VKxMvkkUVTLU6WZQr+L5lGZZLYWyhdzWjW0iGXY7EkwRTjBqvN2EsR81yCTGV/kmg==, tarball: https://registry.npmjs.org/@algolia/autocomplete-shared/-/autocomplete-shared-1.17.7.tgz} + peerDependencies: + '@algolia/client-search': '>= 4.9.1 < 6' + algoliasearch: '>= 4.9.1 < 6' + dependencies: + '@algolia/client-search': 5.56.0 + algoliasearch: 5.56.0 + dev: true + + /@algolia/client-abtesting@5.56.0: + resolution: {integrity: sha512-7r4Z3NC7yU1oAQVWJNA2HX7tX481F3pJvCGyLIXiTdBcthz4Q/o21jwcMYDFkuI92UWTNBQQmHYgwHo1zS5dzg==, tarball: https://registry.npmjs.org/@algolia/client-abtesting/-/client-abtesting-5.56.0.tgz} + engines: {node: '>= 14.0.0'} + dependencies: + '@algolia/client-common': 5.56.0 + '@algolia/requester-browser-xhr': 5.56.0 + '@algolia/requester-fetch': 5.56.0 + '@algolia/requester-node-http': 5.56.0 + dev: true + + /@algolia/client-analytics@5.56.0: + resolution: {integrity: sha512-avmjXQSq+jadFO8Xl2em05/uQdQnEmHsJyOAdVbZkmVgpMfxL12aJwVVfGNwYr9nulcpuJN1X0lTaQ5wxuNGcA==, tarball: https://registry.npmjs.org/@algolia/client-analytics/-/client-analytics-5.56.0.tgz} + engines: {node: '>= 14.0.0'} + dependencies: + '@algolia/client-common': 5.56.0 + '@algolia/requester-browser-xhr': 5.56.0 + '@algolia/requester-fetch': 5.56.0 + '@algolia/requester-node-http': 5.56.0 + dev: true + + /@algolia/client-common@5.56.0: + resolution: {integrity: sha512-v2TPStUhY//ripPjIVclZ8AWc7DEGooXULZGFlFu37zNatgHjw34oZZ+OSbbc/YHO+xZwPl62I1k8xH1m4S2eg==, tarball: https://registry.npmjs.org/@algolia/client-common/-/client-common-5.56.0.tgz} + engines: {node: '>= 14.0.0'} + dev: true + + /@algolia/client-insights@5.56.0: + resolution: {integrity: sha512-P0ehROpM4Sem3Sqo5x2cKPgj67D3G3jy0rh1Amwkcvsfr6tkvIcdCmerieanqTF7NxUMPNFLkpIFeMO8Rpa50w==, tarball: https://registry.npmjs.org/@algolia/client-insights/-/client-insights-5.56.0.tgz} + engines: {node: '>= 14.0.0'} + dependencies: + '@algolia/client-common': 5.56.0 + '@algolia/requester-browser-xhr': 5.56.0 + '@algolia/requester-fetch': 5.56.0 + '@algolia/requester-node-http': 5.56.0 + dev: true + + /@algolia/client-personalization@5.56.0: + resolution: {integrity: sha512-SXK3Vn3WVxyzbm31oePZBJkp1wpOyuWdd4B/Pv7n0aXDxmeSWhC1R1FC1517mMrFAIaPH4Rt0x6RUe7ZNjz8FA==, tarball: https://registry.npmjs.org/@algolia/client-personalization/-/client-personalization-5.56.0.tgz} + engines: {node: '>= 14.0.0'} + dependencies: + '@algolia/client-common': 5.56.0 + '@algolia/requester-browser-xhr': 5.56.0 + '@algolia/requester-fetch': 5.56.0 + '@algolia/requester-node-http': 5.56.0 + dev: true + + /@algolia/client-query-suggestions@5.56.0: + resolution: {integrity: sha512-5+ZdX8garFnmycnZgKhtXHePEaLj5zqDxI/0lkhhluzCcvTn0/PvvTirTg8hHYetQHvn7GDyeAiqTAieMvMW4A==, tarball: https://registry.npmjs.org/@algolia/client-query-suggestions/-/client-query-suggestions-5.56.0.tgz} + engines: {node: '>= 14.0.0'} + dependencies: + '@algolia/client-common': 5.56.0 + '@algolia/requester-browser-xhr': 5.56.0 + '@algolia/requester-fetch': 5.56.0 + '@algolia/requester-node-http': 5.56.0 + dev: true + + /@algolia/client-search@5.56.0: + resolution: {integrity: sha512-+mKUdYvqOi0BcvpAEyCEw49vSBptufIcfibtHz2bdr1pI789M46Yt0uQEk/sxtK3teh71OQvVFHaTDzShUWewQ==, tarball: https://registry.npmjs.org/@algolia/client-search/-/client-search-5.56.0.tgz} + engines: {node: '>= 14.0.0'} + dependencies: + '@algolia/client-common': 5.56.0 + '@algolia/requester-browser-xhr': 5.56.0 + '@algolia/requester-fetch': 5.56.0 + '@algolia/requester-node-http': 5.56.0 + dev: true + + /@algolia/ingestion@1.56.0: + resolution: {integrity: sha512-9g/zj+AZx5moFcdFIrYQoVrueXivjUcc3MQHtCYT8WhIuk1lUh1AyEhvJCS0XBZld09cLvd1AZ3BvDBpVpX2UA==, tarball: https://registry.npmjs.org/@algolia/ingestion/-/ingestion-1.56.0.tgz} + engines: {node: '>= 14.0.0'} + dependencies: + '@algolia/client-common': 5.56.0 + '@algolia/requester-browser-xhr': 5.56.0 + '@algolia/requester-fetch': 5.56.0 + '@algolia/requester-node-http': 5.56.0 + dev: true + + /@algolia/monitoring@1.56.0: + resolution: {integrity: sha512-Qf3Sr6f9A9uxCZUf3MXS0d2b877uYzEB5yxqpVGXAhcJnBCQjrRRon0KvefpGkxy+BshrIJs96OUoMtGqXTFDA==, tarball: https://registry.npmjs.org/@algolia/monitoring/-/monitoring-1.56.0.tgz} + engines: {node: '>= 14.0.0'} + dependencies: + '@algolia/client-common': 5.56.0 + '@algolia/requester-browser-xhr': 5.56.0 + '@algolia/requester-fetch': 5.56.0 + '@algolia/requester-node-http': 5.56.0 + dev: true + + /@algolia/recommend@5.56.0: + resolution: {integrity: sha512-GXWG1rWc5wu8hY4N33Y3b6ernY6sAdAvmKWN/zHAiACOx40WnpG0TVX5YazCAr/9gOYGInSiM2A0y2jy2xbiDA==, tarball: https://registry.npmjs.org/@algolia/recommend/-/recommend-5.56.0.tgz} + engines: {node: '>= 14.0.0'} + dependencies: + '@algolia/client-common': 5.56.0 + '@algolia/requester-browser-xhr': 5.56.0 + '@algolia/requester-fetch': 5.56.0 + '@algolia/requester-node-http': 5.56.0 + dev: true + + /@algolia/requester-browser-xhr@5.56.0: + resolution: {integrity: sha512-7t24cBxaInS3mZb7ddEaZT/tp6q+/aR4YttsQVyP1/i+LmwPR34atO35KjaLFCcRVrlP7sYOAqkCfg6lIRB+ew==, tarball: https://registry.npmjs.org/@algolia/requester-browser-xhr/-/requester-browser-xhr-5.56.0.tgz} + engines: {node: '>= 14.0.0'} + dependencies: + '@algolia/client-common': 5.56.0 + dev: true + + /@algolia/requester-fetch@5.56.0: + resolution: {integrity: sha512-R7ePHgVYmDFjZpvrsVAfbDz/d4RxKAYZ5/vgLfIsCVRZRryjWl/3INOxpOICzitehQ5FjNtNjcLQTrmHPTcHBQ==, tarball: https://registry.npmjs.org/@algolia/requester-fetch/-/requester-fetch-5.56.0.tgz} + engines: {node: '>= 14.0.0'} + dependencies: + '@algolia/client-common': 5.56.0 + dev: true + + /@algolia/requester-node-http@5.56.0: + resolution: {integrity: sha512-PIOUXlSnrqM0S+WOgDRb4RzotydJH7ZoT6tOyL7tAO7qJOfvX5wsEW8Pe+PMKMwvuI4/gIyK9cg2H7lJXqnc4Q==, tarball: https://registry.npmjs.org/@algolia/requester-node-http/-/requester-node-http-5.56.0.tgz} + engines: {node: '>= 14.0.0'} + dependencies: + '@algolia/client-common': 5.56.0 + dev: true + /@babel/code-frame@7.29.7: resolution: {integrity: sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==} engines: {node: '>=6.9.0'} @@ -256,6 +457,50 @@ packages: '@babel/helper-validator-identifier': 7.29.7 dev: true + /@docsearch/css@3.8.2: + resolution: {integrity: sha512-y05ayQFyUmCXze79+56v/4HpycYF3uFqB78pLPrSV5ZKAlDuIAAJNhaRi8tTdRNXh05yxX/TyNnzD6LwSM89vQ==, tarball: https://registry.npmjs.org/@docsearch/css/-/css-3.8.2.tgz} + dev: true + + /@docsearch/js@3.8.2(@algolia/client-search@5.56.0)(search-insights@2.17.3): + resolution: {integrity: sha512-Q5wY66qHn0SwA7Taa0aDbHiJvaFJLOJyHmooQ7y8hlwwQLQ/5WwCcoX0g7ii04Qi2DJlHsd0XXzJ8Ypw9+9YmQ==, tarball: https://registry.npmjs.org/@docsearch/js/-/js-3.8.2.tgz} + dependencies: + '@docsearch/react': 3.8.2(@algolia/client-search@5.56.0)(search-insights@2.17.3) + preact: 10.29.7 + transitivePeerDependencies: + - '@algolia/client-search' + - '@types/react' + - preact-render-to-string + - react + - react-dom + - search-insights + dev: true + + /@docsearch/react@3.8.2(@algolia/client-search@5.56.0)(search-insights@2.17.3): + resolution: {integrity: sha512-xCRrJQlTt8N9GU0DG4ptwHRkfnSnD/YpdeaXe02iKfqs97TkZJv60yE+1eq/tjPcVnTW8dP5qLP7itifFVV5eg==, tarball: https://registry.npmjs.org/@docsearch/react/-/react-3.8.2.tgz} + peerDependencies: + '@types/react': '>= 16.8.0 < 19.0.0' + react: '>= 16.8.0 < 19.0.0' + react-dom: '>= 16.8.0 < 19.0.0' + search-insights: '>= 1 < 3' + peerDependenciesMeta: + '@types/react': + optional: true + react: + optional: true + react-dom: + optional: true + search-insights: + optional: true + dependencies: + '@algolia/autocomplete-core': 1.17.7(@algolia/client-search@5.56.0)(algoliasearch@5.56.0)(search-insights@2.17.3) + '@algolia/autocomplete-preset-algolia': 1.17.7(@algolia/client-search@5.56.0)(algoliasearch@5.56.0) + '@docsearch/css': 3.8.2 + algoliasearch: 5.56.0 + search-insights: 2.17.3 + transitivePeerDependencies: + - '@algolia/client-search' + dev: true + /@es-joy/jsdoccomment@0.50.2: resolution: {integrity: sha512-YAdE/IJSpwbOTiaURNCKECdAwqrJuFiZhylmesBcIRawtYKnBR2wxPhoIewMg+Yu+QuYvHfJNReWpoxGBKOChA==} engines: {node: '>=18'} @@ -268,7 +513,7 @@ packages: dev: true /@esbuild/aix-ppc64@0.21.5: - resolution: {integrity: sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==} + resolution: {integrity: sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==, tarball: https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz} engines: {node: '>=12'} cpu: [ppc64] os: [aix] @@ -277,7 +522,7 @@ packages: optional: true /@esbuild/aix-ppc64@0.25.12: - resolution: {integrity: sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==} + resolution: {integrity: sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==, tarball: https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.12.tgz} engines: {node: '>=18'} cpu: [ppc64] os: [aix] @@ -286,7 +531,7 @@ packages: optional: true /@esbuild/aix-ppc64@0.27.7: - resolution: {integrity: sha512-EKX3Qwmhz1eMdEJokhALr0YiD0lhQNwDqkPYyPhiSwKrh7/4KRjQc04sZ8db+5DVVnZ1LmbNDI1uAMPEUBnQPg==} + resolution: {integrity: sha512-EKX3Qwmhz1eMdEJokhALr0YiD0lhQNwDqkPYyPhiSwKrh7/4KRjQc04sZ8db+5DVVnZ1LmbNDI1uAMPEUBnQPg==, tarball: https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.7.tgz} engines: {node: '>=18'} cpu: [ppc64] os: [aix] @@ -295,7 +540,7 @@ packages: optional: true /@esbuild/android-arm64@0.21.5: - resolution: {integrity: sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==} + resolution: {integrity: sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==, tarball: https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz} engines: {node: '>=12'} cpu: [arm64] os: [android] @@ -304,7 +549,7 @@ packages: optional: true /@esbuild/android-arm64@0.25.12: - resolution: {integrity: sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==} + resolution: {integrity: sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==, tarball: https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.12.tgz} engines: {node: '>=18'} cpu: [arm64] os: [android] @@ -313,7 +558,7 @@ packages: optional: true /@esbuild/android-arm64@0.27.7: - resolution: {integrity: sha512-62dPZHpIXzvChfvfLJow3q5dDtiNMkwiRzPylSCfriLvZeq0a1bWChrGx/BbUbPwOrsWKMn8idSllklzBy+dgQ==} + resolution: {integrity: sha512-62dPZHpIXzvChfvfLJow3q5dDtiNMkwiRzPylSCfriLvZeq0a1bWChrGx/BbUbPwOrsWKMn8idSllklzBy+dgQ==, tarball: https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.7.tgz} engines: {node: '>=18'} cpu: [arm64] os: [android] @@ -322,7 +567,7 @@ packages: optional: true /@esbuild/android-arm@0.21.5: - resolution: {integrity: sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==} + resolution: {integrity: sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==, tarball: https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz} engines: {node: '>=12'} cpu: [arm] os: [android] @@ -331,7 +576,7 @@ packages: optional: true /@esbuild/android-arm@0.25.12: - resolution: {integrity: sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==} + resolution: {integrity: sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==, tarball: https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.12.tgz} engines: {node: '>=18'} cpu: [arm] os: [android] @@ -340,7 +585,7 @@ packages: optional: true /@esbuild/android-arm@0.27.7: - resolution: {integrity: sha512-jbPXvB4Yj2yBV7HUfE2KHe4GJX51QplCN1pGbYjvsyCZbQmies29EoJbkEc+vYuU5o45AfQn37vZlyXy4YJ8RQ==} + resolution: {integrity: sha512-jbPXvB4Yj2yBV7HUfE2KHe4GJX51QplCN1pGbYjvsyCZbQmies29EoJbkEc+vYuU5o45AfQn37vZlyXy4YJ8RQ==, tarball: https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.7.tgz} engines: {node: '>=18'} cpu: [arm] os: [android] @@ -349,7 +594,7 @@ packages: optional: true /@esbuild/android-x64@0.21.5: - resolution: {integrity: sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==} + resolution: {integrity: sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==, tarball: https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz} engines: {node: '>=12'} cpu: [x64] os: [android] @@ -358,7 +603,7 @@ packages: optional: true /@esbuild/android-x64@0.25.12: - resolution: {integrity: sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==} + resolution: {integrity: sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==, tarball: https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.12.tgz} engines: {node: '>=18'} cpu: [x64] os: [android] @@ -367,7 +612,7 @@ packages: optional: true /@esbuild/android-x64@0.27.7: - resolution: {integrity: sha512-x5VpMODneVDb70PYV2VQOmIUUiBtY3D3mPBG8NxVk5CogneYhkR7MmM3yR/uMdITLrC1ml/NV1rj4bMJuy9MCg==} + resolution: {integrity: sha512-x5VpMODneVDb70PYV2VQOmIUUiBtY3D3mPBG8NxVk5CogneYhkR7MmM3yR/uMdITLrC1ml/NV1rj4bMJuy9MCg==, tarball: https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.7.tgz} engines: {node: '>=18'} cpu: [x64] os: [android] @@ -376,7 +621,7 @@ packages: optional: true /@esbuild/darwin-arm64@0.21.5: - resolution: {integrity: sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==} + resolution: {integrity: sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==, tarball: https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz} engines: {node: '>=12'} cpu: [arm64] os: [darwin] @@ -385,7 +630,7 @@ packages: optional: true /@esbuild/darwin-arm64@0.25.12: - resolution: {integrity: sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==} + resolution: {integrity: sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==, tarball: https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.12.tgz} engines: {node: '>=18'} cpu: [arm64] os: [darwin] @@ -394,7 +639,7 @@ packages: optional: true /@esbuild/darwin-arm64@0.27.7: - resolution: {integrity: sha512-5lckdqeuBPlKUwvoCXIgI2D9/ABmPq3Rdp7IfL70393YgaASt7tbju3Ac+ePVi3KDH6N2RqePfHnXkaDtY9fkw==} + resolution: {integrity: sha512-5lckdqeuBPlKUwvoCXIgI2D9/ABmPq3Rdp7IfL70393YgaASt7tbju3Ac+ePVi3KDH6N2RqePfHnXkaDtY9fkw==, tarball: https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.7.tgz} engines: {node: '>=18'} cpu: [arm64] os: [darwin] @@ -403,7 +648,7 @@ packages: optional: true /@esbuild/darwin-x64@0.21.5: - resolution: {integrity: sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==} + resolution: {integrity: sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==, tarball: https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz} engines: {node: '>=12'} cpu: [x64] os: [darwin] @@ -412,7 +657,7 @@ packages: optional: true /@esbuild/darwin-x64@0.25.12: - resolution: {integrity: sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==} + resolution: {integrity: sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==, tarball: https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.12.tgz} engines: {node: '>=18'} cpu: [x64] os: [darwin] @@ -421,7 +666,7 @@ packages: optional: true /@esbuild/darwin-x64@0.27.7: - resolution: {integrity: sha512-rYnXrKcXuT7Z+WL5K980jVFdvVKhCHhUwid+dDYQpH+qu+TefcomiMAJpIiC2EM3Rjtq0sO3StMV/+3w3MyyqQ==} + resolution: {integrity: sha512-rYnXrKcXuT7Z+WL5K980jVFdvVKhCHhUwid+dDYQpH+qu+TefcomiMAJpIiC2EM3Rjtq0sO3StMV/+3w3MyyqQ==, tarball: https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.7.tgz} engines: {node: '>=18'} cpu: [x64] os: [darwin] @@ -430,7 +675,7 @@ packages: optional: true /@esbuild/freebsd-arm64@0.21.5: - resolution: {integrity: sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==} + resolution: {integrity: sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==, tarball: https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz} engines: {node: '>=12'} cpu: [arm64] os: [freebsd] @@ -439,7 +684,7 @@ packages: optional: true /@esbuild/freebsd-arm64@0.25.12: - resolution: {integrity: sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==} + resolution: {integrity: sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==, tarball: https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.12.tgz} engines: {node: '>=18'} cpu: [arm64] os: [freebsd] @@ -448,7 +693,7 @@ packages: optional: true /@esbuild/freebsd-arm64@0.27.7: - resolution: {integrity: sha512-B48PqeCsEgOtzME2GbNM2roU29AMTuOIN91dsMO30t+Ydis3z/3Ngoj5hhnsOSSwNzS+6JppqWsuhTp6E82l2w==} + resolution: {integrity: sha512-B48PqeCsEgOtzME2GbNM2roU29AMTuOIN91dsMO30t+Ydis3z/3Ngoj5hhnsOSSwNzS+6JppqWsuhTp6E82l2w==, tarball: https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.7.tgz} engines: {node: '>=18'} cpu: [arm64] os: [freebsd] @@ -457,7 +702,7 @@ packages: optional: true /@esbuild/freebsd-x64@0.21.5: - resolution: {integrity: sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==} + resolution: {integrity: sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==, tarball: https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz} engines: {node: '>=12'} cpu: [x64] os: [freebsd] @@ -466,7 +711,7 @@ packages: optional: true /@esbuild/freebsd-x64@0.25.12: - resolution: {integrity: sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==} + resolution: {integrity: sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==, tarball: https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.12.tgz} engines: {node: '>=18'} cpu: [x64] os: [freebsd] @@ -475,7 +720,7 @@ packages: optional: true /@esbuild/freebsd-x64@0.27.7: - resolution: {integrity: sha512-jOBDK5XEjA4m5IJK3bpAQF9/Lelu/Z9ZcdhTRLf4cajlB+8VEhFFRjWgfy3M1O4rO2GQ/b2dLwCUGpiF/eATNQ==} + resolution: {integrity: sha512-jOBDK5XEjA4m5IJK3bpAQF9/Lelu/Z9ZcdhTRLf4cajlB+8VEhFFRjWgfy3M1O4rO2GQ/b2dLwCUGpiF/eATNQ==, tarball: https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.7.tgz} engines: {node: '>=18'} cpu: [x64] os: [freebsd] @@ -484,7 +729,7 @@ packages: optional: true /@esbuild/linux-arm64@0.21.5: - resolution: {integrity: sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==} + resolution: {integrity: sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==, tarball: https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz} engines: {node: '>=12'} cpu: [arm64] os: [linux] @@ -493,7 +738,7 @@ packages: optional: true /@esbuild/linux-arm64@0.25.12: - resolution: {integrity: sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==} + resolution: {integrity: sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==, tarball: https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.12.tgz} engines: {node: '>=18'} cpu: [arm64] os: [linux] @@ -502,7 +747,7 @@ packages: optional: true /@esbuild/linux-arm64@0.27.7: - resolution: {integrity: sha512-RZPHBoxXuNnPQO9rvjh5jdkRmVizktkT7TCDkDmQ0W2SwHInKCAV95GRuvdSvA7w4VMwfCjUiPwDi0ZO6Nfe9A==} + resolution: {integrity: sha512-RZPHBoxXuNnPQO9rvjh5jdkRmVizktkT7TCDkDmQ0W2SwHInKCAV95GRuvdSvA7w4VMwfCjUiPwDi0ZO6Nfe9A==, tarball: https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.7.tgz} engines: {node: '>=18'} cpu: [arm64] os: [linux] @@ -511,7 +756,7 @@ packages: optional: true /@esbuild/linux-arm@0.21.5: - resolution: {integrity: sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==} + resolution: {integrity: sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==, tarball: https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz} engines: {node: '>=12'} cpu: [arm] os: [linux] @@ -520,7 +765,7 @@ packages: optional: true /@esbuild/linux-arm@0.25.12: - resolution: {integrity: sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==} + resolution: {integrity: sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==, tarball: https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.12.tgz} engines: {node: '>=18'} cpu: [arm] os: [linux] @@ -529,7 +774,7 @@ packages: optional: true /@esbuild/linux-arm@0.27.7: - resolution: {integrity: sha512-RkT/YXYBTSULo3+af8Ib0ykH8u2MBh57o7q/DAs3lTJlyVQkgQvlrPTnjIzzRPQyavxtPtfg0EopvDyIt0j1rA==} + resolution: {integrity: sha512-RkT/YXYBTSULo3+af8Ib0ykH8u2MBh57o7q/DAs3lTJlyVQkgQvlrPTnjIzzRPQyavxtPtfg0EopvDyIt0j1rA==, tarball: https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.7.tgz} engines: {node: '>=18'} cpu: [arm] os: [linux] @@ -538,7 +783,7 @@ packages: optional: true /@esbuild/linux-ia32@0.21.5: - resolution: {integrity: sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==} + resolution: {integrity: sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==, tarball: https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz} engines: {node: '>=12'} cpu: [ia32] os: [linux] @@ -547,7 +792,7 @@ packages: optional: true /@esbuild/linux-ia32@0.25.12: - resolution: {integrity: sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==} + resolution: {integrity: sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==, tarball: https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.12.tgz} engines: {node: '>=18'} cpu: [ia32] os: [linux] @@ -556,7 +801,7 @@ packages: optional: true /@esbuild/linux-ia32@0.27.7: - resolution: {integrity: sha512-GA48aKNkyQDbd3KtkplYWT102C5sn/EZTY4XROkxONgruHPU72l+gW+FfF8tf2cFjeHaRbWpOYa/uRBz/Xq1Pg==} + resolution: {integrity: sha512-GA48aKNkyQDbd3KtkplYWT102C5sn/EZTY4XROkxONgruHPU72l+gW+FfF8tf2cFjeHaRbWpOYa/uRBz/Xq1Pg==, tarball: https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.7.tgz} engines: {node: '>=18'} cpu: [ia32] os: [linux] @@ -565,7 +810,7 @@ packages: optional: true /@esbuild/linux-loong64@0.21.5: - resolution: {integrity: sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==} + resolution: {integrity: sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==, tarball: https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz} engines: {node: '>=12'} cpu: [loong64] os: [linux] @@ -574,7 +819,7 @@ packages: optional: true /@esbuild/linux-loong64@0.25.12: - resolution: {integrity: sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==} + resolution: {integrity: sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==, tarball: https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.12.tgz} engines: {node: '>=18'} cpu: [loong64] os: [linux] @@ -583,7 +828,7 @@ packages: optional: true /@esbuild/linux-loong64@0.27.7: - resolution: {integrity: sha512-a4POruNM2oWsD4WKvBSEKGIiWQF8fZOAsycHOt6JBpZ+JN2n2JH9WAv56SOyu9X5IqAjqSIPTaJkqN8F7XOQ5Q==} + resolution: {integrity: sha512-a4POruNM2oWsD4WKvBSEKGIiWQF8fZOAsycHOt6JBpZ+JN2n2JH9WAv56SOyu9X5IqAjqSIPTaJkqN8F7XOQ5Q==, tarball: https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.7.tgz} engines: {node: '>=18'} cpu: [loong64] os: [linux] @@ -592,7 +837,7 @@ packages: optional: true /@esbuild/linux-mips64el@0.21.5: - resolution: {integrity: sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==} + resolution: {integrity: sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==, tarball: https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz} engines: {node: '>=12'} cpu: [mips64el] os: [linux] @@ -601,7 +846,7 @@ packages: optional: true /@esbuild/linux-mips64el@0.25.12: - resolution: {integrity: sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==} + resolution: {integrity: sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==, tarball: https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.12.tgz} engines: {node: '>=18'} cpu: [mips64el] os: [linux] @@ -610,7 +855,7 @@ packages: optional: true /@esbuild/linux-mips64el@0.27.7: - resolution: {integrity: sha512-KabT5I6StirGfIz0FMgl1I+R1H73Gp0ofL9A3nG3i/cYFJzKHhouBV5VWK1CSgKvVaG4q1RNpCTR2LuTVB3fIw==} + resolution: {integrity: sha512-KabT5I6StirGfIz0FMgl1I+R1H73Gp0ofL9A3nG3i/cYFJzKHhouBV5VWK1CSgKvVaG4q1RNpCTR2LuTVB3fIw==, tarball: https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.7.tgz} engines: {node: '>=18'} cpu: [mips64el] os: [linux] @@ -619,7 +864,7 @@ packages: optional: true /@esbuild/linux-ppc64@0.21.5: - resolution: {integrity: sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==} + resolution: {integrity: sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==, tarball: https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz} engines: {node: '>=12'} cpu: [ppc64] os: [linux] @@ -628,7 +873,7 @@ packages: optional: true /@esbuild/linux-ppc64@0.25.12: - resolution: {integrity: sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==} + resolution: {integrity: sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==, tarball: https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.12.tgz} engines: {node: '>=18'} cpu: [ppc64] os: [linux] @@ -637,7 +882,7 @@ packages: optional: true /@esbuild/linux-ppc64@0.27.7: - resolution: {integrity: sha512-gRsL4x6wsGHGRqhtI+ifpN/vpOFTQtnbsupUF5R5YTAg+y/lKelYR1hXbnBdzDjGbMYjVJLJTd2OFmMewAgwlQ==} + resolution: {integrity: sha512-gRsL4x6wsGHGRqhtI+ifpN/vpOFTQtnbsupUF5R5YTAg+y/lKelYR1hXbnBdzDjGbMYjVJLJTd2OFmMewAgwlQ==, tarball: https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.7.tgz} engines: {node: '>=18'} cpu: [ppc64] os: [linux] @@ -646,7 +891,7 @@ packages: optional: true /@esbuild/linux-riscv64@0.21.5: - resolution: {integrity: sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==} + resolution: {integrity: sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==, tarball: https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz} engines: {node: '>=12'} cpu: [riscv64] os: [linux] @@ -655,7 +900,7 @@ packages: optional: true /@esbuild/linux-riscv64@0.25.12: - resolution: {integrity: sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==} + resolution: {integrity: sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==, tarball: https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.12.tgz} engines: {node: '>=18'} cpu: [riscv64] os: [linux] @@ -664,7 +909,7 @@ packages: optional: true /@esbuild/linux-riscv64@0.27.7: - resolution: {integrity: sha512-hL25LbxO1QOngGzu2U5xeXtxXcW+/GvMN3ejANqXkxZ/opySAZMrc+9LY/WyjAan41unrR3YrmtTsUpwT66InQ==} + resolution: {integrity: sha512-hL25LbxO1QOngGzu2U5xeXtxXcW+/GvMN3ejANqXkxZ/opySAZMrc+9LY/WyjAan41unrR3YrmtTsUpwT66InQ==, tarball: https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.7.tgz} engines: {node: '>=18'} cpu: [riscv64] os: [linux] @@ -673,7 +918,7 @@ packages: optional: true /@esbuild/linux-s390x@0.21.5: - resolution: {integrity: sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==} + resolution: {integrity: sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==, tarball: https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz} engines: {node: '>=12'} cpu: [s390x] os: [linux] @@ -682,7 +927,7 @@ packages: optional: true /@esbuild/linux-s390x@0.25.12: - resolution: {integrity: sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==} + resolution: {integrity: sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==, tarball: https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.12.tgz} engines: {node: '>=18'} cpu: [s390x] os: [linux] @@ -691,7 +936,7 @@ packages: optional: true /@esbuild/linux-s390x@0.27.7: - resolution: {integrity: sha512-2k8go8Ycu1Kb46vEelhu1vqEP+UeRVj2zY1pSuPdgvbd5ykAw82Lrro28vXUrRmzEsUV0NzCf54yARIK8r0fdw==} + resolution: {integrity: sha512-2k8go8Ycu1Kb46vEelhu1vqEP+UeRVj2zY1pSuPdgvbd5ykAw82Lrro28vXUrRmzEsUV0NzCf54yARIK8r0fdw==, tarball: https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.7.tgz} engines: {node: '>=18'} cpu: [s390x] os: [linux] @@ -700,7 +945,7 @@ packages: optional: true /@esbuild/linux-x64@0.21.5: - resolution: {integrity: sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==} + resolution: {integrity: sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==, tarball: https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz} engines: {node: '>=12'} cpu: [x64] os: [linux] @@ -709,7 +954,7 @@ packages: optional: true /@esbuild/linux-x64@0.25.12: - resolution: {integrity: sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==} + resolution: {integrity: sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==, tarball: https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.12.tgz} engines: {node: '>=18'} cpu: [x64] os: [linux] @@ -718,7 +963,7 @@ packages: optional: true /@esbuild/linux-x64@0.27.7: - resolution: {integrity: sha512-hzznmADPt+OmsYzw1EE33ccA+HPdIqiCRq7cQeL1Jlq2gb1+OyWBkMCrYGBJ+sxVzve2ZJEVeePbLM2iEIZSxA==} + resolution: {integrity: sha512-hzznmADPt+OmsYzw1EE33ccA+HPdIqiCRq7cQeL1Jlq2gb1+OyWBkMCrYGBJ+sxVzve2ZJEVeePbLM2iEIZSxA==, tarball: https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.7.tgz} engines: {node: '>=18'} cpu: [x64] os: [linux] @@ -727,7 +972,7 @@ packages: optional: true /@esbuild/netbsd-arm64@0.25.12: - resolution: {integrity: sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==} + resolution: {integrity: sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==, tarball: https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.12.tgz} engines: {node: '>=18'} cpu: [arm64] os: [netbsd] @@ -736,7 +981,7 @@ packages: optional: true /@esbuild/netbsd-arm64@0.27.7: - resolution: {integrity: sha512-b6pqtrQdigZBwZxAn1UpazEisvwaIDvdbMbmrly7cDTMFnw/+3lVxxCTGOrkPVnsYIosJJXAsILG9XcQS+Yu6w==} + resolution: {integrity: sha512-b6pqtrQdigZBwZxAn1UpazEisvwaIDvdbMbmrly7cDTMFnw/+3lVxxCTGOrkPVnsYIosJJXAsILG9XcQS+Yu6w==, tarball: https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.7.tgz} engines: {node: '>=18'} cpu: [arm64] os: [netbsd] @@ -745,7 +990,7 @@ packages: optional: true /@esbuild/netbsd-x64@0.21.5: - resolution: {integrity: sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==} + resolution: {integrity: sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==, tarball: https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz} engines: {node: '>=12'} cpu: [x64] os: [netbsd] @@ -754,7 +999,7 @@ packages: optional: true /@esbuild/netbsd-x64@0.25.12: - resolution: {integrity: sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==} + resolution: {integrity: sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==, tarball: https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.12.tgz} engines: {node: '>=18'} cpu: [x64] os: [netbsd] @@ -763,7 +1008,7 @@ packages: optional: true /@esbuild/netbsd-x64@0.27.7: - resolution: {integrity: sha512-OfatkLojr6U+WN5EDYuoQhtM+1xco+/6FSzJJnuWiUw5eVcicbyK3dq5EeV/QHT1uy6GoDhGbFpprUiHUYggrw==} + resolution: {integrity: sha512-OfatkLojr6U+WN5EDYuoQhtM+1xco+/6FSzJJnuWiUw5eVcicbyK3dq5EeV/QHT1uy6GoDhGbFpprUiHUYggrw==, tarball: https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.7.tgz} engines: {node: '>=18'} cpu: [x64] os: [netbsd] @@ -772,7 +1017,7 @@ packages: optional: true /@esbuild/openbsd-arm64@0.25.12: - resolution: {integrity: sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==} + resolution: {integrity: sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==, tarball: https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.12.tgz} engines: {node: '>=18'} cpu: [arm64] os: [openbsd] @@ -781,7 +1026,7 @@ packages: optional: true /@esbuild/openbsd-arm64@0.27.7: - resolution: {integrity: sha512-AFuojMQTxAz75Fo8idVcqoQWEHIXFRbOc1TrVcFSgCZtQfSdc1RXgB3tjOn/krRHENUB4j00bfGjyl2mJrU37A==} + resolution: {integrity: sha512-AFuojMQTxAz75Fo8idVcqoQWEHIXFRbOc1TrVcFSgCZtQfSdc1RXgB3tjOn/krRHENUB4j00bfGjyl2mJrU37A==, tarball: https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.7.tgz} engines: {node: '>=18'} cpu: [arm64] os: [openbsd] @@ -790,7 +1035,7 @@ packages: optional: true /@esbuild/openbsd-x64@0.21.5: - resolution: {integrity: sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==} + resolution: {integrity: sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==, tarball: https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz} engines: {node: '>=12'} cpu: [x64] os: [openbsd] @@ -799,7 +1044,7 @@ packages: optional: true /@esbuild/openbsd-x64@0.25.12: - resolution: {integrity: sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==} + resolution: {integrity: sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==, tarball: https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.12.tgz} engines: {node: '>=18'} cpu: [x64] os: [openbsd] @@ -808,7 +1053,7 @@ packages: optional: true /@esbuild/openbsd-x64@0.27.7: - resolution: {integrity: sha512-+A1NJmfM8WNDv5CLVQYJ5PshuRm/4cI6WMZRg1by1GwPIQPCTs1GLEUHwiiQGT5zDdyLiRM/l1G0Pv54gvtKIg==} + resolution: {integrity: sha512-+A1NJmfM8WNDv5CLVQYJ5PshuRm/4cI6WMZRg1by1GwPIQPCTs1GLEUHwiiQGT5zDdyLiRM/l1G0Pv54gvtKIg==, tarball: https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.7.tgz} engines: {node: '>=18'} cpu: [x64] os: [openbsd] @@ -817,7 +1062,7 @@ packages: optional: true /@esbuild/openharmony-arm64@0.25.12: - resolution: {integrity: sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==} + resolution: {integrity: sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==, tarball: https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.12.tgz} engines: {node: '>=18'} cpu: [arm64] os: [openharmony] @@ -826,7 +1071,7 @@ packages: optional: true /@esbuild/openharmony-arm64@0.27.7: - resolution: {integrity: sha512-+KrvYb/C8zA9CU/g0sR6w2RBw7IGc5J2BPnc3dYc5VJxHCSF1yNMxTV5LQ7GuKteQXZtspjFbiuW5/dOj7H4Yw==} + resolution: {integrity: sha512-+KrvYb/C8zA9CU/g0sR6w2RBw7IGc5J2BPnc3dYc5VJxHCSF1yNMxTV5LQ7GuKteQXZtspjFbiuW5/dOj7H4Yw==, tarball: https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.7.tgz} engines: {node: '>=18'} cpu: [arm64] os: [openharmony] @@ -835,7 +1080,7 @@ packages: optional: true /@esbuild/sunos-x64@0.21.5: - resolution: {integrity: sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==} + resolution: {integrity: sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==, tarball: https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz} engines: {node: '>=12'} cpu: [x64] os: [sunos] @@ -844,7 +1089,7 @@ packages: optional: true /@esbuild/sunos-x64@0.25.12: - resolution: {integrity: sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==} + resolution: {integrity: sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==, tarball: https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.12.tgz} engines: {node: '>=18'} cpu: [x64] os: [sunos] @@ -853,7 +1098,7 @@ packages: optional: true /@esbuild/sunos-x64@0.27.7: - resolution: {integrity: sha512-ikktIhFBzQNt/QDyOL580ti9+5mL/YZeUPKU2ivGtGjdTYoqz6jObj6nOMfhASpS4GU4Q/Clh1QtxWAvcYKamA==} + resolution: {integrity: sha512-ikktIhFBzQNt/QDyOL580ti9+5mL/YZeUPKU2ivGtGjdTYoqz6jObj6nOMfhASpS4GU4Q/Clh1QtxWAvcYKamA==, tarball: https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.7.tgz} engines: {node: '>=18'} cpu: [x64] os: [sunos] @@ -862,7 +1107,7 @@ packages: optional: true /@esbuild/win32-arm64@0.21.5: - resolution: {integrity: sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==} + resolution: {integrity: sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==, tarball: https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz} engines: {node: '>=12'} cpu: [arm64] os: [win32] @@ -871,7 +1116,7 @@ packages: optional: true /@esbuild/win32-arm64@0.25.12: - resolution: {integrity: sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==} + resolution: {integrity: sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==, tarball: https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.12.tgz} engines: {node: '>=18'} cpu: [arm64] os: [win32] @@ -880,7 +1125,7 @@ packages: optional: true /@esbuild/win32-arm64@0.27.7: - resolution: {integrity: sha512-7yRhbHvPqSpRUV7Q20VuDwbjW5kIMwTHpptuUzV+AA46kiPze5Z7qgt6CLCK3pWFrHeNfDd1VKgyP4O+ng17CA==} + resolution: {integrity: sha512-7yRhbHvPqSpRUV7Q20VuDwbjW5kIMwTHpptuUzV+AA46kiPze5Z7qgt6CLCK3pWFrHeNfDd1VKgyP4O+ng17CA==, tarball: https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.7.tgz} engines: {node: '>=18'} cpu: [arm64] os: [win32] @@ -889,7 +1134,7 @@ packages: optional: true /@esbuild/win32-ia32@0.21.5: - resolution: {integrity: sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==} + resolution: {integrity: sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==, tarball: https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz} engines: {node: '>=12'} cpu: [ia32] os: [win32] @@ -898,7 +1143,7 @@ packages: optional: true /@esbuild/win32-ia32@0.25.12: - resolution: {integrity: sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==} + resolution: {integrity: sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==, tarball: https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.12.tgz} engines: {node: '>=18'} cpu: [ia32] os: [win32] @@ -907,7 +1152,7 @@ packages: optional: true /@esbuild/win32-ia32@0.27.7: - resolution: {integrity: sha512-SmwKXe6VHIyZYbBLJrhOoCJRB/Z1tckzmgTLfFYOfpMAx63BJEaL9ExI8x7v0oAO3Zh6D/Oi1gVxEYr5oUCFhw==} + resolution: {integrity: sha512-SmwKXe6VHIyZYbBLJrhOoCJRB/Z1tckzmgTLfFYOfpMAx63BJEaL9ExI8x7v0oAO3Zh6D/Oi1gVxEYr5oUCFhw==, tarball: https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.7.tgz} engines: {node: '>=18'} cpu: [ia32] os: [win32] @@ -916,7 +1161,7 @@ packages: optional: true /@esbuild/win32-x64@0.21.5: - resolution: {integrity: sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==} + resolution: {integrity: sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==, tarball: https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz} engines: {node: '>=12'} cpu: [x64] os: [win32] @@ -925,7 +1170,7 @@ packages: optional: true /@esbuild/win32-x64@0.25.12: - resolution: {integrity: sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==} + resolution: {integrity: sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==, tarball: https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.12.tgz} engines: {node: '>=18'} cpu: [x64] os: [win32] @@ -934,7 +1179,7 @@ packages: optional: true /@esbuild/win32-x64@0.27.7: - resolution: {integrity: sha512-56hiAJPhwQ1R4i+21FVF7V8kSD5zZTdHcVuRFMW0hn753vVfQN8xlx4uOPT4xoGH0Z/oVATuR82AiqSTDIpaHg==} + resolution: {integrity: sha512-56hiAJPhwQ1R4i+21FVF7V8kSD5zZTdHcVuRFMW0hn753vVfQN8xlx4uOPT4xoGH0Z/oVATuR82AiqSTDIpaHg==, tarball: https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.7.tgz} engines: {node: '>=18'} cpu: [x64] os: [win32] @@ -1048,6 +1293,16 @@ packages: engines: {node: '>=18.18'} dev: true + /@iconify-json/simple-icons@1.2.90: + resolution: {integrity: sha512-zt2o2ZvQpHVvZJARIkZ51RnaHY2oqcPJMvHE+mVnxkSr+c33fnX4gciiXu+wyX5ei+s0qbVX1wD0DWBbaGBYMA==, tarball: https://registry.npmjs.org/@iconify-json/simple-icons/-/simple-icons-1.2.90.tgz} + dependencies: + '@iconify/types': 2.0.0 + dev: true + + /@iconify/types@2.0.0: + resolution: {integrity: sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==, tarball: https://registry.npmjs.org/@iconify/types/-/types-2.0.0.tgz} + dev: true + /@jridgewell/gen-mapping@0.3.13: resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} dependencies: @@ -1063,7 +1318,7 @@ packages: dev: true /@jridgewell/resolve-uri@3.1.2: - resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} + resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==, tarball: https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz} engines: {node: '>=6.0.0'} dev: true @@ -1072,7 +1327,7 @@ packages: dev: true /@jridgewell/trace-mapping@0.3.31: - resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} + resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==, tarball: https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz} dependencies: '@jridgewell/resolve-uri': 3.1.2 '@jridgewell/sourcemap-codec': 1.5.5 @@ -1083,7 +1338,7 @@ packages: dev: true /@rollup/rollup-android-arm-eabi@4.61.0: - resolution: {integrity: sha512-dnxczajOqt0gesZlN5pGQ1s1imQVrsmCw5G2Ci4oM+0WvNz3pyRnlWrT7McoZIb8VlFwCawdmbWRmxRn7HI+VQ==} + resolution: {integrity: sha512-dnxczajOqt0gesZlN5pGQ1s1imQVrsmCw5G2Ci4oM+0WvNz3pyRnlWrT7McoZIb8VlFwCawdmbWRmxRn7HI+VQ==, tarball: https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.61.0.tgz} cpu: [arm] os: [android] requiresBuild: true @@ -1091,7 +1346,7 @@ packages: optional: true /@rollup/rollup-android-arm64@4.61.0: - resolution: {integrity: sha512-Bp3JpGP00Vu3f238ivRrjf7z3xSzVPXqCmaJYA9t2c+c8vKYvOzmXF7LkkeUalTEGd6cZcSWe+PFIP3Vy48fRg==} + resolution: {integrity: sha512-Bp3JpGP00Vu3f238ivRrjf7z3xSzVPXqCmaJYA9t2c+c8vKYvOzmXF7LkkeUalTEGd6cZcSWe+PFIP3Vy48fRg==, tarball: https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.61.0.tgz} cpu: [arm64] os: [android] requiresBuild: true @@ -1099,7 +1354,7 @@ packages: optional: true /@rollup/rollup-darwin-arm64@4.61.0: - resolution: {integrity: sha512-zaYIpr670mUmmZ1tVzUFplbQbG7h3Gugx3L5FoqhsC2m/YnLlR1a7zVLmXNPy+iY1tFPEbNG+HHBXZGyId0G5w==} + resolution: {integrity: sha512-zaYIpr670mUmmZ1tVzUFplbQbG7h3Gugx3L5FoqhsC2m/YnLlR1a7zVLmXNPy+iY1tFPEbNG+HHBXZGyId0G5w==, tarball: https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.61.0.tgz} cpu: [arm64] os: [darwin] requiresBuild: true @@ -1107,7 +1362,7 @@ packages: optional: true /@rollup/rollup-darwin-x64@4.61.0: - resolution: {integrity: sha512-+P49fvkv2dSoeevUW+lgZ/I2JHSsJCK1Lyjj7Cu6E4UHG4tS9XIefzIjo5qhgELjAclnen1rLzK2PMKJdo+Dyg==} + resolution: {integrity: sha512-+P49fvkv2dSoeevUW+lgZ/I2JHSsJCK1Lyjj7Cu6E4UHG4tS9XIefzIjo5qhgELjAclnen1rLzK2PMKJdo+Dyg==, tarball: https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.61.0.tgz} cpu: [x64] os: [darwin] requiresBuild: true @@ -1115,7 +1370,7 @@ packages: optional: true /@rollup/rollup-freebsd-arm64@4.61.0: - resolution: {integrity: sha512-l3FAAOyKJXH2ea6KNFN+MMgC/rnE94YGLXs2ehYqDcCoHt1DpvgWX75BhUJxN38XojP7Ul+4H8PRn7EdyqSDrw==} + resolution: {integrity: sha512-l3FAAOyKJXH2ea6KNFN+MMgC/rnE94YGLXs2ehYqDcCoHt1DpvgWX75BhUJxN38XojP7Ul+4H8PRn7EdyqSDrw==, tarball: https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.61.0.tgz} cpu: [arm64] os: [freebsd] requiresBuild: true @@ -1123,7 +1378,7 @@ packages: optional: true /@rollup/rollup-freebsd-x64@4.61.0: - resolution: {integrity: sha512-VokPN3TSctKj65cyCNPaUh4vMFA8awxOot/0sp+4J7ZlNRKQEhXhawqPwajoi8H5ZFt61i0ugZJuTKXBjGJ17Q==} + resolution: {integrity: sha512-VokPN3TSctKj65cyCNPaUh4vMFA8awxOot/0sp+4J7ZlNRKQEhXhawqPwajoi8H5ZFt61i0ugZJuTKXBjGJ17Q==, tarball: https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.61.0.tgz} cpu: [x64] os: [freebsd] requiresBuild: true @@ -1131,7 +1386,7 @@ packages: optional: true /@rollup/rollup-linux-arm-gnueabihf@4.61.0: - resolution: {integrity: sha512-DxH0P3wxm+Yzs/p3zrk9dw1rURu8p0Nv5+MRK/L7OtnLNg5rLZraSBFZ8iUXOd9f2BlhJyEpIZUH/emjq4UJ4g==} + resolution: {integrity: sha512-DxH0P3wxm+Yzs/p3zrk9dw1rURu8p0Nv5+MRK/L7OtnLNg5rLZraSBFZ8iUXOd9f2BlhJyEpIZUH/emjq4UJ4g==, tarball: https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.61.0.tgz} cpu: [arm] os: [linux] requiresBuild: true @@ -1139,7 +1394,7 @@ packages: optional: true /@rollup/rollup-linux-arm-musleabihf@4.61.0: - resolution: {integrity: sha512-T6ZvMNe84kAz6TBWHC7hGAoEtzP1LWYw/AqayGWEF6uISt3Abk/st06LqRD9THd7Xz3NxzurUpzAuEAUbZf+nw==} + resolution: {integrity: sha512-T6ZvMNe84kAz6TBWHC7hGAoEtzP1LWYw/AqayGWEF6uISt3Abk/st06LqRD9THd7Xz3NxzurUpzAuEAUbZf+nw==, tarball: https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.61.0.tgz} cpu: [arm] os: [linux] requiresBuild: true @@ -1147,7 +1402,7 @@ packages: optional: true /@rollup/rollup-linux-arm64-gnu@4.61.0: - resolution: {integrity: sha512-q/4hzvQkDs8b4jIBab1pnLiiM0ayTZsN2amBFPDzuyZxjEd4wDwx0UJFYM3cOZzSf5Kw8fnWSprJzIBMkcR44Q==} + resolution: {integrity: sha512-q/4hzvQkDs8b4jIBab1pnLiiM0ayTZsN2amBFPDzuyZxjEd4wDwx0UJFYM3cOZzSf5Kw8fnWSprJzIBMkcR44Q==, tarball: https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.61.0.tgz} cpu: [arm64] os: [linux] requiresBuild: true @@ -1155,7 +1410,7 @@ packages: optional: true /@rollup/rollup-linux-arm64-musl@4.61.0: - resolution: {integrity: sha512-vvYWX3akdEAY6km+9wAqFDnk6pQsbJKVnj7xawcvs/+fdlYBGp+U+Qq/lLfpIxYIZvZLHMAKD9HLdacSx/r3dw==} + resolution: {integrity: sha512-vvYWX3akdEAY6km+9wAqFDnk6pQsbJKVnj7xawcvs/+fdlYBGp+U+Qq/lLfpIxYIZvZLHMAKD9HLdacSx/r3dw==, tarball: https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.61.0.tgz} cpu: [arm64] os: [linux] requiresBuild: true @@ -1163,7 +1418,7 @@ packages: optional: true /@rollup/rollup-linux-loong64-gnu@4.61.0: - resolution: {integrity: sha512-DePa5cqOxDP/Zp0VOXpeWaGew5iIv5DXp9NYbzkX5PFQyWVX9184WCTh3hvr/7lhXo8ZVlbFLkz8+o/q1dU6gA==} + resolution: {integrity: sha512-DePa5cqOxDP/Zp0VOXpeWaGew5iIv5DXp9NYbzkX5PFQyWVX9184WCTh3hvr/7lhXo8ZVlbFLkz8+o/q1dU6gA==, tarball: https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.61.0.tgz} cpu: [loong64] os: [linux] requiresBuild: true @@ -1171,7 +1426,7 @@ packages: optional: true /@rollup/rollup-linux-loong64-musl@4.61.0: - resolution: {integrity: sha512-LV8aWMB8UChglMCEzs7RkN0GsH29RJaLLqwm9fCIjlqwxQTiWAqNcc7wjBkH31hV0PU/yVxGYvrYsgfea2qw6g==} + resolution: {integrity: sha512-LV8aWMB8UChglMCEzs7RkN0GsH29RJaLLqwm9fCIjlqwxQTiWAqNcc7wjBkH31hV0PU/yVxGYvrYsgfea2qw6g==, tarball: https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.61.0.tgz} cpu: [loong64] os: [linux] requiresBuild: true @@ -1179,7 +1434,7 @@ packages: optional: true /@rollup/rollup-linux-ppc64-gnu@4.61.0: - resolution: {integrity: sha512-QoNSnwQtaeNu5grdBbsL0tt1uyl5EnS8DA8Mr3nluMXbhdQNyhN+G4tBax7VCdxLKj8YJ0/4OO9Ho84jMnJtKA==} + resolution: {integrity: sha512-QoNSnwQtaeNu5grdBbsL0tt1uyl5EnS8DA8Mr3nluMXbhdQNyhN+G4tBax7VCdxLKj8YJ0/4OO9Ho84jMnJtKA==, tarball: https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.61.0.tgz} cpu: [ppc64] os: [linux] requiresBuild: true @@ -1187,7 +1442,7 @@ packages: optional: true /@rollup/rollup-linux-ppc64-musl@4.61.0: - resolution: {integrity: sha512-/zZp5MKapIIApE8trN8qLGNSiRN9TUoaUZ1cmVu4XnVdd5LQLOXTtyi+vtfUbNnT3iyjzpPqYeKXmvJ+gJGYWw==} + resolution: {integrity: sha512-/zZp5MKapIIApE8trN8qLGNSiRN9TUoaUZ1cmVu4XnVdd5LQLOXTtyi+vtfUbNnT3iyjzpPqYeKXmvJ+gJGYWw==, tarball: https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.61.0.tgz} cpu: [ppc64] os: [linux] requiresBuild: true @@ -1195,7 +1450,7 @@ packages: optional: true /@rollup/rollup-linux-riscv64-gnu@4.61.0: - resolution: {integrity: sha512-RbrzcD3aJ1k3UbtMRRBNwojdVVyXjuVAFTfn/xPa6EEl6GE9Sm/akPgFTb9aAC9pMKGJ6CtWxaGrqWcabH+ySg==} + resolution: {integrity: sha512-RbrzcD3aJ1k3UbtMRRBNwojdVVyXjuVAFTfn/xPa6EEl6GE9Sm/akPgFTb9aAC9pMKGJ6CtWxaGrqWcabH+ySg==, tarball: https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.61.0.tgz} cpu: [riscv64] os: [linux] requiresBuild: true @@ -1203,7 +1458,7 @@ packages: optional: true /@rollup/rollup-linux-riscv64-musl@4.61.0: - resolution: {integrity: sha512-ZF+onDsBso8PJf1XaG9lB+O9RnBpKGnY6OrzC4CSHrtC1jb6jWLTKK4bRqdoCXHd22gyr2hiYmEAm8Wns/BOCw==} + resolution: {integrity: sha512-ZF+onDsBso8PJf1XaG9lB+O9RnBpKGnY6OrzC4CSHrtC1jb6jWLTKK4bRqdoCXHd22gyr2hiYmEAm8Wns/BOCw==, tarball: https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.61.0.tgz} cpu: [riscv64] os: [linux] requiresBuild: true @@ -1211,7 +1466,7 @@ packages: optional: true /@rollup/rollup-linux-s390x-gnu@4.61.0: - resolution: {integrity: sha512-Atk0aSIk5Zx2Wuh9dgRQgLP0Koc8hOeYpbWryMXyk8G8/HmPkwPPkMqIIDhrXHHYqfUzSJA/I7IWSBv8xSmRBA==} + resolution: {integrity: sha512-Atk0aSIk5Zx2Wuh9dgRQgLP0Koc8hOeYpbWryMXyk8G8/HmPkwPPkMqIIDhrXHHYqfUzSJA/I7IWSBv8xSmRBA==, tarball: https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.61.0.tgz} cpu: [s390x] os: [linux] requiresBuild: true @@ -1219,7 +1474,7 @@ packages: optional: true /@rollup/rollup-linux-x64-gnu@4.61.0: - resolution: {integrity: sha512-0uMOcf3eZ5K+K4cYHkdxShFMPlPXCOdfDFEFn9dNYAEEd2cVvmOfH7zFgRVoDgmtQ1m9k5q7qfrHzyMAubKYUA==} + resolution: {integrity: sha512-0uMOcf3eZ5K+K4cYHkdxShFMPlPXCOdfDFEFn9dNYAEEd2cVvmOfH7zFgRVoDgmtQ1m9k5q7qfrHzyMAubKYUA==, tarball: https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.61.0.tgz} cpu: [x64] os: [linux] requiresBuild: true @@ -1227,7 +1482,7 @@ packages: optional: true /@rollup/rollup-linux-x64-musl@4.61.0: - resolution: {integrity: sha512-mvFtE4A/t/7hRJ7X8Ozmu8FsIkAUat2nzl12pgU337BRmq87AQUJztwHz2Zv5/tjo9/C95E66CK03SI/ToEDJw==} + resolution: {integrity: sha512-mvFtE4A/t/7hRJ7X8Ozmu8FsIkAUat2nzl12pgU337BRmq87AQUJztwHz2Zv5/tjo9/C95E66CK03SI/ToEDJw==, tarball: https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.61.0.tgz} cpu: [x64] os: [linux] requiresBuild: true @@ -1235,7 +1490,7 @@ packages: optional: true /@rollup/rollup-openbsd-x64@4.61.0: - resolution: {integrity: sha512-z9b9+aTxvt8n2rNltMPvyaUfB8NJ+CVyOrGK/MdIKHx7B+lXmZpm/XbRsU7Rpf3fRqJ2uS6mBJiJveCtq8LHDg==} + resolution: {integrity: sha512-z9b9+aTxvt8n2rNltMPvyaUfB8NJ+CVyOrGK/MdIKHx7B+lXmZpm/XbRsU7Rpf3fRqJ2uS6mBJiJveCtq8LHDg==, tarball: https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.61.0.tgz} cpu: [x64] os: [openbsd] requiresBuild: true @@ -1243,7 +1498,7 @@ packages: optional: true /@rollup/rollup-openharmony-arm64@4.61.0: - resolution: {integrity: sha512-jXaXFqKMehsOc+g8R6oo33RRC6w07G9jDBxAE5eAKX7mOcCbZloYIPNhfG9Wl+P9O9IWHFO4OJgPi1Ml2qkt7w==} + resolution: {integrity: sha512-jXaXFqKMehsOc+g8R6oo33RRC6w07G9jDBxAE5eAKX7mOcCbZloYIPNhfG9Wl+P9O9IWHFO4OJgPi1Ml2qkt7w==, tarball: https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.61.0.tgz} cpu: [arm64] os: [openharmony] requiresBuild: true @@ -1251,7 +1506,7 @@ packages: optional: true /@rollup/rollup-win32-arm64-msvc@4.61.0: - resolution: {integrity: sha512-OXNWVFocS2IA4+QplhTZZ2a+8hPZR7T8KuozsNmJKK8y7cp83StHvGksfHzPG3wczWTczyWHVQuqeiTUbjiyBg==} + resolution: {integrity: sha512-OXNWVFocS2IA4+QplhTZZ2a+8hPZR7T8KuozsNmJKK8y7cp83StHvGksfHzPG3wczWTczyWHVQuqeiTUbjiyBg==, tarball: https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.61.0.tgz} cpu: [arm64] os: [win32] requiresBuild: true @@ -1259,7 +1514,7 @@ packages: optional: true /@rollup/rollup-win32-ia32-msvc@4.61.0: - resolution: {integrity: sha512-AlAbNtBO637LxSldqV43z0FfXoGfl2TW1DgAg/bs7aQswFbDewz2SJm3BUhiGfbOVtW571xbc9p+REdxhyN/Eg==} + resolution: {integrity: sha512-AlAbNtBO637LxSldqV43z0FfXoGfl2TW1DgAg/bs7aQswFbDewz2SJm3BUhiGfbOVtW571xbc9p+REdxhyN/Eg==, tarball: https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.61.0.tgz} cpu: [ia32] os: [win32] requiresBuild: true @@ -1267,7 +1522,7 @@ packages: optional: true /@rollup/rollup-win32-x64-gnu@4.61.0: - resolution: {integrity: sha512-QRSrQXyJ1M4tjNXdR0/G/IgV6lzfQQJYBjlWIEYkY2Xs86DRl/iEpQ4blMDjJxSl7n19eDKKXMg0AmuBVYy8pQ==} + resolution: {integrity: sha512-QRSrQXyJ1M4tjNXdR0/G/IgV6lzfQQJYBjlWIEYkY2Xs86DRl/iEpQ4blMDjJxSl7n19eDKKXMg0AmuBVYy8pQ==, tarball: https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.61.0.tgz} cpu: [x64] os: [win32] requiresBuild: true @@ -1275,13 +1530,69 @@ packages: optional: true /@rollup/rollup-win32-x64-msvc@4.61.0: - resolution: {integrity: sha512-tkuFxhvKO/HlGd0VsINF6vHSYH8AF8W0TcNxKDK6JZmrehngFj78pToc8iemtnvwilDjs2G/qSzYFhe9U8q+fw==} + resolution: {integrity: sha512-tkuFxhvKO/HlGd0VsINF6vHSYH8AF8W0TcNxKDK6JZmrehngFj78pToc8iemtnvwilDjs2G/qSzYFhe9U8q+fw==, tarball: https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.61.0.tgz} cpu: [x64] os: [win32] requiresBuild: true dev: true optional: true + /@shikijs/core@2.5.0: + resolution: {integrity: sha512-uu/8RExTKtavlpH7XqnVYBrfBkUc20ngXiX9NSrBhOVZYv/7XQRKUyhtkeflY5QsxC0GbJThCerruZfsUaSldg==, tarball: https://registry.npmjs.org/@shikijs/core/-/core-2.5.0.tgz} + dependencies: + '@shikijs/engine-javascript': 2.5.0 + '@shikijs/engine-oniguruma': 2.5.0 + '@shikijs/types': 2.5.0 + '@shikijs/vscode-textmate': 10.0.2 + '@types/hast': 3.0.5 + hast-util-to-html: 9.0.5 + dev: true + + /@shikijs/engine-javascript@2.5.0: + resolution: {integrity: sha512-VjnOpnQf8WuCEZtNUdjjwGUbtAVKuZkVQ/5cHy/tojVVRIRtlWMYVjyWhxOmIq05AlSOv72z7hRNRGVBgQOl0w==, tarball: https://registry.npmjs.org/@shikijs/engine-javascript/-/engine-javascript-2.5.0.tgz} + dependencies: + '@shikijs/types': 2.5.0 + '@shikijs/vscode-textmate': 10.0.2 + oniguruma-to-es: 3.1.1 + dev: true + + /@shikijs/engine-oniguruma@2.5.0: + resolution: {integrity: sha512-pGd1wRATzbo/uatrCIILlAdFVKdxImWJGQ5rFiB5VZi2ve5xj3Ax9jny8QvkaV93btQEwR/rSz5ERFpC5mKNIw==, tarball: https://registry.npmjs.org/@shikijs/engine-oniguruma/-/engine-oniguruma-2.5.0.tgz} + dependencies: + '@shikijs/types': 2.5.0 + '@shikijs/vscode-textmate': 10.0.2 + dev: true + + /@shikijs/langs@2.5.0: + resolution: {integrity: sha512-Qfrrt5OsNH5R+5tJ/3uYBBZv3SuGmnRPejV9IlIbFH3HTGLDlkqgHymAlzklVmKBjAaVmkPkyikAV/sQ1wSL+w==, tarball: https://registry.npmjs.org/@shikijs/langs/-/langs-2.5.0.tgz} + dependencies: + '@shikijs/types': 2.5.0 + dev: true + + /@shikijs/themes@2.5.0: + resolution: {integrity: sha512-wGrk+R8tJnO0VMzmUExHR+QdSaPUl/NKs+a4cQQRWyoc3YFbUzuLEi/KWK1hj+8BfHRKm2jNhhJck1dfstJpiw==, tarball: https://registry.npmjs.org/@shikijs/themes/-/themes-2.5.0.tgz} + dependencies: + '@shikijs/types': 2.5.0 + dev: true + + /@shikijs/transformers@2.5.0: + resolution: {integrity: sha512-SI494W5X60CaUwgi8u4q4m4s3YAFSxln3tzNjOSYqq54wlVgz0/NbbXEb3mdLbqMBztcmS7bVTaEd2w0qMmfeg==, tarball: https://registry.npmjs.org/@shikijs/transformers/-/transformers-2.5.0.tgz} + dependencies: + '@shikijs/core': 2.5.0 + '@shikijs/types': 2.5.0 + dev: true + + /@shikijs/types@2.5.0: + resolution: {integrity: sha512-ygl5yhxki9ZLNuNpPitBWvcy9fsSKKaRuO4BAlMyagszQidxcpLAr0qiW/q43DtSIDxO6hEbtYLiFZNXO/hdGw==, tarball: https://registry.npmjs.org/@shikijs/types/-/types-2.5.0.tgz} + dependencies: + '@shikijs/vscode-textmate': 10.0.2 + '@types/hast': 3.0.5 + dev: true + + /@shikijs/vscode-textmate@10.0.2: + resolution: {integrity: sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==, tarball: https://registry.npmjs.org/@shikijs/vscode-textmate/-/vscode-textmate-10.0.2.tgz} + dev: true + /@tailwindcss/node@4.3.2: resolution: {integrity: sha512-yWP/sqEcBLaD8JuA6zNwxoYKr75qxTioYwlRwekj5Jr/I5GXnoJfjetH/psLUIv74cYTH2lBUEzBkinthoYcBg==} dependencies: @@ -1295,7 +1606,7 @@ packages: dev: true /@tailwindcss/oxide-android-arm64@4.3.2: - resolution: {integrity: sha512-WHxqIuHpvZ5VtdX6GTl1Ik/Vp2YuN42Et+0CdeaVd/frQ9jAvGmvR8vLT+jk3e8/Q3x8kECB9+R17pgpp2BulA==} + resolution: {integrity: sha512-WHxqIuHpvZ5VtdX6GTl1Ik/Vp2YuN42Et+0CdeaVd/frQ9jAvGmvR8vLT+jk3e8/Q3x8kECB9+R17pgpp2BulA==, tarball: https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.3.2.tgz} engines: {node: '>= 20'} cpu: [arm64] os: [android] @@ -1304,7 +1615,7 @@ packages: optional: true /@tailwindcss/oxide-darwin-arm64@4.3.2: - resolution: {integrity: sha512-GZypeUY/IDJW3877KeM+O67vbXr3MBnbtEL4aYhNErv/JWZhye2vGSWWG9tB6iiqR2MqRNkY8IOUy4NdSZV26w==} + resolution: {integrity: sha512-GZypeUY/IDJW3877KeM+O67vbXr3MBnbtEL4aYhNErv/JWZhye2vGSWWG9tB6iiqR2MqRNkY8IOUy4NdSZV26w==, tarball: https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.3.2.tgz} engines: {node: '>= 20'} cpu: [arm64] os: [darwin] @@ -1313,7 +1624,7 @@ packages: optional: true /@tailwindcss/oxide-darwin-x64@4.3.2: - resolution: {integrity: sha512-UIIzmefR6KO1sDU7MzRqAxC8iBpft/VhkGjTjnhoS6k7Z3rQ9wEgA1ODSiyH/tcSYssulNm4Ci3hOeK1jH7ccQ==} + resolution: {integrity: sha512-UIIzmefR6KO1sDU7MzRqAxC8iBpft/VhkGjTjnhoS6k7Z3rQ9wEgA1ODSiyH/tcSYssulNm4Ci3hOeK1jH7ccQ==, tarball: https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.3.2.tgz} engines: {node: '>= 20'} cpu: [x64] os: [darwin] @@ -1322,7 +1633,7 @@ packages: optional: true /@tailwindcss/oxide-freebsd-x64@4.3.2: - resolution: {integrity: sha512-GN+uAmcI6DNspnCDwtOAZrTz6oukJnp337qZvxqCGLd3BHBzJpO0ZbTLRvJNdztOeAmTzewewGIMPb0tk2R4WA==} + resolution: {integrity: sha512-GN+uAmcI6DNspnCDwtOAZrTz6oukJnp337qZvxqCGLd3BHBzJpO0ZbTLRvJNdztOeAmTzewewGIMPb0tk2R4WA==, tarball: https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.3.2.tgz} engines: {node: '>= 20'} cpu: [x64] os: [freebsd] @@ -1331,7 +1642,7 @@ packages: optional: true /@tailwindcss/oxide-linux-arm-gnueabihf@4.3.2: - resolution: {integrity: sha512-4ABn7qSbdHRwTiDiuWNegCyb5+2FJ4vKIKc3DmKrvAFw7MU1Lm11dIkTPwUaFdTzc7IsOpDbqBrlh0x6y36U/w==} + resolution: {integrity: sha512-4ABn7qSbdHRwTiDiuWNegCyb5+2FJ4vKIKc3DmKrvAFw7MU1Lm11dIkTPwUaFdTzc7IsOpDbqBrlh0x6y36U/w==, tarball: https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.3.2.tgz} engines: {node: '>= 20'} cpu: [arm] os: [linux] @@ -1340,7 +1651,7 @@ packages: optional: true /@tailwindcss/oxide-linux-arm64-gnu@4.3.2: - resolution: {integrity: sha512-wDgEIGwoM8w8pufh9LVt1PahDgNdKXrLC2qfAnV3vAmococ9RWbxeAw4pxPttd/TsJfwjyLf90Dg1y9y8I6Emw==} + resolution: {integrity: sha512-wDgEIGwoM8w8pufh9LVt1PahDgNdKXrLC2qfAnV3vAmococ9RWbxeAw4pxPttd/TsJfwjyLf90Dg1y9y8I6Emw==, tarball: https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.3.2.tgz} engines: {node: '>= 20'} cpu: [arm64] os: [linux] @@ -1349,7 +1660,7 @@ packages: optional: true /@tailwindcss/oxide-linux-arm64-musl@4.3.2: - resolution: {integrity: sha512-J5Nuk0uZQIiMTJj3LEx4sAA9tMFUoXQZFv1J6An+QGYe53HKRJuFDi0rpq/tuouCZeAbOBY3kQ6g8qeD4TUjtA==} + resolution: {integrity: sha512-J5Nuk0uZQIiMTJj3LEx4sAA9tMFUoXQZFv1J6An+QGYe53HKRJuFDi0rpq/tuouCZeAbOBY3kQ6g8qeD4TUjtA==, tarball: https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.3.2.tgz} engines: {node: '>= 20'} cpu: [arm64] os: [linux] @@ -1358,7 +1669,7 @@ packages: optional: true /@tailwindcss/oxide-linux-x64-gnu@4.3.2: - resolution: {integrity: sha512-kqCZpSKOBEJO4mz7OqWoofBZeXTAwaVGPj0ErAj7CojmhKpWVWVOnrt9dE8odoIraZq4oj3ausM37kXi+Tow8w==} + resolution: {integrity: sha512-kqCZpSKOBEJO4mz7OqWoofBZeXTAwaVGPj0ErAj7CojmhKpWVWVOnrt9dE8odoIraZq4oj3ausM37kXi+Tow8w==, tarball: https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.3.2.tgz} engines: {node: '>= 20'} cpu: [x64] os: [linux] @@ -1367,7 +1678,7 @@ packages: optional: true /@tailwindcss/oxide-linux-x64-musl@4.3.2: - resolution: {integrity: sha512-cixpqbh2toJDmkuCRI68nXA8ZxNmdK9Y+9v5h3MC3ZQKy/0BO8AWzlkWyRM7JAFSGBlfig4YVTPsK6MVgqz1uw==} + resolution: {integrity: sha512-cixpqbh2toJDmkuCRI68nXA8ZxNmdK9Y+9v5h3MC3ZQKy/0BO8AWzlkWyRM7JAFSGBlfig4YVTPsK6MVgqz1uw==, tarball: https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.3.2.tgz} engines: {node: '>= 20'} cpu: [x64] os: [linux] @@ -1376,7 +1687,7 @@ packages: optional: true /@tailwindcss/oxide-wasm32-wasi@4.3.2: - resolution: {integrity: sha512-4ec2Z/LOmRsAgU23CS4xeJfcJlmRg94A/XrbGRCF1gyU/zdDfRLYDVsS+ynSZCmGNxQ1jQriQOKMQeQxBA3Isw==} + resolution: {integrity: sha512-4ec2Z/LOmRsAgU23CS4xeJfcJlmRg94A/XrbGRCF1gyU/zdDfRLYDVsS+ynSZCmGNxQ1jQriQOKMQeQxBA3Isw==, tarball: https://registry.npmjs.org/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.3.2.tgz} engines: {node: '>=14.0.0'} cpu: [wasm32] requiresBuild: true @@ -1391,7 +1702,7 @@ packages: - tslib /@tailwindcss/oxide-win32-arm64-msvc@4.3.2: - resolution: {integrity: sha512-Zyr/M0+XcYZu3bZrUytc7TXvrk0ftWfl8gN2MwekNDzhqhKRUucMPSeOzM0o0wH5AWOU49BsKRrfKxI2atCPMQ==} + resolution: {integrity: sha512-Zyr/M0+XcYZu3bZrUytc7TXvrk0ftWfl8gN2MwekNDzhqhKRUucMPSeOzM0o0wH5AWOU49BsKRrfKxI2atCPMQ==, tarball: https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.3.2.tgz} engines: {node: '>= 20'} cpu: [arm64] os: [win32] @@ -1400,7 +1711,7 @@ packages: optional: true /@tailwindcss/oxide-win32-x64-msvc@4.3.2: - resolution: {integrity: sha512-QI9BO7KlNZsp2GuO0jwAAj5jCDABOKXRkCk2XuKTSaNEFSdfzqswYVTtCHBNKHLsqyjFyFkqlDiwkNbTYSssMQ==} + resolution: {integrity: sha512-QI9BO7KlNZsp2GuO0jwAAj5jCDABOKXRkCk2XuKTSaNEFSdfzqswYVTtCHBNKHLsqyjFyFkqlDiwkNbTYSssMQ==, tarball: https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.3.2.tgz} engines: {node: '>= 20'} cpu: [x64] os: [win32] @@ -1470,10 +1781,37 @@ packages: resolution: {integrity: sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==} dev: true + /@types/hast@3.0.5: + resolution: {integrity: sha512-rp/ezSWaD1m44dPKICGhiskI13nVr7qTloFwDa/IYkhhf5nzwP+zIQcIJh3WIFSBOy/H1PzB40jPjMDksN4F+g==, tarball: https://registry.npmjs.org/@types/hast/-/hast-3.0.5.tgz} + dependencies: + '@types/unist': 3.0.3 + dev: true + /@types/json-schema@7.0.15: resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} dev: true + /@types/linkify-it@5.0.0: + resolution: {integrity: sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q==, tarball: https://registry.npmjs.org/@types/linkify-it/-/linkify-it-5.0.0.tgz} + dev: true + + /@types/markdown-it@14.1.2: + resolution: {integrity: sha512-promo4eFwuiW+TfGxhi+0x3czqTYJkG8qB17ZUJiVF10Xm7NLVRSLUsfRTU/6h1e24VvRnXCx+hG7li58lkzog==, tarball: https://registry.npmjs.org/@types/markdown-it/-/markdown-it-14.1.2.tgz} + dependencies: + '@types/linkify-it': 5.0.0 + '@types/mdurl': 2.0.0 + dev: true + + /@types/mdast@4.0.4: + resolution: {integrity: sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==, tarball: https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz} + dependencies: + '@types/unist': 3.0.3 + dev: true + + /@types/mdurl@2.0.0: + resolution: {integrity: sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg==, tarball: https://registry.npmjs.org/@types/mdurl/-/mdurl-2.0.0.tgz} + dev: true + /@types/node@22.19.19: resolution: {integrity: sha512-dyh/xO2Fh5bYrfWaaqGrRQQGkNdmYw6AmaAUvYeUMNTWQtvb796ikLdmTchRmOlOiIJ1TDXfWgVx1QkUlQ6Hew==} dependencies: @@ -1494,6 +1832,14 @@ packages: csstype: 3.2.3 dev: true + /@types/unist@3.0.3: + resolution: {integrity: sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==, tarball: https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz} + dev: true + + /@types/web-bluetooth@0.0.21: + resolution: {integrity: sha512-oIQLCGWtcFZy2JW77j9k8nHzAOpqMHLQejDA48XXMWH6tjCQHz5RCFz1bzsmROyL6PUm+LLnUiI4BCn221inxA==, tarball: https://registry.npmjs.org/@types/web-bluetooth/-/web-bluetooth-0.0.21.tgz} + dev: true + /@typescript-eslint/eslint-plugin@8.60.1(@typescript-eslint/parser@8.60.1)(eslint@9.39.4)(typescript@5.9.3): resolution: {integrity: sha512-JQ4S5GB0tfjO8BuJ4fcX+HodkzJjYBV+7OJ+wLygaX7OGQ7FudyHL4NSCA6ob+w3Yn+5MkKIozOwQhXeM7opVg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -1634,6 +1980,10 @@ packages: eslint-visitor-keys: 5.0.1 dev: true + /@ungap/structured-clone@1.3.3: + resolution: {integrity: sha512-60YRaenCQcVjYEKOcG824+DRGGIQ3VKErcBoAEDJZz5bKIs2ZG+X/H9Nk+Q6EVkwJk5QNApxbrc5QtBSwtrXAg==, tarball: https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.3.tgz} + dev: true + /@vitejs/plugin-react@4.7.0(vite@6.4.3): resolution: {integrity: sha512-gUu9hwfWvvEDBBmgtAowQCojwZmJ5mcLn3aufeCsitijs3+f2NsrPtlAWIR6OPiqljl96GVCUbLe0HyqIpVaoA==} engines: {node: ^14.18.0 || >=16.0.0} @@ -1651,6 +2001,17 @@ packages: - supports-color dev: true + /@vitejs/plugin-vue@5.2.4(vite@5.4.21)(vue@3.5.40): + resolution: {integrity: sha512-7Yx/SXSOcQq5HiiV3orevHUFn+pmMB4cgbEkDYgnkUWb0WfeQ/wa2yFv6D5ICiCQOVpjA7vYDXrC7AGO8yjDHA==, tarball: https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-5.2.4.tgz} + engines: {node: ^18.0.0 || >=20.0.0} + peerDependencies: + vite: ^5.0.0 || ^6.0.0 + vue: ^3.2.25 + dependencies: + vite: 5.4.21(@types/node@22.19.19) + vue: 3.5.40(typescript@5.9.3) + dev: true + /@vitest/expect@2.1.9: resolution: {integrity: sha512-UJCIkTBenHeKT1TTlKMJWy1laZewsRIzYighyYiJKZreqtdxSos/S1t+ktRMQWu2CKqaarrkeszJx1cgC5tGZw==} dependencies: @@ -1712,6 +2073,174 @@ packages: tinyrainbow: 1.2.0 dev: true + /@vue/compiler-core@3.5.40: + resolution: {integrity: sha512-39E8IgOhTbVDnoJFMKc2DvYnypcZwUqgUhQkccva/0m6FUwtIKSGV7n1hpVmYcFaoRAwf9pBcwnKlCEsN63ZEQ==, tarball: https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.40.tgz} + dependencies: + '@babel/parser': 7.29.7 + '@vue/shared': 3.5.40 + entities: 7.0.1 + estree-walker: 2.0.2 + source-map-js: 1.2.1 + dev: true + + /@vue/compiler-dom@3.5.40: + resolution: {integrity: sha512-pwkx4vqlqOspFstrcmzwkKLePVMD3PT65imRzLhanU2V1Fj4K13g6OXjanOyzw3aTAuRk84BOmY8f3rEHqPaVA==, tarball: https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.40.tgz} + dependencies: + '@vue/compiler-core': 3.5.40 + '@vue/shared': 3.5.40 + dev: true + + /@vue/compiler-sfc@3.5.40: + resolution: {integrity: sha512-gIf497P4kpuALcvs5n3AEg1Vdn0pSY4XbjASIfHNYF1/MP3T2Mf2STERTubysBxCRxzJGJYtF/O7vwJrxFB3Vw==, tarball: https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.40.tgz} + dependencies: + '@babel/parser': 7.29.7 + '@vue/compiler-core': 3.5.40 + '@vue/compiler-dom': 3.5.40 + '@vue/compiler-ssr': 3.5.40 + '@vue/shared': 3.5.40 + estree-walker: 2.0.2 + magic-string: 0.30.21 + postcss: 8.5.19 + source-map-js: 1.2.1 + dev: true + + /@vue/compiler-ssr@3.5.40: + resolution: {integrity: sha512-rrE5xiXG663+vHCHa3J9p2z5OcBRjXmoqenprJxAFQxg5pSshzeBiCE6pu46axapRJ2Adk0YDA2BRZVjiHXnhg==, tarball: https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.40.tgz} + dependencies: + '@vue/compiler-dom': 3.5.40 + '@vue/shared': 3.5.40 + dev: true + + /@vue/devtools-api@7.7.10: + resolution: {integrity: sha512-KxtEpUOOpFz/qOGRrAwA36QF7DqIA+FXgCYit9mk9wjbaZt0sXOFz81ElOZtKA4HbWHUdwNjZHBFsFFyp5BZiA==, tarball: https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-7.7.10.tgz} + dependencies: + '@vue/devtools-kit': 7.7.10 + dev: true + + /@vue/devtools-kit@7.7.10: + resolution: {integrity: sha512-3WNi2Kq4tbpVbmhml7RiphmAt0279oh3fKNeWMQIrltfX8Q91b4i5PL8DtyNKdwmcsGrV4fg+erwWOmD05CLIw==, tarball: https://registry.npmjs.org/@vue/devtools-kit/-/devtools-kit-7.7.10.tgz} + dependencies: + '@vue/devtools-shared': 7.7.10 + birpc: 2.9.0 + hookable: 5.5.3 + mitt: 3.0.1 + perfect-debounce: 1.0.0 + speakingurl: 14.0.1 + superjson: 2.2.6 + dev: true + + /@vue/devtools-shared@7.7.10: + resolution: {integrity: sha512-wOPslzB8vTvpxwdaOcR2qAbwmuSP0L+rhpoC6Cf56V3Jip+HWb7PQQXOUPgBNQARpXsbQX/+mvi8kKucmBGRwQ==, tarball: https://registry.npmjs.org/@vue/devtools-shared/-/devtools-shared-7.7.10.tgz} + dependencies: + rfdc: 1.4.1 + dev: true + + /@vue/reactivity@3.5.40: + resolution: {integrity: sha512-B7ot9UlUZOi1zbq61/LvE88ZLTV8IlajTdiZTAEiDQgrnIMIZoPr9kGw0Zw46ObW62O9+H/Be3kMbfb7kYPQZA==, tarball: https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.5.40.tgz} + dependencies: + '@vue/shared': 3.5.40 + dev: true + + /@vue/runtime-core@3.5.40: + resolution: {integrity: sha512-KAZLweuZ6uUJPK1PMSQPgBU5gCjgrrfjUhSglmU9NhH+Zjepa8cnwSydPWDWHDwOgY4g3VcZ+PljbiHlURNCbw==, tarball: https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.5.40.tgz} + dependencies: + '@vue/reactivity': 3.5.40 + '@vue/shared': 3.5.40 + dev: true + + /@vue/runtime-dom@3.5.40: + resolution: {integrity: sha512-ZfrX8ssZQds900L9pr8AuK05ddnMsR4MPMZr8cPN9GoqoPWcXLhjvvbIA2SMv+7a97sJ1vv9pj/zxK0Cq/eEFQ==, tarball: https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.5.40.tgz} + dependencies: + '@vue/reactivity': 3.5.40 + '@vue/runtime-core': 3.5.40 + '@vue/shared': 3.5.40 + csstype: 3.2.3 + dev: true + + /@vue/server-renderer@3.5.40: + resolution: {integrity: sha512-XNJym9WpevhTVt1HuwOrCRJ5Q+9z4BjTMrDtjTrvx74SmUll8spNTw6whWJa9mEkO4PKn5TihI/bm/8ds2QVJw==, tarball: https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.5.40.tgz} + dependencies: + '@vue/compiler-ssr': 3.5.40 + '@vue/runtime-dom': 3.5.40 + '@vue/shared': 3.5.40 + dev: true + + /@vue/shared@3.5.40: + resolution: {integrity: sha512-WxnBtruIqOoV3rA4jeKDWzrYI5h7Cp4+pjwDi8kWGHz+IslhiN+wguLVVhtv2l8VoU02rzDCVfDjgCl1lNpZVg==, tarball: https://registry.npmjs.org/@vue/shared/-/shared-3.5.40.tgz} + dev: true + + /@vueuse/core@12.8.2(typescript@5.9.3): + resolution: {integrity: sha512-HbvCmZdzAu3VGi/pWYm5Ut+Kd9mn1ZHnn4L5G8kOQTPs/IwIAmJoBrmYk2ckLArgMXZj0AW3n5CAejLUO+PhdQ==, tarball: https://registry.npmjs.org/@vueuse/core/-/core-12.8.2.tgz} + dependencies: + '@types/web-bluetooth': 0.0.21 + '@vueuse/metadata': 12.8.2 + '@vueuse/shared': 12.8.2(typescript@5.9.3) + vue: 3.5.40(typescript@5.9.3) + transitivePeerDependencies: + - typescript + dev: true + + /@vueuse/integrations@12.8.2(focus-trap@7.8.0)(typescript@5.9.3): + resolution: {integrity: sha512-fbGYivgK5uBTRt7p5F3zy6VrETlV9RtZjBqd1/HxGdjdckBgBM4ugP8LHpjolqTj14TXTxSK1ZfgPbHYyGuH7g==, tarball: https://registry.npmjs.org/@vueuse/integrations/-/integrations-12.8.2.tgz} + peerDependencies: + async-validator: ^4 + axios: ^1 + change-case: ^5 + drauu: ^0.4 + focus-trap: ^7 + fuse.js: ^7 + idb-keyval: ^6 + jwt-decode: ^4 + nprogress: ^0.2 + qrcode: ^1.5 + sortablejs: ^1 + universal-cookie: ^7 + peerDependenciesMeta: + async-validator: + optional: true + axios: + optional: true + change-case: + optional: true + drauu: + optional: true + focus-trap: + optional: true + fuse.js: + optional: true + idb-keyval: + optional: true + jwt-decode: + optional: true + nprogress: + optional: true + qrcode: + optional: true + sortablejs: + optional: true + universal-cookie: + optional: true + dependencies: + '@vueuse/core': 12.8.2(typescript@5.9.3) + '@vueuse/shared': 12.8.2(typescript@5.9.3) + focus-trap: 7.8.0 + vue: 3.5.40(typescript@5.9.3) + transitivePeerDependencies: + - typescript + dev: true + + /@vueuse/metadata@12.8.2: + resolution: {integrity: sha512-rAyLGEuoBJ/Il5AmFHiziCPdQzRt88VxR+Y/A/QhJ1EWtWqPBBAxTAFaSkviwEuOEZNtW8pvkPgoCZQ+HxqW1A==, tarball: https://registry.npmjs.org/@vueuse/metadata/-/metadata-12.8.2.tgz} + dev: true + + /@vueuse/shared@12.8.2(typescript@5.9.3): + resolution: {integrity: sha512-dznP38YzxZoNloI0qpEfpkms8knDtaoQ6Y/sfS0L7Yki4zh40LFHEhur0odJC6xTHG5dxWVPiUWBXn+wCG2s5w==, tarball: https://registry.npmjs.org/@vueuse/shared/-/shared-12.8.2.tgz} + dependencies: + vue: 3.5.40(typescript@5.9.3) + transitivePeerDependencies: + - typescript + dev: true + /acorn-jsx@5.3.2(acorn@8.16.0): resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} peerDependencies: @@ -1735,6 +2264,26 @@ packages: uri-js: 4.4.1 dev: true + /algoliasearch@5.56.0: + resolution: {integrity: sha512-PrqppUmhT4ENdas2pH9caE7efUcxy6EcSFhWzosiVuQBzu2tQ5yLTI6jwomT/1cuBnivzGfxiJCqDNN9FRRh+Q==, tarball: https://registry.npmjs.org/algoliasearch/-/algoliasearch-5.56.0.tgz} + engines: {node: '>= 14.0.0'} + dependencies: + '@algolia/abtesting': 1.22.0 + '@algolia/client-abtesting': 5.56.0 + '@algolia/client-analytics': 5.56.0 + '@algolia/client-common': 5.56.0 + '@algolia/client-insights': 5.56.0 + '@algolia/client-personalization': 5.56.0 + '@algolia/client-query-suggestions': 5.56.0 + '@algolia/client-search': 5.56.0 + '@algolia/ingestion': 1.56.0 + '@algolia/monitoring': 1.56.0 + '@algolia/recommend': 5.56.0 + '@algolia/requester-browser-xhr': 5.56.0 + '@algolia/requester-fetch': 5.56.0 + '@algolia/requester-node-http': 5.56.0 + dev: true + /ansi-styles@4.3.0: resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} engines: {node: '>=8'} @@ -1775,6 +2324,10 @@ packages: hasBin: true dev: true + /birpc@2.9.0: + resolution: {integrity: sha512-KrayHS5pBi69Xi9JmvoqrIgYGDkD6mcSe/i6YKi3w5kekCLzrX4+nawcXqrj2tIp50Kw/mT/s3p+GVK0A0sKxw==, tarball: https://registry.npmjs.org/birpc/-/birpc-2.9.0.tgz} + dev: true + /brace-expansion@1.1.15: resolution: {integrity: sha512-EwOCDEex4quD37XhqM3omwtMoJjr//isUZz1JopUNWms+4Z2ViyM/k1YIRePpoVNnQhENnxtFjLaxNHrT7xIUg==} dependencies: @@ -1832,6 +2385,10 @@ packages: resolution: {integrity: sha512-MMHtuAz9Ys840zAY5F4k6fV5GaivZ9sPk+nz0mY+GYVzRBnYkN0mpqkSR92oWRQ19yQWo4HvBV/FnC16AJX8MA==} dev: true + /ccount@2.0.1: + resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==, tarball: https://registry.npmjs.org/ccount/-/ccount-2.0.1.tgz} + dev: true + /chai@5.3.3: resolution: {integrity: sha512-4zNhdJD/iOjSH0A05ea+Ke6MU5mmpQcbQsSOkgdaUMJ9zTlDTD/GYlwohmIE2u0gaxHYiVHEn1Fw9mZ/ktJWgw==} engines: {node: '>=18'} @@ -1851,6 +2408,14 @@ packages: supports-color: 7.2.0 dev: true + /character-entities-html4@2.1.0: + resolution: {integrity: sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==, tarball: https://registry.npmjs.org/character-entities-html4/-/character-entities-html4-2.1.0.tgz} + dev: true + + /character-entities-legacy@3.0.0: + resolution: {integrity: sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==, tarball: https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-3.0.0.tgz} + dev: true + /check-error@2.1.3: resolution: {integrity: sha512-PAJdDJusoxnwm1VwW07VWwUN1sl7smmC3OKggvndJFadxxDRyFJBX/ggnu/KE4kQAB7a3Dp8f/YXC1FlUprWmA==} engines: {node: '>= 16'} @@ -1874,6 +2439,10 @@ packages: resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} dev: true + /comma-separated-tokens@2.0.3: + resolution: {integrity: sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==, tarball: https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz} + dev: true + /commander@4.1.1: resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==} engines: {node: '>= 6'} @@ -1901,6 +2470,13 @@ packages: resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} dev: true + /copy-anything@4.0.5: + resolution: {integrity: sha512-7Vv6asjS4gMOuILabD3l739tsaxFQmC+a7pLZm02zyvs8p977bL3zEgq3yDk5rn9B0PbYgIv++jmHcuUab4RhA==, tarball: https://registry.npmjs.org/copy-anything/-/copy-anything-4.0.5.tgz} + engines: {node: '>=18'} + dependencies: + is-what: 5.5.0 + dev: true + /cross-spawn@7.0.6: resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} engines: {node: '>= 8'} @@ -1935,15 +2511,30 @@ packages: resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} dev: true + /dequal@2.0.3: + resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==, tarball: https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz} + engines: {node: '>=6'} + dev: true + /detect-libc@2.1.2: resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==} engines: {node: '>=8'} dev: true + /devlop@1.1.0: + resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==, tarball: https://registry.npmjs.org/devlop/-/devlop-1.1.0.tgz} + dependencies: + dequal: 2.0.3 + dev: true + /electron-to-chromium@1.5.382: resolution: {integrity: sha512-8ETaWbV6SZOrno+G93Ffd9ENsMtetqdnqj4nlfxFW90Sm5GgnuV28Kf62hqQVD6VUgzm7qFQKsTsAPmeUiU3Ug==} dev: true + /emoji-regex-xs@1.0.0: + resolution: {integrity: sha512-LRlerrMYoIDrT6jgpeZ2YYl/L8EulRTt5hQcYjy5AInh7HWXKimpqx68aknBFpGL2+/IcogTcaydJEgaTmOpDg==, tarball: https://registry.npmjs.org/emoji-regex-xs/-/emoji-regex-xs-1.0.0.tgz} + dev: true + /enhanced-resolve@5.21.6: resolution: {integrity: sha512-aNnGCvbJ/RIyWo1IuhNdVjnNF+EjH9wpzpNHt+ci/m9He9LJvUN8wrCcXjp9cWsGNAuvSpVFTx/vraAFQ8qGjQ==} engines: {node: '>=10.13.0'} @@ -1952,12 +2543,17 @@ packages: tapable: 2.3.3 dev: true + /entities@7.0.1: + resolution: {integrity: sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==, tarball: https://registry.npmjs.org/entities/-/entities-7.0.1.tgz} + engines: {node: '>=0.12'} + dev: true + /es-module-lexer@1.7.0: resolution: {integrity: sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==} dev: true /esbuild@0.21.5: - resolution: {integrity: sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==} + resolution: {integrity: sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==, tarball: https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz} engines: {node: '>=12'} hasBin: true requiresBuild: true @@ -2194,6 +2790,10 @@ packages: engines: {node: '>=4.0'} dev: true + /estree-walker@2.0.2: + resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==, tarball: https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz} + dev: true + /estree-walker@3.0.3: resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} dependencies: @@ -2276,8 +2876,14 @@ packages: resolution: {integrity: sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==} dev: true + /focus-trap@7.8.0: + resolution: {integrity: sha512-/yNdlIkpWbM0ptxno3ONTuf+2g318kh2ez3KSeZN5dZ8YC6AAmgeWz+GasYYiBJPFaYcSAPeu4GfhUaChzIJXA==, tarball: https://registry.npmjs.org/focus-trap/-/focus-trap-7.8.0.tgz} + dependencies: + tabbable: 6.5.0 + dev: true + /fsevents@2.3.3: - resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==, tarball: https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz} engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} os: [darwin] requiresBuild: true @@ -2310,6 +2916,36 @@ packages: engines: {node: '>=8'} dev: true + /hast-util-to-html@9.0.5: + resolution: {integrity: sha512-OguPdidb+fbHQSU4Q4ZiLKnzWo8Wwsf5bZfbvu7//a9oTYoqD/fWpe96NuHkoS9h0ccGOTe0C4NGXdtS0iObOw==, tarball: https://registry.npmjs.org/hast-util-to-html/-/hast-util-to-html-9.0.5.tgz} + dependencies: + '@types/hast': 3.0.5 + '@types/unist': 3.0.3 + ccount: 2.0.1 + comma-separated-tokens: 2.0.3 + hast-util-whitespace: 3.0.0 + html-void-elements: 3.0.0 + mdast-util-to-hast: 13.2.1 + property-information: 7.2.0 + space-separated-tokens: 2.0.2 + stringify-entities: 4.0.4 + zwitch: 2.0.4 + dev: true + + /hast-util-whitespace@3.0.0: + resolution: {integrity: sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==, tarball: https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-3.0.0.tgz} + dependencies: + '@types/hast': 3.0.5 + dev: true + + /hookable@5.5.3: + resolution: {integrity: sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==, tarball: https://registry.npmjs.org/hookable/-/hookable-5.5.3.tgz} + dev: true + + /html-void-elements@3.0.0: + resolution: {integrity: sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==, tarball: https://registry.npmjs.org/html-void-elements/-/html-void-elements-3.0.0.tgz} + dev: true + /ignore@5.3.2: resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} engines: {node: '>= 4'} @@ -2350,6 +2986,11 @@ packages: engines: {node: '>=0.12.0'} dev: true + /is-what@5.5.0: + resolution: {integrity: sha512-oG7cgbmg5kLYae2N5IVd3jm2s+vldjxJzK1pcu9LfpGuQ93MQSzo0okvRna+7y5ifrD+20FE8FvjusyGaz14fw==, tarball: https://registry.npmjs.org/is-what/-/is-what-5.5.0.tgz} + engines: {node: '>=18'} + dev: true + /isexe@2.0.0: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} dev: true @@ -2419,7 +3060,7 @@ packages: dev: true /lightningcss-android-arm64@1.32.0: - resolution: {integrity: sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==} + resolution: {integrity: sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==, tarball: https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.32.0.tgz} engines: {node: '>= 12.0.0'} cpu: [arm64] os: [android] @@ -2428,7 +3069,7 @@ packages: optional: true /lightningcss-darwin-arm64@1.32.0: - resolution: {integrity: sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ==} + resolution: {integrity: sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ==, tarball: https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.32.0.tgz} engines: {node: '>= 12.0.0'} cpu: [arm64] os: [darwin] @@ -2437,7 +3078,7 @@ packages: optional: true /lightningcss-darwin-x64@1.32.0: - resolution: {integrity: sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w==} + resolution: {integrity: sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w==, tarball: https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.32.0.tgz} engines: {node: '>= 12.0.0'} cpu: [x64] os: [darwin] @@ -2446,7 +3087,7 @@ packages: optional: true /lightningcss-freebsd-x64@1.32.0: - resolution: {integrity: sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig==} + resolution: {integrity: sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig==, tarball: https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.32.0.tgz} engines: {node: '>= 12.0.0'} cpu: [x64] os: [freebsd] @@ -2455,7 +3096,7 @@ packages: optional: true /lightningcss-linux-arm-gnueabihf@1.32.0: - resolution: {integrity: sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw==} + resolution: {integrity: sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw==, tarball: https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.32.0.tgz} engines: {node: '>= 12.0.0'} cpu: [arm] os: [linux] @@ -2464,7 +3105,7 @@ packages: optional: true /lightningcss-linux-arm64-gnu@1.32.0: - resolution: {integrity: sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ==} + resolution: {integrity: sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ==, tarball: https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.32.0.tgz} engines: {node: '>= 12.0.0'} cpu: [arm64] os: [linux] @@ -2473,7 +3114,7 @@ packages: optional: true /lightningcss-linux-arm64-musl@1.32.0: - resolution: {integrity: sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==} + resolution: {integrity: sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==, tarball: https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.32.0.tgz} engines: {node: '>= 12.0.0'} cpu: [arm64] os: [linux] @@ -2482,7 +3123,7 @@ packages: optional: true /lightningcss-linux-x64-gnu@1.32.0: - resolution: {integrity: sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==} + resolution: {integrity: sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==, tarball: https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.32.0.tgz} engines: {node: '>= 12.0.0'} cpu: [x64] os: [linux] @@ -2491,7 +3132,7 @@ packages: optional: true /lightningcss-linux-x64-musl@1.32.0: - resolution: {integrity: sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==} + resolution: {integrity: sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==, tarball: https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.32.0.tgz} engines: {node: '>= 12.0.0'} cpu: [x64] os: [linux] @@ -2500,7 +3141,7 @@ packages: optional: true /lightningcss-win32-arm64-msvc@1.32.0: - resolution: {integrity: sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==} + resolution: {integrity: sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==, tarball: https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.32.0.tgz} engines: {node: '>= 12.0.0'} cpu: [arm64] os: [win32] @@ -2509,7 +3150,7 @@ packages: optional: true /lightningcss-win32-x64-msvc@1.32.0: - resolution: {integrity: sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q==} + resolution: {integrity: sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q==, tarball: https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.32.0.tgz} engines: {node: '>= 12.0.0'} cpu: [x64] os: [win32] @@ -2577,6 +3218,51 @@ packages: '@jridgewell/sourcemap-codec': 1.5.5 dev: true + /mark.js@8.11.1: + resolution: {integrity: sha512-1I+1qpDt4idfgLQG+BNWmrqku+7/2bi5nLf4YwF8y8zXvmfiTBY3PV3ZibfrjBueCByROpuBjLLFCajqkgYoLQ==, tarball: https://registry.npmjs.org/mark.js/-/mark.js-8.11.1.tgz} + dev: true + + /mdast-util-to-hast@13.2.1: + resolution: {integrity: sha512-cctsq2wp5vTsLIcaymblUriiTcZd0CwWtCbLvrOzYCDZoWyMNV8sZ7krj09FSnsiJi3WVsHLM4k6Dq/yaPyCXA==, tarball: https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-13.2.1.tgz} + dependencies: + '@types/hast': 3.0.5 + '@types/mdast': 4.0.4 + '@ungap/structured-clone': 1.3.3 + devlop: 1.1.0 + micromark-util-sanitize-uri: 2.0.1 + trim-lines: 3.0.1 + unist-util-position: 5.0.0 + unist-util-visit: 5.1.0 + vfile: 6.0.3 + dev: true + + /micromark-util-character@2.1.1: + resolution: {integrity: sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==, tarball: https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz} + dependencies: + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + dev: true + + /micromark-util-encode@2.0.1: + resolution: {integrity: sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==, tarball: https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.1.tgz} + dev: true + + /micromark-util-sanitize-uri@2.0.1: + resolution: {integrity: sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==, tarball: https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.1.tgz} + dependencies: + micromark-util-character: 2.1.1 + micromark-util-encode: 2.0.1 + micromark-util-symbol: 2.0.1 + dev: true + + /micromark-util-symbol@2.0.1: + resolution: {integrity: sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==, tarball: https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz} + dev: true + + /micromark-util-types@2.0.2: + resolution: {integrity: sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==, tarball: https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.2.tgz} + dev: true + /micromatch@4.0.8: resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} engines: {node: '>=8.6'} @@ -2598,6 +3284,14 @@ packages: brace-expansion: 1.1.15 dev: true + /minisearch@7.2.0: + resolution: {integrity: sha512-dqT2XBYUOZOiC5t2HRnwADjhNS2cecp9u+TJRiJ1Qp/f5qjkeT5APcGPjHw+bz89Ms8Jp+cG4AlE+QZ/QnDglg==, tarball: https://registry.npmjs.org/minisearch/-/minisearch-7.2.0.tgz} + dev: true + + /mitt@3.0.1: + resolution: {integrity: sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==, tarball: https://registry.npmjs.org/mitt/-/mitt-3.0.1.tgz} + dev: true + /mlly@1.8.2: resolution: {integrity: sha512-d+ObxMQFmbt10sretNDytwt85VrbkhhUA/JBGm1MPaWJ65Cl4wOgLaB1NYvJSZ0Ef03MMEU/0xpPMXUIQ29UfA==} dependencies: @@ -2639,6 +3333,14 @@ packages: engines: {node: '>=0.10.0'} dev: true + /oniguruma-to-es@3.1.1: + resolution: {integrity: sha512-bUH8SDvPkH3ho3dvwJwfonjlQ4R80vjyvrU8YpxuROddv55vAEJrTuCuCVUhhsHbtlD9tGGbaNApGQckXhS8iQ==, tarball: https://registry.npmjs.org/oniguruma-to-es/-/oniguruma-to-es-3.1.1.tgz} + dependencies: + emoji-regex-xs: 1.0.0 + regex: 6.1.0 + regex-recursion: 6.0.2 + dev: true + /optionator@0.9.4: resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} engines: {node: '>= 0.8.0'} @@ -2705,6 +3407,10 @@ packages: engines: {node: '>= 14.16'} dev: true + /perfect-debounce@1.0.0: + resolution: {integrity: sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA==, tarball: https://registry.npmjs.org/perfect-debounce/-/perfect-debounce-1.0.0.tgz} + dev: true + /picocolors@1.1.1: resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} dev: true @@ -2762,6 +3468,24 @@ packages: source-map-js: 1.2.1 dev: true + /postcss@8.5.19: + resolution: {integrity: sha512-Mz8SaolMd8nB+G13WkORcxQKHZ/NE4xXevtkJHVuG+guo9/wYKlIMTKAqGdEmYOXR2ijPjTYNHssizdaVSUNdQ==, tarball: https://registry.npmjs.org/postcss/-/postcss-8.5.19.tgz} + engines: {node: ^10 || ^12 || >=14} + dependencies: + nanoid: 3.3.12 + picocolors: 1.1.1 + source-map-js: 1.2.1 + dev: true + + /preact@10.29.7: + resolution: {integrity: sha512-DCHYrK/B10yUD3ZjLfhZ3WIE/9Vf9VFUODcRE2dRomTYDpJk6z6L9wecSfhfE6M9ZTHUdyQkoC46arIDhEV84Q==, tarball: https://registry.npmjs.org/preact/-/preact-10.29.7.tgz} + peerDependencies: + preact-render-to-string: '>=5' + peerDependenciesMeta: + preact-render-to-string: + optional: true + dev: true + /prelude-ls@1.2.1: resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} engines: {node: '>= 0.8.0'} @@ -2773,6 +3497,10 @@ packages: hasBin: true dev: true + /property-information@7.2.0: + resolution: {integrity: sha512-IAtzIB6sUiWaJYrX9smp3V46pBGbBeLFRGdh25kg1334VcBlD8HzhPeNIWQH9zhGmo2itIe25EHt9dQP7G5hmg==, tarball: https://registry.npmjs.org/property-information/-/property-information-7.2.0.tgz} + dev: true + /punycode@2.3.1: resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} @@ -2802,6 +3530,22 @@ packages: engines: {node: '>= 14.18.0'} dev: true + /regex-recursion@6.0.2: + resolution: {integrity: sha512-0YCaSCq2VRIebiaUviZNs0cBz1kg5kVS2UKUfNIx8YVs1cN3AV7NTctO5FOKBA+UT2BPJIWZauYHPqJODG50cg==, tarball: https://registry.npmjs.org/regex-recursion/-/regex-recursion-6.0.2.tgz} + dependencies: + regex-utilities: 2.3.0 + dev: true + + /regex-utilities@2.3.0: + resolution: {integrity: sha512-8VhliFJAWRaUiVvREIiW2NXXTmHs4vMNnSzuJVhscgmGav3g9VDxLrQndI3dZZVVdp0ZO/5v0xmX516/7M9cng==, tarball: https://registry.npmjs.org/regex-utilities/-/regex-utilities-2.3.0.tgz} + dev: true + + /regex@6.1.0: + resolution: {integrity: sha512-6VwtthbV4o/7+OaAF9I5L5V3llLEsoPyq9P1JVXkedTP33c7MfCG0/5NOPcSJn0TzXcG9YUrR0gQSWioew3LDg==, tarball: https://registry.npmjs.org/regex/-/regex-6.1.0.tgz} + dependencies: + regex-utilities: 2.3.0 + dev: true + /resolve-from@4.0.0: resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} engines: {node: '>=4'} @@ -2812,6 +3556,10 @@ packages: engines: {node: '>=8'} dev: true + /rfdc@1.4.1: + resolution: {integrity: sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==, tarball: https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz} + dev: true + /rollup@4.61.0: resolution: {integrity: sha512-T9mWdbWfQtp0B5lv/HX+wrhYsmXRlcWnXXmJbXqKJhlRaoS6KMhq0gpyzW4UJfclcxrEdLnTgjT2NjruLONu0g==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} @@ -2851,6 +3599,10 @@ packages: resolution: {integrity: sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==} dev: false + /search-insights@2.17.3: + resolution: {integrity: sha512-RQPdCYTa8A68uM2jwxoY842xDhvx3E5LFL1LxvxCNMev4o5mLuokczhzjAgGwUZBAmOKZknArSxLKmXtIi2AxQ==, tarball: https://registry.npmjs.org/search-insights/-/search-insights-2.17.3.tgz} + dev: true + /semver@6.3.1: resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} hasBin: true @@ -2874,6 +3626,19 @@ packages: engines: {node: '>=8'} dev: true + /shiki@2.5.0: + resolution: {integrity: sha512-mI//trrsaiCIPsja5CNfsyNOqgAZUb6VpJA+340toL42UpzQlXpwRV9nch69X6gaUxrr9kaOOa6e3y3uAkGFxQ==, tarball: https://registry.npmjs.org/shiki/-/shiki-2.5.0.tgz} + dependencies: + '@shikijs/core': 2.5.0 + '@shikijs/engine-javascript': 2.5.0 + '@shikijs/engine-oniguruma': 2.5.0 + '@shikijs/langs': 2.5.0 + '@shikijs/themes': 2.5.0 + '@shikijs/types': 2.5.0 + '@shikijs/vscode-textmate': 10.0.2 + '@types/hast': 3.0.5 + dev: true + /siginfo@2.0.0: resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} dev: true @@ -2888,6 +3653,10 @@ packages: engines: {node: '>= 12'} dev: true + /space-separated-tokens@2.0.2: + resolution: {integrity: sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==, tarball: https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz} + dev: true + /spdx-exceptions@2.5.0: resolution: {integrity: sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==} dev: true @@ -2903,6 +3672,11 @@ packages: resolution: {integrity: sha512-CWLcCCH7VLu13TgOH+r8p1O/Znwhqv/dbb6lqWy67G+pT1kHmeD/+V36AVb/vq8QMIQwVShJ6Ssl5FPh0fuSdw==} dev: true + /speakingurl@14.0.1: + resolution: {integrity: sha512-1POYv7uv2gXoyGFpBCmpDVSNV74IfsWlDW216UPjbWufNf+bSU6GdbDsxdcxtfwb4xlI3yxzOTKClUosxARYrQ==, tarball: https://registry.npmjs.org/speakingurl/-/speakingurl-14.0.1.tgz} + engines: {node: '>=0.10.0'} + dev: true + /stackback@0.0.2: resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} dev: true @@ -2911,6 +3685,13 @@ packages: resolution: {integrity: sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg==} dev: true + /stringify-entities@4.0.4: + resolution: {integrity: sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==, tarball: https://registry.npmjs.org/stringify-entities/-/stringify-entities-4.0.4.tgz} + dependencies: + character-entities-html4: 2.1.0 + character-entities-legacy: 3.0.0 + dev: true + /strip-json-comments@3.1.1: resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} engines: {node: '>=8'} @@ -2930,6 +3711,13 @@ packages: ts-interface-checker: 0.1.13 dev: true + /superjson@2.2.6: + resolution: {integrity: sha512-H+ue8Zo4vJmV2nRjpx86P35lzwDT3nItnIsocgumgr0hHMQ+ZGq5vrERg9kJBo5AWGmxZDhzDo+WVIJqkB0cGA==, tarball: https://registry.npmjs.org/superjson/-/superjson-2.2.6.tgz} + engines: {node: '>=16'} + dependencies: + copy-anything: 4.0.5 + dev: true + /supports-color@7.2.0: resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} engines: {node: '>=8'} @@ -2937,6 +3725,10 @@ packages: has-flag: 4.0.0 dev: true + /tabbable@6.5.0: + resolution: {integrity: sha512-wieBHXygIm7OyQOu5hQlkk62/WyCFYGlWg7L6/ZCUZwx0o398Zkn4pVmMyfYhfMG8kGrj/Krt8eIk6UKC6VzwA==, tarball: https://registry.npmjs.org/tabbable/-/tabbable-6.5.0.tgz} + dev: true + /tailwindcss@4.3.2: resolution: {integrity: sha512-WtctNNSH8A9jlMIqxzuYumOHU5uGZyRv0Q5svQl+oEPy5w84YpBxdb7MdqyiSPQge5jTJ6zFQLq0PFygdccSBA==} dev: true @@ -3002,6 +3794,10 @@ packages: hasBin: true dev: true + /trim-lines@3.0.1: + resolution: {integrity: sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==, tarball: https://registry.npmjs.org/trim-lines/-/trim-lines-3.0.1.tgz} + dev: true + /ts-api-utils@2.5.0(typescript@5.9.3): resolution: {integrity: sha512-OJ/ibxhPlqrMM0UiNHJ/0CKQkoKF243/AEmplt3qpRgkW8VG7IfOS41h7V8TjITqdByHzrjcS/2si+y4lIh8NA==} engines: {node: '>=18.12'} @@ -3097,6 +3893,39 @@ packages: resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} dev: true + /unist-util-is@6.0.1: + resolution: {integrity: sha512-LsiILbtBETkDz8I9p1dQ0uyRUWuaQzd/cuEeS1hoRSyW5E5XGmTzlwY1OrNzzakGowI9Dr/I8HVaw4hTtnxy8g==, tarball: https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.1.tgz} + dependencies: + '@types/unist': 3.0.3 + dev: true + + /unist-util-position@5.0.0: + resolution: {integrity: sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==, tarball: https://registry.npmjs.org/unist-util-position/-/unist-util-position-5.0.0.tgz} + dependencies: + '@types/unist': 3.0.3 + dev: true + + /unist-util-stringify-position@4.0.0: + resolution: {integrity: sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==, tarball: https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz} + dependencies: + '@types/unist': 3.0.3 + dev: true + + /unist-util-visit-parents@6.0.2: + resolution: {integrity: sha512-goh1s1TBrqSqukSc8wrjwWhL0hiJxgA8m4kFxGlQ+8FYQ3C/m11FcTs4YYem7V664AhHVvgoQLk890Ssdsr2IQ==, tarball: https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.2.tgz} + dependencies: + '@types/unist': 3.0.3 + unist-util-is: 6.0.1 + dev: true + + /unist-util-visit@5.1.0: + resolution: {integrity: sha512-m+vIdyeCOpdr/QeQCu2EzxX/ohgS8KbnPDgFni4dQsfSCtpz8UqDyY5GjRru8PDKuYn7Fq19j1CQ+nJSsGKOzg==, tarball: https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.1.0.tgz} + dependencies: + '@types/unist': 3.0.3 + unist-util-is: 6.0.1 + unist-util-visit-parents: 6.0.2 + dev: true + /update-browserslist-db@1.2.3(browserslist@4.28.4): resolution: {integrity: sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==} hasBin: true @@ -3114,6 +3943,20 @@ packages: punycode: 2.3.1 dev: true + /vfile-message@4.0.3: + resolution: {integrity: sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw==, tarball: https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.3.tgz} + dependencies: + '@types/unist': 3.0.3 + unist-util-stringify-position: 4.0.0 + dev: true + + /vfile@6.0.3: + resolution: {integrity: sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==, tarball: https://registry.npmjs.org/vfile/-/vfile-6.0.3.tgz} + dependencies: + '@types/unist': 3.0.3 + vfile-message: 4.0.3 + dev: true + /vite-node@2.1.9(@types/node@22.19.19): resolution: {integrity: sha512-AM9aQ/IPrW/6ENLQg3AGY4K1N2TGZdR5e4gu/MmmR2xR3Ll1+dib+nook92g4TV3PXVyeyxdWwtaCAiUL0hMxA==} engines: {node: ^18.0.0 || >=20.0.0} @@ -3233,13 +4076,72 @@ packages: esbuild: 0.25.12 fdir: 6.5.0(picomatch@4.0.4) picomatch: 4.0.4 - postcss: 8.5.15 + postcss: 8.5.19 rollup: 4.61.0 tinyglobby: 0.2.17 optionalDependencies: fsevents: 2.3.3 dev: true + /vitepress@1.6.4(@algolia/client-search@5.56.0)(@types/node@22.19.19)(search-insights@2.17.3)(typescript@5.9.3): + resolution: {integrity: sha512-+2ym1/+0VVrbhNyRoFFesVvBvHAVMZMK0rw60E3X/5349M1GuVdKeazuksqopEdvkKwKGs21Q729jX81/bkBJg==, tarball: https://registry.npmjs.org/vitepress/-/vitepress-1.6.4.tgz} + hasBin: true + peerDependencies: + markdown-it-mathjax3: ^4 + postcss: ^8 + peerDependenciesMeta: + markdown-it-mathjax3: + optional: true + postcss: + optional: true + dependencies: + '@docsearch/css': 3.8.2 + '@docsearch/js': 3.8.2(@algolia/client-search@5.56.0)(search-insights@2.17.3) + '@iconify-json/simple-icons': 1.2.90 + '@shikijs/core': 2.5.0 + '@shikijs/transformers': 2.5.0 + '@shikijs/types': 2.5.0 + '@types/markdown-it': 14.1.2 + '@vitejs/plugin-vue': 5.2.4(vite@5.4.21)(vue@3.5.40) + '@vue/devtools-api': 7.7.10 + '@vue/shared': 3.5.40 + '@vueuse/core': 12.8.2(typescript@5.9.3) + '@vueuse/integrations': 12.8.2(focus-trap@7.8.0)(typescript@5.9.3) + focus-trap: 7.8.0 + mark.js: 8.11.1 + minisearch: 7.2.0 + shiki: 2.5.0 + vite: 5.4.21(@types/node@22.19.19) + vue: 3.5.40(typescript@5.9.3) + transitivePeerDependencies: + - '@algolia/client-search' + - '@types/node' + - '@types/react' + - async-validator + - axios + - change-case + - drauu + - fuse.js + - idb-keyval + - jwt-decode + - less + - lightningcss + - nprogress + - preact-render-to-string + - qrcode + - react + - react-dom + - sass + - sass-embedded + - search-insights + - sortablejs + - stylus + - sugarss + - terser + - typescript + - universal-cookie + dev: true + /vitest@2.1.9(@types/node@22.19.19): resolution: {integrity: sha512-MSmPM9REYqDGBI8439mA4mWhV5sKmDlBKWIYbA3lRb2PTHACE0mgKwA8yQ2xq9vxDTuk4iPrECBAEW2aoFXY0Q==} engines: {node: ^18.0.0 || >=20.0.0} @@ -3298,6 +4200,22 @@ packages: - terser dev: true + /vue@3.5.40(typescript@5.9.3): + resolution: {integrity: sha512-+8PJ4SJXdn/cHGImF4CKdxlWHIN5Dkt7DoufRREM6h6uVCx2m7QxgcEQmmzyOK8A9mcafg7sFbJFYsdFVubTig==, tarball: https://registry.npmjs.org/vue/-/vue-3.5.40.tgz} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@vue/compiler-dom': 3.5.40 + '@vue/compiler-sfc': 3.5.40 + '@vue/runtime-dom': 3.5.40 + '@vue/server-renderer': 3.5.40 + '@vue/shared': 3.5.40 + typescript: 5.9.3 + dev: true + /which@2.0.2: resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} engines: {node: '>= 8'} @@ -3328,3 +4246,7 @@ packages: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} engines: {node: '>=10'} dev: true + + /zwitch@2.0.4: + resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==, tarball: https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz} + dev: true diff --git a/scripts/release.sh b/scripts/release.sh index 5703760..cb1228a 100755 --- a/scripts/release.sh +++ b/scripts/release.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash # -# Local release driver for the @roulabs/mx npm package. +# Local release driver for the @rousan/mx npm package. # # Reads the target version from npm/package.json (you bump + commit it before # running this), runs the full check/build pipeline, publishes to npm using @@ -90,4 +90,4 @@ ok "Pushed $tag" echo green "Released $name@$version" echo " https://www.npmjs.com/package/$name/v/$version" -echo " https://github.com/roulabs/mx/releases/tag/$tag" +echo " https://github.com/rousan/mx/releases/tag/$tag" diff --git a/templates/CLAUDE.md b/templates/CLAUDE.md index 02d5079..036c73d 100644 --- a/templates/CLAUDE.md +++ b/templates/CLAUDE.md @@ -30,20 +30,20 @@ a newer runtime. Don't try to work around the gate by editing files by hand. `mx/` is where **feature work** happens. Sessions launched here implement a feature inside a `works//` folder. mx *itself* — this template, the `mx` CLI — is maintained in the -`github.com/roulabs/mx` source repo. There are two valid setups for that source: +`github.com/rousan/mx` source repo. There are two valid setups for that source: 1. **It lives elsewhere** (the default): if you were opened here to change how mx works, you're in the wrong place — switch to that repo. Don't edit `repos/`, `works/`, or the runtime files from here. 2. **It's hosted as a work in this runtime** (self-hosting / dogfooding): someone has run - `mx repo add git@github.com:roulabs/mx.git` and created one or more `works//mx/` + `mx repo add git@github.com:rousan/mx.git` and created one or more `works//mx/` worktrees for parallel mx development. In that case, working inside one of those worktrees IS valid — follow that worktree's own `CLAUDE.md` for the developer rules. The runtime rule that still applies here: **never run the worktree's locally-built mx CLI against this runtime**. Locally-built mx (`pnpm mx`, `node npm/bin/mx.js`) must be pointed at a sandbox (`$PWD/.mx` or `/tmp/...`) for any testing — otherwise it may re-stamp this `CLAUDE.md` with a work-in-progress - template. The published `mx` on `$PATH` (from `npm i -g @roulabs/mx`) is the safe one against + template. The published `mx` on `$PATH` (from `npm i -g @rousan/mx`) is the safe one against this runtime. ## Layout