gempilot 0.2.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 (69) hide show
  1. checksums.yaml +7 -0
  2. data/.claude/skills/using-command-kit/SKILL.md +119 -0
  3. data/.claude/skills/using-command-kit/cli-example.rb +84 -0
  4. data/.claude/skills/using-command-kit/generator-pattern.rb +62 -0
  5. data/.rspec +3 -0
  6. data/.rubocop.yml +281 -0
  7. data/.ruby-version +1 -0
  8. data/CLAUDE.md +45 -0
  9. data/LICENSE.txt +21 -0
  10. data/README.md +140 -0
  11. data/Rakefile +44 -0
  12. data/data/templates/gem/Gemfile.erb +23 -0
  13. data/data/templates/gem/LICENSE.txt.erb +21 -0
  14. data/data/templates/gem/README.md.erb +25 -0
  15. data/data/templates/gem/Rakefile.erb +36 -0
  16. data/data/templates/gem/bin/console.erb +7 -0
  17. data/data/templates/gem/bin/setup.erb +5 -0
  18. data/data/templates/gem/dotfiles/github/workflows/ci.yml.erb +33 -0
  19. data/data/templates/gem/dotfiles/gitignore +11 -0
  20. data/data/templates/gem/dotfiles/rubocop.yml.erb +209 -0
  21. data/data/templates/gem/dotfiles/ruby-version.erb +1 -0
  22. data/data/templates/gem/exe/gem_name.erb +3 -0
  23. data/data/templates/gem/gemspec.erb +27 -0
  24. data/data/templates/gem/lib/gem_name/version.rb.erb +7 -0
  25. data/data/templates/gem/lib/gem_name.rb.erb +16 -0
  26. data/data/templates/gem/lib/gem_name_extension.rb.erb +20 -0
  27. data/data/templates/gem/rspec.erb +3 -0
  28. data/data/templates/gem/spec/gem_name_spec.rb.erb +5 -0
  29. data/data/templates/gem/spec/spec_helper.rb.erb +10 -0
  30. data/data/templates/gem/spec/zeitwerk_spec.rb.erb +5 -0
  31. data/data/templates/gem/test/gem_name_test.rb.erb +7 -0
  32. data/data/templates/gem/test/test_helper.rb.erb +7 -0
  33. data/data/templates/gem/test/zeitwerk_test.rb.erb +9 -0
  34. data/data/templates/new/.keep +0 -0
  35. data/data/templates/new/command.rb.erb +15 -0
  36. data/docs/command_kit_comparison.md +249 -0
  37. data/docs/command_kit_reference.md +517 -0
  38. data/docs/plans/2026-02-18-gempilot-add-command.md +718 -0
  39. data/docs/superpowers/plans/2026-04-01-rubocop-new-config.md +838 -0
  40. data/docs/superpowers/plans/2026-04-06-dogfood-inflectable.md +659 -0
  41. data/docs/superpowers/plans/2026-04-06-inflection-tests-and-erb-rename.md +166 -0
  42. data/docs/superpowers/plans/2026-04-06-integrate-version-tools.md +162 -0
  43. data/docs/superpowers/plans/2026-04-06-new-readme.md +185 -0
  44. data/docs/version-management-redesign.md +44 -0
  45. data/exe/gempilot +12 -0
  46. data/issues.rec +77 -0
  47. data/lib/core_ext/string/inflection_methods.rb +68 -0
  48. data/lib/core_ext/string/refinements/inflectable.rb +15 -0
  49. data/lib/gempilot/cli/command.rb +17 -0
  50. data/lib/gempilot/cli/commands/bump.rb +49 -0
  51. data/lib/gempilot/cli/commands/console.rb +38 -0
  52. data/lib/gempilot/cli/commands/create.rb +183 -0
  53. data/lib/gempilot/cli/commands/destroy.rb +136 -0
  54. data/lib/gempilot/cli/commands/new.rb +226 -0
  55. data/lib/gempilot/cli/commands/release.rb +40 -0
  56. data/lib/gempilot/cli/gem_builder.rb +105 -0
  57. data/lib/gempilot/cli/gem_context.rb +40 -0
  58. data/lib/gempilot/cli/generator.rb +90 -0
  59. data/lib/gempilot/cli.rb +19 -0
  60. data/lib/gempilot/github_release.rb +30 -0
  61. data/lib/gempilot/project/version.rb +39 -0
  62. data/lib/gempilot/project.rb +111 -0
  63. data/lib/gempilot/strict_shell.rb +18 -0
  64. data/lib/gempilot/version.rb +3 -0
  65. data/lib/gempilot/version_tag.rb +53 -0
  66. data/lib/gempilot/version_task.rb +108 -0
  67. data/lib/gempilot.rb +17 -0
  68. data/notes.md +31 -0
  69. metadata +165 -0
@@ -0,0 +1,517 @@
1
+ # CommandKit 0.6.0 - Complete Module & Method Reference
2
+
3
+ ## Overview
4
+
5
+ CommandKit is a modular Ruby toolkit for building CLI commands. Rather than a monolithic framework, it provides composable modules that can be included individually or used together via the `CommandKit::Command` base class.
6
+
7
+ **Key design principle:** Every module follows the `include`-based mixin pattern with `ClassMethods` for DSL methods and instance methods for runtime behavior. Modules are testable by injecting `stdin:`, `stdout:`, `stderr:`, and `env:` into `initialize`.
8
+
9
+ ---
10
+
11
+ ## Core Command Class
12
+
13
+ ### `CommandKit::Command`
14
+ **Path:** `lib/command_kit/command.rb`
15
+
16
+ Base class that combines all standard modules. Inheriting from this is optional - you can include individual modules instead.
17
+
18
+ **Includes (in order):** Main, Env, Stdio, Printing, Help, Usage, Arguments, Options, Examples, Description, ExceptionHandler, FileUtils
19
+
20
+ ---
21
+
22
+ ## Lifecycle Modules
23
+
24
+ ### `CommandKit::Main`
25
+ **Path:** `lib/command_kit/main.rb`
26
+
27
+ Entry point and command lifecycle management.
28
+
29
+ | Method | Type | Signature | Purpose |
30
+ |--------|------|-----------|---------|
31
+ | `start` | Class | `start(argv=ARGV, **kwargs)` | Creates instance, calls `main`, exits with status. Catches `Interrupt` (exit 130) and `Errno::EPIPE` (exit 0) |
32
+ | `main` | Class | `main(argv=[], **kwargs) -> Integer` | Creates instance, calls instance `#main`, returns exit code |
33
+ | `main` | Instance | `main(argv=[]) -> Integer` | Calls `run(*argv)`, catches `SystemExit`, returns 0 by default |
34
+ | `run` | Instance | `run(*args)` | Abstract. Override with command logic |
35
+
36
+ ---
37
+
38
+ ### `CommandKit::Env`
39
+ **Path:** `lib/command_kit/env.rb`
40
+
41
+ Testable access to environment variables.
42
+
43
+ | Method | Type | Signature | Purpose |
44
+ |--------|------|-----------|---------|
45
+ | `env` | Instance | `-> Hash` | Returns `@env` (defaults to `ENV`) |
46
+
47
+ Initialize with `env: { 'KEY' => 'val' }` for testing.
48
+
49
+ ---
50
+
51
+ ### `CommandKit::Stdio`
52
+ **Path:** `lib/command_kit/stdio.rb`
53
+
54
+ Testable stream access. Initialize with `stdin:`, `stdout:`, `stderr:` for testing.
55
+
56
+ | Method | Type | Signature | Purpose |
57
+ |--------|------|-----------|---------|
58
+ | `stdin` | Instance | `-> IO` | Returns `@stdin` or `$stdin` |
59
+ | `stdout` | Instance | `-> IO` | Returns `@stdout` or `$stdout` |
60
+ | `stderr` | Instance | `-> IO` | Returns `@stderr` or `$stderr` |
61
+ | `gets` | Instance | `gets(*args)` | Delegates to `stdin.gets` |
62
+ | `readline` | Instance | `readline(*args)` | Delegates to `stdin.readline` |
63
+ | `readlines` | Instance | `readlines(*args)` | Delegates to `stdin.readlines` |
64
+ | `putc` | Instance | `putc(*args)` | Delegates to `stdout.putc` |
65
+ | `puts` | Instance | `puts(*args)` | Delegates to `stdout.puts` |
66
+ | `print` | Instance | `print(*args)` | Delegates to `stdout.print` |
67
+ | `printf` | Instance | `printf(*args)` | Delegates to `stdout.printf` |
68
+ | `abort` | Instance | `abort(message=nil)` | Prints to stderr, exits(1) |
69
+
70
+ ---
71
+
72
+ ## CLI Definition Modules
73
+
74
+ ### `CommandKit::CommandName`
75
+ **Path:** `lib/command_kit/command_name.rb`
76
+
77
+ Derives command name from class name or sets it explicitly.
78
+
79
+ | Method | Type | Signature | Purpose |
80
+ |--------|------|-----------|---------|
81
+ | `command_name` | Class | `command_name(name=nil) -> String` | Gets/sets. Defaults to `Inflector.underscore(Inflector.demodularize(self.name))` |
82
+ | `command_name` | Instance | `-> String` | Reader |
83
+
84
+ ---
85
+
86
+ ### `CommandKit::Usage`
87
+ **Path:** `lib/command_kit/usage.rb`
88
+ **Includes:** CommandName, Help
89
+
90
+ | Method | Type | Signature | Purpose |
91
+ |--------|------|-----------|---------|
92
+ | `usage` | Class | `usage(str=nil) -> String\|Array` | Gets/sets usage string(s). Example: `usage '[options] FILE'` |
93
+ | `usage` | Instance | `-> String\|Array` | Prepends `command_name` to class usage |
94
+ | `help_usage` | Instance | `-> nil` | Prints formatted `usage: ...` |
95
+
96
+ ---
97
+
98
+ ### `CommandKit::Description`
99
+ **Path:** `lib/command_kit/description.rb`
100
+ **Includes:** Help
101
+
102
+ | Method | Type | Signature | Purpose |
103
+ |--------|------|-----------|---------|
104
+ | `description` | Class | `description(str=nil) -> String\|nil` | Gets/sets description |
105
+ | `description` | Instance | `-> String\|nil` | Reader |
106
+ | `help_description` | Instance | `-> nil` | Prints description section |
107
+
108
+ ---
109
+
110
+ ### `CommandKit::Examples`
111
+ **Path:** `lib/command_kit/examples.rb`
112
+ **Includes:** Help, CommandName
113
+
114
+ | Method | Type | Signature | Purpose |
115
+ |--------|------|-----------|---------|
116
+ | `examples` | Class | `examples(arr=nil) -> Array\|nil` | Gets/sets example strings |
117
+ | `examples` | Instance | `-> Array\|nil` | Reader, prepends `command_name` |
118
+ | `help_examples` | Instance | `-> nil` | Prints examples section |
119
+
120
+ ---
121
+
122
+ ### `CommandKit::Arguments`
123
+ **Path:** `lib/command_kit/arguments.rb`
124
+ **Includes:** Usage, Main, Help, Printing
125
+
126
+ | Method | Type | Signature | Purpose |
127
+ |--------|------|-----------|---------|
128
+ | `arguments` | Class | `-> Hash{Symbol => Argument}` | All defined arguments (inherits) |
129
+ | `argument` | Class | `argument(name, required: true, repeats: false, desc:, usage: nil)` | Define a positional argument |
130
+ | `main` | Instance | `main(argv=[]) -> Integer` | Validates argument count, then calls super |
131
+ | `help_arguments` | Instance | `-> nil` | Prints arguments section |
132
+
133
+ **Argument options:**
134
+ - `required:` (Boolean, default: true)
135
+ - `repeats:` (Boolean, default: false) - allows multiple values
136
+ - `desc:` (String or Array<String>) - description
137
+ - `usage:` (String) - override display name (defaults to uppercase `name`)
138
+
139
+ ---
140
+
141
+ ### `CommandKit::Options`
142
+ **Path:** `lib/command_kit/options.rb`
143
+ **Includes:** Arguments, Options::Parser
144
+
145
+ | Method | Type | Signature | Purpose |
146
+ |--------|------|-----------|---------|
147
+ | `options` | Class | `-> Hash{Symbol => Option}` | All defined options (inherits) |
148
+ | `option` | Class | `option(name, short:, long:, equals:, value:, desc:, category:, &block)` | Define an option |
149
+ | `options` | Instance | `-> Hash{Symbol => Object}` | Parsed option values |
150
+
151
+ **Option parameters:**
152
+ - `short:` (String, e.g. `'-f'`)
153
+ - `long:` (String, defaults to `"--#{dasherize(name)}"`)
154
+ - `equals:` (Boolean) - use `--opt=VALUE` form
155
+ - `value:` (Hash or true/false/nil):
156
+ - `type:` (Class, Hash, Array, Regexp) - `String`, `Integer`, `Float`, `Numeric`, `Date`, `Time`, `URI`, `Regexp`, `Hash{'a'=>:a}`, `Array[:a,:b]`
157
+ - `usage:` (String) - value placeholder
158
+ - `default:` (Object or Proc)
159
+ - `required:` (Boolean)
160
+ - `desc:` (String or Array<String>)
161
+ - `category:` (String) - groups options in help
162
+ - `&block` - receives parsed value for custom processing
163
+
164
+ ---
165
+
166
+ ### `CommandKit::Options::Parser`
167
+ **Path:** `lib/command_kit/options/parser.rb`
168
+ **Includes:** Usage, Main, Printing
169
+
170
+ | Method | Type | Signature | Purpose |
171
+ |--------|------|-----------|---------|
172
+ | `option_parser` | Instance | `-> OptionParser` | The underlying OptionParser |
173
+ | `main` | Instance | `main(argv=[]) -> Integer` | Parses options then calls super |
174
+ | `parse_options` | Instance | `parse_options(argv) -> Array` | Parses, returns remaining args |
175
+ | `on_parse_error` | Instance | `on_parse_error(error)` | Prints error + "Try --help", exits(1) |
176
+ | `on_invalid_option` | Instance | `on_invalid_option(error)` | Override for OptionParser::InvalidOption |
177
+ | `on_ambiguous_option` | Instance | `on_ambiguous_option(error)` | Override for OptionParser::AmbiguousOption |
178
+ | `on_invalid_argument` | Instance | `on_invalid_argument(error)` | Override for OptionParser::InvalidArgument |
179
+ | `on_missing_argument` | Instance | `on_missing_argument(error)` | Override for OptionParser::MissingArgument |
180
+ | `on_needless_argument` | Instance | `on_needless_argument(error)` | Override for OptionParser::NeedlessArgument |
181
+
182
+ ---
183
+
184
+ ### Pre-built Option Modules
185
+
186
+ #### `CommandKit::Options::Verbose`
187
+ Adds `-v, --verbose` flag. Provides `verbose?` -> Boolean.
188
+
189
+ #### `CommandKit::Options::VerboseLevel`
190
+ Adds `-v, --verbose` that increments on each use. Provides `verbose` -> Integer, `verbose?` -> Boolean.
191
+
192
+ #### `CommandKit::Options::Quiet`
193
+ Adds `-q, --quiet` flag. Provides `quiet?` -> Boolean.
194
+
195
+ #### `CommandKit::Options::Version`
196
+ Adds `-V, --version` flag. Class method `version(str)` sets version. `print_version` prints `"#{command_name} #{version}"`.
197
+
198
+ ---
199
+
200
+ ## Subcommand System
201
+
202
+ ### `CommandKit::Commands`
203
+ **Path:** `lib/command_kit/commands.rb`
204
+ **Includes:** CommandName, Usage, Options, Stdio, Env
205
+
206
+ When included, automatically sets usage to `"[options] [COMMAND [ARGS...]]"` and mounts a `Help` subcommand.
207
+
208
+ | Method | Type | Signature | Purpose |
209
+ |--------|------|-----------|---------|
210
+ | `commands` | Class | `-> Hash{String => Subcommand}` | Registered subcommands (inherits) |
211
+ | `command_aliases` | Class | `-> Hash{String => String}` | Alias mappings (inherits) |
212
+ | `command` | Class | `command(name=nil, klass, summary:, aliases:)` | Register a subcommand |
213
+ | `get_command` | Class | `get_command(name) -> Class\|nil` | Look up by name or alias |
214
+ | `command` | Instance | `command(name) -> Object\|nil` | Instantiate subcommand with inherited context |
215
+ | `invoke` | Instance | `invoke(name, *argv) -> Integer` | Invoke subcommand, return exit status |
216
+ | `run` | Instance | `run(cmd=nil, *argv)` | Dispatch to subcommand or show help |
217
+ | `command_not_found` | Instance | `command_not_found(name)` | Print error, exit(1) |
218
+ | `on_unknown_command` | Instance | `on_unknown_command(name, argv)` | Override for custom handling |
219
+ | `help_commands` | Instance | `-> nil` | Print commands list |
220
+
221
+ ---
222
+
223
+ ### `CommandKit::Commands::AutoLoad`
224
+ **Path:** `lib/command_kit/commands/auto_load.rb`
225
+
226
+ Auto-discovers subcommands from a directory. Used like:
227
+ ```ruby
228
+ include CommandKit::Commands::AutoLoad.new(
229
+ dir: "#{__dir__}/commands",
230
+ namespace: "#{self}::Commands"
231
+ )
232
+ ```
233
+
234
+ | Method | Type | Signature | Purpose |
235
+ |--------|------|-----------|---------|
236
+ | `new` | Class | `new(dir:, namespace:)` | Creates an auto-loading module |
237
+ | `join` | Instance | `join(path)` | Joins dir + path |
238
+ | `files` | Instance | `-> Hash{String => String}` | Maps command names to file paths |
239
+ | `commands` | Instance | `-> Hash{String => Subcommand}` | Lazily loads commands from files |
240
+
241
+ Files are discovered as `dir/*.rb` and command names derived via `Inflector.demodularize`.
242
+
243
+ ---
244
+
245
+ ### `CommandKit::Commands::AutoRequire`
246
+ **Path:** `lib/command_kit/commands/auto_require.rb`
247
+
248
+ Similar to AutoLoad but uses `require` with a namespace prefix instead of file paths.
249
+
250
+ ---
251
+
252
+ ### `CommandKit::Commands::ParentCommand`
253
+ **Path:** `lib/command_kit/commands/parent_command.rb`
254
+
255
+ | Method | Type | Signature | Purpose |
256
+ |--------|------|-----------|---------|
257
+ | `parent_command` | Instance | `-> Object` | Reader for the parent command |
258
+
259
+ ---
260
+
261
+ ## Interactive Input
262
+
263
+ ### `CommandKit::Interactive`
264
+ **Path:** `lib/command_kit/interactive.rb`
265
+ **Includes:** Stdio
266
+
267
+ | Method | Type | Signature | Purpose |
268
+ |--------|------|-----------|---------|
269
+ | `ask` | Instance | `ask(prompt, default: nil, required: false) -> String` | Prompt for text input |
270
+ | `ask_yes_or_no` | Instance | `ask_yes_or_no(prompt, default: nil) -> Boolean` | Y/N prompt |
271
+ | `ask_multiple_choice` | Instance | `ask_multiple_choice(prompt, choices) -> String` | Numbered selection. `choices` is Array or Hash |
272
+ | `ask_secret` | Instance | `ask_secret(prompt, required: true) -> String` | Input with echo disabled |
273
+ | `ask_multiline` | Instance | `ask_multiline(prompt, terminator: :ctrl_d) -> String` | Multi-line input. Terminator: `:ctrl_d` or `:double_newline` |
274
+
275
+ ---
276
+
277
+ ## Output Modules
278
+
279
+ ### `CommandKit::Printing`
280
+ **Path:** `lib/command_kit/printing.rb`
281
+ **Includes:** Stdio
282
+
283
+ | Method | Type | Signature | Purpose |
284
+ |--------|------|-----------|---------|
285
+ | `print_error` | Instance | `print_error(message)` | Print to stderr, prefix with command_name |
286
+ | `print_exception` | Instance | `print_exception(error)` | Print exception to stderr with formatting |
287
+
288
+ **Constant:** `EOL = $/` (platform-independent newline)
289
+
290
+ ---
291
+
292
+ ### `CommandKit::Printing::Indent`
293
+ **Path:** `lib/command_kit/printing/indent.rb`
294
+
295
+ | Method | Type | Signature | Purpose |
296
+ |--------|------|-----------|---------|
297
+ | `indent` | Instance | `indent(n=2) { ... }` | Increase indent for block, then restore |
298
+ | `puts` | Instance | `puts(*lines)` | Override: prepends indent padding |
299
+
300
+ ---
301
+
302
+ ### `CommandKit::Printing::Fields`
303
+ **Path:** `lib/command_kit/printing/fields.rb`
304
+ **Includes:** Indent
305
+
306
+ | Method | Type | Signature | Purpose |
307
+ |--------|------|-----------|---------|
308
+ | `print_fields` | Instance | `print_fields(fields)` | Print aligned key: value pairs |
309
+
310
+ ---
311
+
312
+ ### `CommandKit::Printing::Lists`
313
+ **Path:** `lib/command_kit/printing/lists.rb`
314
+ **Includes:** Indent
315
+
316
+ | Method | Type | Signature | Purpose |
317
+ |--------|------|-----------|---------|
318
+ | `print_list` | Instance | `print_list(list, bullet: '*')` | Print bulleted list with nesting support |
319
+
320
+ ---
321
+
322
+ ### `CommandKit::Printing::Tables`
323
+ **Path:** `lib/command_kit/printing/tables.rb`
324
+ **Includes:** Indent
325
+
326
+ | Method | Type | Signature | Purpose |
327
+ |--------|------|-----------|---------|
328
+ | `print_table` | Instance | `print_table(rows, header:, border:, padding:, justify:, justify_header:, separate_rows:)` | Print formatted table |
329
+
330
+ **Border styles:** `:ascii` (+-|), `:line` (Unicode box), `:double_line` (Unicode double), `nil` (no borders), or custom Hash.
331
+
332
+ ---
333
+
334
+ ### `CommandKit::Colors`
335
+ **Path:** `lib/command_kit/colors.rb`
336
+ **Includes:** Stdio, Env
337
+
338
+ | Method | Type | Signature | Purpose |
339
+ |--------|------|-----------|---------|
340
+ | `ansi?` | Instance | `ansi?(stream=stdout) -> Boolean` | Check if stream supports ANSI (respects `NO_COLOR`, `TERM=dumb`) |
341
+ | `colors` | Instance | `colors(stream=stdout) -> ANSI\|PlainText` | Returns color module |
342
+
343
+ **Color methods** (on the returned `colors` object):
344
+ `reset`, `bold`, `black`, `red`, `green`, `yellow`, `blue`, `magenta`, `cyan`, `white`, `bright_black`/`gray`, `bright_red`, `bright_green`, `bright_yellow`, `bright_blue`, `bright_magenta`, `bright_cyan`, `bright_white`
345
+
346
+ All have corresponding `on_*` background variants. Each accepts optional string: `colors.red("error")` or returns code: `colors.red`.
347
+
348
+ ---
349
+
350
+ ## Utilities
351
+
352
+ ### `CommandKit::Inflector`
353
+ **Path:** `lib/command_kit/inflector.rb`
354
+
355
+ All module-level methods (no include needed):
356
+
357
+ | Method | Signature | Purpose |
358
+ |--------|-----------|---------|
359
+ | `demodularize` | `demodularize(name) -> String` | `"Foo::Bar::Baz"` -> `"Baz"` |
360
+ | `underscore` | `underscore(name) -> String` | `"MyCommandName"` -> `"my_command_name"` |
361
+ | `dasherize` | `dasherize(name) -> String` | `"my_command_name"` -> `"my-command-name"` |
362
+ | `camelize` | `camelize(name) -> String` | `"my_command_name"` -> `"MyCommandName"`, `"my/cmd"` -> `"My::Cmd"` |
363
+
364
+ ---
365
+
366
+ ### `CommandKit::FileUtils`
367
+ **Path:** `lib/command_kit/file_utils.rb`
368
+ **Includes:** `::FileUtils` (Ruby stdlib)
369
+
370
+ | Method | Type | Signature | Purpose |
371
+ |--------|------|-----------|---------|
372
+ | `erb` | Instance | `erb(source, dest=nil) -> String\|nil` | Render ERB template. If `dest`, writes file. Otherwise returns string. Uses `trim_mode: '-'` |
373
+
374
+ All standard Ruby `FileUtils` methods are also available (`mkdir_p`, `cp`, `rm`, `chmod`, etc.).
375
+
376
+ ---
377
+
378
+ ### `CommandKit::Edit`
379
+ **Path:** `lib/command_kit/edit.rb`
380
+ **Includes:** Env
381
+
382
+ | Method | Type | Signature | Purpose |
383
+ |--------|------|-----------|---------|
384
+ | `editor` | Instance | `-> String` | Returns `$EDITOR` or `"nano"` |
385
+ | `edit` | Instance | `edit(*arguments) -> Boolean\|nil` | Opens editor via `system` |
386
+
387
+ ---
388
+
389
+ ### `CommandKit::Pager`
390
+ **Path:** `lib/command_kit/pager.rb`
391
+ **Includes:** Env, Env::Path, Stdio, Terminal
392
+
393
+ | Method | Type | Signature | Purpose |
394
+ |--------|------|-----------|---------|
395
+ | `pager` | Instance | `pager { \|io\| ... }` | Pipe output through pager (less/more) |
396
+ | `print_or_page` | Instance | `print_or_page(data)` | Auto-page if data exceeds terminal height |
397
+ | `pipe_to_pager` | Instance | `pipe_to_pager(cmd, *args)` | Pipe command output through pager |
398
+
399
+ ---
400
+
401
+ ### `CommandKit::Terminal`
402
+ **Path:** `lib/command_kit/terminal.rb`
403
+ **Includes:** Stdio, Env
404
+
405
+ | Method | Type | Signature | Purpose |
406
+ |--------|------|-----------|---------|
407
+ | `terminal?` / `tty?` | Instance | `-> Boolean` | Check if stdout is a TTY |
408
+ | `terminal` | Instance | `-> IO\|nil` | Returns `IO.console` or nil |
409
+ | `terminal_height` | Instance | `-> Integer` | Terminal rows (default 25) |
410
+ | `terminal_width` | Instance | `-> Integer` | Terminal columns (default 80) |
411
+ | `terminal_size` | Instance | `-> [Integer, Integer]` | `[height, width]` |
412
+
413
+ ---
414
+
415
+ ### `CommandKit::OS`
416
+ **Path:** `lib/command_kit/os.rb`
417
+
418
+ | Method | Type | Signature | Purpose |
419
+ |--------|------|-----------|---------|
420
+ | `os` | Class | `-> Symbol\|nil` | Detects OS: `:linux`, `:macos`, `:freebsd`, `:openbsd`, `:netbsd`, `:windows` |
421
+ | `os` | Instance | `-> Symbol\|nil` | Reader |
422
+ | `linux?` | Instance | `-> Boolean` | |
423
+ | `macos?` | Instance | `-> Boolean` | |
424
+ | `bsd?` | Instance | `-> Boolean` | Any BSD variant |
425
+ | `unix?` | Instance | `-> Boolean` | Linux, macOS, or BSD |
426
+ | `windows?` | Instance | `-> Boolean` | |
427
+
428
+ ---
429
+
430
+ ### `CommandKit::PackageManager`
431
+ **Path:** `lib/command_kit/package_manager.rb`
432
+ **Includes:** OS, OS::Linux, Env::Path, Sudo
433
+
434
+ | Method | Type | Signature | Purpose |
435
+ |--------|------|-----------|---------|
436
+ | `package_manager` | Instance | `-> Symbol\|nil` | Detected manager: `:apt`, `:dnf`, `:yum`, `:zypper`, `:pacman`, `:brew`, `:port`, `:pkg`, `:pkg_add` |
437
+ | `install_packages` | Instance | `install_packages(*packages, yes:, apt:, brew:, dnf:, ...)` | Install packages cross-platform |
438
+
439
+ ---
440
+
441
+ ### `CommandKit::Sudo`
442
+ **Path:** `lib/command_kit/sudo.rb`
443
+ **Includes:** OS
444
+
445
+ | Method | Type | Signature | Purpose |
446
+ |--------|------|-----------|---------|
447
+ | `sudo` | Instance | `sudo(command, *args) -> Boolean\|nil` | Run command with sudo/runas if not root |
448
+
449
+ ---
450
+
451
+ ### `CommandKit::Open`
452
+ **Path:** `lib/command_kit/open.rb`
453
+ **Includes:** Stdio, Printing
454
+
455
+ | Method | Type | Signature | Purpose |
456
+ |--------|------|-----------|---------|
457
+ | `open` | Instance | `open(path, mode='r', &block)` | Open file with error handling. `"-"` maps to stdin/stdout |
458
+
459
+ ---
460
+
461
+ ### `CommandKit::OpenApp`
462
+ **Path:** `lib/command_kit/open_app.rb`
463
+ **Includes:** OS, Env::Path
464
+
465
+ | Method | Type | Signature | Purpose |
466
+ |--------|------|-----------|---------|
467
+ | `open_app_for` | Instance | `open_app_for(file_or_uri)` | Open with system app (`open`/`xdg-open`/`start`) |
468
+
469
+ ---
470
+
471
+ ### `CommandKit::BugReport`
472
+ **Path:** `lib/command_kit/bug_report.rb`
473
+ **Includes:** ExceptionHandler, Printing
474
+
475
+ | Method | Type | Signature | Purpose |
476
+ |--------|------|-----------|---------|
477
+ | `bug_report_url` | Class | `bug_report_url(url=nil) -> String\|nil` | Gets/sets bug report URL |
478
+ | `on_exception` | Instance | `on_exception(error)` | Prints bug report with URL, exits(-1) |
479
+
480
+ ---
481
+
482
+ ### `CommandKit::XDG`
483
+ **Path:** `lib/command_kit/xdg.rb`
484
+ **Includes:** CommandName, Env::Home
485
+
486
+ | Method | Type | Signature | Purpose |
487
+ |--------|------|-----------|---------|
488
+ | `xdg_namespace` | Class | `xdg_namespace(ns=nil) -> String` | Gets/sets XDG subdirectory name |
489
+ | `config_dir` | Instance | `-> String` | `~/.config/<namespace>` |
490
+ | `local_share_dir` | Instance | `-> String` | `~/.local/share/<namespace>` |
491
+ | `cache_dir` | Instance | `-> String` | `~/.cache/<namespace>` |
492
+
493
+ Respects `$XDG_CONFIG_HOME`, `$XDG_DATA_HOME`, `$XDG_CACHE_HOME`.
494
+
495
+ ---
496
+
497
+ ### `CommandKit::Help::Man`
498
+ **Path:** `lib/command_kit/help/man.rb`
499
+ **Includes:** CommandName, Help, Stdio, CommandKit::Man
500
+
501
+ | Method | Type | Signature | Purpose |
502
+ |--------|------|-----------|---------|
503
+ | `man_dir` | Class | `man_dir(path=nil) -> String` | Gets/sets man page directory |
504
+ | `man_page` | Class | `man_page(page=nil) -> String` | Gets/sets man page file (defaults to `"#{command_name}.1"`) |
505
+ | `help_man` | Instance | `help_man(page)` | Display man page |
506
+ | `help` | Instance | `-> nil` | Shows man page if TTY, else falls back to text help |
507
+
508
+ ---
509
+
510
+ ### `CommandKit::ProgramName`
511
+ **Path:** `lib/command_kit/program_name.rb`
512
+
513
+ | Method | Type | Signature | Purpose |
514
+ |--------|------|-----------|---------|
515
+ | `program_name` | Class | `-> String\|nil` | Returns `$PROGRAM_NAME` (ignores `-e`, `irb`, `rspec`) |
516
+ | `program_name` | Instance | `-> String\|nil` | Delegates to class |
517
+ | `command_name` | Instance | `-> String\|nil` | Alias for `program_name` |