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,166 @@
1
+ # Inflection Tests and ERB Rename Implementation Plan
2
+
3
+ > **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
4
+
5
+ **Goal:** Add unit tests for `String::Inflectable` and rename `version.rake.erb` to `version.rake` since it no longer contains ERB tags.
6
+
7
+ **Architecture:** Two independent tasks. Task 1 adds an RSpec spec for the inflection refinement covering `camelize`, `underscore`, and `dasherize` with edge cases. Task 2 renames the template file and switches `gem_builder.rb` from `erb` to `cp`.
8
+
9
+ **Tech Stack:** Ruby, RSpec
10
+
11
+ ---
12
+
13
+ ## File Structure
14
+
15
+ | Action | Path | Responsibility |
16
+ |--------|------|----------------|
17
+ | Create | `spec/core_ext/string/inflectable_spec.rb` | Unit tests for inflection refinement |
18
+ | Rename | `data/templates/gem/rakelib/version.rake.erb` → `data/templates/gem/rakelib/version.rake` | Remove misleading ERB extension |
19
+ | Modify | `lib/gempilot/cli/gem_builder.rb:48` | Switch from `erb` to `cp` for version.rake |
20
+
21
+ ---
22
+
23
+ ### Task 1: Add inflection unit tests
24
+
25
+ **Files:**
26
+ - Create: `spec/core_ext/string/inflectable_spec.rb`
27
+
28
+ - [ ] **Step 1: Write the spec**
29
+
30
+ ```ruby
31
+ require_relative "../../lib/core_ext/string/refinements/inflectable"
32
+
33
+ using String::Inflectable
34
+
35
+ RSpec.describe String::Inflectable do
36
+ describe "#camelize" do
37
+ it "camelizes a snake_case string" do
38
+ expect("my_gem".camelize).to eq("MyGem")
39
+ end
40
+
41
+ it "camelizes a path with slashes into namespaces" do
42
+ expect("my/gem".camelize).to eq("My::Gem")
43
+ end
44
+
45
+ it "handles a single word" do
46
+ expect("gem".camelize).to eq("Gem")
47
+ end
48
+
49
+ it "handles a hyphenated string" do
50
+ expect("my-gem".camelize).to eq("MyGem")
51
+ end
52
+
53
+ it "preserves numeric segments" do
54
+ expect("v_2".camelize).to eq("V_2")
55
+ end
56
+ end
57
+
58
+ describe "#underscore" do
59
+ it "underscores a CamelCase string" do
60
+ expect("MyGem".underscore).to eq("my_gem")
61
+ end
62
+
63
+ it "underscores consecutive capitals" do
64
+ expect("CLI".underscore).to eq("cli")
65
+ end
66
+
67
+ it "underscores mixed case with acronyms" do
68
+ expect("HTTPClient".underscore).to eq("http_client")
69
+ end
70
+
71
+ it "preserves existing underscores" do
72
+ expect("my_gem".underscore).to eq("my_gem")
73
+ end
74
+
75
+ it "converts hyphens to underscores" do
76
+ expect("my-gem".underscore).to eq("my_gem")
77
+ end
78
+ end
79
+
80
+ describe "#dasherize" do
81
+ it "converts underscores to hyphens" do
82
+ expect("my_gem".dasherize).to eq("my-gem")
83
+ end
84
+
85
+ it "leaves non-underscored strings alone" do
86
+ expect("mygem".dasherize).to eq("mygem")
87
+ end
88
+ end
89
+
90
+ describe "class method form" do
91
+ it "camelizes via String.camelize" do
92
+ expect(String.camelize("my_gem")).to eq("MyGem")
93
+ end
94
+
95
+ it "underscores via String.underscore" do
96
+ expect(String.underscore("MyGem")).to eq("my_gem")
97
+ end
98
+
99
+ it "dasherizes via String.dasherize" do
100
+ expect(String.dasherize("my_gem")).to eq("my-gem")
101
+ end
102
+ end
103
+ end
104
+ ```
105
+
106
+ - [ ] **Step 2: Run the spec**
107
+
108
+ Run: `bundle exec rspec spec/core_ext/string/inflectable_spec.rb --format documentation`
109
+ Expected: All examples pass
110
+
111
+ - [ ] **Step 3: Run rubocop**
112
+
113
+ Run: `bundle exec rubocop spec/core_ext/string/inflectable_spec.rb`
114
+ Expected: No offenses
115
+
116
+ - [ ] **Step 4: Commit**
117
+
118
+ ```bash
119
+ git add spec/core_ext/string/inflectable_spec.rb
120
+ git commit -m "Add unit tests for String::Inflectable refinement"
121
+ ```
122
+
123
+ ---
124
+
125
+ ### Task 2: Rename version.rake.erb to version.rake
126
+
127
+ **Files:**
128
+ - Rename: `data/templates/gem/rakelib/version.rake.erb` → `data/templates/gem/rakelib/version.rake`
129
+ - Modify: `lib/gempilot/cli/gem_builder.rb:48`
130
+
131
+ - [ ] **Step 1: Rename the template file**
132
+
133
+ ```bash
134
+ git mv data/templates/gem/rakelib/version.rake.erb data/templates/gem/rakelib/version.rake
135
+ ```
136
+
137
+ - [ ] **Step 2: Update `gem_builder.rb`**
138
+
139
+ In `lib/gempilot/cli/gem_builder.rb` line 48, change:
140
+
141
+ ```ruby
142
+ erb "rakelib/version.rake.erb", "#{@gem_name}/rakelib/version.rake"
143
+ ```
144
+
145
+ To:
146
+
147
+ ```ruby
148
+ cp "rakelib/version.rake", "#{@gem_name}/rakelib/version.rake"
149
+ ```
150
+
151
+ - [ ] **Step 3: Run tests**
152
+
153
+ Run: `bundle exec rake test spec`
154
+ Expected: All pass
155
+
156
+ - [ ] **Step 4: Run rubocop**
157
+
158
+ Run: `bundle exec rubocop`
159
+ Expected: No offenses
160
+
161
+ - [ ] **Step 5: Commit**
162
+
163
+ ```bash
164
+ git add data/templates/gem/rakelib/version.rake lib/gempilot/cli/gem_builder.rb
165
+ git commit -m "Rename version.rake.erb to version.rake — no ERB tags remain"
166
+ ```
@@ -0,0 +1,162 @@
1
+ # Package Version Tools as Gem Dependency
2
+
3
+ ## Context
4
+
5
+ Generated gems currently get 8 files copied into them (rakelib support classes + core_ext inflection files). This creates maintenance burden — files diverge, every gem carries duplicate code, updates require regenerating. The CLI `bump` command also reimplements version logic that `Project` already provides.
6
+
7
+ Instead: the domain model (`Project`, `Project::Version`, `VersionTag`, `GithubRelease`) lives in `lib/gempilot/` as first-class autoloaded classes. A `VersionTasks` class provides the rake integration. Generated gems add `gem "gempilot"` and `require "gempilot/version_tasks"`. The CLI `bump` command delegates to `rake version:bump` like `release` already delegates to `rake release`.
8
+
9
+ ## Architecture
10
+
11
+ ```
12
+ lib/gempilot/
13
+ project.rb — Gempilot::Project (gem introspection)
14
+ project/
15
+ version.rb — Gempilot::Project::Version (semver value object)
16
+ version_tag.rb — Gempilot::VersionTag (git release ops)
17
+ github_release.rb — Gempilot::GithubRelease (github release ops)
18
+ strict_shell.rb — Gempilot::StrictShell (shared shell mixin)
19
+ version_tasks.rb — Gempilot::VersionTasks < Rake::TaskLib (entry point)
20
+ ```
21
+
22
+ Only `VersionTasks` depends on Rake. The rest are plain Ruby domain objects that Zeitwerk autoloads normally. `VersionTasks` is ignored by Zeitwerk (requires Rake as a side effect) and loaded via explicit `require "gempilot/version_tasks"`.
23
+
24
+ ## Files
25
+
26
+ ### Create
27
+ | Path | Class |
28
+ |------|-------|
29
+ | `lib/gempilot/strict_shell.rb` | `Gempilot::StrictShell` |
30
+ | `lib/gempilot/project.rb` | `Gempilot::Project` |
31
+ | `lib/gempilot/project/version.rb` | `Gempilot::Project::Version` |
32
+ | `lib/gempilot/version_tag.rb` | `Gempilot::VersionTag` |
33
+ | `lib/gempilot/github_release.rb` | `Gempilot::GithubRelease` |
34
+ | `lib/gempilot/version_tasks.rb` | `Gempilot::VersionTasks` |
35
+
36
+ ### Delete
37
+ | Path | Reason |
38
+ |------|--------|
39
+ | `rakelib/project.rb` | Moved to lib/gempilot/ |
40
+ | `rakelib/project_version.rb` | Moved to lib/gempilot/project/version.rb |
41
+ | `rakelib/version_tag.rb` | Moved to lib/gempilot/ |
42
+ | `rakelib/github_release.rb` | Moved to lib/gempilot/ |
43
+ | `rakelib/strict_shell.rb` | Moved to lib/gempilot/ |
44
+ | `rakelib/version.rake` | Replaced by VersionTasks |
45
+ | `data/templates/gem/rakelib/` | Entire directory (6 symlinks) |
46
+ | `data/templates/gem/lib/core_ext/` | Entire directory (2 symlinks) |
47
+
48
+ ### Modify
49
+ | Path | Change |
50
+ |------|--------|
51
+ | `lib/gempilot.rb` | Add `LOADER.ignore` for `version_tasks.rb` |
52
+ | `gempilot.gemspec` | Add `warning` runtime dep, fix fallback glob |
53
+ | `Gemfile` | Remove `gem "warning"` |
54
+ | `Rakefile` | Use `require "gempilot/version_tasks"` + `Gempilot::VersionTasks.new` |
55
+ | `lib/gempilot/cli/commands/bump.rb` | Delegate to `rake version:bump[SEGMENT]` |
56
+ | `lib/gempilot/cli/commands/release.rb` | Delegate to `rake version:release` (already similar) |
57
+ | `data/templates/gem/Rakefile.erb` | Add require + VersionTasks.new |
58
+ | `data/templates/gem/Gemfile.erb` | Add `gem "gempilot", require: false` |
59
+ | `data/templates/gem/gemspec.erb` | Change fallback glob `{lib,exe,rakelib}` → `{lib,exe}` |
60
+ | `data/templates/gem/lib/gem_name.rb.erb` | Remove `LOADER.ignore("#{__dir__}/core_ext")` |
61
+ | `lib/gempilot/cli/gem_builder.rb` | Remove `render_version_rake`, `render_core_ext` + calls |
62
+ | Specs | Update require paths + class references |
63
+ | `test/gempilot/cli/create_command_test.rb` | Update assertions for new generated gem structure |
64
+
65
+ ## Domain Model Changes
66
+
67
+ ### `Project::Version#bump(segment)` — add segment support
68
+
69
+ Currently `next_version` only increments the last segment. Add `bump(segment = :patch)`:
70
+
71
+ ```ruby
72
+ def bump(segment = :patch)
73
+ major, minor, patch = value.split(".").map(&:to_i)
74
+ new_value = case segment.to_sym
75
+ when :major then "#{major + 1}.0.0"
76
+ when :minor then "#{major}.#{minor + 1}.0"
77
+ when :patch then "#{major}.#{minor}.#{patch + 1}"
78
+ end
79
+ with(value: new_value)
80
+ end
81
+ ```
82
+
83
+ `next_version` stays as an alias for `bump(:patch)` for backwards compatibility with the existing specs.
84
+
85
+ ### `version:bump` rake task — accept segment argument
86
+
87
+ ```ruby
88
+ desc "Bump version (patch default, or rake version:bump[minor])"
89
+ task :bump, [:segment] do |_t, args|
90
+ segment = (args[:segment] || :patch).to_sym
91
+ old_version = project.version
92
+ new_version = old_version.bump(segment)
93
+ project.write_version!(old_version, new_version)
94
+ project.refresh_version!
95
+ puts "Version bumped from #{old_version.value} to #{project.version_value}"
96
+ end
97
+ ```
98
+
99
+ ### `Bump` CLI command — delegate to rake
100
+
101
+ Replace the 104-line implementation with a thin rake delegation (same pattern as `Release`):
102
+
103
+ ```ruby
104
+ def run(segment = "patch")
105
+ detect_gem_context
106
+ validate_segment(segment)
107
+ run_rake_bump(segment)
108
+ end
109
+
110
+ private
111
+
112
+ def run_rake_bump(segment)
113
+ success = Bundler.with_unbundled_env do
114
+ system("bundle", "exec", "rake", "version:bump[#{segment}]")
115
+ end
116
+ exit 1 unless success
117
+ end
118
+ ```
119
+
120
+ ## Tasks
121
+
122
+ ### Task 1: Create domain classes in lib/gempilot/
123
+
124
+ Move and namespace the 5 domain classes + create `VersionTasks`. Each is a mechanical translation wrapping in `module Gempilot`. Add `Version#bump(segment)` method. Add `LOADER.ignore` for `version_tasks.rb` only (the rest autoload normally). Add `warning` to gemspec runtime deps.
125
+
126
+ ### Task 2: Dogfood — switch gempilot's Rakefile
127
+
128
+ Add `require "gempilot/version_tasks"` + `Gempilot::VersionTasks.new`. Delete all 6 `rakelib/` files. Verify `rake -T version` and `rake version:current`.
129
+
130
+ ### Task 3: Update specs
131
+
132
+ Change require paths and class references in all rakelib specs. Add spec for `Version#bump(:minor)` and `Version#bump(:major)`. Run specs.
133
+
134
+ ### Task 4: Simplify CLI Bump command
135
+
136
+ Replace the 104-line implementation with rake delegation. Keep `validate_segment` for the CLI-side error message. Remove duplicate `VERSION_PATTERN`, `read_current_version`, `write_new_version`, `increment` methods.
137
+
138
+ ### Task 5: Update templates + generator
139
+
140
+ - `Rakefile.erb`: add `require "gempilot/version_tasks"` + `Gempilot::VersionTasks.new`
141
+ - `Gemfile.erb`: add `gem "gempilot", require: false`
142
+ - `gemspec.erb`: change fallback glob to `{lib,exe}`
143
+ - `gem_name.rb.erb`: remove `LOADER.ignore("#{__dir__}/core_ext")`
144
+ - `gem_builder.rb`: remove `render_version_rake`, `render_core_ext` + calls
145
+ - Delete `data/templates/gem/rakelib/` and `data/templates/gem/lib/core_ext/`
146
+
147
+ ### Task 6: Update create_command_test.rb
148
+
149
+ Remove assertions about rakelib/core_ext files in generated gems. Add assertions for Gemfile containing `gempilot` and Rakefile containing `VersionTasks`.
150
+
151
+ ### Task 7: Integration test
152
+
153
+ Generate a test gem. Verify: no `rakelib/` support files, no `lib/core_ext/`, `gem "gempilot"` in Gemfile, `rake -T version` lists 12 tasks, `rake version:current` works, `bundle exec rake` passes.
154
+
155
+ ## Verification
156
+
157
+ 1. `bundle exec rake test spec` — gempilot suite passes
158
+ 2. `bundle exec rubocop` — 0 offenses
159
+ 3. `bundle exec rake -T version` — 12 tasks via the new require
160
+ 4. `bundle exec rake version:bump[minor]` — segment argument works
161
+ 5. `gempilot bump minor` — CLI delegates to rake
162
+ 6. Generate a test gem — works end-to-end with gempilot as a Gemfile dependency
@@ -0,0 +1,185 @@
1
+ # New README Implementation Plan
2
+
3
+ > **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
4
+
5
+ **Goal:** Replace the default bundler scaffold README with a real project README documenting gempilot's commands, generated gem features, and version management tasks.
6
+
7
+ **Architecture:** Single file rewrite. Content sourced from command implementations in `lib/gempilot/cli/commands/`, template files in `data/templates/gem/`, and the CLAUDE.md project notes.
8
+
9
+ **Tech Stack:** Markdown
10
+
11
+ ---
12
+
13
+ ## File Structure
14
+
15
+ | Action | Path | Responsibility |
16
+ |--------|------|----------------|
17
+ | Rewrite | `README.md` | Project documentation |
18
+
19
+ ---
20
+
21
+ ### Task 1: Write the README
22
+
23
+ **Files:**
24
+ - Rewrite: `README.md`
25
+
26
+ - [ ] **Step 1: Write `README.md`**
27
+
28
+ ```markdown
29
+ # Gempilot
30
+
31
+ A CLI toolkit for creating and managing Ruby gems with modern conventions.
32
+
33
+ Gempilot scaffolds production-ready gems with Zeitwerk autoloading, RuboCop,
34
+ GitHub Actions CI, and integrated version management. It also generates
35
+ classes, modules, and commands within existing gems.
36
+
37
+ ## Installation
38
+
39
+ ```bash
40
+ gem install gempilot
41
+ ```
42
+
43
+ Requires Ruby >= 3.4.
44
+
45
+ ## Quick Start
46
+
47
+ ```bash
48
+ gempilot create my_gem
49
+ cd my_gem
50
+ bundle exec rake
51
+ ```
52
+
53
+ This creates a fully configured gem with tests, linting, CI, and version
54
+ management — ready to develop.
55
+
56
+ ## Commands
57
+
58
+ ### `gempilot create`
59
+
60
+ Scaffold a new gem.
61
+
62
+ ```bash
63
+ gempilot create my_gem
64
+ gempilot create --test rspec --exe my_gem
65
+ gempilot create --test minitest --no-git my_gem
66
+ ```
67
+
68
+ Options:
69
+
70
+ | Option | Description | Default |
71
+ |--------|-------------|---------|
72
+ | `--test {minitest\|rspec}` | Test framework | prompted |
73
+ | `--[no-]exe` | Create executable in `exe/` | prompted |
74
+ | `--[no-]git` | Initialize git repo | prompted |
75
+ | `--branch NAME` | Git branch name | `master` |
76
+ | `--summary TEXT` | One-line gem description | prompted |
77
+ | `--author NAME` | Author name | `git config user.name` |
78
+ | `--email EMAIL` | Author email | `git config user.email` |
79
+ | `--ruby-version VER` | Minimum Ruby version | current Ruby |
80
+
81
+ All options are prompted interactively if omitted.
82
+
83
+ ### `gempilot new`
84
+
85
+ Generate a class, module, or command in an existing gem. Run from the gem root.
86
+
87
+ ```bash
88
+ gempilot new class MyGem::Services::Authentication
89
+ gempilot new module MyGem::Middleware
90
+ gempilot new command deploy
91
+ ```
92
+
93
+ Creates the source file under `lib/` and a corresponding test file. For
94
+ commands, generates a CommandKit command class in `lib/<gem>/cli/commands/`.
95
+
96
+ ### `gempilot destroy`
97
+
98
+ Remove a class, module, or command. Cleans up empty parent directories.
99
+
100
+ ```bash
101
+ gempilot destroy class MyGem::Services::Authentication
102
+ gempilot destroy command deploy
103
+ ```
104
+
105
+ ### `gempilot bump`
106
+
107
+ Bump the version in `lib/<gem>/version.rb`.
108
+
109
+ ```bash
110
+ gempilot bump # patch (default)
111
+ gempilot bump minor
112
+ gempilot bump major
113
+ ```
114
+
115
+ ### `gempilot release`
116
+
117
+ Delegates to `rake release` to build and push the gem.
118
+
119
+ ### `gempilot console`
120
+
121
+ Delegates to `bin/console` for an interactive IRB session with the gem loaded.
122
+
123
+ ## Generated Gem Features
124
+
125
+ Every gem scaffolded by `gempilot create` includes:
126
+
127
+ - **Zeitwerk autoloading** with `LOADER` constant and `rake zeitwerk:validate`
128
+ - **Test framework** — Minitest or RSpec, with a Zeitwerk eager-load test
129
+ - **RuboCop** with `rubocop-claude`, `rubocop-performance`, `rubocop-rake`, and
130
+ framework-specific plugins (`rubocop-minitest` or `rubocop-rspec`)
131
+ - **GitHub Actions CI** running tests and RuboCop
132
+ - **Version management** rake tasks (see below)
133
+ - **`bin/console`** and **`bin/setup`** scripts
134
+ - **Gemspec** with `git ls-files` and glob fallback, MFA required for RubyGems
135
+
136
+ ### Version Management Tasks
137
+
138
+ Generated gems include rake tasks for the full version lifecycle:
139
+
140
+ | Task | Description |
141
+ |------|-------------|
142
+ | `rake version:current` | Display the current version |
143
+ | `rake version:bump` | Increment the patch version |
144
+ | `rake version:commit` | Commit the version file change |
145
+ | `rake version:tag` | Create a git tag for the version |
146
+ | `rake version:untag` | Delete the version git tag |
147
+ | `rake version:reset` | Reset the version bump commit |
148
+ | `rake version:revert` | Revert the version bump commit |
149
+ | `rake version:release` | Bump, commit, and tag (combined) |
150
+ | `rake version:unrelease` | Untag and reset (combined) |
151
+ | `rake version:github:release` | Push and create a GitHub release |
152
+ | `rake version:github:unrelease` | Delete the GitHub release |
153
+ | `rake version:github:list` | List GitHub releases |
154
+
155
+ ## Development
156
+
157
+ ```bash
158
+ git clone https://github.com/gillisd/gempilot.git
159
+ cd gempilot
160
+ bundle install
161
+ bundle exec rake
162
+ ```
163
+
164
+ `rake` runs the Minitest suite, RSpec suite, and RuboCop.
165
+
166
+ ## License
167
+
168
+ MIT License. See [LICENSE.txt](LICENSE.txt).
169
+ ```
170
+
171
+ - [ ] **Step 2: Review for accuracy**
172
+
173
+ Cross-check against:
174
+ - `lib/gempilot/cli/commands/create.rb` — verify all `--options` are listed
175
+ - `lib/gempilot/cli/commands/new.rb` — verify types (class, module, command)
176
+ - `lib/gempilot/cli/commands/bump.rb` — verify patch/minor/major
177
+ - `rakelib/version.rake` — verify all 12 task names match
178
+ - `gempilot.gemspec` — verify Ruby version requirement
179
+
180
+ - [ ] **Step 3: Commit**
181
+
182
+ ```bash
183
+ git add README.md
184
+ git commit -m "Replace scaffold README with project documentation"
185
+ ```
@@ -0,0 +1,44 @@
1
+ # Version Management Redesign
2
+
3
+ Review notes for `new_version_utils.patch`. To be addressed in a follow-up PR.
4
+
5
+ ## Patch summary
6
+
7
+ Replaces inline rake task logic (including the `ActiveVersion` delegator) with
8
+ proper domain objects: `Project`, `Project::Version`, `VersionTag`,
9
+ `GithubRelease`, and `StrictShell`. Fixes the stale `require_relative` bug by
10
+ using `load` + `refresh_version!` to re-read from disk after mutations.
11
+
12
+ ## What works well
13
+
14
+ - Clean domain decomposition with single-responsibility classes
15
+ - `Version` as a `Data.define` value object with `tag` and `next_version`
16
+ - Symmetric `version:release` / `version:unrelease` task pairs
17
+ - Array-form `sh` calls throughout (no shell interpolation risk)
18
+ - `VersionTag` depends on a version object, not the full project
19
+
20
+ ## Open items
21
+
22
+ 1. **`release_full_spec.rb` is stale** -- matches `task full: ["version:bump",
23
+ "version:commit", :release]` but the new rake file has
24
+ `task release: ["version:bump", "version:commit", "version:tag"]`.
25
+
26
+ 2. **rakelib couples to lib** -- `Project` requires
27
+ `lib/core_ext/string/refinements/inflectable`. Generated gems using this
28
+ rakelib pattern would need that refinement at that exact path.
29
+
30
+ 3. **`Project#klass` loads the gem module** -- `Object.const_get(name.camelize)`
31
+ combined with `load` in `fetch_version` means the gem must be loadable from
32
+ the rake context. Gems with load-time side effects could behave unexpectedly.
33
+
34
+ 4. **`Project` has two responsibilities** -- structure discovery (name, lib path,
35
+ module) and version lifecycle (increment, write, refresh). Cohesive enough for
36
+ now, but the seam is visible if either grows.
37
+
38
+ 5. **`warning` gem dependency** -- `Project` requires the `warning` gem. Needs to
39
+ be a development dependency in the gemspec (and in generated gem templates).
40
+
41
+ 6. **Template expansion** -- If this rakelib replaces `version.rake.erb`, the
42
+ template needs to generate all five support files (`project.rb`,
43
+ `project_version.rb`, `version_tag.rb`, `github_release.rb`,
44
+ `strict_shell.rb`), significantly expanding the scaffold.
data/exe/gempilot ADDED
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ gemfile = File.expand_path("../Gemfile", __dir__)
4
+
5
+ if File.exist?(gemfile)
6
+ ENV["BUNDLE_GEMFILE"] ||= gemfile
7
+ require "bundler/setup"
8
+ end
9
+
10
+ require "gempilot/cli"
11
+
12
+ Gempilot::CLI.start
data/issues.rec ADDED
@@ -0,0 +1,77 @@
1
+ %rec: Issue
2
+ %key: Id
3
+ %typedef: text_t regexp /.*/
4
+ %typedef: Status_t enum open in_progress closed
5
+ %type: Id uuid
6
+ %type: Title line
7
+ %type: Description text_t
8
+ %type: Updated date
9
+ %type: Status Status_t
10
+ %auto: Id Updated
11
+ %mandatory: Title Description
12
+
13
+ Id: 6F683910-2EFA-4356-B1FE-3E4FE3E20A38
14
+ Updated: Mon, 02 Mar 2026 10:31:07 -0500
15
+ Title: Rake build triggers gem to be built twice?
16
+ Description: Why am I seeing 2 messages about gempilot being built to pkg/gempilot-0.1.0.gem
17
+ Status: open
18
+
19
+ Id: 011FB117-BC52-453F-A8E8-6955FE3EBCE8
20
+ Updated: Mon, 02 Mar 2026 10:31:39 -0500
21
+ Title: rubocop-rake is not active
22
+ Description: It should be active for this project
23
+ Status: open
24
+
25
+ Id: F0833E66-A35C-4054-884B-F90C81F08838
26
+ Updated: Mon, 02 Mar 2026 10:37:33 -0500
27
+ Title: Error handling should be graceful
28
+ Description: I did "gempilot create", and entered "A foo" as the title, and it crashed horrifically. This particular example should have validation at the minimum. Need to also use command kit's error bubbling/handling mechanism to swallow errors and print message to user. Can always use verbose or debug mode to see full trace.
29
+ Status: open
30
+
31
+ Id: 741FFD05-9BD7-44EB-BB99-E7D705F12681
32
+ Updated: Mon, 02 Mar 2026 11:25:24 -0500
33
+ Title: Reduce dependencies
34
+ Description:
35
+ Status: open
36
+
37
+ Id: 131EA3CE-2F3D-4E37-9D9B-A25E0A651F1B
38
+ Updated: Tue, 10 Mar 2026 17:40:50 -0400
39
+ Title: irb is required now as a gem
40
+ Description: Needs to go in template gemfile
41
+ Status: open
42
+
43
+ Id: 3178AC5C-09A9-44A9-ACE1-11BED0BA7276
44
+ Updated: Mon, 06 Apr 2026 00:00:00 -0400
45
+ Title: Add a version:* rake task that supports just bumping and committing
46
+ Description: Right now the only "combo" rake task for bumping version is the one that releases in full. Should make a composite one for more generalized purposes
47
+ Status: closed
48
+
49
+ Id: E6EB289D-BE84-4872-8012-D936707989B1
50
+ Updated: Mon, 06 Apr 2026 00:00:00 -0400
51
+ Title: Rake task version:commit should add version tag to commit
52
+ Description: The commit should be tagged with git tag upon committing, as this is a key part of releasing
53
+ Status: closed
54
+
55
+ Id: 7825507C-ABD2-4618-A591-BCDB54152C6B
56
+ Updated: Sat, 28 Mar 2026 12:48:05 -0400
57
+ Title: Rake task version:bump should support "dev increments", like "0.2.1.dev3". Perhaps a task like "version:bump:dev" is created to allow for this
58
+ Description: open
59
+ Status: open
60
+
61
+ Id: 5E4D51AB-F9BF-4C72-8165-F1B900799FA7
62
+ Updated: Sat, 28 Mar 2026 12:55:14 -0400
63
+ Title: Hundreds of rubocop failures exist
64
+ Description: These need to be addressed
65
+ Status: open
66
+
67
+ Id: 74D0FD90-0421-4452-8591-2798EE6FD23E
68
+ Updated: Sat, 28 Mar 2026 12:59:40 -0400
69
+ Title: Publish gem
70
+ Description: At some point the repo should be moved to public viz, and the gem should be published.
71
+ Status: open
72
+
73
+ Id: 8C356024-3122-11F1-89F3-FE6CB9572C2F
74
+ Updated: Mon, 06 Apr 2026 00:00:00 -0400
75
+ Title: Replace 4.0.1 with 3.4.8
76
+ Description: Need to move ruby version down to 3.4.8
77
+ Status: closed