From 8d2c3184541fa867f6e5ffa8924463bedf5cb03e Mon Sep 17 00:00:00 2001 From: "dgesteves-release[bot]" <343266878+dgesteves-release[bot]@users.noreply.github.com> Date: Fri, 16 Oct 2026 09:42:25 +0000 Subject: [PATCH] chore: release --- .changeset/check-scope-and-summary.md | 11 ------ .changeset/codex-apply-patch-hook.md | 7 ---- .changeset/exclude-adds-to-defaults.md | 5 --- .changeset/exclude-one-scope.md | 7 ---- .changeset/init-registry-folders.md | 5 --- .changeset/installed-source-packages.md | 5 --- .changeset/registry-aware-zero-config.md | 7 ---- .changeset/rule-precision.md | 10 ----- CHANGELOG.md | 39 +++++++++++++++++++ package.json | 2 +- plugins/onsystem-agent/mcp.json | 2 +- plugins/onsystem-agent/plugin.json | 2 +- .../.cursor-plugin/plugin.json | 2 +- plugins/onsystem-cursor/mcp.json | 2 +- plugins/onsystem/.claude-plugin/plugin.json | 2 +- plugins/onsystem/.mcp.json | 2 +- plugins/onsystem/hooks/check-ui.mjs | 2 +- server.json | 4 +- 18 files changed, 49 insertions(+), 67 deletions(-) delete mode 100644 .changeset/check-scope-and-summary.md delete mode 100644 .changeset/codex-apply-patch-hook.md delete mode 100644 .changeset/exclude-adds-to-defaults.md delete mode 100644 .changeset/exclude-one-scope.md delete mode 100644 .changeset/init-registry-folders.md delete mode 100644 .changeset/installed-source-packages.md delete mode 100644 .changeset/registry-aware-zero-config.md delete mode 100644 .changeset/rule-precision.md diff --git a/.changeset/check-scope-and-summary.md b/.changeset/check-scope-and-summary.md deleted file mode 100644 index aafd7202..00000000 --- a/.changeset/check-scope-and-summary.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -'onsystem': minor ---- - -`check` and `check_ui` read only JS and TS files. A CSS, Markdown or JSON file named outright or matched by a glob, as `check $(git diff --name-only)`, lint-staged's `"*"` or `check "**/*"` passes them, was parsed as TSX and gave hundreds of syntax errors (209 for a shadcn/ui `app/globals.css`), so the run failed on files with no UI code in them. `check` now skips such a file and counts it in the summary line (`3 files that are not JS or TS skipped`). `check_ui` answers with an error for a `path` or `filename` that is not `.tsx`, `.jsx`, `.ts` or `.js` (or `.mts`, `.cts`, `.mjs`, `.cjs`): a `.vue` or `.css` file was checked as TSX before. - -`--require-design-system` also fails (exit code 2) when the folders and globs it is given leave no file to check, so CI cannot pass by checking nothing: a JavaScript app whose pages are `.js` files, a job that runs in a design-system package, whose files are all its own components, or a glob that matches only styles. Files named outright that are not JS or TS still pass with nothing to check. This can fail a job that passed before. - -Folders still stand for their `.tsx` and `.jsx` files, and `check` now names the `.js` files in them that have JSX (Next.js's JavaScript template writes `app/page.js`) with the command that checks them, such as `check . "**/*.js"`, in place of "no files match" for a folder of `.js` pages, and as the first line of the `--require-design-system` failure. In the GitHub Action, `paths: . **/*.js` checks them. - -A run with 50 findings or more ends, in the default output, with the count per rule and the ten Tailwind palette classes it found most, each with the token to use. `--format json`, `sarif` and `github` print the findings alone, as before. diff --git a/.changeset/codex-apply-patch-hook.md b/.changeset/codex-apply-patch-hook.md deleted file mode 100644 index 49406f95..00000000 --- a/.changeset/codex-apply-patch-hook.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -'onsystem': patch ---- - -The plugin's hook now checks edits in Codex. Codex installs the Claude Code plugin from the same marketplace and runs its hook on `apply_patch`, but the hook read only `tool_input.file_path`, and Codex puts the patch in `tool_input.command`, so every edit passed unchecked. The hook now reads the files a patch adds or updates from its `*** Add File:`, `*** Update File:` and `*** Move to:` lines, checks each `.tsx` or `.jsx` file in one run per project, and holds an updated file to the lines its hunks change, as it holds an Edit. It also reads the file from `path` or `filePath`, as other clients' tools name it, when the tool's input carries the text it wrote. Codex runs a plugin's hooks once you trust them in `/hooks`. - -`init`, run in a terminal, offers to add a short section to the project's `AGENTS.md` (create-next-app writes one) or `CLAUDE.md`: use the onsystem tools before writing UI, and run `check_ui`, or `npx -y onsystem check ` without the tools, on every UI file changed. It sits between `BEGIN:onsystem-agent-rules` and `END:onsystem-agent-rules` comment markers, which a later run updates in place. A `CLAUDE.md` that imports `AGENTS.md` is left alone, and `--yes` never writes it. diff --git a/.changeset/exclude-adds-to-defaults.md b/.changeset/exclude-adds-to-defaults.md deleted file mode 100644 index 1a604abb..00000000 --- a/.changeset/exclude-adds-to-defaults.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'onsystem': minor ---- - -`exclude` adds to the defaults instead of replacing them. A config whose `exclude` lists folders without repeating the defaults now also leaves out tests and stories (`*.test.tsx`, `*.stories.tsx`, `__tests__`, `__stories__` and `__mocks__` folders) and `.d.ts` files, which it checked before. To check one of them again, add the default with `!` in front (`"!**/*.{test,spec,stories}.{ts,tsx,js,jsx}"`), or pass `--include-tests` to check tests and stories for one run; a `!` pattern that names no default gets a warning. A design-system package's `exclude` adds to the defaults for finding its own components too. diff --git a/.changeset/exclude-one-scope.md b/.changeset/exclude-one-scope.md deleted file mode 100644 index 5220abc5..00000000 --- a/.changeset/exclude-one-scope.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -'onsystem': patch ---- - -`exclude` leaves out the same files everywhere. A folder in it (`app/legacy`, `app/legacy/`, `./app/legacy`, `app\legacy` or `**/legacy`) left out everything in it only for `check` in the project: `check .` at a monorepo root and the ESLint plugin matched it against each file's own path, so they still reported the folder's files, and a CI job at the root failed on code the team had excluded. Now all of them leave the folder out, and `check .` at the root reports what `check .` in each project does. Patterns are read the same way everywhere, with `*`, `**`, `?`, `{a,b}`, `[abc]` and `\` escapes: an unescaped Next.js route group (`app/(marketing)/**`) now matches that folder in a project too, and extglobs (`app/@(old|legacy)/**`), which only `check` in a project read before, match nothing. - -The Claude Code hook no longer blocks Claude on a file that `exclude` covers, tests and stories by default (`*.test.tsx`, `*.stories.tsx`) or a folder you list: it runs the new `check --skip-excluded`, which leaves such a file out even though it is named, and says so in the summary line. Without the flag, a file named outright is still checked whatever `exclude` says. With a project's own install from before this release, which does not know the flag, the hook checks the file as before. `check_ui` leaves out a `path` or `filename` that `exclude` covers, and says why in `skipped`; code without a `filename` is still checked. diff --git a/.changeset/init-registry-folders.md b/.changeset/init-registry-folders.md deleted file mode 100644 index db0c7553..00000000 --- a/.changeset/init-registry-folders.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'onsystem': patch ---- - -`init` in a shadcn/ui app now adds to `components`, next to `components/ui`, the folders `npx shadcn add` copies other registries' code into: for each registry in the `registries` of `components.json`, the folder of that name under the `components` alias (`@signoff-ui` → `components/signoff-ui`, `@ai-elements` → `components/ai-elements`). A folder with no `.tsx` or `.jsx` file yet is added too, and so is one that does not exist yet: a registry is often named in `components.json` before its first `shadcn add`, and an item of only `.ts` files, such as signoff-ui's `ag-ui`, makes the folder before a component lands in it. `check`, the Claude Code hook, the dry run and the baseline skip that code as they skip `components/ui`, so the next `shadcn add` no longer brings findings in registry files nobody edited, and the app's code is checked against every component those files export, helpers included. `init` names each folder it added, with a link to how to leave the helpers out or check that code as your own. When it cannot add them (`--components` given, or an `importPath` that names a package), it says that `check` reads that code as the app's own, and names the glob that sets it apart: for `components`, or, when the config imports its components by a package name, for an `overrides` entry that turns the rules off. Code a registry puts loose in `components/`, as React Bits does, is still checked as the app's. Configs written before are not changed. diff --git a/.changeset/installed-source-packages.md b/.changeset/installed-source-packages.md deleted file mode 100644 index c0318fde..00000000 --- a/.changeset/installed-source-packages.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'onsystem': minor ---- - -Zero config now reads a design-system package installed from a registry when it is named like one (`@acme/ui`, `@acme/design-system`) and its `exports` point at the `.tsx` or `.jsx` sources it publishes, directly or through barrels, as it reads a workspace package, with no config in the app or the package. Before, such an app got no components and no tokens: a package that publishes `src/`, such as one whose `exports` point at `./src/index.ts`, was skipped as compiled. Its exported stylesheets are its tokens, with the ones of the package they `@import`, and an app stylesheet's `@import "@acme/ui/globals.css"` is followed into `node_modules` when the app's config names no `tokens`. Other installed packages, such as `tailwindcss`, are not read. Its `exports` are read through the conditions an app resolves (`import`, `require`, `module-sync`, `node`, `module`, `browser`, `style`, `default`), and the first of them decides, for its components and its stylesheets alike, so a package whose `source` or `expo-source` condition points at `src/` before a `default` that points at its build, such as `@expo/ui` or one built with react-native-builder-bob, is not read either. Unlike in a workspace package, exports that point at `dist/` are not followed back to `src/`, and nothing compiled in the package is read (JavaScript, JSX or CSS in `dist/`, `build/`, `lib/`, `out/`, `esm/` or `cjs/`, or an export that points at JavaScript anywhere, such as `./index.js` or `./es/index.mjs`, whose re-exports are not followed), so a component kit named like a design system that publishes `src/` next to `dist/` for its source maps is not read as a second design system. With pnpm the package is read in `node_modules/.pnpm`, so the props its components take from their own dependencies resolve. A package whose `exports` point at build output is still not read, and `inspect --explain` now says why: `its exports point at build output (node_modules/@acme/ui/dist/index.mjs), not at component sources`, instead of calling every installed package compiled. An app whose own config leaves `components` unset now picks up such a package too. diff --git a/.changeset/registry-aware-zero-config.md b/.changeset/registry-aware-zero-config.md deleted file mode 100644 index 4b1612ef..00000000 --- a/.changeset/registry-aware-zero-config.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -'onsystem': minor ---- - -Zero config reads the folders `npx shadcn add` copies other registries' code into as read-only design systems, next to `components/ui`: for each registry in the `registries` of `components.json`, the folder of that name under the `components` alias (`@signoff-ui` → `components/signoff-ui`, `@ai-elements` → `components/ai-elements`). Before, that code was checked as the app's own: in VoltAgent's chatbot starter, which the corpus now checks, 11 of the 14 findings of `check .` were in `components/ai-elements`, and the next `shadcn add` could bring findings in registry files nobody edited, which failed `check` and the GitHub Action. Now `check`, the Claude Code hook, the ESLint plugin and the Action skip those files, as they skip `components/ui`; `search_components`, `get_component` and `list_components` find their components, and `get_component` says which registry one was installed from and that changes to it belong upstream; and the app's code is checked against them, so `` or `` is a finding, and so is an icon-only registry button without a name. None of them is suggested in place of a native element, and the helpers in a folder's `lib/` (signoff-ui's `Img` and icons) are left out of `list_components` and `search_components`. `inspect` names the folders on its `detected` line, and `inspect --explain` says why each was read or not. A folder is not read when the app's components come from a workspace package imported through its `exports`, and code a registry copies loose into `components/` is still checked as the app's. `init` names those folders on its "Found the design system" line instead of a note of its own. - -A config that lists such a folder in `components`, as `init` writes it, reads it the same way: its components are no longer suggested for native elements (signoff-ui's `Img` for an ``); map one in `elements` to have it suggested. A folder that `components.json` names in no `registries` entry is read as before. diff --git a/.changeset/rule-precision.md b/.changeset/rule-precision.md deleted file mode 100644 index b4675a53..00000000 --- a/.changeset/rule-precision.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -'onsystem': minor ---- - -`check`, `check_ui`, the hook and the ESLint plugin report more of the hardcoded styling agents write, so code that passed can get new findings: - -- `no-hardcoded-color` reports Tailwind's `white` and `black` (`bg-white`, `text-black`, `border-white`), which passed while `bg-[white]`, `style={{ color: "white" }}` and `fill="white"` were reported, so `bg-white dark:bg-zinc-900` had only its dark half fixed. They are fixed only to a token of exactly that color (`bg-white` → `bg-background` in a stock shadcn/ui theme), and suggested without a fix otherwise. A theme that defines `--color-white` or `--color-black` makes them its tokens, which are not reported. White or black text, fill or stroke is a warning without a fix, since its token depends on the surface under it. A hardcoded background (`bg-white`, `bg-zinc-900`, `bg-[#111]`) under hardcoded text that keeps no fix (white or black, `text-black/80`, or a color such as `text-neutral-800` held back as another shade), on it, inside it or inherited from around it, is not fixed to a token unless the text still stands out from it in every mode, by 0.25 of lightness or 3:1 contrast as it did on the hardcoded color: `bg-black text-white` would become `bg-primary text-white`, white on near white in dark mode, and `bg-white text-neutral-800` dark gray on near black. The message says to change the text with it (`text-primary-foreground`). Before, `bg-zinc-900 text-white` was fixed that way, and so was a palette background under palette text that keeps no fix. The text is not reported on a surface it stands out from in each mode it shows in: one its class list sets (shadcn/ui's `bg-destructive text-white`), its component's variants set, its `style` sets (a color swatch), or the nearest element around it sets. With an opacity modifier (`bg-black/50`, `border-white/10`) white and black are left alone, as they are inside an SVG ``. A palette color written as its CSS variable (`bg-[var(--color-green-50)]`) is reported as the palette class. -- Class strings are followed to where the same file keeps them: a `const` (`className={tone}`, `cn("p-4", extra)`), a key of a `const` object map (`className={statusStyles[status]}`), or what a function of the file returns (`className={toneOf(status)}`). A palette color in a status map passed as clean. A value from another file, a prop or a `let` is still not followed. -- `icon-button-accessible-name` checks an icon-only link that a button renders through `asChild` (``), which it skipped, and puts the label fix on the link. -- `no-hardcoded-spacing` and `no-hardcoded-radius` no longer fix a length in `em`: `px-[0.5em]` grows with the font, and was fixed to `px-2` with the message that it "is 8px, which is on the spacing scale". The nearest step is suggested without a fix. diff --git a/CHANGELOG.md b/CHANGELOG.md index 3f0f6bee..4ab48a20 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,44 @@ # onsystem (formerly @dgesteves/design-system-mcp) +## 0.8.0 + +### Minor Changes + +- [#180](https://github.com/dgesteves/onsystem/pull/180) [`9f40cac`](https://github.com/dgesteves/onsystem/commit/9f40cac3d68beae27b3474bbbac3f675cf32f114) - `check` and `check_ui` read only JS and TS files. A CSS, Markdown or JSON file named outright or matched by a glob, as `check $(git diff --name-only)`, lint-staged's `"*"` or `check "**/*"` passes them, was parsed as TSX and gave hundreds of syntax errors (209 for a shadcn/ui `app/globals.css`), so the run failed on files with no UI code in them. `check` now skips such a file and counts it in the summary line (`3 files that are not JS or TS skipped`). `check_ui` answers with an error for a `path` or `filename` that is not `.tsx`, `.jsx`, `.ts` or `.js` (or `.mts`, `.cts`, `.mjs`, `.cjs`): a `.vue` or `.css` file was checked as TSX before. + + `--require-design-system` also fails (exit code 2) when the folders and globs it is given leave no file to check, so CI cannot pass by checking nothing: a JavaScript app whose pages are `.js` files, a job that runs in a design-system package, whose files are all its own components, or a glob that matches only styles. Files named outright that are not JS or TS still pass with nothing to check. This can fail a job that passed before. + + Folders still stand for their `.tsx` and `.jsx` files, and `check` now names the `.js` files in them that have JSX (Next.js's JavaScript template writes `app/page.js`) with the command that checks them, such as `check . "**/*.js"`, in place of "no files match" for a folder of `.js` pages, and as the first line of the `--require-design-system` failure. In the GitHub Action, `paths: . **/*.js` checks them. + + A run with 50 findings or more ends, in the default output, with the count per rule and the ten Tailwind palette classes it found most, each with the token to use. `--format json`, `sarif` and `github` print the findings alone, as before. + +- [#183](https://github.com/dgesteves/onsystem/pull/183) [`7159b5b`](https://github.com/dgesteves/onsystem/commit/7159b5bf65dc4d5a097f52db535ecb2eaeccc377) - `exclude` adds to the defaults instead of replacing them. A config whose `exclude` lists folders without repeating the defaults now also leaves out tests and stories (`*.test.tsx`, `*.stories.tsx`, `__tests__`, `__stories__` and `__mocks__` folders) and `.d.ts` files, which it checked before. To check one of them again, add the default with `!` in front (`"!**/*.{test,spec,stories}.{ts,tsx,js,jsx}"`), or pass `--include-tests` to check tests and stories for one run; a `!` pattern that names no default gets a warning. A design-system package's `exclude` adds to the defaults for finding its own components too. + +- [#176](https://github.com/dgesteves/onsystem/pull/176) [`e7335d8`](https://github.com/dgesteves/onsystem/commit/e7335d80e6e98c52fab78a7dc883daa9a38428c2) - Zero config now reads a design-system package installed from a registry when it is named like one (`@acme/ui`, `@acme/design-system`) and its `exports` point at the `.tsx` or `.jsx` sources it publishes, directly or through barrels, as it reads a workspace package, with no config in the app or the package. Before, such an app got no components and no tokens: a package that publishes `src/`, such as one whose `exports` point at `./src/index.ts`, was skipped as compiled. Its exported stylesheets are its tokens, with the ones of the package they `@import`, and an app stylesheet's `@import "@acme/ui/globals.css"` is followed into `node_modules` when the app's config names no `tokens`. Other installed packages, such as `tailwindcss`, are not read. Its `exports` are read through the conditions an app resolves (`import`, `require`, `module-sync`, `node`, `module`, `browser`, `style`, `default`), and the first of them decides, for its components and its stylesheets alike, so a package whose `source` or `expo-source` condition points at `src/` before a `default` that points at its build, such as `@expo/ui` or one built with react-native-builder-bob, is not read either. Unlike in a workspace package, exports that point at `dist/` are not followed back to `src/`, and nothing compiled in the package is read (JavaScript, JSX or CSS in `dist/`, `build/`, `lib/`, `out/`, `esm/` or `cjs/`, or an export that points at JavaScript anywhere, such as `./index.js` or `./es/index.mjs`, whose re-exports are not followed), so a component kit named like a design system that publishes `src/` next to `dist/` for its source maps is not read as a second design system. With pnpm the package is read in `node_modules/.pnpm`, so the props its components take from their own dependencies resolve. A package whose `exports` point at build output is still not read, and `inspect --explain` now says why: `its exports point at build output (node_modules/@acme/ui/dist/index.mjs), not at component sources`, instead of calling every installed package compiled. An app whose own config leaves `components` unset now picks up such a package too. + +- [#183](https://github.com/dgesteves/onsystem/pull/183) [`83a40a0`](https://github.com/dgesteves/onsystem/commit/83a40a00510e051c793a92146e885b94e5be39b6) - Zero config reads the folders `npx shadcn add` copies other registries' code into as read-only design systems, next to `components/ui`: for each registry in the `registries` of `components.json`, the folder of that name under the `components` alias (`@signoff-ui` → `components/signoff-ui`, `@ai-elements` → `components/ai-elements`). Before, that code was checked as the app's own: in VoltAgent's chatbot starter, which the corpus now checks, 11 of the 14 findings of `check .` were in `components/ai-elements`, and the next `shadcn add` could bring findings in registry files nobody edited, which failed `check` and the GitHub Action. Now `check`, the Claude Code hook, the ESLint plugin and the Action skip those files, as they skip `components/ui`; `search_components`, `get_component` and `list_components` find their components, and `get_component` says which registry one was installed from and that changes to it belong upstream; and the app's code is checked against them, so `` or `` is a finding, and so is an icon-only registry button without a name. None of them is suggested in place of a native element, and the helpers in a folder's `lib/` (signoff-ui's `Img` and icons) are left out of `list_components` and `search_components`. `inspect` names the folders on its `detected` line, and `inspect --explain` says why each was read or not. A folder is not read when the app's components come from a workspace package imported through its `exports`, and code a registry copies loose into `components/` is still checked as the app's. `init` names those folders on its "Found the design system" line instead of a note of its own. + + A config that lists such a folder in `components`, as `init` writes it, reads it the same way: its components are no longer suggested for native elements (signoff-ui's `Img` for an ``); map one in `elements` to have it suggested. A folder that `components.json` names in no `registries` entry is read as before. + +- [#174](https://github.com/dgesteves/onsystem/pull/174) [`005d204`](https://github.com/dgesteves/onsystem/commit/005d2048d28a48d3c581e6f3ac39c9fd3a0e876e) - `check`, `check_ui`, the hook and the ESLint plugin report more of the hardcoded styling agents write, so code that passed can get new findings: + + - `no-hardcoded-color` reports Tailwind's `white` and `black` (`bg-white`, `text-black`, `border-white`), which passed while `bg-[white]`, `style={{ color: "white" }}` and `fill="white"` were reported, so `bg-white dark:bg-zinc-900` had only its dark half fixed. They are fixed only to a token of exactly that color (`bg-white` → `bg-background` in a stock shadcn/ui theme), and suggested without a fix otherwise. A theme that defines `--color-white` or `--color-black` makes them its tokens, which are not reported. White or black text, fill or stroke is a warning without a fix, since its token depends on the surface under it. A hardcoded background (`bg-white`, `bg-zinc-900`, `bg-[[#111](https://github.com/dgesteves/onsystem/issues/111)]`) under hardcoded text that keeps no fix (white or black, `text-black/80`, or a color such as `text-neutral-800` held back as another shade), on it, inside it or inherited from around it, is not fixed to a token unless the text still stands out from it in every mode, by 0.25 of lightness or 3:1 contrast as it did on the hardcoded color: `bg-black text-white` would become `bg-primary text-white`, white on near white in dark mode, and `bg-white text-neutral-800` dark gray on near black. The message says to change the text with it (`text-primary-foreground`). Before, `bg-zinc-900 text-white` was fixed that way, and so was a palette background under palette text that keeps no fix. The text is not reported on a surface it stands out from in each mode it shows in: one its class list sets (shadcn/ui's `bg-destructive text-white`), its component's variants set, its `style` sets (a color swatch), or the nearest element around it sets. With an opacity modifier (`bg-black/50`, `border-white/10`) white and black are left alone, as they are inside an SVG ``. A palette color written as its CSS variable (`bg-[var(--color-green-50)]`) is reported as the palette class. + - Class strings are followed to where the same file keeps them: a `const` (`className={tone}`, `cn("p-4", extra)`), a key of a `const` object map (`className={statusStyles[status]}`), or what a function of the file returns (`className={toneOf(status)}`). A palette color in a status map passed as clean. A value from another file, a prop or a `let` is still not followed. + - `icon-button-accessible-name` checks an icon-only link that a button renders through `asChild` (``), which it skipped, and puts the label fix on the link. + - `no-hardcoded-spacing` and `no-hardcoded-radius` no longer fix a length in `em`: `px-[0.5em]` grows with the font, and was fixed to `px-2` with the message that it "is 8px, which is on the spacing scale". The nearest step is suggested without a fix. + +### Patch Changes + +- [#182](https://github.com/dgesteves/onsystem/pull/182) [`64a92cb`](https://github.com/dgesteves/onsystem/commit/64a92cb2669864c9c74e68d03b4528371ad1caca) - The plugin's hook now checks edits in Codex. Codex installs the Claude Code plugin from the same marketplace and runs its hook on `apply_patch`, but the hook read only `tool_input.file_path`, and Codex puts the patch in `tool_input.command`, so every edit passed unchecked. The hook now reads the files a patch adds or updates from its `*** Add File:`, `*** Update File:` and `*** Move to:` lines, checks each `.tsx` or `.jsx` file in one run per project, and holds an updated file to the lines its hunks change, as it holds an Edit. It also reads the file from `path` or `filePath`, as other clients' tools name it, when the tool's input carries the text it wrote. Codex runs a plugin's hooks once you trust them in `/hooks`. + + `init`, run in a terminal, offers to add a short section to the project's `AGENTS.md` (create-next-app writes one) or `CLAUDE.md`: use the onsystem tools before writing UI, and run `check_ui`, or `npx -y onsystem check ` without the tools, on every UI file changed. It sits between `BEGIN:onsystem-agent-rules` and `END:onsystem-agent-rules` comment markers, which a later run updates in place. A `CLAUDE.md` that imports `AGENTS.md` is left alone, and `--yes` never writes it. + +- [#175](https://github.com/dgesteves/onsystem/pull/175) [`d1b19d1`](https://github.com/dgesteves/onsystem/commit/d1b19d16787f860005a6a49d18872e3a0b5f19b7) - `exclude` leaves out the same files everywhere. A folder in it (`app/legacy`, `app/legacy/`, `./app/legacy`, `app\legacy` or `**/legacy`) left out everything in it only for `check` in the project: `check .` at a monorepo root and the ESLint plugin matched it against each file's own path, so they still reported the folder's files, and a CI job at the root failed on code the team had excluded. Now all of them leave the folder out, and `check .` at the root reports what `check .` in each project does. Patterns are read the same way everywhere, with `*`, `**`, `?`, `{a,b}`, `[abc]` and `\` escapes: an unescaped Next.js route group (`app/(marketing)/**`) now matches that folder in a project too, and extglobs (`app/@(old|legacy)/**`), which only `check` in a project read before, match nothing. + + The Claude Code hook no longer blocks Claude on a file that `exclude` covers, tests and stories by default (`*.test.tsx`, `*.stories.tsx`) or a folder you list: it runs the new `check --skip-excluded`, which leaves such a file out even though it is named, and says so in the summary line. Without the flag, a file named outright is still checked whatever `exclude` says. With a project's own install from before this release, which does not know the flag, the hook checks the file as before. `check_ui` leaves out a `path` or `filename` that `exclude` covers, and says why in `skipped`; code without a `filename` is still checked. + +- [#173](https://github.com/dgesteves/onsystem/pull/173) [`1817817`](https://github.com/dgesteves/onsystem/commit/1817817d6a1db6036d2a87c8bae040d3cab95fea) - `init` in a shadcn/ui app now adds to `components`, next to `components/ui`, the folders `npx shadcn add` copies other registries' code into: for each registry in the `registries` of `components.json`, the folder of that name under the `components` alias (`@signoff-ui` → `components/signoff-ui`, `@ai-elements` → `components/ai-elements`). A folder with no `.tsx` or `.jsx` file yet is added too, and so is one that does not exist yet: a registry is often named in `components.json` before its first `shadcn add`, and an item of only `.ts` files, such as signoff-ui's `ag-ui`, makes the folder before a component lands in it. `check`, the Claude Code hook, the dry run and the baseline skip that code as they skip `components/ui`, so the next `shadcn add` no longer brings findings in registry files nobody edited, and the app's code is checked against every component those files export, helpers included. `init` names each folder it added, with a link to how to leave the helpers out or check that code as your own. When it cannot add them (`--components` given, or an `importPath` that names a package), it says that `check` reads that code as the app's own, and names the glob that sets it apart: for `components`, or, when the config imports its components by a package name, for an `overrides` entry that turns the rules off. Code a registry puts loose in `components/`, as React Bits does, is still checked as the app's. Configs written before are not changed. + ## 0.7.0 ### Minor Changes diff --git a/package.json b/package.json index f95809a1..8652506c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "onsystem", - "version": "0.7.0", + "version": "0.8.0", "mcpName": "io.github.dgesteves/onsystem", "description": "Keeps coding agents on your design system: catches palette colors, native elements and APIs your system lacks, at every edit and pull request, with the fix. Set it up once in your design-system package; every app in your monorepo gets it.", "keywords": [ diff --git a/plugins/onsystem-agent/mcp.json b/plugins/onsystem-agent/mcp.json index c7c4c86f..35fd4b85 100644 --- a/plugins/onsystem-agent/mcp.json +++ b/plugins/onsystem-agent/mcp.json @@ -4,7 +4,7 @@ "onsystem": { "type": "stdio", "command": "npx", - "args": ["-y", "onsystem@0.7.0"] + "args": ["-y", "onsystem@0.8.0"] } } } diff --git a/plugins/onsystem-agent/plugin.json b/plugins/onsystem-agent/plugin.json index 7df8a189..66aa13fe 100644 --- a/plugins/onsystem-agent/plugin.json +++ b/plugins/onsystem-agent/plugin.json @@ -1,7 +1,7 @@ { "$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json", "name": "onsystem", - "version": "0.7.0", + "version": "0.8.0", "description": "Keeps coding agents on your design system: catches palette colors, native elements and APIs your system lacks, at every edit and pull request, with the fix. Set it up once in your design-system package; every app in your monorepo gets it.", "author": { "name": "Diogo Esteves", diff --git a/plugins/onsystem-cursor/.cursor-plugin/plugin.json b/plugins/onsystem-cursor/.cursor-plugin/plugin.json index 89d1f4ea..66d8d7e1 100644 --- a/plugins/onsystem-cursor/.cursor-plugin/plugin.json +++ b/plugins/onsystem-cursor/.cursor-plugin/plugin.json @@ -1,7 +1,7 @@ { "name": "onsystem", "displayName": "onsystem", - "version": "0.7.0", + "version": "0.8.0", "description": "Keeps coding agents on your design system: catches palette colors, native elements and APIs your system lacks, at every edit and pull request, with the fix. Set it up once in your design-system package; every app in your monorepo gets it.", "author": { "name": "Diogo Esteves" diff --git a/plugins/onsystem-cursor/mcp.json b/plugins/onsystem-cursor/mcp.json index 0b4a378a..42481613 100644 --- a/plugins/onsystem-cursor/mcp.json +++ b/plugins/onsystem-cursor/mcp.json @@ -2,7 +2,7 @@ "mcpServers": { "onsystem": { "command": "npx", - "args": ["-y", "onsystem@0.7.0"] + "args": ["-y", "onsystem@0.8.0"] } } } diff --git a/plugins/onsystem/.claude-plugin/plugin.json b/plugins/onsystem/.claude-plugin/plugin.json index 7087e179..f220a3a3 100644 --- a/plugins/onsystem/.claude-plugin/plugin.json +++ b/plugins/onsystem/.claude-plugin/plugin.json @@ -1,7 +1,7 @@ { "name": "onsystem", "displayName": "onsystem", - "version": "0.7.0", + "version": "0.8.0", "description": "Keeps coding agents on your design system: catches palette colors, native elements and APIs your system lacks, at every edit and pull request, with the fix. Set it up once in your design-system package; every app in your monorepo gets it.", "author": { "name": "Diogo Esteves", diff --git a/plugins/onsystem/.mcp.json b/plugins/onsystem/.mcp.json index 0b4a378a..42481613 100644 --- a/plugins/onsystem/.mcp.json +++ b/plugins/onsystem/.mcp.json @@ -2,7 +2,7 @@ "mcpServers": { "onsystem": { "command": "npx", - "args": ["-y", "onsystem@0.7.0"] + "args": ["-y", "onsystem@0.8.0"] } } } diff --git a/plugins/onsystem/hooks/check-ui.mjs b/plugins/onsystem/hooks/check-ui.mjs index a281c295..2dcbac6e 100644 --- a/plugins/onsystem/hooks/check-ui.mjs +++ b/plugins/onsystem/hooks/check-ui.mjs @@ -61,7 +61,7 @@ import path from 'node:path'; const PACKAGE = 'onsystem'; // The exact release this plugin runs; scripts/sync-versions.mjs sets it with each release. -const VERSION = '0.7.0'; +const VERSION = '0.8.0'; const UI_FILE = /\.[jt]sx$/i; const MAX_FINDINGS = 30; // Both runs together, within the 60 seconds hooks.json gives the hook. Tests shorten it. diff --git a/server.json b/server.json index 55dedb3d..4cdfc8fd 100644 --- a/server.json +++ b/server.json @@ -20,12 +20,12 @@ "sizes": ["180x180"] } ], - "version": "0.7.0", + "version": "0.8.0", "packages": [ { "registryType": "npm", "identifier": "onsystem", - "version": "0.7.0", + "version": "0.8.0", "transport": { "type": "stdio" }