rails-hyperdrive 0.5.0 → 0.6.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 +34 -4
- data/README.md +33 -29
- data/lib/generators/hyperdrive/install/install_generator.rb +9 -6
- data/lib/generators/hyperdrive/sync/sync_generator.rb +1 -1
- data/lib/rails/hyperdrive/tools/run_sql.rb +1 -1
- data/lib/rails/hyperdrive/version.rb +1 -1
- data/lib/rails/hyperdrive.rb +0 -22
- metadata +1 -2
- data/lib/generators/hyperdrive/install/templates/initializer.rb.tt +0 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: f1a89d616d54ce6f324e1105894dd01741a0d42e9887bb018fceea00aafbe6f1
|
|
4
|
+
data.tar.gz: b279e9c105a9cbb75c7bffc8a46224f55ff94b6a5412a335db3ba4fe9c3f3812
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 891f3bcced1126be5b1eb48d456e369b05dcb87cda0f87c82b5d27d7eeea9e57c4ed39ca7549f5a573b13ef800efe7b56f75c39c6cfb544f15cfb1518a9b0d82
|
|
7
|
+
data.tar.gz: 218fe629a71711e1915af9ad10a1cc58923ee9dc41ab16514224191526d19f249ed2df6658c5d281c25b1fa9b6430cfd75c163ee4b9d669853164f5889427780
|
data/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,35 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.6.0] - 2026-08-17
|
|
11
|
+
|
|
12
|
+
### Changed
|
|
13
|
+
|
|
14
|
+
- `run_sql` now labels an over-cap result `(showing first 100 of <total> rows)`
|
|
15
|
+
instead of `(<total> rows, truncated)`, which read as though rows beyond the
|
|
16
|
+
count shown had been dropped from a smaller set.
|
|
17
|
+
- The connection check printed under `hyperdrive:init`'s "Next steps" is now a
|
|
18
|
+
JSON-RPC `tools/list` POST carrying the `Content-Type` and `Accept` headers
|
|
19
|
+
the endpoint requires. The previous bare `curl <url>` was a GET, which the
|
|
20
|
+
stateless MCP transport answers with 405 — the suggested check read as a
|
|
21
|
+
failure against a perfectly working install.
|
|
22
|
+
|
|
23
|
+
### Removed
|
|
24
|
+
|
|
25
|
+
- **BREAKING:** `Rails::Hyperdrive.configure` /
|
|
26
|
+
`Rails::Hyperdrive::Configuration`, and the `config/initializers/hyperdrive.rb`
|
|
27
|
+
initializer that `hyperdrive:init --mount-at` used to write. The
|
|
28
|
+
initializer's only setting, `config.mount_at`, was read by nothing — the
|
|
29
|
+
live mount is the `mount Rails::Hyperdrive::Engine` line the generator
|
|
30
|
+
writes into `config/routes.rb`, and `.mcp.json` records the URL — so
|
|
31
|
+
editing it never moved the endpoint. The `--mount-at` flag is unchanged.
|
|
32
|
+
|
|
33
|
+
**Manual migration:** delete `config/initializers/hyperdrive.rb` if an
|
|
34
|
+
earlier `hyperdrive:init --mount-at` wrote one. The file calls
|
|
35
|
+
`Rails::Hyperdrive.configure` unguarded, so with the gem in the
|
|
36
|
+
`:development` group it raises `NameError` on any boot that excludes that
|
|
37
|
+
group (e.g. a production deploy) — deleting it also removes that hazard.
|
|
38
|
+
|
|
10
39
|
## [0.5.0] - 2026-08-15
|
|
11
40
|
|
|
12
41
|
### Added
|
|
@@ -40,9 +69,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
40
69
|
`require "rails/hyperdrive/skill_tasks"` in the Rakefile provides
|
|
41
70
|
`rake hyperdrive:skills:render` (generate each template's static `SKILL.md`
|
|
42
71
|
with the fail-open canonical binding — every gem present, `gem_version`
|
|
43
|
-
`nil`; the generated face
|
|
44
|
-
|
|
45
|
-
|
|
72
|
+
`nil`; the generated face is the rendered template verbatim — with gating
|
|
73
|
+
in the gem-root manifest there are no installer keys to strip) and
|
|
74
|
+
`rake hyperdrive:skills:check` (fail listing stale generated
|
|
46
75
|
files — the CI freshness gate). Rails-free; rails-hyperdrive as a
|
|
47
76
|
development dependency suffices.
|
|
48
77
|
- A gem's top-level `skills/` directory is now scanned as a default skills
|
|
@@ -423,7 +452,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
423
452
|
- `hyperdrive:init` generator that installs architecture skills and auto-discovers
|
|
424
453
|
per-gem skills.
|
|
425
454
|
|
|
426
|
-
[Unreleased]: https://github.com/rails-hyperdrive/rails-hyperdrive/compare/v0.
|
|
455
|
+
[Unreleased]: https://github.com/rails-hyperdrive/rails-hyperdrive/compare/v0.6.0...HEAD
|
|
456
|
+
[0.6.0]: https://github.com/rails-hyperdrive/rails-hyperdrive/releases/tag/v0.6.0
|
|
427
457
|
[0.5.0]: https://github.com/rails-hyperdrive/rails-hyperdrive/releases/tag/v0.5.0
|
|
428
458
|
[0.4.0]: https://github.com/rails-hyperdrive/rails-hyperdrive/releases/tag/v0.4.0
|
|
429
459
|
[0.3.0]: https://github.com/rails-hyperdrive/rails-hyperdrive/releases/tag/v0.3.0
|
data/README.md
CHANGED
|
@@ -10,12 +10,16 @@
|
|
|
10
10
|
[](https://github.com/rails-hyperdrive/rails-hyperdrive/actions/workflows/ci.yml)
|
|
11
11
|
[](LICENSE.txt)
|
|
12
12
|
|
|
13
|
-
Rails Hyperdrive is a development-only Rails engine for working on Rails apps with AI coding agents. It gives the agent two things it can't get from source alone
|
|
13
|
+
Rails Hyperdrive is a development-only Rails engine for working on Rails apps with AI coding agents. It gives the agent two things it can't get from source alone: live answers from the booted app, and guidance specific to the gems and versions in the bundle.
|
|
14
14
|
|
|
15
15
|
- **Live introspection.** The engine mounts an [MCP (Model Context Protocol)](https://modelcontextprotocol.io) server at `http://localhost:3000/_hyperdrive/mcp` with **8 tools** that answer from the running app itself: eval Ruby, query the DB (read-only), tail logs, list models and routes, jump to source, look up docs, snapshot the stack. The agent asks the router instead of grepping `routes.rb`, and reads the live schema instead of replaying migrations.
|
|
16
16
|
- **Stack-specific knowledge.** `bin/rails hyperdrive:init` discovers **skills** and **guidelines** shipped by companion gems and installs only the ones matching your Gemfile: guidance targeting Sidekiq, for example, lands only if your app bundles Sidekiq, at a version the guidance covers.
|
|
17
17
|
|
|
18
|
-
**rails-hyperdrive is the mechanism; companion gems are the content.** The gem itself ships no skills or guidelines
|
|
18
|
+
**rails-hyperdrive is the mechanism; companion gems are the content.** The gem itself ships no skills or guidelines, only the contract and the discovery/install engine. Content reaches your app three ways:
|
|
19
|
+
|
|
20
|
+
- **Native support**: the library gem itself ships a top-level `skills/` directory in the [skills.sh](https://www.skills.sh) layout and opts in as a hyperdrive companion. The preferred route when the maintainer is on board: one gem, one source of truth.
|
|
21
|
+
- **Adopted skill repos**: an existing skills.sh skill repo packaged as a gem, content untouched, gating declared on the side.
|
|
22
|
+
- **Dedicated companion gems**: third-party guidance for a library that ships none itself. A name like `rails-hyperdrive-<library>` or `<library>-skills` keeps the gem legible in a Gemfile, but naming plays no part in discovery.
|
|
19
23
|
|
|
20
24
|
---
|
|
21
25
|
|
|
@@ -57,7 +61,7 @@ $ bin/dev
|
|
|
57
61
|
# → agent has 8 tools, the eager guidelines (via CLAUDE.md), and the lazy skills
|
|
58
62
|
```
|
|
59
63
|
|
|
60
|
-
|
|
64
|
+
The generated `.mcp.json` points at `http://localhost:3000<mount>/mcp`. If your dev server runs on another port, edit the URL there.
|
|
61
65
|
|
|
62
66
|
---
|
|
63
67
|
|
|
@@ -76,38 +80,38 @@ That's it. No API keys, no config files to write, no per-project setup beyond th
|
|
|
76
80
|
| 7 | `describe_app` | Snapshot: Rails/Ruby/DB versions + direct gem dependencies |
|
|
77
81
|
| 8 | `list_routes` | All routes: HTTP verb, path, controller#action, named route |
|
|
78
82
|
|
|
79
|
-
Plus two MCP resources: `hyperdrive://stack-profile` (JSON snapshot of your resolved stack) and `hyperdrive://skills/{name}` (the markdown body of each installed skill).
|
|
83
|
+
Plus two MCP resources: `hyperdrive://stack-profile` (JSON snapshot of your resolved stack) and `hyperdrive://skills/{name}` (the markdown body of each installed skill). The skill list is enumerated at server boot and the stack snapshot is memoized per process, so a newly installed skill or a changed bundle reaches these two only after a dev-server restart.
|
|
80
84
|
|
|
81
85
|
### Two kinds of knowledge
|
|
82
86
|
|
|
83
87
|
Companion gems ship two artifact types, tuned for how agents consume context:
|
|
84
88
|
|
|
85
|
-
- **Skills
|
|
86
|
-
- **Guidelines
|
|
89
|
+
- **Skills**: *lazy*. Loaded on demand via Claude Code's native description matcher. Procedural knowledge: "how to write an idempotent Sidekiq job". Installed to `.claude/skills/<name>/SKILL.md`, optionally with supporting files (references, examples, workflows) alongside.
|
|
90
|
+
- **Guidelines**: *eager*. Always in context via a single `@`-include from `CLAUDE.md`. Declarative facts: "this app uses ActionPolicy, not Pundit". Installed to `.claude/hyperdrive/guidelines/<name>.md`.
|
|
87
91
|
|
|
88
|
-
|
|
92
|
+
A companion gem declares in its manifest which gem each artifact targets and at which versions, so what lands in your app is what matches your `Gemfile.lock`, and nothing aimed at a library or version you don't run.
|
|
89
93
|
|
|
90
|
-
With no companion gems, `hyperdrive:init` sets up just the server plumbing (`.mcp.json`, the engine mount, the lockfile) and puts **nothing** into your agent's context window.
|
|
94
|
+
With no companion gems, `hyperdrive:init` sets up just the server plumbing (`.mcp.json`, the engine mount, the lockfile) and puts **nothing** into your agent's context window.
|
|
91
95
|
|
|
92
96
|
---
|
|
93
97
|
|
|
94
98
|
## Staying in sync
|
|
95
99
|
|
|
96
|
-
**After `bundle install
|
|
100
|
+
**After `bundle install`: automatic.** `hyperdrive:init` registers the [`bundler-rails-hyperdrive`](bundler-rails-hyperdrive/) Bundler plugin in your Gemfile. From then on, adding a companion gem lands its artifacts on that very `bundle install`, with no extra command to run. The plugin is additive only (it never touches an existing file); version bumps and orphaned artifacts are only reported, with a pointer to `hyperdrive:sync`.
|
|
97
101
|
|
|
98
|
-
**`bin/rails hyperdrive:sync
|
|
102
|
+
**`bin/rails hyperdrive:sync`: on demand.** Run it any time (e.g. after `bundle update`) to refresh installed content to the current bundle. It touches no bootstrap artifact and leaves locally modified files untouched (skip + warn). When you *have* edited an installed file and its gem ships a new version, three mutually exclusive flags reconcile the two:
|
|
99
103
|
|
|
100
104
|
| Strategy | What happens to the live file | What happens to your edits |
|
|
101
105
|
|---|---|---|
|
|
102
|
-
| `--merge` | Rewritten with a git three-way merge when it applies cleanly; otherwise untouched and the upstream lands as a `--sidecar` delivery | Kept
|
|
106
|
+
| `--merge` | Rewritten with a git three-way merge when it applies cleanly; otherwise untouched and the upstream lands as a `--sidecar` delivery | Kept: a merge that would need conflict markers falls back to the sidecar, so nothing half-merged ever goes live |
|
|
103
107
|
| `--sidecar` | Untouched; the new upstream body is written next to it as `<file>.new` | Kept, byte-for-byte |
|
|
104
108
|
| `--overwrite` | Restored to the gem-shipped content | Discarded |
|
|
105
109
|
|
|
106
|
-
A sidecar is inert
|
|
110
|
+
A sidecar is inert (Claude Code loads only `SKILL.md` and the `index.md` `@`-lines, never a `.new` file), and it shows up in `git status` as your prompt to resolve. Resolve it by folding what you want into the live file and deleting the `.new`, or `mv <file>.new <file>` to accept the upstream wholesale. Either way the lockfile already records that delivery, so the next sync doesn't re-offer the same version (and a leftover sidecar you haven't touched is cleaned up once the live file catches up). `--merge` needs the previously installed gem version still present on disk to reconstruct the merge ancestor; when it isn't (CI, after `gem cleanup`), it degrades to the sidecar with a note saying why.
|
|
107
111
|
|
|
108
112
|
The sidecar pair is also how an AI coding agent reconciles for you, with no extra machinery: run `bin/rails hyperdrive:sync --sidecar`, have the agent merge the live/`.new` pair semantically (it has both full texts), then delete the sidecar.
|
|
109
113
|
|
|
110
|
-
**`bin/rails hyperdrive:discover
|
|
114
|
+
**`bin/rails hyperdrive:discover`: find what you're missing.** Queries rubygems for companion gems published for your stack that you haven't installed yet, and prints the `bundle add` lines to run. It is read-only, caches results for 24h (`--refresh` re-queries), and never touches your Gemfile or makes network calls unless you invoke it.
|
|
111
115
|
|
|
112
116
|
---
|
|
113
117
|
|
|
@@ -122,21 +126,21 @@ CLAUDE.md # user-owned; ONE injected line: @.claude
|
|
|
122
126
|
guidelines/<name>.md # companion-shipped, frontmatter stripped
|
|
123
127
|
.claude/skills/<name>/
|
|
124
128
|
SKILL.md # companion-shipped, installed verbatim (frontmatter included)
|
|
125
|
-
<supporting files> # optional
|
|
129
|
+
<supporting files> # optional extras (references/, examples/, …), installed as shipped (*.md.erb rendered)
|
|
126
130
|
.hyperdrive/lock.yml # git-tracked manifest (source gem, version, content hash)
|
|
127
131
|
```
|
|
128
132
|
|
|
129
|
-
A `git diff` is where you review what a companion gem added. The install summary names each artifact's source gem and version, and every installed file is hashed and attributed to its source in the git-tracked `.hyperdrive/lock.yml
|
|
133
|
+
A `git diff` is where you review what a companion gem added. The install summary names each artifact's source gem and version, and every installed file is hashed and attributed to its source in the git-tracked `.hyperdrive/lock.yml`. The files themselves land byte-identical to what the gem ships, with nothing injected. `hyperdrive:init` warns if your app gitignores these paths, since that empties the diff without changing what reaches the agent. The `hyperdrive:discover` cache is the one file rails-hyperdrive adds to `.gitignore`.
|
|
130
134
|
|
|
131
|
-
`CLAUDE.md` and `index.md` are the **eager chain
|
|
135
|
+
`CLAUDE.md` and `index.md` are the **eager chain**: they exist only because a companion gem ships a guideline, and both go when the last one leaves the bundle (the guideline file itself is left on disk and reported as an orphan).
|
|
132
136
|
|
|
133
137
|
### Your edits win
|
|
134
138
|
|
|
135
|
-
Installed files are yours to modify. The lockfile hash tells the installer whether a file is still gem-pristine: unedited files are refreshed on upgrade, edited files are skipped with a warning
|
|
139
|
+
Installed files are yours to modify. The lockfile hash tells the installer whether a file is still gem-pristine: unedited files are refreshed on upgrade, edited files are skipped with a warning, never silently overwritten. `hyperdrive:sync --overwrite` is the explicit way back to gem-shipped content.
|
|
136
140
|
|
|
137
141
|
### Turning off a single artifact
|
|
138
142
|
|
|
139
|
-
A companion gem you want for one skill but not another doesn't have to be all-or-nothing. Add the artifact's name to the `disabled:` list in `.hyperdrive/lock.yml
|
|
143
|
+
A companion gem you want for one skill but not another doesn't have to be all-or-nothing. Add the artifact's name to the `disabled:` list in `.hyperdrive/lock.yml`. It is written empty on every install, so the shape is already there:
|
|
140
144
|
|
|
141
145
|
```yaml
|
|
142
146
|
disabled:
|
|
@@ -146,15 +150,15 @@ disabled:
|
|
|
146
150
|
- jobs-sidekiq
|
|
147
151
|
```
|
|
148
152
|
|
|
149
|
-
A disabled artifact is never installed, and one already on disk is removed on the next `hyperdrive:init` or `hyperdrive:sync
|
|
153
|
+
A disabled artifact is never installed, and one already on disk is removed on the next `hyperdrive:init` or `hyperdrive:sync`, but **only if you haven't edited it**. A locally modified file is reported and left alone, for you to delete when you're ready. Disabling a skill removes its shipped supporting files under the same per-file rule; files you created yourself in the skill directory survive and keep the directory alive. Disabling a guideline also drops its line from `index.md`, so it leaves eager context along with the file.
|
|
150
154
|
|
|
151
|
-
The list is yours to edit; the generator only reads it and carries it forward. Delete a name to get the artifact back on the next run. When two companion gems ship the same artifact name, both install under a `<name>--<source-gem>` suffix
|
|
155
|
+
The list is yours to edit; the generator only reads it and carries it forward. Delete a name to get the artifact back on the next run. When two companion gems ship the same artifact name, both install under a `<name>--<source-gem>` suffix: the plain name disables both, the suffixed name disables one.
|
|
152
156
|
|
|
153
157
|
To skip installed content wholesale instead, pass `--skip-content` to `hyperdrive:init`.
|
|
154
158
|
|
|
155
159
|
### Opting into a gem's bundled skills
|
|
156
160
|
|
|
157
|
-
Ordinary gems (not built as hyperdrive companions) sometimes ship a top-level `skills/` directory of
|
|
161
|
+
Ordinary gems (not built as hyperdrive companions) sometimes ship a top-level `skills/` directory of skills.sh-style skills. Those are never installed automatically: `hyperdrive:init` and `hyperdrive:sync` only report them, e.g. `gem 'foo' ships 2 skills.sh skill(s)`. To install them, name the gem in the `enabled:` list in `.hyperdrive/lock.yml` and re-run `hyperdrive:sync`:
|
|
158
162
|
|
|
159
163
|
```yaml
|
|
160
164
|
enabled:
|
|
@@ -167,7 +171,7 @@ An enabled gem is treated as a companion from then on: its skills install throug
|
|
|
167
171
|
|
|
168
172
|
## Safety
|
|
169
173
|
|
|
170
|
-
Rails Hyperdrive is **dev-only**, enforced in depth: the engine refuses
|
|
174
|
+
Rails Hyperdrive is **dev-only**, enforced in depth: the engine refuses requests outside `Rails.env.development?`, applies an origin allowlist (`localhost`, `127.0.0.1`, `[::1]`), and every tool re-checks the dev guard on invocation. `run_sql` accepts read-only statements and refuses anything else. See [SECURITY.md](SECURITY.md).
|
|
171
175
|
|
|
172
176
|
---
|
|
173
177
|
|
|
@@ -180,9 +184,9 @@ skills/<name>/SKILL.md # skill (dir-per-skill, m
|
|
|
180
184
|
lib/<gem_name>/hyperdrive/guidelines/<name>.md # guideline (flat file)
|
|
181
185
|
```
|
|
182
186
|
|
|
183
|
-
Top-level `skills/` is the recommended home for skill content
|
|
187
|
+
Top-level `skills/` is the recommended home for skill content: it is the tool-agnostic face of your gem, readable by skills.sh and plain git-clone consumers as well as hyperdrive, and it is scanned by default. `lib/<gem_name>/hyperdrive/` is the hyperdrive-specific root: guidelines, and ERB skill templates (`SKILL.md.erb`, which must stay out of `skills/` so raw ERB never reaches generic consumers). Plain skills shipped under it remain scanned as well.
|
|
184
188
|
|
|
185
|
-
Frontmatter is pure
|
|
189
|
+
Frontmatter is pure skills.sh: only `name` and `description` are read, so a skill repo's content integrates without modification:
|
|
186
190
|
|
|
187
191
|
```yaml
|
|
188
192
|
---
|
|
@@ -191,7 +195,7 @@ description: Background job conventions for Sidekiq.
|
|
|
191
195
|
---
|
|
192
196
|
```
|
|
193
197
|
|
|
194
|
-
Gating
|
|
198
|
+
Gating (which bundles an artifact installs into) lives in a `hyperdrive.yml` manifest at the gem root (or at the path named by a `rails_hyperdrive_manifest` gemspec metadata key), never in the content. Every key is optional; no manifest (or an empty one) means everything installs universally:
|
|
195
199
|
|
|
196
200
|
```yaml
|
|
197
201
|
gem: sidekiq # gem-wide default: TARGET gem(s), resolved + version-matched in the bundle
|
|
@@ -204,20 +208,20 @@ guidelines: # per-guideline overrides, keyed by filename
|
|
|
204
208
|
gem: sidekiq
|
|
205
209
|
```
|
|
206
210
|
|
|
207
|
-
Shipping a `hyperdrive.yml` (or declaring `rails_hyperdrive_manifest`) opts your gem in as a companion. Also declare your targets in gemspec metadata
|
|
211
|
+
Shipping a `hyperdrive.yml` (or declaring `rails_hyperdrive_manifest`) opts your gem in as a companion. Also declare your targets in gemspec metadata. That opts your gem in too, and it is the pre-install targeting signal (how `hyperdrive:discover` suggests you before anyone installs you):
|
|
208
212
|
|
|
209
213
|
```ruby
|
|
210
214
|
spec.metadata["rails_hyperdrive_targets"] = "sidekiq"
|
|
211
215
|
```
|
|
212
216
|
|
|
213
|
-
|
|
217
|
+
[docs/COMPANION_GEMS.md](docs/COMPANION_GEMS.md) has the full contract: multi-target artifacts, multi-file skills, per-file gem gating, ERB-templated content, the template/content paired layout that also serves `npx skills` and git-clone consumers, and the collision and dedup rules.
|
|
214
218
|
|
|
215
219
|
---
|
|
216
220
|
|
|
217
221
|
## Requirements
|
|
218
222
|
|
|
219
|
-
Ruby ≥ 3.2, Rails ≥ 7.2. Tested against Rails 7.2 and 8.1 on Ruby 3.2
|
|
223
|
+
Ruby ≥ 3.2, Rails ≥ 7.2. Tested against Rails 7.2 and 8.1 on Ruby 3.2-3.4.
|
|
220
224
|
|
|
221
225
|
## License
|
|
222
226
|
|
|
223
|
-
MIT
|
|
227
|
+
MIT. See [LICENSE.txt](LICENSE.txt).
|
|
@@ -22,6 +22,8 @@ module Rails
|
|
|
22
22
|
GEMFILE = "Gemfile".freeze
|
|
23
23
|
BUNDLER_PLUGIN = "bundler-rails-hyperdrive".freeze
|
|
24
24
|
|
|
25
|
+
# No templates are rendered; source_root exists so Rails resolves the
|
|
26
|
+
# sibling USAGE file for `--help`.
|
|
25
27
|
source_root File.expand_path("templates", __dir__)
|
|
26
28
|
|
|
27
29
|
class_option :mount_at, type: :string, default: DEFAULT_MOUNT_AT, desc: "Engine mount path."
|
|
@@ -77,11 +79,6 @@ module Rails
|
|
|
77
79
|
append_to_file GEMFILE, "#{prefix}plugin #{BUNDLER_PLUGIN.inspect}\n"
|
|
78
80
|
end
|
|
79
81
|
|
|
80
|
-
def write_initializer
|
|
81
|
-
return if mount_path == DEFAULT_MOUNT_AT
|
|
82
|
-
template "initializer.rb.tt", "config/initializers/hyperdrive.rb"
|
|
83
|
-
end
|
|
84
|
-
|
|
85
82
|
def mount_engine
|
|
86
83
|
routes_file = "config/routes.rb"
|
|
87
84
|
unless File.exist?(::Rails.root.join(routes_file))
|
|
@@ -117,10 +114,16 @@ module Rails
|
|
|
117
114
|
say " Next steps:"
|
|
118
115
|
say " 1. bin/rails server"
|
|
119
116
|
say " 2. Open Claude Code in this directory; it will read .mcp.json"
|
|
120
|
-
say " 3. Verify the connection:
|
|
117
|
+
say " 3. Verify the connection: #{connection_check_command}"
|
|
121
118
|
end
|
|
122
119
|
|
|
123
120
|
no_tasks do
|
|
121
|
+
def connection_check_command
|
|
122
|
+
"curl -s http://localhost:3000#{mount_path}/mcp " \
|
|
123
|
+
"-H 'Content-Type: application/json' -H 'Accept: application/json' " \
|
|
124
|
+
"-d '{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"tools/list\"}'"
|
|
125
|
+
end
|
|
126
|
+
|
|
124
127
|
def mcp_json_on_disk
|
|
125
128
|
abs = ::Rails.root.join(MCP_JSON_PATH)
|
|
126
129
|
File.exist?(abs) ? File.read(abs) : nil
|
|
@@ -6,7 +6,7 @@ module Rails
|
|
|
6
6
|
module Generators
|
|
7
7
|
module Hyperdrive
|
|
8
8
|
# Content-only by contract: no step may write a bootstrap artifact
|
|
9
|
-
# (.mcp.json, the engine mount, the
|
|
9
|
+
# (.mcp.json, the engine mount, the .gitignore rule).
|
|
10
10
|
class SyncGenerator < ::Rails::Generators::Base
|
|
11
11
|
include ContentSyncSupport
|
|
12
12
|
|
|
@@ -40,7 +40,7 @@ module Rails
|
|
|
40
40
|
shown = rows.first(ROW_CAP)
|
|
41
41
|
lines = [result.columns.join("\t")]
|
|
42
42
|
shown.each { |row| lines << row.map { |v| v.to_s }.join("\t") }
|
|
43
|
-
lines << "(#{rows.length} rows
|
|
43
|
+
lines << "(showing first #{ROW_CAP} of #{rows.length} rows)" if rows.length > ROW_CAP
|
|
44
44
|
lines.join("\n")
|
|
45
45
|
end
|
|
46
46
|
end
|
data/lib/rails/hyperdrive.rb
CHANGED
|
@@ -2,16 +2,6 @@ require "rails/hyperdrive/version"
|
|
|
2
2
|
|
|
3
3
|
module Rails
|
|
4
4
|
module Hyperdrive
|
|
5
|
-
class Configuration
|
|
6
|
-
DEFAULT_MOUNT_AT = "/_hyperdrive".freeze
|
|
7
|
-
|
|
8
|
-
attr_accessor :mount_at
|
|
9
|
-
|
|
10
|
-
def initialize
|
|
11
|
-
@mount_at = DEFAULT_MOUNT_AT
|
|
12
|
-
end
|
|
13
|
-
end
|
|
14
|
-
|
|
15
5
|
def self.root
|
|
16
6
|
@root ||= File.expand_path("..", __dir__)
|
|
17
7
|
end
|
|
@@ -19,18 +9,6 @@ module Rails
|
|
|
19
9
|
def self.dev_mode?
|
|
20
10
|
defined?(::Rails) && ::Rails.respond_to?(:env) && ::Rails.env.development?
|
|
21
11
|
end
|
|
22
|
-
|
|
23
|
-
def self.configuration
|
|
24
|
-
@configuration ||= Configuration.new
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
def self.configure
|
|
28
|
-
yield(configuration)
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
def self.reset_configuration!
|
|
32
|
-
@configuration = nil
|
|
33
|
-
end
|
|
34
12
|
end
|
|
35
13
|
end
|
|
36
14
|
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: rails-hyperdrive
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.6.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Bakaface
|
|
@@ -89,7 +89,6 @@ files:
|
|
|
89
89
|
- lib/generators/hyperdrive/gitignore_support.rb
|
|
90
90
|
- lib/generators/hyperdrive/install/USAGE
|
|
91
91
|
- lib/generators/hyperdrive/install/install_generator.rb
|
|
92
|
-
- lib/generators/hyperdrive/install/templates/initializer.rb.tt
|
|
93
92
|
- lib/generators/hyperdrive/install_summary.rb
|
|
94
93
|
- lib/generators/hyperdrive/sync/USAGE
|
|
95
94
|
- lib/generators/hyperdrive/sync/sync_generator.rb
|