adamantite 0.41.0 → 0.43.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.
Files changed (39) hide show
  1. package/README.md +393 -35
  2. package/dist/index.js +47 -28
  3. package/dist/presets/analyze.d.ts +6 -2
  4. package/dist/presets/analyze.js +7 -1
  5. package/dist/presets/lint/core.d.ts +5 -3
  6. package/dist/presets/lint/core.js +1 -0
  7. package/dist/presets/lint/custom.d.ts +60 -0
  8. package/dist/presets/lint/custom.js +142 -0
  9. package/dist/presets/lint/effect.d.ts +5 -0
  10. package/dist/presets/lint/effect.js +106 -0
  11. package/dist/presets/lint/plugin/imports.d.ts +19 -0
  12. package/dist/presets/lint/plugin/imports.js +53 -0
  13. package/dist/presets/lint/plugin/index.d.ts +17 -0
  14. package/dist/presets/lint/plugin/index.js +20 -0
  15. package/dist/presets/lint/plugin/options.d.ts +11 -0
  16. package/dist/presets/lint/plugin/options.js +33 -0
  17. package/dist/presets/lint/plugin/rules/no-overzealous-destructuring.d.ts +5 -0
  18. package/dist/presets/lint/plugin/rules/no-overzealous-destructuring.js +92 -0
  19. package/dist/presets/lint/plugin/rules/no-query-data-in-state.d.ts +5 -0
  20. package/dist/presets/lint/plugin/rules/no-query-data-in-state.js +85 -0
  21. package/dist/presets/lint/plugin/rules/no-react-state-hooks.d.ts +10 -0
  22. package/dist/presets/lint/plugin/rules/no-react-state-hooks.js +128 -0
  23. package/dist/presets/lint/plugin/rules/query-from-loader.d.ts +5 -0
  24. package/dist/presets/lint/plugin/rules/query-from-loader.js +110 -0
  25. package/dist/presets/lint/react-doctor.d.ts +5 -0
  26. package/dist/presets/lint/react-doctor.js +20 -0
  27. package/dist/presets/lint/react-strict.d.ts +5 -0
  28. package/dist/presets/lint/react-strict.js +11 -0
  29. package/dist/presets/lint/shadcn.d.ts +5 -0
  30. package/dist/presets/lint/shadcn.js +22 -0
  31. package/dist/presets/lint/strict.d.ts +5 -0
  32. package/dist/presets/lint/strict.js +18 -0
  33. package/dist/presets/lint/tanstack.d.ts +5 -0
  34. package/dist/presets/lint/tanstack.js +14 -0
  35. package/dist/presets/lint/vendor/antislop/plugin.d.mts +18 -2
  36. package/dist/presets/rules/index.d.ts +9 -0
  37. package/dist/presets/rules/index.js +29 -0
  38. package/package.json +31 -22
  39. package/skills/adamantite/SKILL.md +105 -11
@@ -8,6 +8,7 @@ metadata:
8
8
  sources:
9
9
  - "adelrodriguez/adamantite:src/cli.ts"
10
10
  - "adelrodriguez/adamantite:src/commands/*.ts"
11
+ - "adelrodriguez/adamantite:src/lib/workspace/custom-rules.ts"
11
12
  ---
12
13
 
13
14
  # Adamantite
@@ -28,12 +29,66 @@ npx adamantite init --non-interactive --script check --script fix --typescript -
28
29
  Repeat `--script`, `--preset`, and `--editor` for multiple values. Available values are:
29
30
 
30
31
  - Scripts: `check`, `fix`, `analyze`. In a detected monorepo, `analyze` also installs Sherif.
31
- The legacy `check:monorepo` and `fix:monorepo` values are rejected.
32
- - Presets: `react`, `nextjs`, `vue`, `jest`, `vitest`, `node`, `antislop`; editors:
33
- `vscode`, `zed`
32
+ - Presets: `react`, `react-strict`, `react-doctor`, `tanstack`, `nextjs`, `vue`, `effect`, `jest`,
33
+ `vitest`, `node`, `strict`, `antislop`, `shadcn`;
34
+ editors: `vscode`, `zed`
34
35
  - Optional flags: `--typescript`, `--install-extensions`, `--github-actions`, `--agents`,
35
36
  `--overwrite-scripts`
36
37
 
38
+ The `react-strict` preset needs no extra package. Its `adamantite/no-react-state-hooks` rule
39
+ reports React state, effect, and memoization hooks outside hook modules (`useCart.ts`,
40
+ `use-cart.ts`, and files under `hooks/`), and each message tells what to do instead. Do not move a hook call into
41
+ a hook module only to silence the rule: follow the message. Set the rule's `allow` option
42
+ when the project keeps hooks elsewhere.
43
+
44
+ The `strict` preset needs no extra package either. Its `adamantite/no-overzealous-destructuring`
45
+ rule reports destructuring nested more than 2 levels deep or object patterns with more than 5
46
+ properties; keep the object and read its members, or split the pattern. Do not raise
47
+ `maxDepth` or `maxProperties` only to silence a report. The preset also bans type assertions
48
+ outside tests.
49
+
50
+ The `tanstack` preset needs no extra package. Its `adamantite/query-from-loader` rule reports
51
+ TanStack Query hooks in route files (files that call `createFileRoute`, `createRoute`, or another
52
+ route factory from `@tanstack/react-router`) that take a plain options object or a `queryOptions()` call made inside a
53
+ function; define the query once with `queryOptions()` at module scope or in an exported factory,
54
+ preload it in the route loader with `ensureQueryData()`, and pass the same options to the hook. For
55
+ `useInfiniteQuery` and `useSuspenseInfiniteQuery`, use `infiniteQueryOptions()` and
56
+ `ensureInfiniteQueryData()`. Its
57
+ `adamantite/no-query-data-in-state` rule reports `useState` initialized from query data; read the
58
+ value from the query result and keep only the user's edits in state. Do not wrap options in a
59
+ spread object, or move the hook out of the route file, only to silence `query-from-loader`.
60
+
61
+ The `react-doctor` preset requires the `react` preset and the `oxlint-plugin-react-doctor`
62
+ package, which `init` installs at a pinned version and doctor and `update` keep in sync. It
63
+ enables curated React Doctor rules for React state and effect misuse, such as
64
+ `no-effect-event-handler` and `no-fetch-in-effect`, and adds to `react-strict`. The package has
65
+ a modified MIT license: using it as machine learning training data or selling it as a
66
+ hosted product needs written permission from the copyright holder. Tell the user before you
67
+ select the preset.
68
+
69
+ The `effect` preset needs the `@effect/tsgo` package, which `init` installs at a pinned
70
+ version and doctor and `update` keep in sync. Its rules exist only in Oxlint binaries that
71
+ `adamantite prepare` patched, so the `prepare` script in `package.json` must run
72
+ `adamantite prepare`; without the patch, Oxlint stops with `Unknown plugin: 'effecttsgo'`.
73
+ Do not remove the patch or the preset to get past that error: run `adamantite prepare`. If a
74
+ production-only install fails at `adamantite prepare`, add `--ignore-scripts` to that
75
+ install instead of changing the script. `tsconfig.json` needs
76
+ `{ "name": "@effect/language-service", "diagnostics": false }` in `compilerOptions.plugins`,
77
+ and `knip.config.ts` needs `ignoreDependencies.effect`. To allow an unstable Effect module
78
+ on purpose, add it to `allowedUnstableApis` in that tsconfig entry. Do not turn off
79
+ `effecttsgo/unstable-api-usage`.
80
+
81
+ The `shadcn` preset needs Tailwind v4 and the `@shadcn/lint` package, which `init` installs
82
+ at a pinned version and doctor and `update` keep in sync. The plugin finds components and
83
+ the theme through `components.json`. Without that file it looks in `components/ui` or
84
+ `src/components/ui` and discovers the stylesheet that imports Tailwind; when components
85
+ live elsewhere, set `settings.shadcn` (for example `{ ui: "@/ds" }`) in `oxlint.config.ts`.
86
+ The preset turns off the component-owned rules under `**/components/ui/**`; add the same
87
+ override for another component directory.
88
+
89
+ Adamantite requires TypeScript 7 or later as a dependency in the project's own
90
+ `package.json`. Without that entry, npm cannot add or update a managed plugin.
91
+
37
92
  Only select options supported by the project. Presets and TypeScript require `check` or `fix`;
38
93
  extension installation requires an editor; `--github-actions` requires a CI-compatible script
39
94
  and a supported package manager (bun, deno, npm, pnpm, or yarn). Omitted boolean flags are
@@ -53,11 +108,10 @@ adamantite fix
53
108
  adamantite analyze
54
109
  ```
55
110
 
56
- - Use `check` for read-only formatting, lint, and type-error validation.
111
+ - Use `check` for read-only formatting, lint, and type-error validation. `check --only lint` or `check --only format`
112
+ runs one stage.
57
113
  - Use `fix` for automatic Oxlint fixes followed by Oxfmt formatting. Add `--suggested`, `--dangerous`, or `--all` only
58
- with explicit permission after reviewing their impact.
59
- - Do not use `format`. It is deprecated and the next release removes it. `fix` writes formatting changes and `check`
60
- verifies formatting for read-only CI checks.
114
+ with explicit permission after reviewing their impact. `fix --only lint` or `fix --only format` runs one stage.
61
115
  - Use `analyze` for unused dependencies, exports, and files. In a monorepo it first checks
62
116
  workspace dependency consistency with Sherif. `analyze --only monorepo` or
63
117
  `analyze --only unused` runs one stage. `analyze --fix` may remove files, so inspect
@@ -68,8 +122,6 @@ adamantite analyze
68
122
  use `analyze --only unused --fix` to skip Sherif.
69
123
  - `analyze` runs Sherif without flags. Put Sherif exceptions in the `sherif` field of the root
70
124
  `package.json` (camelCase CLI options, e.g. `"ignoreDependency": ["tailwindcss"]`).
71
- - Do not use `monorepo`. It is deprecated and the next release removes it. Use `analyze`, or
72
- `analyze --only monorepo` to run only Sherif.
73
125
 
74
126
  To pass arguments to Knip, Oxlint, or Sherif, place them after `--`. For `check` and `fix` they
75
127
  go to Oxlint. For `analyze` they go to Knip, or to the stage that `--only` selects, so a Sherif
@@ -105,8 +157,48 @@ adamantite update
105
157
  adamantite doctor
106
158
  ```
107
159
 
108
- `update` updates Adamantite-managed dependencies. It then reports any remaining doctor
109
- findings. Follow those findings and review the resulting diff.
160
+ `update` updates Adamantite-managed dependencies and, with the effect preset, patches Oxlint
161
+ and TypeScript again. It then reports any remaining doctor findings. Follow those findings and review the resulting diff.
162
+
163
+ ## Custom rules
164
+
165
+ <!-- Keep this section the same as the AGENTS.md text in src/lib/workspace/custom-rules.ts. -->
166
+
167
+ Each file in the rules folder, `.adamantite/rules/` by default, is an Oxlint rule that this
168
+ project owns. `custom()` from `adamantite/lint/custom` loads the folder and enables each
169
+ rule as `error` under the `project` plugin: `no-process-env.ts` becomes
170
+ `project/no-process-env`. Add a file to add a rule. Delete the file to remove the rule.
171
+ `adamantite rule add <name>` writes a correct stub.
172
+
173
+ - A file that starts with `_`, such as `_helpers.ts`, is a helper, not a rule. Subfolders are
174
+ not read.
175
+ - Export the rule as default with `defineRule` from `adamantite/rules`. The same module exports
176
+ the `Context`, `Rule`, `Visitor`, and `ESTree` node types.
177
+ - Use `createOnce`. It runs one time for each lint run, not one time for each file. Reset
178
+ per-file state in `before`, and report collected results in `after`. `context.filename`,
179
+ `context.sourceCode`, and `context.settings` are not available in the body of
180
+ `createOnce`. Read them in `before` or in a visitor.
181
+ - Write erasable TypeScript only. Oxlint loads rule files with Node.js type stripping, so
182
+ `enum`, a `namespace` with values, parameter properties, and `import x = require()` stop
183
+ the lint run.
184
+ - Rules get no type information. Use only the AST and `context.sourceCode`.
185
+ - Report with a `messageId`, and put each message in `meta.messages`. Describe the options in
186
+ `meta.schema`, and read them from `context.options`.
187
+ - A rule that throws prints an error for each file, and the lint run still exits 0. After you
188
+ change a rule, run the lint and read all of its output.
189
+ - To find node names, run `adamantite rule ast <file>` on real code. It prints the same
190
+ ESTree-shaped AST that rules visit.
191
+ - To test a rule, use `RuleTester` from `oxlint/plugins-dev`. Adamantite does not run rule
192
+ tests.
193
+ - Oxlint caches the rules for each run. Restart the editor language server after you change a
194
+ rule.
195
+ - TypeScript does not check `.adamantite/rules/` by default, because its name starts with a dot. Add
196
+ `".adamantite/rules"` to `include` in `tsconfig.json` to check it.
197
+ - In a monorepo, give each rules folder its own plugin name, such as `custom({ name: "web" })`:
198
+ Oxlint rejects two plugins with the same name in one run. A relative `dir` resolves from the
199
+ file that calls `custom()`, so a shared tooling package can own the rules with
200
+ `custom({ dir: "rules", name: "acme" })`. A nested Oxlint config replaces the root config, so
201
+ a package that needs the root rules extends the root config.
110
202
 
111
203
  ## Decision guide
112
204
 
@@ -115,4 +207,6 @@ findings. Follow those findings and review the resulting diff.
115
207
  - Existing project upgrading Adamantite: `update`, then the doctor sequence.
116
208
  - Code-quality failure: choose `check` or `analyze` based on the failing subsystem; do not
117
209
  reinitialize the project.
210
+ - Project-specific lint rule: add a custom rule with `adamantite rule add <name>`; do not
211
+ edit Adamantite presets.
118
212
  - Unknown option or behavior: run `adamantite <command> --help` before guessing.