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 +194 -52
- package/dist/index.js +26 -35
- package/dist/presets/analyze.d.ts +19 -1
- package/dist/presets/analyze.js +16 -1
- package/dist/presets/lint/plugin/index.d.ts +15 -0
- package/dist/presets/lint/plugin/index.js +16 -0
- package/dist/presets/lint/plugin/options.d.ts +12 -0
- package/dist/presets/lint/plugin/options.js +33 -0
- package/dist/presets/lint/plugin/rules/no-overzealous-destructuring.d.ts +5 -0
- package/dist/presets/lint/plugin/rules/no-overzealous-destructuring.js +92 -0
- package/dist/presets/lint/plugin/rules/no-react-state-hooks.d.ts +10 -0
- package/dist/presets/lint/plugin/rules/no-react-state-hooks.js +160 -0
- package/dist/presets/lint/react-doctor.d.ts +5 -0
- package/dist/presets/lint/react-doctor.js +20 -0
- package/dist/presets/lint/react-strict.d.ts +5 -0
- package/dist/presets/lint/react-strict.js +11 -0
- package/dist/presets/lint/shadcn.d.ts +5 -0
- package/dist/presets/lint/shadcn.js +22 -0
- package/dist/presets/lint/strict.d.ts +5 -0
- package/dist/presets/lint/strict.js +18 -0
- package/dist/presets/lint/vendor/antislop/plugin.d.mts +18 -2
- package/package.json +10 -6
- package/skills/adamantite/SKILL.md +62 -23
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`,
|
|
93
|
-
|
|
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.
|
|
98
|
-
|
|
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
|
|
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
|
-
|
|
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
|
|
141
|
-
adamantite format
|
|
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.
|
|
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
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
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
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
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
|
|
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
|
|
229
|
-
|
|
|
230
|
-
| `adamantite/lint`
|
|
231
|
-
| `adamantite/lint/react`
|
|
232
|
-
| `adamantite/lint/
|
|
233
|
-
| `adamantite/lint/
|
|
234
|
-
| `adamantite/lint/
|
|
235
|
-
| `adamantite/lint/
|
|
236
|
-
| `adamantite/lint/
|
|
237
|
-
| `adamantite/lint/
|
|
238
|
-
| `adamantite/
|
|
239
|
-
| `adamantite/
|
|
240
|
-
| `adamantite/
|
|
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`, `
|
|
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
|
|