rubocop-kata 0.7.0 → 0.9.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +124 -0
- data/README.md +88 -7
- data/config/default.yml +463 -33
- data/exe/rubocop-kata +7 -2
- data/lib/rubocop/cop/kata/agent_noun.rb +14 -23
- data/lib/rubocop/cop/kata/env_discipline.rb +5 -0
- data/lib/rubocop/cop/kata/good_class_name.rb +41 -0
- data/lib/rubocop/cop/kata/good_method_name.rb +9 -2
- data/lib/rubocop/cop/kata/good_module_name.rb +41 -0
- data/lib/rubocop/kata/kit.rb +23 -0
- data/lib/rubocop/kata/plan.rb +100 -0
- data/lib/rubocop/kata/version.rb +1 -1
- data/lib/rubocop-kata.rb +3 -2
- data/skills/rubocop-kata/SKILL.md +127 -0
- metadata +11 -5
- data/lib/rubocop/cop/kata/no_util_name.rb +0 -19
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 6c1ecc1a90d7d43dba2861011f7f9c8c1ecc97e71040908f1018df3199aca660
|
|
4
|
+
data.tar.gz: 216cb124bc0565ab89d5cf3ee52225e24771d6f4d0812e8a272b0fc14517e45e
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 5a806b0b657d6fa01fe422361616304f6581e23e041f76a70d3dc33f61814a600a808439282417de3f8ea34d03612927fdfcbced3f18010b90660407ffa165f7
|
|
7
|
+
data.tar.gz: 687dd4b67fb477cd51e4440e79f7d81a020f4712c1802541447eb489f97be8fab728cb26460c947113a2789f1fddf1f0e93ecd9bad70d2eadd232cbe025bf74d
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,129 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.9.0] - 2026-08-27
|
|
4
|
+
|
|
5
|
+
- The shared rule behind the naming cops is now explicit: compound syntax is
|
|
6
|
+
not the smell — multiple semantic concepts are. A name should name one thing,
|
|
7
|
+
not describe where it came from, what it manipulates, or which layer it
|
|
8
|
+
lives in.
|
|
9
|
+
- New `Kata/GoodClassName` replaces `Kata/AgentNoun` and the class half of
|
|
10
|
+
`Kata/NoUtilName`: a class names one object that exists in the model. It
|
|
11
|
+
keeps the doer check and its derived suggestions, adds junk-drawer names
|
|
12
|
+
matched whole or as a trailing segment (`Service` catches `InvoiceService`),
|
|
13
|
+
and flags names packing more than `MaxWords` concepts
|
|
14
|
+
(`CustomerOrderPayment`) unless `Terms` blesses them as one concept
|
|
15
|
+
(`CreditCard`). The default `Terms` ships the established technical
|
|
16
|
+
compounds: `AbstractSyntaxTree`, `RedBlackTree`, `UnitOfWork`,
|
|
17
|
+
`TimeWithZone`, `HashWithIndifferentAccess` and kin.
|
|
18
|
+
- New `Kata/GoodModuleName` replaces the module half of `Kata/NoUtilName`: a
|
|
19
|
+
module names a domain vocabulary, not an implementation category. Layer
|
|
20
|
+
buckets (`Services`, `Helpers`, `Logic` — so `BusinessLogic` too), vague
|
|
21
|
+
shared namespaces (`Common`, `Shared`, `Core`), doer modules, and crowded
|
|
22
|
+
names are flagged; `AccessControl` and `Billing` pass.
|
|
23
|
+
- `Kata/GoodMethodName` flags names chaining actions with a conjunction
|
|
24
|
+
(`validate_and_save`, `find_or_create`): each action wants its own method.
|
|
25
|
+
Traversal names (`customer_address`) were already priced by the word rule;
|
|
26
|
+
the message stays advisory — the cop cannot know your object model.
|
|
27
|
+
- `Kata/GoodMethodName` and `Kata/GoodVariableName` bless grammatical
|
|
28
|
+
suffixes `id` and `ms` (`user_id`, `timeout_ms`) alongside `at`, the role
|
|
29
|
+
prefixes `max`/`min`/`start`/`end` (`max_retries`, `start_time`), and ship
|
|
30
|
+
established lexical compounds and protocol vocabulary as default `Terms`:
|
|
31
|
+
`first_name`, `postal_code`, `time_zone`, `ip_address`, `user_agent`,
|
|
32
|
+
`mime_type`, `status_code`, `access_token` and kin — names that read as one
|
|
33
|
+
concept. Where names must mirror an external schema, `Exclude` the file:
|
|
34
|
+
the file is the boundary.
|
|
35
|
+
- The defaults were then pressure-tested against corpora of real stdlib, gem,
|
|
36
|
+
Rails, and business-domain names, and grew to absorb what any codebase hits:
|
|
37
|
+
role suffixes (`number`, `code`, `price`, `rate`, `date`, `path`, `url`,
|
|
38
|
+
`count`, `size`, `key`, `token`, `params`, `secret`, `level`, `file`, `dir`,
|
|
39
|
+
`period`, `seconds`, `cents`), role prefixes (`current`, `default`, `total`,
|
|
40
|
+
`new`, `other`, `raw`, `set`, `sort`, `expected`, `actual`, `assert`),
|
|
41
|
+
domain terms (`line_item`, `credit_card`, `payment_method`,
|
|
42
|
+
`billing_address`, `date_of_birth`, `dry_run`, `stack_trace` and kin), and
|
|
43
|
+
the contract names of Ruby, Rails, Sidekiq, Devise, Pundit and RSpec
|
|
44
|
+
(`perform_async`, `deconstruct_keys`, `authenticate_user!`, `policy_scope`,
|
|
45
|
+
`failure_message` and kin). Name suffixes that would bless owner+property
|
|
46
|
+
(`name`, `message`, `amount`) stayed out on purpose: `user_name` and
|
|
47
|
+
`error_message` are still priced.
|
|
48
|
+
- `Kata/GoodClassName` `AllowedNames` also covers the class families a
|
|
49
|
+
framework resolves or subclasses by name (`Validator`, `Decorator`,
|
|
50
|
+
`Presenter`, `Helper`, `Job`, `Logger`, `Delegator`, `Enumerator`,
|
|
51
|
+
`Driver`) and more thing-words (`Center`, `Transfer`);
|
|
52
|
+
`Kata/GoodModuleName` mirrors the class cop's allowed list, and its
|
|
53
|
+
`BannedNames` grows the layer plurals (`Jobs`, `Workers`, `Queries`,
|
|
54
|
+
`Policies`, `Forms`, `Decorators`, `Presenters`, `Serializers`,
|
|
55
|
+
`Validators`, `Mixins`, `Extensions`).
|
|
56
|
+
- The doer check no longer flags thing-words that merely end in `-er`/`-or`:
|
|
57
|
+
`User`, `Order`, `Customer`, `Monitor`, `Buffer` and kin ship in
|
|
58
|
+
`Kata/GoodClassName` `AllowedNames`. `Kata/GoodModuleName` ships the
|
|
59
|
+
framework suffixes (`Controller`, `Mailer`, `Serializer`) so reopening
|
|
60
|
+
`ActionController` is not an offense. `Kata/GoodMethodName` exempts the
|
|
61
|
+
names Ruby and Rails resolve by contract: `method_missing`,
|
|
62
|
+
`respond_to_missing?`, `marshal_dump`, `deep_dup`, `table_name`,
|
|
63
|
+
`primary_key` and kin.
|
|
64
|
+
|
|
65
|
+
## [0.8.0] - 2026-08-20
|
|
66
|
+
|
|
67
|
+
- New `rubocop-kata plan` command: buckets the backlog into `structure`,
|
|
68
|
+
`naming`, `prose` and `rest`, and names the stage to take next. Kata's
|
|
69
|
+
structural cops create names and its naming cops charge for them, so the net
|
|
70
|
+
offense count moves the wrong way mid-refactor and cannot be read as progress.
|
|
71
|
+
- New `rubocop-kata skill` command: prints an agent skill to stdout, so
|
|
72
|
+
redirecting it installs the skill wherever an agent reads them from. It works
|
|
73
|
+
the stage `plan` names one file at a time, checks every name it introduces
|
|
74
|
+
against the dictionary `Kata/RealWords` reads, and reports removed and
|
|
75
|
+
created separately.
|
|
76
|
+
- `Kata/AgentNoun` no longer truncates a compound to its prefix. Truncation is
|
|
77
|
+
not injective — `EvidencePoller`, `EvidenceValidator` and `EvidenceWaiter`
|
|
78
|
+
were each told to become `Evidence` — and it lands on names that already
|
|
79
|
+
exist elsewhere, which a per-file cop cannot see. It now derives the agent
|
|
80
|
+
word and keeps the rest, so `EvidenceValidator` suggests
|
|
81
|
+
`EvidenceValidation`, and stays quiet when no derivation applies.
|
|
82
|
+
- `Kata/AgentNoun` `AllowedNames` gains `Controller`, `Mailer` and
|
|
83
|
+
`Serializer`: suffixes a framework resolves a class by are contracts, not
|
|
84
|
+
naming choices.
|
|
85
|
+
- `Kata/EnvDiscipline` no longer flags `ENV` as a parameter default.
|
|
86
|
+
`def enabled?(env = ENV)` is the injection the cop asks for: the parameter
|
|
87
|
+
is the seam, and the default is what the boot layer would pass anyway.
|
|
88
|
+
- Every cop that excluded `spec/**/*` now excludes `test/**/*` too. Fifteen
|
|
89
|
+
cops shipped an RSpec-only exclusion, so a Minitest suite got the
|
|
90
|
+
production rules.
|
|
91
|
+
- The boot layer that `Kata/EnvDiscipline`, `Kata/IoDiscipline` and
|
|
92
|
+
`Kata/ClockDiscipline` exempt now covers an application's, not only a gem's:
|
|
93
|
+
`config/`, `db/seeds.rb`, `db/seeds/`, `lib/tasks/`, `Rakefile` and
|
|
94
|
+
`*.rake`, alongside `bin/` and `exe/`.
|
|
95
|
+
- `Kata/NoComments` now exempts `Gemfile` as it already exempts `*.gemspec`. A
|
|
96
|
+
dependency manifest cannot say why a dependency is pinned in code.
|
|
97
|
+
- `Metrics/MethodLength` counts an array, hash, heredoc or method call that
|
|
98
|
+
spans lines as one line. `Max: 5` and `Layout/LineLength: 120` were
|
|
99
|
+
otherwise unsatisfiable together: wrapping a long line spent method budget.
|
|
100
|
+
- `Layout/ArgumentAlignment` now uses `with_fixed_indentation`. Its default
|
|
101
|
+
aligns continuation arguments under the first argument's column, a step
|
|
102
|
+
`Elegant/MonotonicIndents` rejects.
|
|
103
|
+
- `Layout/EmptyLinesAroundAttributeAccessor` is off. It requires a blank line
|
|
104
|
+
after `attr_reader` where `Elegant/NoEmptyLinesInBlocks` forbids one; inside
|
|
105
|
+
an `included do` block the two autocorrect in a loop.
|
|
106
|
+
- `Lint/NumberConversion` is off. Its message names a replacement that
|
|
107
|
+
raises: `Integer(x, 10)` is only valid when `x` is a String, and a `.to_i`
|
|
108
|
+
receiver is usually a Time, a BigDecimal or an Integer.
|
|
109
|
+
- The five bundled cops that exempt test files now also match Rails'
|
|
110
|
+
`foo_test.rb`, `foo_spec.rb`, and suites addressed by directory. Upstream
|
|
111
|
+
matched `**/*Test.rb` and `**/test_*.rb` only.
|
|
112
|
+
- `Elegant/ClassInModule` is off. Its offenses cannot be cleared: it reports a
|
|
113
|
+
class nested in a class as global, and `Elegant/NoClassInModule` forbids the
|
|
114
|
+
module its message asks for, so the pair admits no shape. It also reads a
|
|
115
|
+
top-level constant as a defect, which is how Rails resolves one. Reported
|
|
116
|
+
upstream as yegor256/rubocop-elegant#75.
|
|
117
|
+
- `Elegant/PairedBrackets` autocorrect is off. It inserts a newline beside a
|
|
118
|
+
bracket without taking the whitespace already there, so corrected lines drift
|
|
119
|
+
right and `Elegant/MonotonicIndents` then reports the line it just wrote. The
|
|
120
|
+
rule still reports; fix the brackets by hand. Reported upstream as
|
|
121
|
+
yegor256/rubocop-elegant#76.
|
|
122
|
+
- Development runs against giacope/rubocop-elegant#fixes, the released gem plus
|
|
123
|
+
five open pull requests. A gemspec cannot name a git source, so consumers who
|
|
124
|
+
want the fixes rather than the workarounds add the same line to their own
|
|
125
|
+
Gemfile; the README says how.
|
|
126
|
+
|
|
3
127
|
## [0.7.0] - 2026-08-16
|
|
4
128
|
|
|
5
129
|
- New `rubocop-kata doctor` command: reports `.rubocop.yml` entries that
|
data/README.md
CHANGED
|
@@ -14,10 +14,10 @@ that dodge with a shipped dictionary instead of a word list you maintain:
|
|
|
14
14
|
|
|
15
15
|
- **One dependency.** Bundles rubocop-rspec, rubocop-performance, rubocop-elegant, rubocop-packaging, and rubocop-thread_safety behind a single gem.
|
|
16
16
|
- **Opinionated defaults.** Methods under 5 lines, classes under 100, 4 parameters max, 120-column lines, double quotes, `NewCops: enable`. See [config/default.yml](config/default.yml).
|
|
17
|
-
- **Fifteen house cops.** Naming, dependency discipline, and data honesty in the Elegant Objects spirit — from `Kata/
|
|
17
|
+
- **Fifteen house cops.** Naming, dependency discipline, and data honesty in the Elegant Objects spirit — from `Kata/GoodClassName` to `Kata/ClockDiscipline`.
|
|
18
18
|
|
|
19
19
|
```ruby
|
|
20
|
-
class PaymentProcessor # Kata/
|
|
20
|
+
class PaymentProcessor # Kata/GoodClassName: `PaymentProcessor` names a doer; name the class
|
|
21
21
|
end # for the thing it is, not the work it does. Try `Payment`.
|
|
22
22
|
|
|
23
23
|
class Payment # OK
|
|
@@ -53,17 +53,62 @@ bundle exec rubocop
|
|
|
53
53
|
|
|
54
54
|
That's it. The plugin loads the bundled extensions and the shared defaults, so your `.rubocop.yml` keeps only what's specific to your project. Requires Ruby >= 3.4 and RuboCop ~> 1.75.
|
|
55
55
|
|
|
56
|
+
### The bundled rubocop-elegant
|
|
57
|
+
|
|
58
|
+
The released `rubocop-elegant` 0.7.1 has four defects this project reported
|
|
59
|
+
upstream: `NoRedundantVariable` autocorrect corrupts Ruby 3.1 shorthand
|
|
60
|
+
([#74](https://github.com/yegor256/rubocop-elegant/issues/74)), `ClassInModule`
|
|
61
|
+
reports a class nested in a class as global
|
|
62
|
+
([#75](https://github.com/yegor256/rubocop-elegant/issues/75)),
|
|
63
|
+
`PairedBrackets` autocorrect drifts the indent
|
|
64
|
+
([#76](https://github.com/yegor256/rubocop-elegant/issues/76)), and the
|
|
65
|
+
test-file exclusions never match a Rails or RSpec suite
|
|
66
|
+
([#77](https://github.com/yegor256/rubocop-elegant/issues/77)).
|
|
67
|
+
|
|
68
|
+
The defaults here neutralise all four. `Elegant/ClassInModule` is off, because
|
|
69
|
+
its offences cannot be cleared: the cop it ships beside forbids the module it
|
|
70
|
+
asks for. The two broken correctors are set to report only, because their
|
|
71
|
+
offences can be cleared, by hand. The exclusions are widened. Nothing corrupts
|
|
72
|
+
your code out of the box, and nothing reports a defect you cannot fix.
|
|
73
|
+
|
|
74
|
+
A gemspec cannot name a git source, so to take the fixes themselves rather than
|
|
75
|
+
the workarounds, add this to your own `Gemfile`:
|
|
76
|
+
|
|
77
|
+
```ruby
|
|
78
|
+
gem "rubocop-elegant", github: "giacope/rubocop-elegant", branch: "fixes"
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
That branch is the released gem plus the five pull requests, with the version
|
|
82
|
+
pinned so Bundler resolves it. With it in place you can turn the two correctors
|
|
83
|
+
back on:
|
|
84
|
+
|
|
85
|
+
```yaml
|
|
86
|
+
Elegant/NoRedundantVariable:
|
|
87
|
+
AutoCorrect: true
|
|
88
|
+
|
|
89
|
+
Elegant/PairedBrackets:
|
|
90
|
+
AutoCorrect: true
|
|
91
|
+
|
|
92
|
+
Elegant/ClassInModule:
|
|
93
|
+
Enabled: true
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
Drop all three once upstream releases the fixes. On a Rails codebase, consider
|
|
97
|
+
leaving `Elegant/ClassInModule` off for good: it wants every class inside a
|
|
98
|
+
module, and Zeitwerk resolves `class Account` from `app/models/account.rb` as a
|
|
99
|
+
top-level constant by design.
|
|
100
|
+
|
|
56
101
|
## The cops
|
|
57
102
|
|
|
58
103
|
| Cop | Default | What it enforces |
|
|
59
104
|
| --- | --- | --- |
|
|
60
|
-
| `Kata/
|
|
105
|
+
| `Kata/GoodClassName` | on | A class names one object that exists in the model: no `-er`/`-or` doers (suggests the better name when it can derive one), no junk drawers (`Service`, `Util`, `Data`), no packing several concepts into one name (`CustomerOrderPayment`). Compound syntax is not the smell — `CreditCard` is one concept, and `Terms` holds those. `AllowedNames` and `BannedNames` match a whole name or a trailing segment, so `Error` covers `UsageError` and `Service` catches `InvoiceService`. |
|
|
106
|
+
| `Kata/GoodModuleName` | on | A module names a domain vocabulary (`Billing`, `AccessControl`), not an implementation category: no layer buckets (`Services`, `Helpers`, `Logic`), no vague shared namespaces (`Common`, `Shared`, `Core`), no doers. Tune via `BannedNames`/`Terms`/`AllowedNames`. |
|
|
61
107
|
| `Kata/NoComments` | on | No prose comments; say it in the code. Magic comments, linter directives, and licence headers survive. Autocorrects. |
|
|
62
|
-
| `Kata/IoDiscipline` | on | No bare `puts`/`warn`/`pp`/`p` outside
|
|
108
|
+
| `Kata/IoDiscipline` | on | No bare `puts`/`warn`/`pp`/`p` outside the test suite and the boot layer; write through an injected `@io` or an explicit receiver. |
|
|
63
109
|
| `Kata/ProsePlacement` | off | Sentence-length strings belong in the presentation layer. Enable with an `Include`/`Exclude` matching your layering. |
|
|
64
|
-
| `Kata/NoUtilName` | on | No junk-drawer names (`Util`, `Helper`, `Manager`, `Service`, …). Tune via `BannedNames`. |
|
|
65
110
|
| `Kata/RealWords` | on | Every name segment is a word the shipped dictionary knows — `errorcount` (smash) and `cfg` (abbreviation) both fail, with no word list to maintain. Tune via `Terms`/`BannedWords`/`AllowedNames`. |
|
|
66
|
-
| `Kata/GoodMethodName` | on | One word per method name; a second word needs a role prefix (`after_fork`), a role suffix (`file_of`), or a reviewed `Terms` entry. Tune via `MaxWords`/`Prefixes`/`Suffixes`/`Terms`/`AllowedNames`. |
|
|
111
|
+
| `Kata/GoodMethodName` | on | One word per method name; a second word needs a role prefix (`after_fork`), a role suffix (`file_of`), or a reviewed `Terms` entry. A name chaining actions (`validate_and_save`, `find_or_create`) is flagged as two methods in one. Tune via `MaxWords`/`Prefixes`/`Suffixes`/`Terms`/`AllowedNames`. |
|
|
67
112
|
| `Kata/GoodVariableName` | on | The same rule for locals, parameters, ivars, class variables, and globals; `_name` and `@_name` stay exempt. |
|
|
68
113
|
| `Kata/BuilderNoun` | on | Builders named for what they return: `total`, not `calculate_total`. Tune via `BannedPrefixes`/`AllowedNames`. |
|
|
69
114
|
| `Kata/NoBooleanFlag` | on | No positional boolean arguments; split the method or use a keyword. |
|
|
@@ -71,7 +116,7 @@ That's it. The plugin loads the bundled extensions and the shared defaults, so y
|
|
|
71
116
|
| `Kata/NoClassMethodLogic` | on | Class methods construct (`build`, `parse`, `of`, `from_*`); instances do the work. |
|
|
72
117
|
| `Kata/NoHashAsObject` | on | A hash with `MaxKeys`+ keys (default 4) wants to be an object. Keyword-argument call sites exempt. |
|
|
73
118
|
| `Kata/ClockDiscipline` | on | No bare `Time.now`/`Date.today`/`.current`; inject a clock. |
|
|
74
|
-
| `Kata/EnvDiscipline` | on | `ENV` reads only in the boot layer (`config/`, `bin/`, `exe/`). |
|
|
119
|
+
| `Kata/EnvDiscipline` | on | `ENV` reads only in the boot layer (`config/`, `db/seeds*`, `lib/tasks/`, rake files, `bin/`, `exe/`) — or as a parameter default, which is the seam the cop asks for. |
|
|
75
120
|
|
|
76
121
|
## Dead configuration
|
|
77
122
|
|
|
@@ -92,6 +137,42 @@ lib/registry.rb:44: the directive names `Elegant/GoodMethodName`, which is not e
|
|
|
92
137
|
|
|
93
138
|
It exits non-zero when it finds something, so it can gate CI.
|
|
94
139
|
|
|
140
|
+
## Adoption order
|
|
141
|
+
|
|
142
|
+
Kata's structural cops create names and its naming cops charge for them, so a
|
|
143
|
+
structural refactor removes offenses and adds more. A single total cannot tell
|
|
144
|
+
progress from regression. `plan` buckets the backlog into the stages that cause
|
|
145
|
+
each other and names the one to take next.
|
|
146
|
+
|
|
147
|
+
```sh
|
|
148
|
+
bundle exec rubocop-kata plan # or: plan path/to/project
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
```
|
|
152
|
+
structure 184 Kata/ConstructorDiscipline 92, Kata/NoHashAsObject 48, Kata/EnvDiscipline 44
|
|
153
|
+
naming 263 Kata/RealWords 141, Kata/GoodVariableName 88, Kata/GoodClassName 34
|
|
154
|
+
prose 57 Kata/NoComments 57
|
|
155
|
+
rest 412 Elegant/PairedBrackets 300, Layout/LineLength 112
|
|
156
|
+
next: structure — 184 offenses in 61 files; these mint the names `naming` then prices, so take them first
|
|
157
|
+
densest: app/models/account.rb (14)
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
Structure before naming, because doing naming first means renaming things the
|
|
161
|
+
structural pass is about to move.
|
|
162
|
+
|
|
163
|
+
The gem also ships an agent skill that runs this loop: it works the stage `plan`
|
|
164
|
+
names, checks every name it introduces against the same dictionary
|
|
165
|
+
`Kata/RealWords` reads, and reports removed and created separately instead of a
|
|
166
|
+
net total.
|
|
167
|
+
|
|
168
|
+
```sh
|
|
169
|
+
mkdir -p .claude/skills/rubocop-kata
|
|
170
|
+
bundle exec rubocop-kata skill > .claude/skills/rubocop-kata/SKILL.md
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
It writes to stdout, so the same command installs it anywhere an agent reads
|
|
174
|
+
skills from — a project, `~/.claude/skills/`, or a plugin.
|
|
175
|
+
|
|
95
176
|
## The defaults
|
|
96
177
|
|
|
97
178
|
Double-quoted strings, `Metrics/MethodLength: 5`, `Metrics/ClassLength: 100`,
|