adamantite 0.40.0 → 0.42.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -52,7 +52,6 @@ and agent guidance. After setup, use the scripts written to `package.json`:
52
52
  ```sh
53
53
  bun run check
54
54
  bun run fix
55
- bun run format
56
55
  bun run analyze
57
56
  ```
58
57
 
@@ -62,9 +61,7 @@ scripts:
62
61
  ```sh
63
62
  adamantite check
64
63
  adamantite fix
65
- adamantite format
66
64
  adamantite analyze
67
- adamantite monorepo
68
65
  ```
69
66
 
70
67
  ## Non-interactive setup
@@ -77,7 +74,6 @@ npx adamantite init \
77
74
  --non-interactive \
78
75
  --script check \
79
76
  --script fix \
80
- --script format \
81
77
  --script analyze \
82
78
  --preset react \
83
79
  --editor vscode \
@@ -89,19 +85,21 @@ npx adamantite init \
89
85
 
90
86
  Available setup values:
91
87
 
92
- - Scripts: `check`, `fix`, `format`, `analyze`, `check:monorepo`, and `fix:monorepo`.
93
- - Presets: `react`, `nextjs`, `vue`, `jest`, `vitest`, and `node`.
88
+ - Scripts: `check`, `fix`, and `analyze`. In a detected monorepo, `analyze` also installs
89
+ Sherif.
90
+ - Presets: `react`, `react-strict`, `react-doctor`, `nextjs`, `vue`, `jest`, `vitest`,
91
+ `node`, `strict`, `antislop`, and `shadcn`. `react-doctor` requires `react`.
94
92
  - Editors: `vscode` and `zed`.
95
93
 
96
94
  Presets and TypeScript require the `check` or `fix` script. Editor extension installation
97
- requires an editor. Monorepo scripts require a detected monorepo. GitHub Actions requires a
98
- compatible script and a supported package manager. Omitted boolean flags are disabled.
95
+ requires an editor. GitHub Actions requires a compatible script and a supported package
96
+ manager. Omitted boolean flags are disabled.
99
97
 
100
98
  Existing package scripts whose commands differ from Adamantite's are kept and reported
101
99
  instead of being replaced. The interactive initializer asks before overwriting them; in
102
100
  non-interactive mode, pass `--overwrite-scripts` to replace them. To keep custom flags,
103
101
  forward them to the Adamantite command after `--`, e.g.
104
- `adamantite monorepo -- --ignore-dependency tailwindcss`.
102
+ `adamantite analyze -- --directory packages/app`.
105
103
 
106
104
  In a detected monorepo, TypeScript setup does not write a root `tsconfig.json`, because a
107
105
  catch-all root config makes TypeScript treat all packages as one project. Adamantite
@@ -114,16 +112,24 @@ Run `adamantite --help` or `adamantite <command> --help` for the complete CLI re
114
112
 
115
113
  ### `adamantite check`
116
114
 
117
- Find lint and type errors without changing files:
115
+ Find formatting, lint, and type errors without changing files:
118
116
 
119
117
  ```sh
120
118
  adamantite check
121
119
  adamantite check src
122
120
  ```
123
121
 
122
+ Use `--only` to run one stage. Arguments after `--` go to that stage, and to Oxlint when
123
+ both run:
124
+
125
+ ```sh
126
+ adamantite check --only lint
127
+ adamantite check --only format
128
+ ```
129
+
124
130
  ### `adamantite fix`
125
131
 
126
- Apply safe Oxlint fixes. Suggested and dangerous fixes require explicit flags:
132
+ Apply safe Oxlint fixes, then format the files with Oxfmt. Suggested and dangerous fixes require explicit flags:
127
133
 
128
134
  ```sh
129
135
  adamantite fix
@@ -132,35 +138,47 @@ adamantite fix --dangerous
132
138
  adamantite fix --all
133
139
  ```
134
140
 
135
- ### `adamantite format`
136
-
137
- Format files with Oxfmt, or check formatting without writing:
141
+ Use `--only` to run one stage. Arguments after `--` go to that stage, and to Oxlint when
142
+ both run:
138
143
 
139
144
  ```sh
140
- adamantite format
141
- adamantite format src/index.ts
142
- adamantite format --check
145
+ adamantite fix --only lint
146
+ adamantite fix --only format
143
147
  ```
144
148
 
145
149
  ### `adamantite analyze`
146
150
 
147
- Find unused dependencies, exports, and files with Knip. The `--fix` option can remove
151
+ Find unused dependencies, exports, and files with Knip. In a detected monorepo, `analyze`
152
+ first finds dependency consistency problems with Sherif. The `--fix` option can remove
148
153
  unused files, so review its effect before use.
149
154
 
150
155
  ```sh
151
156
  adamantite analyze
152
157
  adamantite analyze --strict
153
158
  adamantite analyze --fix
159
+ adamantite analyze --only unused
160
+ adamantite analyze --only monorepo --fix -- --select highest
154
161
  ```
155
162
 
156
- ### `adamantite monorepo`
157
-
158
- Find dependency consistency problems in a monorepo with Sherif:
159
-
160
- ```sh
161
- adamantite monorepo
162
- adamantite monorepo --fix
163
- ```
163
+ - The `monorepo` stage (Sherif) runs first, and only in a detected monorepo. The `unused`
164
+ stage (Knip) always runs.
165
+ - Without `--fix`, both stages run and the exit code comes from the first failure. With
166
+ `--fix`, a Sherif failure skips Knip, because Knip must not remove code against a
167
+ dependency graph that Sherif did not repair.
168
+ - `--fix` applies to each stage that runs. `--strict` applies to Knip only.
169
+ - `--only monorepo` or `--only unused` runs one stage. `--only monorepo` fails outside a
170
+ monorepo and with `--strict`.
171
+ - Arguments after `--` go to Knip, or to the stage that `--only` selects.
172
+ - `analyze` runs Sherif without flags. Put project exceptions in the `sherif` field of the
173
+ root `package.json`, which Sherif reads. The keys are the Sherif CLI options in camelCase:
174
+ `ignoreDependency`, `ignoreRule`, `ignorePackage`, `select`, `noInstall`, and
175
+ `failOnWarnings`. For example: `"sherif": { "ignoreDependency": ["tailwindcss"] }`.
176
+ - A Sherif fix that must choose between versions prompts in a terminal. Without a terminal,
177
+ set `"sherif": { "select": "highest" }` in the root `package.json`, or run
178
+ `adamantite analyze --only monorepo --fix -- --select highest`.
179
+ - Use `--fix` locally, not in CI. Sherif refuses to fix in a CI environment (for example when
180
+ `CI` is set), so `analyze --fix` fails there in a monorepo. CI runs `adamantite analyze`
181
+ without `--fix`.
164
182
 
165
183
  ### `adamantite doctor`
166
184
 
@@ -173,15 +191,13 @@ adamantite doctor
173
191
 
174
192
  In an interactive terminal, Doctor presents each finding as formatted text and offers to
175
193
  hand off to an installed coding agent, or to copy one combined Markdown repair prompt. A
176
- handoff starts the selected agent CLI in the terminal with a short seed prompt; the agent
177
- runs `adamantite doctor` itself to read the findings and edits the project under its own
178
- permission and trust flow. When the agent session ends, Doctor reassesses and exits 0
179
- only when no findings remain. Doctor detects installed agents by probing each supported
180
- CLI — Claude Code (`claude`), Codex (`codex`), Cursor (`cursor-agent`), Gemini CLI
181
- (`gemini`), Grok Build (`grok`), and OpenCode (`opencode`) — and lists only the ones
182
- found on `PATH`. It warns before starting an agent on a working tree that is not known
183
- to be clean. OpenCode pre-fills its input with the seed prompt, so that handoff needs
184
- one Enter press to start.
194
+ handoff starts the selected agent CLI in the terminal seeded with that same Markdown
195
+ repair prompt; the agent edits the project under its own permission and trust flow. When
196
+ the agent session ends, Doctor reassesses and exits 0 only when no findings remain.
197
+ Doctor detects installed agents by probing each supported CLI — Claude Code (`claude`),
198
+ Codex (`codex`), Cursor (`cursor-agent`), Gemini CLI (`gemini`), Grok Build (`grok`),
199
+ and OpenCode (`opencode`) — and lists only the ones found on `PATH`. OpenCode pre-fills
200
+ its input with the seed prompt, so that handoff needs one Enter press to start.
185
201
 
186
202
  A coding agent can also run `adamantite doctor` in the target project to receive Markdown
187
203
  directly. In a non-interactive run, Doctor prints the combined repair prompt and exits 1
@@ -207,8 +223,7 @@ Commands that invoke Knip, Oxlint, Oxfmt, or Sherif forward arguments after `--`
207
223
  ```sh
208
224
  adamantite analyze --strict -- --directory packages/app
209
225
  adamantite check src -- --deny-warnings
210
- adamantite format -- --ignore-path .formatignore
211
- adamantite monorepo -- --ignore-package package-a
226
+ adamantite analyze --only monorepo -- --ignore-package package-a
212
227
  ```
213
228
 
214
229
  Package managers consume one separator, so package scripts need a second one:
@@ -225,19 +240,23 @@ underlying CLI.
225
240
 
226
241
  Adamantite publishes configuration that can also be consumed directly:
227
242
 
228
- | Export | Purpose |
229
- | -------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
230
- | `adamantite/lint` | Core Oxlint rules. |
231
- | `adamantite/lint/react` | React, JSX accessibility, and performance. |
232
- | `adamantite/lint/nextjs` | Next.js rules. |
233
- | `adamantite/lint/vue` | Vue rules. |
234
- | `adamantite/lint/node` | Node.js rules. |
235
- | `adamantite/lint/jest` | Jest rules. |
236
- | `adamantite/lint/vitest` | Vitest rules. |
237
- | `adamantite/lint/antislop` | Vendored [anti-slop](https://github.com/dmmulroy/anti-slop) rules that reject low-evidence, low-signal patterns. Also turns off `typescript/consistent-indexed-object-style` and `unicorn/no-immediate-mutation` from the core preset, which conflict with these rules. |
238
- | `adamantite/format` | Oxfmt configuration. |
239
- | `adamantite/analyze` | Knip configuration. |
240
- | `adamantite/typescript` | Strict TypeScript configuration for TS 7+. |
243
+ | Export | Purpose |
244
+ | ------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
245
+ | `adamantite/lint` | Core Oxlint rules. |
246
+ | `adamantite/lint/react` | React, JSX accessibility, and performance. |
247
+ | `adamantite/lint/react-strict` | Opinions for React feature code: no state, effect, or memoization hooks outside hook modules. See [the react-strict preset](#the-react-strict-preset). |
248
+ | `adamantite/lint/react-doctor` | Curated [React Doctor](https://github.com/millionco/react-doctor) rules for React state and effect misuse. See [the react-doctor preset](#the-react-doctor-preset). |
249
+ | `adamantite/lint/nextjs` | Next.js rules. |
250
+ | `adamantite/lint/vue` | Vue rules. |
251
+ | `adamantite/lint/node` | Node.js rules. |
252
+ | `adamantite/lint/jest` | Jest rules. |
253
+ | `adamantite/lint/vitest` | Vitest rules. |
254
+ | `adamantite/lint/strict` | Framework-neutral opinions: no deep or wide destructuring, and no type assertions outside tests. See [the strict preset](#the-strict-preset). |
255
+ | `adamantite/lint/antislop` | Vendored [anti-slop](https://github.com/dmmulroy/anti-slop) rules that reject low-evidence, low-signal patterns. Also turns off `typescript/consistent-indexed-object-style` and `unicorn/no-immediate-mutation` from the core preset, which conflict with these rules. |
256
+ | `adamantite/lint/shadcn` | [@shadcn/lint](https://github.com/shadcn-ui/lint) rules for Tailwind v4 design systems: no restyled components, raw colors, arbitrary values, inline styles, unknown classes, or unreadable class expressions. shadcn/ui is not required. See [the shadcn preset](#the-shadcn-preset). |
257
+ | `adamantite/format` | Oxfmt configuration. |
258
+ | `adamantite/analyze` | Knip configuration. The `ignoreDependencies` named export groups suggested ignore lists; `init` sets `ignoreDependencies.monorepo` in a monorepo. |
259
+ | `adamantite/typescript` | Strict TypeScript configuration for TS 7+. |
241
260
 
242
261
  When consuming the lint presets directly, hoist the core preset's ignore patterns onto the
243
262
  root config. Oxlint does not merge `ignorePatterns` from extended configs, so without the
@@ -256,17 +275,140 @@ export default defineConfig({
256
275
 
257
276
  Configs generated by `adamantite init` include this automatically.
258
277
 
278
+ ### The react-strict preset
279
+
280
+ `adamantite/lint/react-strict` keeps state and side effects out of React feature code. Use
281
+ it together with `adamantite/lint/react`. It needs no extra package: the rules come from
282
+ Adamantite's own Oxlint plugin, which ships inside the package.
283
+
284
+ `adamantite/no-react-state-hooks` reports calls to `useState`, `useReducer`, `useEffect`,
285
+ `useLayoutEffect`, `useSyncExternalStore`, `useMemo`, and `useCallback` imported from
286
+ `react`, including aliased imports and `React.useState(...)`. Each message tells what to do
287
+ instead: derive state from loader data or URL params, move side effects to loaders, actions,
288
+ or event handlers, and let the React Compiler memoize. For the opinions that do not depend
289
+ on React, add [the strict preset](#the-strict-preset).
290
+
291
+ Hooks stay allowed in hook modules: files that match `**/use[A-Z]*.{ts,tsx}`, `**/use-*.{ts,tsx}`, or `**/hooks/**`, such as `useCart.ts`
292
+ or `use-cart.ts`. A file such as `userProfile.tsx` is feature code.
293
+ Globs match paths relative to the working directory. Set `allow` to use another layout, and
294
+ `hooks` to change the list of reported hooks:
295
+
296
+ ```ts
297
+ import { defineConfig } from "oxlint"
298
+ import core from "adamantite/lint"
299
+ import react from "adamantite/lint/react"
300
+ import reactStrict from "adamantite/lint/react-strict"
301
+
302
+ export default defineConfig({
303
+ extends: [core, react, reactStrict],
304
+ ignorePatterns: core.ignorePatterns,
305
+ rules: {
306
+ "adamantite/no-react-state-hooks": [
307
+ "error",
308
+ { allow: ["src/state/**", "**/use[A-Z]*.{ts,tsx}"], hooks: ["useState", "useEffect"] },
309
+ ],
310
+ },
311
+ })
312
+ ```
313
+
314
+ Each option replaces its default list.
315
+
316
+ ### The react-doctor preset
317
+
318
+ `adamantite/lint/react-doctor` reports specific misuse of React state and effects. Use it
319
+ together with `adamantite/lint/react`. It needs the `oxlint-plugin-react-doctor` package.
320
+ `adamantite init` installs the pinned version when you select the preset, and
321
+ `adamantite doctor` and `adamantite update` keep it on that version. If you add the preset
322
+ by hand, install `oxlint-plugin-react-doctor` as a devDependency too.
323
+
324
+ The plugin exports more than 900 rules. The preset enables only rules that run on one file
325
+ and that the native `react`, `react-hooks`, `jsx-a11y`, and `unicorn` rules do not already
326
+ report. Examples are an effect that does the work of an event handler (`no-effect-event-handler`), data fetched in an effect
327
+ (`no-fetch-in-effect`), and state changed in place (`no-direct-state-mutation`). The
328
+ TanStack Query and TanStack Start rules are not in this preset. See
329
+ [ADR 0005](docs/adr/0005-curate-react-doctor-rules.md) for the criteria.
330
+
331
+ The preset works together with `adamantite/lint/react-strict`. React Doctor rules report
332
+ specific misuse, and `react-strict` bans the hooks in feature code. Some React Doctor rules
333
+ skip test files and fixtures by path, such as `__tests__/` and `*.test.tsx`.
334
+
335
+ `oxlint-plugin-react-doctor` has a modified MIT license. It needs written permission from
336
+ the copyright holder to use the software as machine learning training data, or to sell it
337
+ as a hosted product. Read the
338
+ [license](https://www.npmjs.com/package/oxlint-plugin-react-doctor?activeTab=code) before
339
+ you select the preset.
340
+
341
+ ### The strict preset
342
+
343
+ `adamantite/lint/strict` holds framework-neutral opinions. Use it with any other preset. Like
344
+ `react-strict`, it needs no extra package.
345
+
346
+ - `adamantite/no-overzealous-destructuring` reports destructuring patterns nested more than
347
+ `maxDepth` levels deep (default 2), such as `const { data: { user: { name } } } = query`,
348
+ and object patterns that take more than `maxProperties` properties (default 5). A rest
349
+ element does not count. Keep the object and read its members, or split the pattern.
350
+ - `typescript/consistent-type-assertions` bans type assertions. `as const` stays allowed,
351
+ and test files (`*.test.*`, `*.spec.*`, and `__tests__/`) keep the core preset's setting.
352
+
353
+ Set `maxDepth` and `maxProperties` to change the destructuring limits:
354
+
355
+ ```ts
356
+ import { defineConfig } from "oxlint"
357
+ import core from "adamantite/lint"
358
+ import strict from "adamantite/lint/strict"
359
+
360
+ export default defineConfig({
361
+ extends: [core, strict],
362
+ ignorePatterns: core.ignorePatterns,
363
+ rules: {
364
+ "adamantite/no-overzealous-destructuring": ["error", { maxDepth: 1, maxProperties: 3 }],
365
+ },
366
+ })
367
+ ```
368
+
369
+ ### The shadcn preset
370
+
371
+ `adamantite/lint/shadcn` needs Tailwind v4 and the `@shadcn/lint` package. `adamantite init`
372
+ installs the pinned version when you select the preset, and `adamantite doctor` and
373
+ `adamantite update` keep it on that version. If you add the preset by hand, install
374
+ `@shadcn/lint` as a devDependency too. The plugin finds your components and theme
375
+ through `components.json`. Without that file it looks for components in `components/ui`
376
+ or `src/components/ui` and discovers the stylesheet that imports Tailwind. When your
377
+ components live elsewhere, set `settings.shadcn.ui`:
378
+
379
+ ```ts
380
+ import { defineConfig } from "oxlint"
381
+ import core from "adamantite/lint"
382
+ import shadcn from "adamantite/lint/shadcn"
383
+
384
+ export default defineConfig({
385
+ extends: [core, shadcn],
386
+ ignorePatterns: core.ignorePatterns,
387
+ settings: { shadcn: { ui: "@/ds" } },
388
+ })
389
+ ```
390
+
391
+ The preset allows layout classes such as `mt-4` and `w-[320px]` on components, and turns
392
+ off `no-restyle`, `no-arbitrary-values`, and `require-static-classes` under
393
+ `**/components/ui/**`, where components own their appearance. Add the same override for
394
+ another component directory. See the
395
+ [@shadcn/lint documentation](https://github.com/shadcn-ui/lint#settings) for settings,
396
+ contracts, and custom messages.
397
+
259
398
  ## Requirements and boundaries
260
399
 
261
400
  - Adamantite requires Bun 1.0 or later when run with Bun, or Node.js 22.19 or later when
262
401
  run with Node.js.
402
+ - Adamantite requires TypeScript 7 or later. List `typescript` as a dependency in your own
403
+ `package.json`. Do not rely on the copy that a package manager installs for Adamantite's
404
+ peer dependency: npm cannot add or update a managed plugin such as `@shadcn/lint` in a
405
+ project that has no `typescript` entry of its own.
263
406
  - This repository uses pnpm and Node.js for development, but the CLI can configure
264
407
  projects that use Bun, Deno, npm, pnpm, or Yarn where the selected integration supports
265
408
  them.
266
409
  - Adamantite manages recognized package scripts and supported configuration shapes. It
267
410
  reports custom configurations that require manual work instead of overwriting them.
268
- - `fix`, `format`, `analyze --fix`, `monorepo --fix`, `init`, and `update` can change
269
- project files. Doctor is read-only.
411
+ - `fix`, `analyze --fix`, `init`, and `update` can change project files. Doctor is read-only.
270
412
 
271
413
  ## Agent skill
272
414