From e02011905a243a87676937a8dbcdfe2e8b6671cc Mon Sep 17 00:00:00 2001 From: tegwick Date: Sat, 27 Jun 2026 15:15:47 +0200 Subject: [PATCH] feat(publish): make package installable from Gitea npm registry (WHYNOT-WP-0003 T02) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - package.json: private:false; real repository.url; publishConfig.registry → coulomb Gitea npm; lit dependency → peerDependency (^3) + devDependency; ship the ir/ consumer contract (files + ./ir/* export); add PUBLISHING.md to files. - .npmrc: real @whynot scope registry + ${NPM_AUTH_TOKEN} ref (no secret committed). - PUBLISHING.md: publish flow, token routing (operator/OpenBao — warden route is not in this CLI), and consumer install. - README: registry-install path + lit peer note. CHANGELOG: Added/Changed entries. Config + packaging validated via `npm pack --dry-run` (ir/, tokens, CSS, PUBLISHING.md included; .npmrc excluded). Actual `npm publish` + install-verify is gated on a Gitea NPM_AUTH_TOKEN (operator-owned) and an explicit outward-publish go-ahead. Co-Authored-By: Claude Opus 4.8 --- .npmrc | 11 ++-- CHANGELOG.md | 14 +++++ PUBLISHING.md | 55 +++++++++++++++++++ README.md | 12 +++- package.json | 17 ++++-- .../WHYNOT-WP-0003-downstream-consumption.md | 2 +- 6 files changed, 99 insertions(+), 12 deletions(-) create mode 100644 PUBLISHING.md diff --git a/.npmrc b/.npmrc index 3e48c85..8c0c82b 100644 --- a/.npmrc +++ b/.npmrc @@ -1,5 +1,6 @@ -# When ready to publish to Gitea Packages, uncomment and set NPM_AUTH_TOKEN -# in your shell or CI secrets. -# -# @whynot:registry=https://gitea.example.com/api/packages/whynot/npm/ -# //gitea.example.com/api/packages/whynot/npm/:_authToken=${NPM_AUTH_TOKEN} +# @whynot/* is published to and installed from the coulomb Gitea npm registry. +# The auth token is NOT stored here — set NPM_AUTH_TOKEN in your shell/CI. +# It is operator/OpenBao-owned (credential-routing.md: tokens route, never vend); +# obtain a Gitea package token from the operator. Publish flow: see PUBLISHING.md. +@whynot:registry=https://gitea.coulomb.social/api/packages/coulomb/npm/ +//gitea.coulomb.social/api/packages/coulomb/npm/:_authToken=${NPM_AUTH_TOKEN} diff --git a/CHANGELOG.md b/CHANGELOG.md index 06f77d1..79bfb6a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,20 @@ Format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). Version ## [Unreleased] +### Added + +- **Publishable to the coulomb Gitea npm registry** (WHYNOT-WP-0003 T02) — `private:false`, + `publishConfig.registry`, real `repository.url`, an `.npmrc` scope + `${NPM_AUTH_TOKEN}` + reference (no secret committed), and `PUBLISHING.md` (publish flow + consumer install + + token routing). The package now ships the `ir/` consumer contract (added to `files` and + the `./ir/*` export) so consumers can pin a version and track it. + +### Changed + +- **`lit` is now a `peerDependency`** (`^3`), not a direct dependency. Consumers must + install `lit` alongside `@whynot/design` (`npm i @whynot/design lit`) so their bundler + dedupes to a single `lit` instance. + ## [0.3.0] — 2026-06-27 ### Added diff --git a/PUBLISHING.md b/PUBLISHING.md new file mode 100644 index 0000000..08743cd --- /dev/null +++ b/PUBLISHING.md @@ -0,0 +1,55 @@ +# Publishing `@whynot/design` + +`@whynot/design` is published to the **coulomb Gitea npm registry** so consuming +repos can pin a version (`npm i @whynot/design@x.y.z`) and track it at their own pace +(WHYNOT-WP-0003). The git tag cut by `make release` (see `DesignSystemIntroduction.md` +§6) is the version; publishing makes that version installable. + +- Registry: `https://gitea.coulomb.social/api/packages/coulomb/npm/` +- `package.json` `publishConfig.registry` already points `npm publish` here. +- `lit` is a **peerDependency** — consumers install it themselves so their bundler + dedupes to a single `lit` instance. + +## The token (never commit it) + +Publishing and installing `@whynot/*` need a Gitea package token. It is **not stored in +this repo** — per `.claude/rules/credential-routing.md`, tokens are routed, not vended: +a Gitea package token is operator/OpenBao-owned (`railiance-platform`). Obtain one from +the operator and export it: + +```sh +export NPM_AUTH_TOKEN=… # Gitea package token; never paste into git/chat/logs +``` + +`.npmrc` (committed) references it via `${NPM_AUTH_TOKEN}` — no secret lives in the file. + +## Publish (maintainer) + +```sh +git checkout main && git pull --ff-only +make release VERSION=x.y.z # bumps, cuts CHANGELOG, commits, tags (§6) +git push --follow-tags origin main +npm publish # uses publishConfig.registry + NPM_AUTH_TOKEN +``` + +`npm publish` is **outward and immutable** — a published version cannot be silently +replaced. Confirm the tag and `npm pack --dry-run` contents first. + +## Install (consumer) + +Add an `.npmrc` to the consuming repo so the `@whynot` scope resolves to the registry, +then install the package plus the `lit` peer: + +```ini +# .npmrc +@whynot:registry=https://gitea.coulomb.social/api/packages/coulomb/npm/ +//gitea.coulomb.social/api/packages/coulomb/npm/:_authToken=${NPM_AUTH_TOKEN} +``` + +```sh +npm i @whynot/design@x.y.z lit +``` + +The installed package carries the consumer-facing contract under `ir/` (component +contracts, `tokens.json`, exemplars) reachable via the `./ir/*` export — that is what +the `drift` check (WHYNOT-WP-0003 T05) reads to report changes between versions. diff --git a/README.md b/README.md index a3bd39a..c872041 100644 --- a/README.md +++ b/README.md @@ -38,8 +38,18 @@ Framework-agnostic by design. Consumers do **not** re-implement components per f ### Node-tooled consumer (React, Vite, Next, Vue, …) +Install from the coulomb Gitea npm registry (add the scope to your `.npmrc` first — see +[`PUBLISHING.md`](./PUBLISHING.md) for the token). `lit` is a peer dependency: + +```ini +# .npmrc +@whynot:registry=https://gitea.coulomb.social/api/packages/coulomb/npm/ +//gitea.coulomb.social/api/packages/coulomb/npm/:_authToken=${NPM_AUTH_TOKEN} +``` + ```sh -pnpm add git+ssh://git@gitea.coulomb.social/coulomb/whynot-design.git#v0.3.0 +npm i @whynot/design@v0.3.0 lit +# or pin straight from git: pnpm add git+ssh://git@gitea.coulomb.social/coulomb/whynot-design.git#v0.3.0 ``` ```js diff --git a/package.json b/package.json index 4ff572e..88f149d 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "@whynot/design", "version": "0.3.0", "description": "The neutral, mostly-black-and-white visual language for whynot — prototype cards, signal records, beta plans, decision documents, and any other deliberately-unfinished artefact. Ships tokens, CSS, and Lit-based web components consumable from React, Django, Vue, plain HTML, or anywhere a custom element runs.", - "private": true, + "private": false, "type": "module", "main": "./src/index.js", "module": "./src/index.js", @@ -21,17 +21,20 @@ "./tokens/type": "./tokens/type.json", "./tokens/spacing": "./tokens/spacing.json", "./adapters/django": "./adapters/django/README.md", + "./ir/*": "./ir/*", "./assets/*": "./assets/*", "./skill": "./SKILL.md" }, "files": [ "src", "tokens", + "ir", "assets", "adapters", "SKILL.md", "DesignSystemIntroduction.md", "MultiFrameworkSupport.md", + "PUBLISHING.md", "README.md", "CHANGELOG.md" ], @@ -47,16 +50,20 @@ "showcase": "npx --yes serve -l 4321 .", "example": "npx --yes serve -l 4322 examples/whynot-control" }, - "dependencies": { - "lit": "^3.2.1" + "peerDependencies": { + "lit": "^3" }, "devDependencies": { - "@playwright/test": "^1.45.0" + "@playwright/test": "^1.45.0", + "lit": "^3.2.1" }, "keywords": ["whynot", "design-system", "wireframe", "prototype", "lit", "web-components", "django", "react"], "repository": { "type": "git", - "url": "git+ssh://git@gitea.example.com/whynot/whynot-design.git" + "url": "git+ssh://git@gitea.coulomb.social/coulomb/whynot-design.git" + }, + "publishConfig": { + "registry": "https://gitea.coulomb.social/api/packages/coulomb/npm/" }, "license": "UNLICENSED" } diff --git a/workplans/WHYNOT-WP-0003-downstream-consumption.md b/workplans/WHYNOT-WP-0003-downstream-consumption.md index 274509d..3994c8b 100644 --- a/workplans/WHYNOT-WP-0003-downstream-consumption.md +++ b/workplans/WHYNOT-WP-0003-downstream-consumption.md @@ -100,7 +100,7 @@ tagged. Tag the current state as the first real anchor. ```task id: WHYNOT-WP-0003-T02 -status: todo +status: wait priority: high state_hub_task_id: "dbd3a2e6-0623-4efd-8293-399002e85ea2" ```