diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 7745385..359439c 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,15 +1,29 @@ name: Release -# Every push to main (i.e. every merged PR) must produce a new release. +# Every push to main that changes PACKAGE content must produce a new release. # The release version is whatever sits in npm/package.json — the PR is # responsible for bumping it. If that version was already released (its # vX.Y.Z tag already exists), the workflow FAILS, prompting a version bump, -# because a merge to main without a version bump is a mistake under this -# contract. +# because a merge to main with package changes but no version bump is a mistake +# under this contract. +# +# The `paths-ignore` below exempts non-package changes (the landing site, docs, +# repo tooling, markdown) — those ship to main without an npm release, so a +# docs/site iteration doesn't force a version bump. If a push touches ONLY +# ignored paths, this workflow doesn't run; touch any non-ignored file and it +# does (and then demands a bump). on: push: branches: [main] + paths-ignore: + - 'apps/landing/**' + - 'docs/**' + - 'assets/**' + - '.npmrc' + - '**/*.md' + - '.github/workflows/deploy-landing.yml' + - '.github/workflows/release.yml' # Never run two releases at once; let an in-flight one finish. concurrency: diff --git a/.npmrc b/.npmrc new file mode 100644 index 0000000..c96f1aa --- /dev/null +++ b/.npmrc @@ -0,0 +1,7 @@ +# Pin this repo to the public npm registry, regardless of any global ~/.npmrc +# (e.g. a corporate Artifactory mirror). This keeps `pnpm install` — and the +# resolution URLs it writes into pnpm-lock.yaml — pointed at registry.npmjs.org, +# so the lockfile stays installable on CI and never gets a private-registry host +# baked in. (In an .npmrc the key is `registry=`; the equivalent env var is +# npm_config_registry.) +registry=https://registry.npmjs.org/ diff --git a/README.md b/README.md index 5ad3f6a..2ecc147 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,19 @@ -# mx +

+ mx logo +

+ +

mx

+ +

Work on parallel features using coding agents.

+ +

+ npm version + license + node version + docs +

+ +--- Source and tooling for **mx** ("multiplexer") — a system for working on several features in parallel across multiple shared repos, using git worktrees. Each feature gets an isolated environment (its own worktrees, branches, ports, editor workspace), so you can switch between features instantly without stashing or branch-juggling. @@ -114,7 +129,7 @@ Read commands take `--porcelain` for stable JSON; mutations echo the resulting o ## Release -Releases are **CI-driven**: bump `npm/package.json`'s `"version"` in a PR and merge to `main` — `.github/workflows/release.yml` runs the check pipeline, `npm publish`es from `npm/` (auth via the `NPM_TOKEN` secret), tags `vX.Y.Z`, and creates a GitHub Release. **Every merge to `main` must bump the version** or the run fails on the existing-tag guard. `pnpm release` (`scripts/release.sh`) remains a local fallback for emergencies. CI (`.github/workflows/ci.yml`) runs typecheck/lint/test/build on every PR. +Releases are **CI-driven**: bump `npm/package.json`'s `"version"` in a PR and merge to `main` — `.github/workflows/release.yml` runs the check pipeline, `npm publish`es from `npm/` (auth via the `NPM_TOKEN` secret), tags `vX.Y.Z`, and creates a GitHub Release. **Every merge to `main` that changes package content must bump the version** or the run fails on the existing-tag guard. Merges touching only non-package paths — the landing site (`apps/landing/**`), `docs/**`, markdown, or repo tooling — are exempt via the workflow's `paths-ignore`, so a docs/site iteration ships to `main` (and redeploys the site) without an npm release. `pnpm release` (`scripts/release.sh`) remains a local fallback for emergencies. CI (`.github/workflows/ci.yml`) runs typecheck/lint/test/build on every PR. See **[docs/release.md](docs/release.md)** for the full runbook, the `NPM_TOKEN` setup, and every gotcha caught the hard way (npm name similarity, fresh-scope propagation lag, etc.). diff --git a/apps/landing/public/favicon.svg b/apps/landing/public/favicon.svg index 6daedc1..19e6e87 100644 --- a/apps/landing/public/favicon.svg +++ b/apps/landing/public/favicon.svg @@ -1,13 +1,11 @@ - - - - - - - - - - + + + + + + + + diff --git a/apps/landing/src/index.css b/apps/landing/src/index.css index c986f80..2fc9fc2 100644 --- a/apps/landing/src/index.css +++ b/apps/landing/src/index.css @@ -9,14 +9,16 @@ @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`). + * Semantic design tokens — a calm, mostly-monochrome grayscale base with a warm + * amber/yellow accent drawn from the Tailwind palette (amber for the UI accent; + * the logo itself stays multi-pastel — teal/amber/rose with a violet source + * node). 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 @@ -35,13 +37,13 @@ --text-soft: #3f3f46; --muted: #71717a; --faint: #a1a1aa; - --accent: #c0562f; - --accent-ink: #b04a26; - --accent-2: #c0562f; - --accent-soft: rgba(192, 86, 47, 0.1); + --accent: #d97706; /* amber-600 (readable amber on white) */ + --accent-ink: #b45309; /* amber-700 (readable link on white) */ + --accent-2: #d97706; + --accent-soft: rgba(245, 158, 11, 0.14); /* amber-500 @ 14% */ --accent-strong: #18181b; --on-accent: #ffffff; - --cta: #c0562f; + --cta: #f59e0b; /* amber-500 button, white text */ --on-cta: #ffffff; --amber: #71717a; --code-bg: #f6f6f7; @@ -58,13 +60,13 @@ --text-soft: #c8c8ce; --muted: #9a9aa4; --faint: #63636d; - --accent: #e0793f; - --accent-ink: #ea8a5a; - --accent-2: #e0793f; - --accent-soft: rgba(224, 121, 63, 0.15); + --accent: #fbbf24; /* amber-400 (bright gold on the dark canvas) */ + --accent-ink: #fcd34d; /* amber-300 */ + --accent-2: #fbbf24; + --accent-soft: rgba(251, 191, 36, 0.16); /* amber-400 @ 16% */ --accent-strong: #fafafa; --on-accent: #18181b; - --cta: #c0562f; + --cta: #f59e0b; /* amber-500 button, white text */ --on-cta: #ffffff; --amber: #a1a1aa; --code-bg: #0d0d11; diff --git a/apps/landing/src/sections/Footer.tsx b/apps/landing/src/sections/Footer.tsx index 2b06978..edaf209 100644 --- a/apps/landing/src/sections/Footer.tsx +++ b/apps/landing/src/sections/Footer.tsx @@ -33,7 +33,7 @@ export function Footer() {
- + mx

diff --git a/apps/landing/src/sections/Hero.tsx b/apps/landing/src/sections/Hero.tsx index c11d322..d1ec9e1 100644 --- a/apps/landing/src/sections/Hero.tsx +++ b/apps/landing/src/sections/Hero.tsx @@ -14,7 +14,7 @@ export function Hero() {

- +