From 5f7af7f4ab2ac226e24174772dfbcebca9550f3b Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 23 Jul 2026 20:34:19 +0000 Subject: [PATCH 1/4] Fix release workflow: remove invalid xpecs bump from changeset The root "xpecs" package.json isn't listed in the npm workspaces field (only packages/*, skill, website are), so changesets doesn't recognize it as a workspace package. The modern-icon-library changeset referenced "xpecs": minor, which made `changeset version` fail in CI with "Found changeset modern-icon-library for package xpecs which is not in the workspace". --- .changeset/modern-icon-library.md | 1 - 1 file changed, 1 deletion(-) diff --git a/.changeset/modern-icon-library.md b/.changeset/modern-icon-library.md index 80b21d1..fe741ec 100644 --- a/.changeset/modern-icon-library.md +++ b/.changeset/modern-icon-library.md @@ -1,6 +1,5 @@ --- "@xpecs/xote": minor -"xpecs": minor --- Add a modern SVG icon library with an `Icon` component. From 45feafcdb588392883a050c12a55ac1d029c40b7 Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 23 Jul 2026 20:58:34 +0000 Subject: [PATCH 2/4] Rename npm scope from `@xpecs` to `@prescriptive` The `@xpecs` scope is unavailable on npm, so this renames it across all workspace packages (`@prescriptive/tokens`, `@prescriptive/xote`, `@prescriptive/reativa`, `@prescriptive/skill`), the lockfile, changesets, docs, build scripts, and the website's ReScript/Reativa sources. The root private package (name "xpecs") and the website package (name "xpecs-website") are unscoped and unaffected. --- .changeset/modern-icon-library.md | 6 +-- .changeset/reativa-components-package.md | 12 ++--- CHANGELOG.md | 2 +- README.md | 12 ++--- RELEASING.md | 8 ++-- package-lock.json | 48 +++++++++---------- package.json | 4 +- packages/reativa/README.md | 10 ++-- packages/reativa/package.json | 6 +-- packages/reativa/scripts/build.mjs | 6 +-- .../reativa/scripts/generate-contracts.mjs | 2 +- packages/reativa/src/Button.mlx | 2 +- packages/tokens/README.md | 12 ++--- packages/tokens/package.json | 2 +- packages/tokens/scripts/build.mjs | 4 +- packages/xote/README.md | 12 ++--- packages/xote/package.json | 6 +-- packages/xote/rescript.json | 2 +- skill/package.json | 2 +- website/README.md | 6 +-- website/package.json | 4 +- website/rescript.json | 2 +- website/scripts/build-reativa.mjs | 6 +-- website/scripts/check-conformance.mjs | 2 +- website/scripts/generate-snippets.mjs | 2 +- website/src/ReativaExamples.res | 2 +- website/src/reativa.bundle.js | 4 +- 27 files changed, 93 insertions(+), 93 deletions(-) diff --git a/.changeset/modern-icon-library.md b/.changeset/modern-icon-library.md index fe741ec..387b95c 100644 --- a/.changeset/modern-icon-library.md +++ b/.changeset/modern-icon-library.md @@ -1,16 +1,16 @@ --- -"@xpecs/xote": minor +"@prescriptive/xote": minor --- Add a modern SVG icon library with an `Icon` component. -- **`@xpecs/xote`**: new `Icons` module — a curated outline icon set (50 glyphs) +- **`@prescriptive/xote`**: new `Icons` module — a curated outline icon set (50 glyphs) in the Feather / Lucide visual language (24×24 grid, no fill, 2px round strokes) — and an `Icon` element that renders a named glyph as an inline SVG. Icons inherit the surrounding text color and optical size; pass `label` for a meaningful icon (role=img + accessible name) or omit it to mark it decorative. Sizes: `xs`, `sm`, `md`, `lg`, `xl`. -- **`@xpecs/xote`**: `Alert` now renders its `icon` as a glyph from the icon set +- **`@prescriptive/xote`**: `Alert` now renders its `icon` as a glyph from the icon set (the prop takes an icon name) and shows a sensible per-variant default when none is given. - **`xpecs`**: the `icon` element spec now types `size` as an enum and maps its diff --git a/.changeset/reativa-components-package.md b/.changeset/reativa-components-package.md index fcb4516..8b4fd98 100644 --- a/.changeset/reativa-components-package.md +++ b/.changeset/reativa-components-package.md @@ -1,18 +1,18 @@ --- -"@xpecs/reativa": minor +"@prescriptive/reativa": minor --- -Add `@xpecs/reativa` — the ReasonML/OCaml (reativa + Melange) sibling of -`@xpecs/xote`, as its own package. +Add `@prescriptive/reativa` — the ReasonML/OCaml (reativa + Melange) sibling of +`@prescriptive/xote`, as its own package. -- Implements the same set `@xpecs/xote` covers — 22 elements, 8 components, and +- Implements the same set `@prescriptive/xote` covers — 22 elements, 8 components, and 7 blocks — in `.mlx` (JSX-for-OCaml) over `Reativa.View`, styled against - `@xpecs/tokens`, with the same behaviour and accessibility semantics as the + `@prescriptive/tokens`, with the same behaviour and accessibility semantics as the Xote components. - Enum prop types (`variant`, `size`, …) are generated from the specs' `## API` contracts into `src/Contracts.ml` by `npm run contracts`, so the OCaml compiler enforces that the implementation can't drift from the spec — the same - guarantee `@xpecs/xote` has. + guarantee `@prescriptive/xote` has. - `src/Registry.mlx` renders one live example per spec and exports the JS surface the website's **Reativa** preview consumes (`mount_example`, `example_ids`, `built`). The website's example block now has two tab strips: one picks the diff --git a/CHANGELOG.md b/CHANGELOG.md index e448632..b02537b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,7 +25,7 @@ follows [Semantic Versioning](https://semver.org/) and the format of - `announcement-bar` — a slim, dismissible, page-width strip for one timely message (a launch, promotion, or notice). - **First block-level Xote components.** All seven new blocks ship with - `implementation:`-mapped components in `@xpecs/xote` (`PageHeader`, + `implementation:`-mapped components in `@prescriptive/xote` (`PageHeader`, `StatGrid`, `LogoCloud`, `Steps`, `ContactSection`, `Newsletter`, `AnnouncementBar`), so the conformance gate now checks blocks too. The `steps` and `announcement-bar` enum props are compiler-enforced via the diff --git a/README.md b/README.md index ad043f1..5d416c4 100644 --- a/README.md +++ b/README.md @@ -88,8 +88,8 @@ derived, consumable artifacts live under [`packages/`](packages/): | Package | What it is | | ------- | ---------- | | **`xpecs`** (root) | The spec catalogue + design tokens — the source of truth every package below is generated from. | -| **[`@xpecs/tokens`](packages/tokens)** | The design tokens as ready-to-use artifacts: CSS custom properties, a **Tailwind v4 preset**, `[data-theme]`/`[data-mode]` overlays, and a typed JS export. | -| **[`@xpecs/xote`](packages/xote)** | Accessible [Xote](https://xote.dev)/ReScript components implementing the specs. Their prop types are generated from each spec's `## API`, so the compiler enforces they can't drift. Styled via `@xpecs/tokens`. | +| **[`@prescriptive/tokens`](packages/tokens)** | The design tokens as ready-to-use artifacts: CSS custom properties, a **Tailwind v4 preset**, `[data-theme]`/`[data-mode]` overlays, and a typed JS export. | +| **[`@prescriptive/xote`](packages/xote)** | Accessible [Xote](https://xote.dev)/ReScript components implementing the specs. Their prop types are generated from each spec's `## API`, so the compiler enforces they can't drift. Styled via `@prescriptive/tokens`. | | **[`skill/`](skill/)** | An **Agent Skill** — the specs, traits, tokens, and responsive vocabulary compiled into a reference an AI coding agent loads to implement UI to the contracts. | Each package is generated from the framework source, so nothing downstream can @@ -139,8 +139,8 @@ xpecs/ # root workspace = the `xpecs` spec + tokens sourc ├── templates/ # SPEC_TEMPLATE.md — the document pattern to copy ├── skill/ # the distributable Agent Skill ├── packages/ -│ ├── tokens/ # @xpecs/tokens (CSS vars, Tailwind preset, JS) -│ └── xote/ # @xpecs/xote (Xote/ReScript components) +│ ├── tokens/ # @prescriptive/tokens (CSS vars, Tailwind preset, JS) +│ └── xote/ # @prescriptive/xote (Xote/ReScript components) ├── website/ # interactive catalogue (Vite + ReScript + Xote) ├── INDEX.md # generated registry of every spec └── CHANGELOG.md @@ -158,12 +158,12 @@ breakpoints — live in [`tokens/`](tokens/) in the standard **[W3C Design Tokens (DTCG) format](https://www.w3.org/community/design-tokens/)**, with ready-made themes in [`themes.json`](tokens/themes.json). Consume them as CSS variables, a Tailwind preset, or a JS object via -[`@xpecs/tokens`](packages/tokens). See [`tokens/README.md`](tokens/README.md). +[`@prescriptive/tokens`](packages/tokens). See [`tokens/README.md`](tokens/README.md). ## Website An interactive catalogue lives in [`website/`](website/): it lists every spec, -renders a **live example** of each (composed from `@xpecs/xote`), shows the API +renders a **live example** of each (composed from `@prescriptive/xote`), shows the API contract and responsive behavior, and lets you retheme the whole site live from the design tokens. Built with Vite, ReScript, [Xote](https://xote.dev), and Tailwind CSS. See [`website/README.md`](website/README.md) to run it. diff --git a/RELEASING.md b/RELEASING.md index 1b0ceef..44183c2 100644 --- a/RELEASING.md +++ b/RELEASING.md @@ -7,13 +7,13 @@ and GitHub Actions. Four packages are published from this monorepo; the | Package | Contents | | ------- | -------- | | `xpecs` | The spec catalogue + tokens (the repo root). | -| `@xpecs/tokens` | CSS variables, Tailwind preset, theme overlays, JS export. | -| `@xpecs/xote` | The Xote/ReScript component library. | -| `@xpecs/skill` | The Agent Skill (`SKILL.md` + compiled `reference/`). | +| `@prescriptive/tokens` | CSS variables, Tailwind preset, theme overlays, JS export. | +| `@prescriptive/xote` | The Xote/ReScript component library. | +| `@prescriptive/skill` | The Agent Skill (`SKILL.md` + compiled `reference/`). | ## One-time setup -1. **npm scope.** The publishing npm account must own the `@xpecs` scope +1. **npm scope.** The publishing npm account must own the `@prescriptive` scope (create an org named `xpecs`, or publish under an account that owns it). The scoped packages already declare `publishConfig.access = public`. 2. **`NPM_TOKEN` secret.** Add a repository secret `NPM_TOKEN` (Settings → diff --git a/package-lock.json b/package-lock.json index c4c8245..ffb887f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -418,6 +418,22 @@ "node": ">= 8" } }, + "node_modules/@prescriptive/reativa": { + "resolved": "packages/reativa", + "link": true + }, + "node_modules/@prescriptive/skill": { + "resolved": "skill", + "link": true + }, + "node_modules/@prescriptive/tokens": { + "resolved": "packages/tokens", + "link": true + }, + "node_modules/@prescriptive/xote": { + "resolved": "packages/xote", + "link": true + }, "node_modules/@rescript/core": { "version": "1.6.1", "resolved": "https://registry.npmjs.org/@rescript/core/-/core-1.6.1.tgz", @@ -525,22 +541,6 @@ "undici-types": "~8.3.0" } }, - "node_modules/@xpecs/reativa": { - "resolved": "packages/reativa", - "link": true - }, - "node_modules/@xpecs/skill": { - "resolved": "skill", - "link": true - }, - "node_modules/@xpecs/tokens": { - "resolved": "packages/tokens", - "link": true - }, - "node_modules/@xpecs/xote": { - "resolved": "packages/xote", - "link": true - }, "node_modules/ansi-colors": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", @@ -1500,24 +1500,24 @@ "link": true }, "packages/reativa": { - "name": "@xpecs/reativa", + "name": "@prescriptive/reativa", "version": "0.1.0", "license": "MIT", "dependencies": { - "@xpecs/tokens": "^0.1.0" + "@prescriptive/tokens": "^0.1.0" } }, "packages/tokens": { - "name": "@xpecs/tokens", + "name": "@prescriptive/tokens", "version": "0.1.0", "license": "MIT" }, "packages/xote": { - "name": "@xpecs/xote", + "name": "@prescriptive/xote", "version": "0.1.0", "license": "MIT", "dependencies": { - "@xpecs/tokens": "^0.1.0" + "@prescriptive/tokens": "^0.1.0" }, "peerDependencies": { "@rescript/core": ">=1.6.0", @@ -1527,7 +1527,7 @@ } }, "skill": { - "name": "@xpecs/skill", + "name": "@prescriptive/skill", "version": "0.1.0", "license": "MIT" }, @@ -1535,8 +1535,8 @@ "name": "xpecs-website", "version": "0.1.0", "dependencies": { - "@xpecs/tokens": "*", - "@xpecs/xote": "*", + "@prescriptive/tokens": "*", + "@prescriptive/xote": "*", "rescript-signals": "3.1.1", "xote": "7.0.0" }, diff --git a/package.json b/package.json index fd0a0e4..c01eb2b 100644 --- a/package.json +++ b/package.json @@ -10,8 +10,8 @@ "scripts": { "index": "node scripts/generate-index.mjs", "skill": "node scripts/generate-skill.mjs", - "build:tokens": "npm run build --workspace @xpecs/tokens", - "build:packages": "npm run build --workspace @xpecs/tokens && npm run build --workspace @xpecs/xote && npm run build --workspace @xpecs/skill", + "build:tokens": "npm run build --workspace @prescriptive/tokens", + "build:packages": "npm run build --workspace @prescriptive/tokens && npm run build --workspace @prescriptive/xote && npm run build --workspace @prescriptive/skill", "changeset": "changeset", "version": "changeset version", "release": "npm run build:packages && changeset publish" diff --git a/packages/reativa/README.md b/packages/reativa/README.md index 39900bd..148e616 100644 --- a/packages/reativa/README.md +++ b/packages/reativa/README.md @@ -1,11 +1,11 @@ -# @xpecs/reativa +# @prescriptive/reativa Accessible UI components for **[reativa](https://github.com/brnrdog/reativa)** (OCaml + Melange) that implement the [Xpecs](https://github.com/brnrdog/ux-archetypes) contracts — the ReasonML/OCaml sibling of -[`@xpecs/xote`](../xote). Every element, component, and block is written in +[`@prescriptive/xote`](../xote). Every element, component, and block is written in `.mlx` (JSX-for-OCaml) over `Reativa.View`, styled against -[`@xpecs/tokens`](../tokens), so a re-theme cascades through these exactly like +[`@prescriptive/tokens`](../tokens), so a re-theme cascades through these exactly like it does through the Xote components. There is no virtual DOM: `View.mount` builds real DOM nodes once and only the @@ -13,7 +13,7 @@ reactive regions (driven by signals) update in place. ## What's implemented -The same set `@xpecs/xote` covers — 22 elements, 8 components, and 7 blocks: +The same set `@prescriptive/xote` covers — 22 elements, 8 components, and 7 blocks: | Layer | Specs | | ----- | ----- | @@ -54,7 +54,7 @@ opam install dune melange mlx Then: ```bash -npm run build --workspace @xpecs/reativa # contracts → melange → esbuild bundle +npm run build --workspace @prescriptive/reativa # contracts → melange → esbuild bundle ``` To move to a newer reativa, bump `REATIVA_REF` in `scripts/build.mjs`. diff --git a/packages/reativa/package.json b/packages/reativa/package.json index 0fafee6..868b165 100644 --- a/packages/reativa/package.json +++ b/packages/reativa/package.json @@ -1,7 +1,7 @@ { - "name": "@xpecs/reativa", + "name": "@prescriptive/reativa", "version": "0.1.0", - "description": "Accessible UI components for Reativa (OCaml + Melange) that implement the Xpecs contracts — the ReasonML/OCaml sibling of @xpecs/xote. Styled against @xpecs/tokens; prop types are generated from the spec API contracts, so the implementation can't drift from the spec.", + "description": "Accessible UI components for Reativa (OCaml + Melange) that implement the Xpecs contracts — the ReasonML/OCaml sibling of @prescriptive/xote. Styled against @prescriptive/tokens; prop types are generated from the spec API contracts, so the implementation can't drift from the spec.", "license": "MIT", "author": "brnrdog", "keywords": [ @@ -27,7 +27,7 @@ "prepack": "npm run contracts" }, "dependencies": { - "@xpecs/tokens": "^0.1.0" + "@prescriptive/tokens": "^0.1.0" }, "repository": { "type": "git", diff --git a/packages/reativa/scripts/build.mjs b/packages/reativa/scripts/build.mjs index 5a400ef..7bbb797 100644 --- a/packages/reativa/scripts/build.mjs +++ b/packages/reativa/scripts/build.mjs @@ -1,4 +1,4 @@ -// Build the @xpecs/reativa component bundle (consumed by the website's Reativa +// Build the @prescriptive/reativa component bundle (consumed by the website's Reativa // tab). reativa's core library is a *private* dune library (no public_name), so // it can't be consumed as an installed opam library — its own demo works only // because it lives inside the reativa dune project. We do the same: clone @@ -10,7 +10,7 @@ // Requires: an opam switch with `dune`, `melange`, `mlx` installed, plus git and // esbuild. Not part of `npm run build:packages`/the website's default build // (it needs opam/melange, which the rest of the build does not) — invoked -// explicitly by `npm run build --workspace @xpecs/reativa`, and by CI so PRs +// explicitly by `npm run build --workspace @prescriptive/reativa`, and by CI so PRs // compile the components and Pages ships the real bundle. import { execFileSync } from "node:child_process"; @@ -88,4 +88,4 @@ sh( pkgDir, ); -console.log(`\n✓ @xpecs/reativa bundle written to ${outfile}`); +console.log(`\n✓ @prescriptive/reativa bundle written to ${outfile}`); diff --git a/packages/reativa/scripts/generate-contracts.mjs b/packages/reativa/scripts/generate-contracts.mjs index 16e1365..b086338 100644 --- a/packages/reativa/scripts/generate-contracts.mjs +++ b/packages/reativa/scripts/generate-contracts.mjs @@ -5,7 +5,7 @@ // sync with the contract's allowed values. // // This is the OCaml counterpart of packages/xote/scripts/generate-contracts.mjs -// (which emits ReScript polymorphic variants for @xpecs/xote); both read the +// (which emits ReScript polymorphic variants for @prescriptive/xote); both read the // same specs so the two implementations expose the same contract types. import { readFileSync, writeFileSync, readdirSync, mkdirSync } from "node:fs"; import { join, dirname, basename } from "node:path"; diff --git a/packages/reativa/src/Button.mlx b/packages/reativa/src/Button.mlx index 1bed64b..6d47bab 100644 --- a/packages/reativa/src/Button.mlx +++ b/packages/reativa/src/Button.mlx @@ -4,7 +4,7 @@ navbar, and other examples. Its [variant]/[size]/[type_] prop types come from the spec's `## API` contract (Contracts.ml, generated), so the compiler enforces that this implementation stays in sync with the spec's allowed - values — exactly as @xpecs/xote's Button does. *) + values — exactly as @prescriptive/xote's Button does. *) open Reativa diff --git a/packages/tokens/README.md b/packages/tokens/README.md index 2f197f2..2af6ad1 100644 --- a/packages/tokens/README.md +++ b/packages/tokens/README.md @@ -1,4 +1,4 @@ -# @xpecs/tokens +# @prescriptive/tokens The design tokens of [Xpecs](https://github.com/brnrdog/ux-archetypes) as ready-to-consume artifacts — CSS custom properties, a Tailwind v4 preset, @@ -8,7 +8,7 @@ source of truth, so they never drift from the specs. ## Install ```sh -npm install @xpecs/tokens +npm install @prescriptive/tokens ``` ## Use @@ -16,7 +16,7 @@ npm install @xpecs/tokens **Plain CSS** — every token as a `--ux-*` custom property: ```css -@import "@xpecs/tokens/variables.css"; +@import "@prescriptive/tokens/variables.css"; .button { background: var(--ux-color-action-default); color: var(--ux-color-action-onAction); } ``` @@ -26,14 +26,14 @@ npm install @xpecs/tokens ```css @import "tailwindcss"; -@import "@xpecs/tokens/tailwind.css"; +@import "@prescriptive/tokens/tailwind.css"; ``` **Theming** — opt into a named theme and light/dark by setting attributes on any ancestor (usually ``); the overlays re-point the token variables: ```css -@import "@xpecs/tokens/themes.css"; +@import "@prescriptive/tokens/themes.css"; ``` ```html @@ -42,7 +42,7 @@ ancestor (usually ``); the overlays re-point the token variables: **JS / TS** — the resolved values as data: ```js -import { tokens, flat, themes } from "@xpecs/tokens"; +import { tokens, flat, themes } from "@prescriptive/tokens"; flat["color.action.default"]; // "#1b1917" tokens.color.neutral["900"]; // "#1b1917" diff --git a/packages/tokens/package.json b/packages/tokens/package.json index 6a3daa4..fa4eeb1 100644 --- a/packages/tokens/package.json +++ b/packages/tokens/package.json @@ -1,5 +1,5 @@ { - "name": "@xpecs/tokens", + "name": "@prescriptive/tokens", "version": "0.1.0", "description": "Design tokens for Xpecs — CSS custom properties, a Tailwind v4 preset, theme overlays, and a typed JS export. Generated from the framework's W3C DTCG tokens.", "license": "MIT", diff --git a/packages/tokens/scripts/build.mjs b/packages/tokens/scripts/build.mjs index a88dd83..fe89b42 100644 --- a/packages/tokens/scripts/build.mjs +++ b/packages/tokens/scripts/build.mjs @@ -73,7 +73,7 @@ function themeValueFor(tok) { // --- variables.css : the --ux-* custom properties --------------------------- const rootLines = Object.entries(flat).map(([p, t]) => ` ${uxVar(p)}: ${uxValueFor(t)};`); -const banner = `/* GENERATED — @xpecs/tokens. Source: framework tokens.json (DTCG). */`; +const banner = `/* GENERATED — @prescriptive/tokens. Source: framework tokens.json (DTCG). */`; writeFileSync(join(dist, "variables.css"), `${banner}\n:root {\n${rootLines.join("\n")}\n}\n`); // --- tailwind.css : Tailwind v4 @theme preset + the --ux-* mirror ----------- @@ -142,5 +142,5 @@ copyFileSync(srcTokens, join(dist, "tokens.json")); copyFileSync(srcThemes, join(dist, "themes.json")); console.log( - `@xpecs/tokens: ${Object.keys(flat).length} tokens, ${themeList.length} themes → dist/`, + `@prescriptive/tokens: ${Object.keys(flat).length} tokens, ${themeList.length} themes → dist/`, ); diff --git a/packages/xote/README.md b/packages/xote/README.md index 7686171..65fc110 100644 --- a/packages/xote/README.md +++ b/packages/xote/README.md @@ -1,4 +1,4 @@ -# @xpecs/xote +# @prescriptive/xote Accessible UI components for [Xote](https://xote.dev) / ReScript that implement the [Xpecs](https://github.com/brnrdog/ux-archetypes) contracts. Each @@ -6,7 +6,7 @@ component's prop types are **generated from the spec's `## API` contract** (`Contracts.res`), so the compiler enforces that the implementation can't drift from the spec's allowed values. -Styled against [`@xpecs/tokens`](../tokens) via the semantic utilities +Styled against [`@prescriptive/tokens`](../tokens) via the semantic utilities (`bg-action`, `text-ink`, …), so re-theming is a token change, not a code change. ## Components @@ -40,7 +40,7 @@ an ancestor tints the icon. Icon paths are adapted from ## Install ```sh -npm install @xpecs/xote @xpecs/tokens +npm install @prescriptive/xote @prescriptive/tokens ``` Peer dependencies: `rescript`, `@rescript/core`, `rescript-signals`, `xote`. @@ -51,7 +51,7 @@ Add it to your `rescript.json` dependencies (the package builds `namespace:false so its modules are available unqualified): ```json -{ "dependencies": ["@rescript/core", "rescript-signals", "xote", "@xpecs/xote"] } +{ "dependencies": ["@rescript/core", "rescript-signals", "xote", "@prescriptive/xote"] } ``` ```rescript @@ -60,11 +60,11 @@ so its modules are available unqualified): ``` -Import the token CSS once at your app entry (see `@xpecs/tokens`): +Import the token CSS once at your app entry (see `@prescriptive/tokens`): ```css @import "tailwindcss"; -@import "@xpecs/tokens/tailwind.css"; +@import "@prescriptive/tokens/tailwind.css"; ``` ## Build diff --git a/packages/xote/package.json b/packages/xote/package.json index b6a987c..8292b0d 100644 --- a/packages/xote/package.json +++ b/packages/xote/package.json @@ -1,7 +1,7 @@ { - "name": "@xpecs/xote", + "name": "@prescriptive/xote", "version": "0.1.0", - "description": "Accessible UI components for Xote/ReScript that implement the Xpecs contracts. Styled against @xpecs/tokens; prop types are generated from the spec API contracts, so the implementation can't drift from the spec.", + "description": "Accessible UI components for Xote/ReScript that implement the Xpecs contracts. Styled against @prescriptive/tokens; prop types are generated from the spec API contracts, so the implementation can't drift from the spec.", "license": "MIT", "author": "brnrdog", "keywords": [ @@ -32,7 +32,7 @@ "xote": ">=7.0.0" }, "dependencies": { - "@xpecs/tokens": "^0.1.0" + "@prescriptive/tokens": "^0.1.0" }, "repository": { "type": "git", diff --git a/packages/xote/rescript.json b/packages/xote/rescript.json index a2146c6..bbda2cb 100644 --- a/packages/xote/rescript.json +++ b/packages/xote/rescript.json @@ -1,5 +1,5 @@ { - "name": "@xpecs/xote", + "name": "@prescriptive/xote", "namespace": false, "sources": [ { diff --git a/skill/package.json b/skill/package.json index e8363b6..da01bd8 100644 --- a/skill/package.json +++ b/skill/package.json @@ -1,5 +1,5 @@ { - "name": "@xpecs/skill", + "name": "@prescriptive/skill", "version": "0.1.0", "description": "The Xpecs Agent Skill — UI specs, traits, design tokens, and the responsive vocabulary compiled into a reference an AI coding agent loads to implement UI to the contracts.", "license": "MIT", diff --git a/website/README.md b/website/README.md index 7bc95c7..ac672dd 100644 --- a/website/README.md +++ b/website/README.md @@ -60,17 +60,17 @@ Specs without an example fall back to a graceful placeholder. ## Xote / Reativa implementations -Every element, component, and block that `@xpecs/xote` implements is **also** +Every element, component, and block that `@prescriptive/xote` implements is **also** implemented in OCaml with [reativa](https://github.com/brnrdog/reativa) — the signal-based sibling of Xote — in the -[`@xpecs/reativa`](../packages/reativa) package. The example block has two tab +[`@prescriptive/reativa`](../packages/reativa) package. The example block has two tab strips: one picks the **view** (Preview / Playground / Code) and one picks the **implementation** rendered in the preview (**Xote** or **Reativa**), so the two render the same spec from the same design tokens, side by side. The reativa build is a self-contained Melange workspace, kept **separate** from this ReScript/Vite build (it needs opam + melange, the website doesn't). -`npm run reativa` builds `@xpecs/reativa` and copies its bundle to +`npm run reativa` builds `@prescriptive/reativa` and copies its bundle to `src/reativa.bundle.js`; a checked-in placeholder keeps the site compiling until then. See [`packages/reativa/README.md`](../packages/reativa/README.md). diff --git a/website/package.json b/website/package.json index 10038be..7235a81 100644 --- a/website/package.json +++ b/website/package.json @@ -29,8 +29,8 @@ "smoke": "node scripts/smoke-all.mjs" }, "dependencies": { - "@xpecs/tokens": "*", - "@xpecs/xote": "*", + "@prescriptive/tokens": "*", + "@prescriptive/xote": "*", "rescript-signals": "3.1.1", "xote": "7.0.0" }, diff --git a/website/rescript.json b/website/rescript.json index 67abee0..04d4336 100644 --- a/website/rescript.json +++ b/website/rescript.json @@ -11,7 +11,7 @@ "in-source": true }, "suffix": ".res.mjs", - "dependencies": ["@rescript/core", "rescript-signals", "xote", "@xpecs/xote"], + "dependencies": ["@rescript/core", "rescript-signals", "xote", "@prescriptive/xote"], "jsx": { "version": 4, "module": "XoteJSX" diff --git a/website/scripts/build-reativa.mjs b/website/scripts/build-reativa.mjs index 6e5946f..dbcb56a 100644 --- a/website/scripts/build-reativa.mjs +++ b/website/scripts/build-reativa.mjs @@ -1,7 +1,7 @@ // Build the reativa (OCaml + Melange) component bundle consumed by the website's // "Reativa" preview, and drop it next to the website sources. // -// The components live in the @xpecs/reativa package (packages/reativa); this +// The components live in the @prescriptive/reativa package (packages/reativa); this // script just delegates to that package's build (clone reativa → dune build // @melange → esbuild bundle) and copies the resulting dist/reativa.bundle.js // into website/src/reativa.bundle.js, overwriting the checked-in placeholder. @@ -19,9 +19,9 @@ const websiteDir = resolve(fileURLToPath(import.meta.url), "../.."); const repoRoot = resolve(websiteDir, ".."); const pkgDir = resolve(repoRoot, "packages/reativa"); -// 1. Build @xpecs/reativa (generates Contracts.ml, compiles with Melange, and +// 1. Build @prescriptive/reativa (generates Contracts.ml, compiles with Melange, and // bundles to packages/reativa/dist/reativa.bundle.js). -execFileSync("npm", ["run", "build", "--workspace", "@xpecs/reativa"], { +execFileSync("npm", ["run", "build", "--workspace", "@prescriptive/reativa"], { cwd: repoRoot, stdio: "inherit", }); diff --git a/website/scripts/check-conformance.mjs b/website/scripts/check-conformance.mjs index f851a06..a270711 100644 --- a/website/scripts/check-conformance.mjs +++ b/website/scripts/check-conformance.mjs @@ -9,7 +9,7 @@ import { fileURLToPath } from "node:url"; const here = dirname(fileURLToPath(import.meta.url)); const specsDir = join(here, "..", "..", "specs"); -// The component implementations live in the @xpecs/xote package. +// The component implementations live in the @prescriptive/xote package. const srcDir = join(here, "..", "..", "packages", "xote", "src"); const layers = ["elements", "components", "blocks", "pages", "flows"]; diff --git a/website/scripts/generate-snippets.mjs b/website/scripts/generate-snippets.mjs index 5310dbc..149939c 100644 --- a/website/scripts/generate-snippets.mjs +++ b/website/scripts/generate-snippets.mjs @@ -10,7 +10,7 @@ import { fileURLToPath } from "node:url"; const here = dirname(fileURLToPath(import.meta.url)); const srcDir = join(here, "..", "src"); -// Reusable components now live in the @xpecs/xote package. +// Reusable components now live in the @prescriptive/xote package. const compDir = join(here, "..", "..", "packages", "xote", "src"); const examplesSrc = readFileSync(join(srcDir, "Examples.res"), "utf8"); const outFile = join(srcDir, "ExampleSource.res"); diff --git a/website/src/ReativaExamples.res b/website/src/ReativaExamples.res index 6f613e5..01c26a0 100644 --- a/website/src/ReativaExamples.res +++ b/website/src/ReativaExamples.res @@ -1,5 +1,5 @@ // Bridges the reativa (OCaml + Melange) component implementations into the -// ReScript/Xote website. The components live in the @xpecs/reativa package +// ReScript/Xote website. The components live in the @prescriptive/reativa package // (packages/reativa/src/*.mlx) and are compiled + bundled to // website/src/reativa.bundle.js by `npm run reativa`. // diff --git a/website/src/reativa.bundle.js b/website/src/reativa.bundle.js index b3ab014..c8b29a2 100644 --- a/website/src/reativa.bundle.js +++ b/website/src/reativa.bundle.js @@ -1,6 +1,6 @@ // PLACEHOLDER — not the real bundle. // -// The reativa (OCaml + Melange) Xpecs components live in the @xpecs/reativa +// The reativa (OCaml + Melange) Xpecs components live in the @prescriptive/reativa // package (packages/reativa/src/*.mlx). Building them needs the OCaml toolchain // (opam + melange), which isn't part of the ReScript/Vite website build, so this // checked-in stub keeps the site building and the "Reativa" tab present (showing @@ -10,7 +10,7 @@ // // cd website && npm run reativa // -// which builds @xpecs/reativa and copies its dist/reativa.bundle.js here. +// which builds @prescriptive/reativa and copies its dist/reativa.bundle.js here. // See packages/reativa/README.md for the toolchain setup. export const built = false; From 01d4a993cb61ebca604f16e8e071d93602fd9478 Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 23 Jul 2026 21:07:36 +0000 Subject: [PATCH 3/4] Rename project from Xpecs to Prescriptive Rebrands the project throughout: the display name (Xpecs -> Prescriptive) in docs, website UI, and the Agent Skill; the root package (`xpecs` -> `prescriptive`) and the website package (`xpecs-website` -> `prescriptive-website`); internal DOM id prefixes (`xpecs-*` -> `prescriptive-*`) in the Xote and Reativa component sources; the `prescriptive_reativa` build directory; and the repository URLs and schema `$id`s (github.com/brnrdog/ux-archetypes -> github.com/brnrdog/prescriptive), plus the project-name npm keyword. The GitHub Pages base path is derived from the repo name at deploy time, so it follows the repository rename automatically. Historical CHANGELOG entries are left intact, since they record the name the project actually had at the time. --- .changeset/modern-icon-library.md | 2 +- .github/workflows/ci.yml | 4 ++-- .github/workflows/deploy-pages.yml | 6 +++--- CONTRIBUTING.md | 2 +- README.md | 8 ++++---- RELEASING.md | 4 ++-- package-lock.json | 14 +++++++------- package.json | 4 ++-- packages/reativa/README.md | 2 +- packages/reativa/package.json | 6 +++--- packages/reativa/scripts/build.mjs | 4 ++-- packages/reativa/src/Checkbox.mlx | 2 +- packages/reativa/src/Icon.ml | 2 +- packages/reativa/src/Icons.ml | 2 +- packages/reativa/src/RadioGroup.mlx | 2 +- packages/reativa/src/Ui.ml | 2 +- packages/tokens/README.md | 2 +- packages/tokens/package.json | 6 +++--- packages/xote/README.md | 2 +- packages/xote/package.json | 6 +++--- packages/xote/src/Checkbox.res | 2 +- packages/xote/src/RadioGroup.res | 2 +- schema/api.schema.json | 2 +- schema/spec.schema.json | 2 +- schema/trait.schema.json | 2 +- skill/SKILL.md | 4 ++-- skill/package.json | 4 ++-- skill/reference/themes.json | 2 +- skill/reference/tokens.json | 2 +- tokens/themes.json | 2 +- tokens/tokens.json | 2 +- website/README.md | 6 +++--- website/index.html | 2 +- website/package.json | 2 +- website/rescript.json | 2 +- website/src/App.res | 18 +++++++++--------- website/src/Main.res | 2 +- website/src/reativa.bundle.js | 2 +- website/src/styles.css | 2 +- website/vite.config.js | 2 +- 40 files changed, 73 insertions(+), 73 deletions(-) diff --git a/.changeset/modern-icon-library.md b/.changeset/modern-icon-library.md index 387b95c..bd2f7ef 100644 --- a/.changeset/modern-icon-library.md +++ b/.changeset/modern-icon-library.md @@ -13,6 +13,6 @@ Add a modern SVG icon library with an `Icon` component. - **`@prescriptive/xote`**: `Alert` now renders its `icon` as a glyph from the icon set (the prop takes an icon name) and shows a sensible per-variant default when none is given. -- **`xpecs`**: the `icon` element spec now types `size` as an enum and maps its +- **`prescriptive`**: the `icon` element spec now types `size` as an enum and maps its implementation to `Icon.res`, so the component is compiler-checked against the contract. diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9d154d4..e6f3fc1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -34,7 +34,7 @@ jobs: # Clones reativa (pinned), compiles the .mlx examples inside its dune # project, and bundles the output to website/src/reativa.bundle.js. - name: Build reativa bundle (OCaml → esbuild) - run: npm run reativa --workspace xpecs-website + run: npm run reativa --workspace prescriptive-website # Build the publishable packages (tokens → xote → skill). - name: Build packages @@ -42,4 +42,4 @@ jobs: # Build the website, which runs every conformance gate (npm run checks). - name: Build website + run gates - run: npm run build --workspace xpecs-website + run: npm run build --workspace prescriptive-website diff --git a/.github/workflows/deploy-pages.yml b/.github/workflows/deploy-pages.yml index 7eff2a2..7eb1984 100644 --- a/.github/workflows/deploy-pages.yml +++ b/.github/workflows/deploy-pages.yml @@ -35,7 +35,7 @@ jobs: node-version: 20 cache: npm - # Install the whole workspace so the website can resolve @xpecs/*. + # Install the whole workspace so the website can resolve @prescriptive/*. - name: Install run: npm ci @@ -55,14 +55,14 @@ jobs: # Clones reativa (pinned), compiles the .mlx examples inside its dune # project, and bundles the output to website/src/reativa.bundle.js. - name: Build reativa bundle (OCaml → esbuild) - run: npm run reativa --workspace xpecs-website + run: npm run reativa --workspace prescriptive-website # Build the packages the website consumes (tokens → xote), then the site. - name: Build packages run: npm run build:packages - name: Build website - run: npm run build --workspace xpecs-website + run: npm run build --workspace prescriptive-website env: # Project site path = repository name. BASE_PATH: /${{ github.event.repository.name }}/ diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 87fd55c..b5006ec 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,6 +1,6 @@ # Contributing -Thanks for helping grow the Xpecs collection. The goal is a set of +Thanks for helping grow the Prescriptive collection. The goal is a set of patterns that stay **consistent**, **stack-agnostic**, and **useful to both humans and AI agents**. Consistency is the whole value, so the process is mostly about keeping the shape uniform. diff --git a/README.md b/README.md index 5d416c4..b30742e 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Xpecs +# Prescriptive A catalogue of **UX specs** — reusable, technology-agnostic definitions of UI patterns, written to be a shared source of truth for **humans and AI agents**. @@ -21,7 +21,7 @@ maps specs onto its own tokens, framework, and visual language. Design systems and component libraries get re-invented on every project and every stack. The visual skin and the framework change, but the underlying _pattern_ — what a Button is, what a Navbar must do, what a Dashboard is for — -does not. Xpecs captures those stable patterns once, so they can be: +does not. Prescriptive captures those stable patterns once, so they can be: - **Reused** across projects and stacks (React, Vue, SwiftUI, design tools, …). - **Referenced** by AI agents as a source of truth when generating UI. @@ -87,7 +87,7 @@ derived, consumable artifacts live under [`packages/`](packages/): | Package | What it is | | ------- | ---------- | -| **`xpecs`** (root) | The spec catalogue + design tokens — the source of truth every package below is generated from. | +| **`prescriptive`** (root) | The spec catalogue + design tokens — the source of truth every package below is generated from. | | **[`@prescriptive/tokens`](packages/tokens)** | The design tokens as ready-to-use artifacts: CSS custom properties, a **Tailwind v4 preset**, `[data-theme]`/`[data-mode]` overlays, and a typed JS export. | | **[`@prescriptive/xote`](packages/xote)** | Accessible [Xote](https://xote.dev)/ReScript components implementing the specs. Their prop types are generated from each spec's `## API`, so the compiler enforces they can't drift. Styled via `@prescriptive/tokens`. | | **[`skill/`](skill/)** | An **Agent Skill** — the specs, traits, tokens, and responsive vocabulary compiled into a reference an AI coding agent loads to implement UI to the contracts. | @@ -129,7 +129,7 @@ Because the specs are structured, the build **checks** them (`npm run checks` in ## Repository layout ``` -xpecs/ # root workspace = the `xpecs` spec + tokens source +prescriptive/ # root workspace = the `prescriptive` spec + tokens source ├── specs/ # the catalogue, one file per spec │ ├── elements/ components/ blocks/ pages/ flows/ ├── traits/ # shared interaction contracts diff --git a/RELEASING.md b/RELEASING.md index 44183c2..c3314cf 100644 --- a/RELEASING.md +++ b/RELEASING.md @@ -6,7 +6,7 @@ and GitHub Actions. Four packages are published from this monorepo; the | Package | Contents | | ------- | -------- | -| `xpecs` | The spec catalogue + tokens (the repo root). | +| `prescriptive` | The spec catalogue + tokens (the repo root). | | `@prescriptive/tokens` | CSS variables, Tailwind preset, theme overlays, JS export. | | `@prescriptive/xote` | The Xote/ReScript component library. | | `@prescriptive/skill` | The Agent Skill (`SKILL.md` + compiled `reference/`). | @@ -14,7 +14,7 @@ and GitHub Actions. Four packages are published from this monorepo; the ## One-time setup 1. **npm scope.** The publishing npm account must own the `@prescriptive` scope - (create an org named `xpecs`, or publish under an account that owns it). The + (create an org named `prescriptive`, or publish under an account that owns it). The scoped packages already declare `publishConfig.access = public`. 2. **`NPM_TOKEN` secret.** Add a repository secret `NPM_TOKEN` (Settings → Secrets → Actions) containing an npm **Automation** token with publish diff --git a/package-lock.json b/package-lock.json index ffb887f..708f8bd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,11 +1,11 @@ { - "name": "xpecs", + "name": "prescriptive", "version": "0.8.0", "lockfileVersion": 3, "requires": true, "packages": { "": { - "name": "xpecs", + "name": "prescriptive", "version": "0.8.0", "license": "MIT", "workspaces": [ @@ -1135,6 +1135,10 @@ "node": ">=6" } }, + "node_modules/prescriptive-website": { + "resolved": "website", + "link": true + }, "node_modules/prettier": { "version": "2.8.8", "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", @@ -1495,10 +1499,6 @@ "rescript-signals": "^3.1.0" } }, - "node_modules/xpecs-website": { - "resolved": "website", - "link": true - }, "packages/reativa": { "name": "@prescriptive/reativa", "version": "0.1.0", @@ -1532,7 +1532,7 @@ "license": "MIT" }, "website": { - "name": "xpecs-website", + "name": "prescriptive-website", "version": "0.1.0", "dependencies": { "@prescriptive/tokens": "*", diff --git a/package.json b/package.json index c01eb2b..c74a31b 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,5 @@ { - "name": "xpecs", + "name": "prescriptive", "version": "0.8.0", "description": "A technology-agnostic collection of User Experience Specs: reusable definitions of UI patterns for humans and AI agents, spanning elements, components, blocks, pages, and flows.", "workspaces": [ @@ -42,7 +42,7 @@ ], "repository": { "type": "git", - "url": "https://github.com/brnrdog/ux-archetypes" + "url": "https://github.com/brnrdog/prescriptive" }, "devDependencies": { "@changesets/cli": "^2.31.1" diff --git a/packages/reativa/README.md b/packages/reativa/README.md index 148e616..5b3d9ad 100644 --- a/packages/reativa/README.md +++ b/packages/reativa/README.md @@ -1,7 +1,7 @@ # @prescriptive/reativa Accessible UI components for **[reativa](https://github.com/brnrdog/reativa)** -(OCaml + Melange) that implement the [Xpecs](https://github.com/brnrdog/ux-archetypes) +(OCaml + Melange) that implement the [Prescriptive](https://github.com/brnrdog/prescriptive) contracts — the ReasonML/OCaml sibling of [`@prescriptive/xote`](../xote). Every element, component, and block is written in `.mlx` (JSX-for-OCaml) over `Reativa.View`, styled against diff --git a/packages/reativa/package.json b/packages/reativa/package.json index 868b165..e433c8a 100644 --- a/packages/reativa/package.json +++ b/packages/reativa/package.json @@ -1,7 +1,7 @@ { "name": "@prescriptive/reativa", "version": "0.1.0", - "description": "Accessible UI components for Reativa (OCaml + Melange) that implement the Xpecs contracts — the ReasonML/OCaml sibling of @prescriptive/xote. Styled against @prescriptive/tokens; prop types are generated from the spec API contracts, so the implementation can't drift from the spec.", + "description": "Accessible UI components for Reativa (OCaml + Melange) that implement the Prescriptive contracts — the ReasonML/OCaml sibling of @prescriptive/xote. Styled against @prescriptive/tokens; prop types are generated from the spec API contracts, so the implementation can't drift from the spec.", "license": "MIT", "author": "brnrdog", "keywords": [ @@ -12,7 +12,7 @@ "components", "ui", "design-system", - "ux-archetypes", + "prescriptive", "accessibility" ], "type": "module", @@ -31,7 +31,7 @@ }, "repository": { "type": "git", - "url": "https://github.com/brnrdog/ux-archetypes", + "url": "https://github.com/brnrdog/prescriptive", "directory": "packages/reativa" }, "publishConfig": { diff --git a/packages/reativa/scripts/build.mjs b/packages/reativa/scripts/build.mjs index 7bbb797..cc447d5 100644 --- a/packages/reativa/scripts/build.mjs +++ b/packages/reativa/scripts/build.mjs @@ -32,7 +32,7 @@ const srcDir = resolve(pkgDir, "src"); const buildDir = resolve(pkgDir, ".build"); const clone = resolve(buildDir, "reativa"); // The subdirectory inside the reativa dune project we drop our sources into. -const exDir = resolve(clone, "xpecs_reativa"); +const exDir = resolve(clone, "prescriptive_reativa"); const distDir = resolve(pkgDir, "dist"); const sh = (file, args, cwd) => execFileSync(file, args, { cwd, stdio: "inherit" }); @@ -63,7 +63,7 @@ sh("opam", ["exec", "--", "dune", "build", "@melange"], clone); // mirrors the source path under the target dir, so the entry is normally // //output/Registry.js — but locate it defensively in case // the nesting differs across dune/melange versions. -const outputRoot = resolve(clone, "_build/default/xpecs_reativa/output"); +const outputRoot = resolve(clone, "_build/default/prescriptive_reativa/output"); const findEntry = (dir) => { for (const name of readdirSync(dir, { withFileTypes: true })) { const p = join(dir, name.name); diff --git a/packages/reativa/src/Checkbox.mlx b/packages/reativa/src/Checkbox.mlx index 329e729..ff76545 100644 --- a/packages/reativa/src/Checkbox.mlx +++ b/packages/reativa/src/Checkbox.mlx @@ -22,7 +22,7 @@ let make ?(indeterminate = false) ?(disabled = false) ?(required = false) ?(labe let id = if indeterminate then begin incr seq; - let id = "xpecs-reativa-checkbox-" ^ string_of_int !seq in + let id = "prescriptive-reativa-checkbox-" ^ string_of_int !seq in Ui.set_indeterminate_by_id id true; Some id end diff --git a/packages/reativa/src/Icon.ml b/packages/reativa/src/Icon.ml index a43b143..86e2ebb 100644 --- a/packages/reativa/src/Icon.ml +++ b/packages/reativa/src/Icon.ml @@ -42,6 +42,6 @@ let make ?(size : Contracts.Icon.size = `md) ?(label = "") ?(extra_class = "") ~ let markup = Icons.svg ~dims ~extra ~role_attrs body in View.dyn (fun () -> incr counter; - let id = "xpecs-reativa-icon-" ^ string_of_int !counter in + let id = "prescriptive-reativa-icon-" ^ string_of_int !counter in Ui.set_inner_html_by_id id markup; View.element ~attrs:[ View.Attr.id (View.static id) ] "span" []) \ No newline at end of file diff --git a/packages/reativa/src/Icons.ml b/packages/reativa/src/Icons.ml index 5a2a9cc..387467e 100644 --- a/packages/reativa/src/Icons.ml +++ b/packages/reativa/src/Icons.ml @@ -1,6 +1,6 @@ [@@@warning "-a"] -(* Icons — the same small outline icon set as @xpecs/xote's [Icons], in the +(* Icons — the same small outline icon set as @prescriptive/xote's [Icons], in the Feather / Lucide visual language: every glyph is drawn on a 24×24 grid with no fill, 2px strokes, and round caps and joins, so it inherits the surrounding text color and optical weight. The geometry lives here as data diff --git a/packages/reativa/src/RadioGroup.mlx b/packages/reativa/src/RadioGroup.mlx index 7e6e3fa..57fbac6 100644 --- a/packages/reativa/src/RadioGroup.mlx +++ b/packages/reativa/src/RadioGroup.mlx @@ -15,7 +15,7 @@ let make ?(legend = "") ?(name = "") ?(orientation : Contracts.RadioGroup.orient let group_name = if name = "" then begin incr seq; - "xpecs-reativa-radio-group-" ^ string_of_int !seq + "prescriptive-reativa-radio-group-" ^ string_of_int !seq end else name in diff --git a/packages/reativa/src/Ui.ml b/packages/reativa/src/Ui.ml index 8b68906..4cac514 100644 --- a/packages/reativa/src/Ui.ml +++ b/packages/reativa/src/Ui.ml @@ -2,7 +2,7 @@ (* Shared monochrome design tokens (Tailwind class strings) and small DOM helpers used across the reativa example implementations — the OCaml - counterpart of @xpecs/xote's [Ui] module. + counterpart of @prescriptive/xote's [Ui] module. The class strings are the same token-driven Tailwind utilities the Xote components use (bg-action, text-on-action, border-status-*, …) so editing a diff --git a/packages/tokens/README.md b/packages/tokens/README.md index 2af6ad1..9a81cee 100644 --- a/packages/tokens/README.md +++ b/packages/tokens/README.md @@ -1,6 +1,6 @@ # @prescriptive/tokens -The design tokens of [Xpecs](https://github.com/brnrdog/ux-archetypes) +The design tokens of [Prescriptive](https://github.com/brnrdog/prescriptive) as ready-to-consume artifacts — CSS custom properties, a Tailwind v4 preset, theme overlays, and a typed JS export. Generated from the framework's W3C DTCG source of truth, so they never drift from the specs. diff --git a/packages/tokens/package.json b/packages/tokens/package.json index fa4eeb1..00206f3 100644 --- a/packages/tokens/package.json +++ b/packages/tokens/package.json @@ -1,7 +1,7 @@ { "name": "@prescriptive/tokens", "version": "0.1.0", - "description": "Design tokens for Xpecs — CSS custom properties, a Tailwind v4 preset, theme overlays, and a typed JS export. Generated from the framework's W3C DTCG tokens.", + "description": "Design tokens for Prescriptive — CSS custom properties, a Tailwind v4 preset, theme overlays, and a typed JS export. Generated from the framework's W3C DTCG tokens.", "license": "MIT", "author": "brnrdog", "keywords": [ @@ -10,7 +10,7 @@ "tailwind", "theme", "dtcg", - "ux-archetypes" + "prescriptive" ], "type": "module", "sideEffects": [ @@ -36,7 +36,7 @@ }, "repository": { "type": "git", - "url": "https://github.com/brnrdog/ux-archetypes", + "url": "https://github.com/brnrdog/prescriptive", "directory": "packages/tokens" }, "publishConfig": { diff --git a/packages/xote/README.md b/packages/xote/README.md index 65fc110..e4a1662 100644 --- a/packages/xote/README.md +++ b/packages/xote/README.md @@ -1,7 +1,7 @@ # @prescriptive/xote Accessible UI components for [Xote](https://xote.dev) / ReScript that implement -the [Xpecs](https://github.com/brnrdog/ux-archetypes) contracts. Each +the [Prescriptive](https://github.com/brnrdog/prescriptive) contracts. Each component's prop types are **generated from the spec's `## API` contract** (`Contracts.res`), so the compiler enforces that the implementation can't drift from the spec's allowed values. diff --git a/packages/xote/package.json b/packages/xote/package.json index 8292b0d..4334c1d 100644 --- a/packages/xote/package.json +++ b/packages/xote/package.json @@ -1,7 +1,7 @@ { "name": "@prescriptive/xote", "version": "0.1.0", - "description": "Accessible UI components for Xote/ReScript that implement the Xpecs contracts. Styled against @prescriptive/tokens; prop types are generated from the spec API contracts, so the implementation can't drift from the spec.", + "description": "Accessible UI components for Xote/ReScript that implement the Prescriptive contracts. Styled against @prescriptive/tokens; prop types are generated from the spec API contracts, so the implementation can't drift from the spec.", "license": "MIT", "author": "brnrdog", "keywords": [ @@ -10,7 +10,7 @@ "components", "ui", "design-system", - "ux-archetypes", + "prescriptive", "accessibility" ], "type": "module", @@ -36,7 +36,7 @@ }, "repository": { "type": "git", - "url": "https://github.com/brnrdog/ux-archetypes", + "url": "https://github.com/brnrdog/prescriptive", "directory": "packages/xote" }, "publishConfig": { diff --git a/packages/xote/src/Checkbox.res b/packages/xote/src/Checkbox.res index 93ec025..99b02a1 100644 --- a/packages/xote/src/Checkbox.res +++ b/packages/xote/src/Checkbox.res @@ -26,7 +26,7 @@ let make = ( // The browser clears it on the first user toggle, as the spec expects. let id = if indeterminate { seq := seq.contents + 1 - let id = "xpecs-checkbox-" ++ Int.toString(seq.contents) + let id = "prescriptive-checkbox-" ++ Int.toString(seq.contents) Ui.setIndeterminateById(id, true) Some(id) } else { diff --git a/packages/xote/src/RadioGroup.res b/packages/xote/src/RadioGroup.res index 433897b..bdad606 100644 --- a/packages/xote/src/RadioGroup.res +++ b/packages/xote/src/RadioGroup.res @@ -18,7 +18,7 @@ let make = ( ) => { let groupName = if name == "" { seq := seq.contents + 1 - "xpecs-radio-group-" ++ Int.toString(seq.contents) + "prescriptive-radio-group-" ++ Int.toString(seq.contents) } else { name } diff --git a/schema/api.schema.json b/schema/api.schema.json index 9f6a4f3..a16caaf 100644 --- a/schema/api.schema.json +++ b/schema/api.schema.json @@ -1,6 +1,6 @@ { "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "https://github.com/brnrdog/ux-archetypes/schema/api.schema.json", + "$id": "https://github.com/brnrdog/prescriptive/schema/api.schema.json", "title": "UI Spec API contract", "description": "Machine-readable interface contract embedded as a `json` fenced block under the `## API` heading of a spec document. Skin-agnostic: it names the axes of variation, structural slots, events, accessibility expectations, and the design-token roles the spec consumes. Implementations are validated against it.", "type": "object", diff --git a/schema/spec.schema.json b/schema/spec.schema.json index 36e9b8d..6a1b429 100644 --- a/schema/spec.schema.json +++ b/schema/spec.schema.json @@ -1,6 +1,6 @@ { "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "https://github.com/brnrdog/ux-archetypes/schema/spec.schema.json", + "$id": "https://github.com/brnrdog/prescriptive/schema/spec.schema.json", "title": "UI Spec metadata", "description": "Schema for the YAML frontmatter metadata block of a spec document.", "type": "object", diff --git a/schema/trait.schema.json b/schema/trait.schema.json index 951369d..c598b8c 100644 --- a/schema/trait.schema.json +++ b/schema/trait.schema.json @@ -1,6 +1,6 @@ { "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "https://github.com/brnrdog/ux-archetypes/schema/trait.schema.json", + "$id": "https://github.com/brnrdog/prescriptive/schema/trait.schema.json", "title": "UX Behavior Trait metadata", "description": "Frontmatter for a behavior trait — a reusable, cross-cutting interaction contract (dismiss, focus-trap, anchored positioning, roving focus, typeahead) that many specs share instead of re-describing it each time.", "type": "object", diff --git a/skill/SKILL.md b/skill/SKILL.md index beafbbf..89e1000 100644 --- a/skill/SKILL.md +++ b/skill/SKILL.md @@ -1,9 +1,9 @@ --- -name: xpecs +name: prescriptive description: Implement UI to a technology-agnostic spec. Use when building or reviewing user-interface elements, components, page sections, pages, or flows (buttons, inputs, dialogs, tabs, menus, forms, navbars, cards, data tables, etc.), a design system, or design tokens — in any framework. Provides each pattern's interface contract (props, slots, events, states), accessibility and keyboard behavior, structural composition, shared behavior traits, and a themeable design-token system, so the implementation is correct and consistent instead of improvised. --- -# Xpecs +# Prescriptive A catalogue of **UX specs** — technology-agnostic definitions of UI patterns — plus a design-token system. Use it to implement UI **to a contract** rather diff --git a/skill/package.json b/skill/package.json index da01bd8..dcbe530 100644 --- a/skill/package.json +++ b/skill/package.json @@ -1,7 +1,7 @@ { "name": "@prescriptive/skill", "version": "0.1.0", - "description": "The Xpecs Agent Skill — UI specs, traits, design tokens, and the responsive vocabulary compiled into a reference an AI coding agent loads to implement UI to the contracts.", + "description": "The Prescriptive Agent Skill — UI specs, traits, design tokens, and the responsive vocabulary compiled into a reference an AI coding agent loads to implement UI to the contracts.", "license": "MIT", "author": "brnrdog", "keywords": [ @@ -25,7 +25,7 @@ }, "repository": { "type": "git", - "url": "https://github.com/brnrdog/ux-archetypes", + "url": "https://github.com/brnrdog/prescriptive", "directory": "skill" }, "publishConfig": { diff --git a/skill/reference/themes.json b/skill/reference/themes.json index 228bd82..d017ebe 100644 --- a/skill/reference/themes.json +++ b/skill/reference/themes.json @@ -1,5 +1,5 @@ { - "$description": "Named theme presets for the Xpecs tokens. A theme carries the palette identity (accent, status, radius, font, and a light-mode tint of the neutral ramp) as a map of token paths to values. `modes` are orthogonal light/dark variants applied on top of any theme: `dark` inverts the neutral ramp so surfaces go dark and text light, while the theme's accent/status/radius/font are preserved. `swatches` are representative colors for a preview chip. Consumed by the website (see website/scripts/generate-themes.mjs) and by any tool that wants ready-made themes.", + "$description": "Named theme presets for the Prescriptive tokens. A theme carries the palette identity (accent, status, radius, font, and a light-mode tint of the neutral ramp) as a map of token paths to values. `modes` are orthogonal light/dark variants applied on top of any theme: `dark` inverts the neutral ramp so surfaces go dark and text light, while the theme's accent/status/radius/font are preserved. `swatches` are representative colors for a preview chip. Consumed by the website (see website/scripts/generate-themes.mjs) and by any tool that wants ready-made themes.", "modes": { "dark": { "color.neutral.0": "#100f0d", diff --git a/skill/reference/tokens.json b/skill/reference/tokens.json index 4d78d52..6df4553 100644 --- a/skill/reference/tokens.json +++ b/skill/reference/tokens.json @@ -1,5 +1,5 @@ { - "$description": "Xpecs design tokens — a technology-agnostic, monochrome baseline in the W3C Design Tokens (DTCG) format. Projects consume these directly or map them onto their own theme (see website/ for a Tailwind mapping). Aliases use the {group.token} reference syntax.", + "$description": "Prescriptive design tokens — a technology-agnostic, monochrome baseline in the W3C Design Tokens (DTCG) format. Projects consume these directly or map them onto their own theme (see website/ for a Tailwind mapping). Aliases use the {group.token} reference syntax.", "color": { "$type": "color", "neutral": { diff --git a/tokens/themes.json b/tokens/themes.json index 228bd82..d017ebe 100644 --- a/tokens/themes.json +++ b/tokens/themes.json @@ -1,5 +1,5 @@ { - "$description": "Named theme presets for the Xpecs tokens. A theme carries the palette identity (accent, status, radius, font, and a light-mode tint of the neutral ramp) as a map of token paths to values. `modes` are orthogonal light/dark variants applied on top of any theme: `dark` inverts the neutral ramp so surfaces go dark and text light, while the theme's accent/status/radius/font are preserved. `swatches` are representative colors for a preview chip. Consumed by the website (see website/scripts/generate-themes.mjs) and by any tool that wants ready-made themes.", + "$description": "Named theme presets for the Prescriptive tokens. A theme carries the palette identity (accent, status, radius, font, and a light-mode tint of the neutral ramp) as a map of token paths to values. `modes` are orthogonal light/dark variants applied on top of any theme: `dark` inverts the neutral ramp so surfaces go dark and text light, while the theme's accent/status/radius/font are preserved. `swatches` are representative colors for a preview chip. Consumed by the website (see website/scripts/generate-themes.mjs) and by any tool that wants ready-made themes.", "modes": { "dark": { "color.neutral.0": "#100f0d", diff --git a/tokens/tokens.json b/tokens/tokens.json index ea6b5e7..22955b1 100644 --- a/tokens/tokens.json +++ b/tokens/tokens.json @@ -1,5 +1,5 @@ { - "$description": "Xpecs design tokens — a technology-agnostic, monochrome baseline in the W3C Design Tokens (DTCG) format. Projects consume these directly or map them onto their own theme (see website/ for a Tailwind mapping). Aliases use the {group.token} reference syntax.", + "$description": "Prescriptive design tokens — a technology-agnostic, monochrome baseline in the W3C Design Tokens (DTCG) format. Projects consume these directly or map them onto their own theme (see website/ for a Tailwind mapping). Aliases use the {group.token} reference syntax.", "color": { "$type": "color", "neutral": { diff --git a/website/README.md b/website/README.md index ac672dd..8d3ce1d 100644 --- a/website/README.md +++ b/website/README.md @@ -1,4 +1,4 @@ -# Xpecs — Website +# Prescriptive — Website An interactive catalogue for the specs in this repository. Browse every spec in the sidebar and see a **live implementation rendered with @@ -107,14 +107,14 @@ SPA fallback and `.nojekyll`, and publishes `website/dist`. live at: ``` -https://brnrdog.github.io/ux-archetypes/ +https://brnrdog.github.io/prescriptive/ ``` Notes: - The build injects the base path; `Router.init(~basePath=…)` reads Vite's `BASE_URL`, so client-side routing and deep links resolve under the subpath. -- Deep links (e.g. `/ux-archetypes/a/button`) are served through `404.html` +- Deep links (e.g. `/prescriptive/a/button`) are served through `404.html` (a copy of `index.html`), which boots the app and lets the router take over — the standard SPA pattern for a static host. - For a custom domain / user site served from `/`, no base is needed; the same diff --git a/website/index.html b/website/index.html index e317b98..16aa959 100644 --- a/website/index.html +++ b/website/index.html @@ -7,7 +7,7 @@ rel="icon" href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Crect width='100' height='100' rx='20' fill='%23171717'/%3E%3Ctext x='50' y='72' font-size='64' font-family='sans-serif' font-weight='700' text-anchor='middle' fill='white'%3EU%3C/text%3E%3C/svg%3E" /> - Xpecs + Prescriptive diff --git a/website/package.json b/website/package.json index 7235a81..c070eb3 100644 --- a/website/package.json +++ b/website/package.json @@ -1,5 +1,5 @@ { - "name": "xpecs-website", + "name": "prescriptive-website", "version": "0.1.0", "private": true, "type": "module", diff --git a/website/rescript.json b/website/rescript.json index 04d4336..efe8be7 100644 --- a/website/rescript.json +++ b/website/rescript.json @@ -1,5 +1,5 @@ { - "name": "xpecs-website", + "name": "prescriptive-website", "sources": [ { "dir": "src", diff --git a/website/src/App.res b/website/src/App.res index cedb147..c2aeb56 100644 --- a/website/src/App.res +++ b/website/src/App.res @@ -12,7 +12,7 @@ let traitById = id => TraitsData.all->Array.find(t => t.id == id) let specsWithTrait = tid => all->Array.filter(a => a.traits->Array.includes(tid)) let layerPlural = layer => layer ++ "s" let docUrl = a => - "https://github.com/brnrdog/ux-archetypes/blob/main/specs/" ++ + "https://github.com/brnrdog/prescriptive/blob/main/specs/" ++ layerPlural(a.layer) ++ "/" ++ a.id ++ ".md" let matches = (a, q) => @@ -261,7 +261,7 @@ module Topbar = { "X" - +
@@ -506,7 +506,7 @@ module Guide = {
"Get started"

- "Xpecs" + "Prescriptive"

@@ -521,7 +521,7 @@ module Guide = {

- "Most UI is rebuilt from scratch on every project and every framework, and the accessibility and edge cases are reinvented (often incompletely) each time. Xpecs captures the durable part — what a pattern " + "Most UI is rebuilt from scratch on every project and every framework, and the accessibility and edge cases are reinvented (often incompletely) each time. Prescriptive captures the durable part — what a pattern " "is" @@ -590,9 +590,9 @@ module Guide = {

"2 · Consume"

"Install the package (" - "npm i xpecs" + "npm i prescriptive" ") to read the specs, tokens, and contracts in your build tooling — or add the bundled " - "Agent Skill" + "Agent Skill" " so an AI implements to the contracts for you."

"3 · Implement"

@@ -606,7 +606,7 @@ module Guide = { - + "GitHub" @@ -1009,7 +1009,7 @@ module Tokens = {

"The primitives every spec is built on — generated from the framework's " - + "tokens.json" ". Edit any value below and watch it cascade through the whole site — the theme is driven entirely by these. Changes persist locally." diff --git a/website/src/Main.res b/website/src/Main.res index 754e7e1..487044f 100644 --- a/website/src/Main.res +++ b/website/src/Main.res @@ -1,4 +1,4 @@ -// Vite injects the deploy base ("/" locally, "/ux-archetypes/" on Pages). +// Vite injects the deploy base ("/" locally, "/prescriptive/" on Pages). // The router uses it as its base path so client-side navigation and deep // links resolve correctly under a subpath. let baseUrl: string = %raw(`import.meta.env.BASE_URL`) diff --git a/website/src/reativa.bundle.js b/website/src/reativa.bundle.js index c8b29a2..f4f47ae 100644 --- a/website/src/reativa.bundle.js +++ b/website/src/reativa.bundle.js @@ -1,6 +1,6 @@ // PLACEHOLDER — not the real bundle. // -// The reativa (OCaml + Melange) Xpecs components live in the @prescriptive/reativa +// The reativa (OCaml + Melange) Prescriptive components live in the @prescriptive/reativa // package (packages/reativa/src/*.mlx). Building them needs the OCaml toolchain // (opam + melange), which isn't part of the ReScript/Vite website build, so this // checked-in stub keeps the site building and the "Reativa" tab present (showing diff --git a/website/src/styles.css b/website/src/styles.css index cf02170..6a29049 100644 --- a/website/src/styles.css +++ b/website/src/styles.css @@ -7,7 +7,7 @@ @import "./tokens.generated.css"; /* Scan the ReScript sources and their compiled output for class names — the - * website's own and the @xpecs/xote component library's, so classes used only + * website's own and the @prescriptive/xote component library's, so classes used only * inside a library component (border-status-*, …) still generate utilities. */ @source "./**/*.res"; @source "./**/*.res.mjs"; diff --git a/website/vite.config.js b/website/vite.config.js index 9657aff..532f640 100644 --- a/website/vite.config.js +++ b/website/vite.config.js @@ -2,7 +2,7 @@ import { defineConfig } from "vite"; import tailwindcss from "@tailwindcss/vite"; // On GitHub Pages a project site is served from "//", so the CI build -// sets BASE_PATH (e.g. "/ux-archetypes/"). Locally it defaults to "/". +// sets BASE_PATH (e.g. "/prescriptive/"). Locally it defaults to "/". const base = process.env.BASE_PATH || "/"; export default defineConfig({ From cc27d3615b6d42929e542c7eacc1b34a2b9c27cb Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 23 Jul 2026 21:19:39 +0000 Subject: [PATCH 4/4] Fix reativa build: build