rails-ai-context 5.34.0 → 5.35.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 +66 -0
- data/CLAUDE.md +3 -0
- data/CONTEXT.md +33 -1
- data/README.md +193 -149
- data/docs/CLI.md +53 -5
- data/docs/COMPATIBILITY.md +10 -0
- data/docs/CONFIGURATION.md +1 -0
- data/docs/FAQ.md +12 -3
- data/docs/GUIDE.md +52 -23
- data/docs/PROMPTS.md +394 -0
- data/docs/QUICKSTART.md +17 -5
- data/docs/RELEASING.md +15 -6
- data/docs/SETUP.md +59 -39
- data/docs/STANDALONE.md +9 -3
- data/docs/TOOLS.md +1 -1
- data/docs/TROUBLESHOOTING.md +23 -4
- data/docs/adr/0006-strong-params-resolve-as-ruby-runs.md +10 -0
- data/docs/adr/0007-every-install-question-has-a-flag.md +25 -0
- data/docs/index.md +1 -0
- data/exe/rails-ai-context +148 -25
- data/lib/generators/rails_ai_context/install/install_generator.rb +71 -22
- data/lib/rails_ai_context/install/ai_tool.rb +13 -1
- data/lib/rails_ai_context/install/cleanup.rb +34 -2
- data/lib/rails_ai_context/install/program.rb +221 -43
- data/lib/rails_ai_context/install/uninstall.rb +105 -0
- data/lib/rails_ai_context/install/validation_hook.rb +48 -0
- data/lib/rails_ai_context/legacy_cleanup.rb +8 -5
- data/lib/rails_ai_context/mcp_config_generator.rb +14 -4
- data/lib/rails_ai_context/version.rb +1 -1
- data/server.json +1 -1
- metadata +6 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 63645c29cd90be888f3a5417ecdc022404033905ec0ecef3d8da431602060931
|
|
4
|
+
data.tar.gz: 82365666d69092f451df32c00345ac88adac5b975987ecf3da1e55141ca06088
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 5e04445f7c8580e3e963d4c013a8dfe001162e4966144e8b9989786e3e21f962c188ff2c12352282684584dfb72c05d2dcf52fa2bc9548c17c944c91c0e6e96c
|
|
7
|
+
data.tar.gz: c3f2708a684212fede795c107421c1b6491d9705c23d9a06f2ec5e190f24dd1f87394ee61d2fc4cda4205c0ade2321a9a7ec17f446d159d6fa15399fd3cbe9cd
|
data/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,72 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [5.35.0] - 2026-10-12
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- **Copy-paste prompts.** `docs/PROMPTS.md` holds a prompt for every way
|
|
13
|
+
to set the gem up, change it, upgrade it, fix it and remove it, plus
|
|
14
|
+
prompts for daily work. Paste one into Claude Code, Cursor, GitHub
|
|
15
|
+
Copilot, OpenCode or Codex CLI and it runs the install in its own shell.
|
|
16
|
+
Prompts cover the Gemfile and standalone installs, the three setups, a
|
|
17
|
+
team, a folder of apps, a private setup, a try-out, HTTP, Ruby in Docker
|
|
18
|
+
and MCP clients the gem writes no config for.
|
|
19
|
+
- **Every install question has a flag.** `init` and the install generator
|
|
20
|
+
take `--tools claude,cursor` (or `all`), `--mcp`, `--cli`, `--prune`, and `init`
|
|
21
|
+
takes `--defaults` too; the generator also takes `--hook`. With them an AI
|
|
22
|
+
tool or a script runs the install to the end with nobody at the keyboard.
|
|
23
|
+
A flag the install cannot read, such as a tool name it does not know,
|
|
24
|
+
`--cli` with `--mcp-only`, or a flag the generator does not have, stops it
|
|
25
|
+
with exit status 1 before anything is written. Only `--prune` removes
|
|
26
|
+
files: a dropped tool's, the gem's MCP entries on a switch to the CLI
|
|
27
|
+
setup, the generated context files on a switch to the MCP-only setup, and
|
|
28
|
+
legacy files.
|
|
29
|
+
ADR-0007 records the design.
|
|
30
|
+
- **`rails-ai-context uninstall`.** It removes each AI tool's context files
|
|
31
|
+
and MCP entries, `.rails-ai-context.yml`, `.ai-context.json`, the
|
|
32
|
+
initializer, the `.gitignore` lines and the pre-commit hook it installed,
|
|
33
|
+
and keeps what you wrote: your lines in a shared `CLAUDE.md`, other
|
|
34
|
+
servers in an MCP config, a hook you changed. It names a
|
|
35
|
+
`mount RailsAiContext::Engine` line instead of editing routes, works in a
|
|
36
|
+
folder of apps, and needs no boot.
|
|
37
|
+
- **`rails-ai-context mcp-entry`.** It prints a server entry for an MCP
|
|
38
|
+
client the gem writes no config for (Claude Desktop, Windsurf, Zed, a
|
|
39
|
+
JetBrains IDE), with the Ruby binary, the executable and the app by their
|
|
40
|
+
full paths and the gem environment beside them, so it starts from
|
|
41
|
+
whatever folder the client uses.
|
|
42
|
+
|
|
43
|
+
### Changed
|
|
44
|
+
|
|
45
|
+
- **A re-run's default is what the app has.** An empty answer, or
|
|
46
|
+
`--defaults`, on a re-run keeps the recorded AI tools and setup. It used
|
|
47
|
+
to take all five tools and the MCP setup, so running the install again to
|
|
48
|
+
repair a CLI or MCP-only install switched it. A first install's defaults
|
|
49
|
+
are unchanged, and `--mcp` names the MCP setup outright. In a folder of
|
|
50
|
+
apps that recorded different setups, `--defaults` asks for a setup flag
|
|
51
|
+
instead of picking one.
|
|
52
|
+
- **Switching to the MCP-only setup offers to remove the generated context
|
|
53
|
+
files.** Nothing refreshes them once the install writes none, so they
|
|
54
|
+
went stale; the question lists them, `--prune` answers yes, and the lines
|
|
55
|
+
you wrote stay.
|
|
56
|
+
- **The install summary names each AI tool's next step.** It said the MCP
|
|
57
|
+
config was "auto-detected on project open" with "no manual config
|
|
58
|
+
needed", but every tool holds a project's server back until you approve
|
|
59
|
+
it (Claude Code), turn it on (Cursor), trust the folder (VS Code, Codex
|
|
60
|
+
CLI) or restart (OpenCode). The summary now says which, per tool.
|
|
61
|
+
|
|
62
|
+
## [5.34.1] - 2026-10-12
|
|
63
|
+
|
|
64
|
+
### Changed
|
|
65
|
+
|
|
66
|
+
- **The repository tracks `CLAUDE.md`.** It points at `AGENTS.md`, and the
|
|
67
|
+
gem ships it beside the `AGENTS.md` and `CONTEXT.md` it already shipped.
|
|
68
|
+
The code is v5.34.0's.
|
|
69
|
+
- **The glossary defines strong params and notable gems.** `CONTEXT.md` says
|
|
70
|
+
what makes a method strong params and which gems count as notable, and
|
|
71
|
+
ADR-0006 records why a strong params call is read as the method Ruby
|
|
72
|
+
would run.
|
|
73
|
+
|
|
8
74
|
## [5.34.0] - 2026-10-12
|
|
9
75
|
|
|
10
76
|
### Security
|
data/CLAUDE.md
ADDED
data/CONTEXT.md
CHANGED
|
@@ -66,7 +66,7 @@ The other half of the same problem is the reverse trip. Once a name is the decla
|
|
|
66
66
|
|
|
67
67
|
## Table name
|
|
68
68
|
|
|
69
|
-
The table a model reads. Rails builds it as `table_name_prefix` + the demodulized class name, pluralized unless `pluralize_table_names` is off, + `table_name_suffix`, unless the class assigns one itself or is an STI child, which reads its parent's. The static tier answers the same order from source: an explicit `self.table_name =`, else the table of the model it inherits from, else the prefix and suffix the enclosing modules declare around the file's own basename. That basename is pluralized unless the class, then its superclass chain, then the app sets `pluralize_table_names = false`. A class on a parent the app does not define (`Tag < ActsAsTaggableOn::Tag`) reads the parent's table, which the static tier takes from the
|
|
69
|
+
The table a model reads. Rails builds it as `table_name_prefix` + the demodulized class name, pluralized unless `pluralize_table_names` is off, + `table_name_suffix`, unless the class assigns one itself or is an STI child, which reads its parent's. The static tier answers the same order from source: an explicit `self.table_name =`, else the table of the model it inherits from, else the prefix and suffix the enclosing modules declare around the file's own basename. That basename is pluralized unless the class, then its superclass chain, then the app sets `pluralize_table_names = false`. A class on a parent the app does not define (`Tag < ActsAsTaggableOn::Tag`) reads the parent's table, which the static tier takes from the dumps: the one table the primary's schema holds among the parent's names and the class's own, else the one another database's dump holds. The app-wide affixes and pluralize setting come from `ActiveRecordSettings`, which reads config/application.rb, the environment file, the initializers and `on_load(:active_record)` blocks. Never the underscored constant as an answer - that turns `Admin::ActionLog` into `admin/action_logs` and `OAuthClientConfig` into `o_auth_client_configs`, neither of which is a table; a gem parent's underscored name is only a candidate the schema must hold.
|
|
70
70
|
|
|
71
71
|
`TableName` reads the five declarations of one class body (`table_name`, `table_name_prefix`, `table_name_suffix`, `pluralize_table_names` and `primary_key`) and holds the two derivations; walking the namespace and the superclass chain belongs to the caller, because only it has the other files. A reader that starts from a model name instead of a file asks `TableName.for_model_name`, which takes the table the model tier already recorded before falling back to the convention. A module prefix declared outside the model directories is still invisible, an engine's in `lib/**/engine.rb` aside, so the answer stays [STATIC].
|
|
72
72
|
|
|
@@ -153,6 +153,18 @@ Which filters a controller runs, and which of them a given action runs. `ActionF
|
|
|
153
153
|
|
|
154
154
|
**What it cannot see is stated rather than guessed.** The walk reads `ApplicationController`'s file by the one name Rails fixes, so its filters are in the chain; a parent the listing does not hold and the app has no file for - a gem-owned base other than Devise's or Doorkeeper's (there the walk resumes at the parent the initializer names), or one an inflection renames - still ends the walk. `docs/COMPATIBILITY.md` says both halves.
|
|
155
155
|
|
|
156
|
+
## Strong params
|
|
157
|
+
|
|
158
|
+
A controller method that returns permitted params: it calls `permit`, `permit!` or `expect` on params, or returns what `super`, another strong params method, or a call handed the whole params gives back. What it returns makes one, never its name: a `*_params` method that builds associations is not one. A controller has its own and each superclass's that no nearer class redefines.
|
|
159
|
+
|
|
160
|
+
**A call reaches the method Ruby would run.** That is the nearest class in the controller's chain that defines the name, so a parent's helper counts whatever it is called (Mastodon's `params_slice`), a child that redefines it decides for every class above it, and a class method or a nested class's method of that name redefines nothing. A name none of the controller's classes defines, a concern's, a gem's or Pundit's, is taken at its `*_params` or `permitted_*` name. ADR-0006 records why.
|
|
161
|
+
|
|
162
|
+
**An action and a strong params method can be one method.** An action that permits inline is an action, not strong params. A public `*_params` method that permits is strong params, and since Rails can dispatch to it, the **Action** reading lists it too.
|
|
163
|
+
|
|
164
|
+
## Notable gem
|
|
165
|
+
|
|
166
|
+
A gem the context calls out because it shapes how the app is built, counted only when the app itself runs it: the Gemfile names it (or a gemspec or path gem it pulls in does), it hooks into Rails on its own whichever gem brings it (a railtie or an engine, and OmniAuth), or it is a Rails framework the app loads. A gem that sits in the lockfile only because another gem needs it is not one.
|
|
167
|
+
|
|
156
168
|
## Payload
|
|
157
169
|
|
|
158
170
|
The introspection context hash, in the sense consumers read it. `Payload` is the reading side: a section guard and pinned list readers whose key pairs a spec checks against the producing introspector's own output, so a renamed key fails a test instead of silently emptying a section everywhere. Facts rendered from it live once (`SectionFacts`); membership judgments are applied at the introspector seam, and readers trust the payload rather than re-filtering it.
|
|
@@ -178,3 +190,23 @@ A folder an editor or agent is opened at that is no app and has no app above it,
|
|
|
178
190
|
**Server name** - the key an entry has in a config. An app's own config calls its server `rails-ai-context`; a workspace's calls each one `rails-ai-context-<app folder>` (`Install::Workspace.server_names`), with the whole path where two apps share a folder name, and a hash where the name would be too long for the tools. `McpConfigGenerator::OWN_SERVER_NAME` matches every form, and `own_entry?` claims the ones that run the gem's server, so removal never leaves one behind and never takes an entry somebody else named that way. Not the **announced name**, which the running server gives the tool (`config.server_name`, or, in place of its default, `RAILS_AI_CONTEXT_SERVER_NAME` for one process): a workspace server announces its app first, because VS Code names tools after that and keeps 13 characters of it.
|
|
179
191
|
|
|
180
192
|
**Workspace entry** - the server entry itself: `--app-path` relative to the workspace, because the file may be committed; spelled from the tool's own name for its config's folder (`${workspaceFolder}`) where it has one, bare where the tool starts servers in the folder it was launched in. For an in-Gemfile app it adds `BUNDLE_GEMFILE` naming the Gemfile the app's bundle reads (its own, else the shared one its `config/boot.rb` names, else the one `bundle exec` run inside the app would find), because `bundle exec` started in the workspace would never find it. ADR-0005 records the per-tool facts this rests on.
|
|
193
|
+
|
|
194
|
+
## Setup
|
|
195
|
+
|
|
196
|
+
What an install writes, one of three. Qualify it; "mode" alone names only one of its two parts.
|
|
197
|
+
|
|
198
|
+
**MCP setup** - the MCP config for each AI tool plus its context files. The default.
|
|
199
|
+
|
|
200
|
+
**CLI setup** - the context files and no MCP config (`tool_mode: cli`). The AI tool runs the tools as shell commands, and the context files tell it how.
|
|
201
|
+
|
|
202
|
+
**MCP-only setup** - the MCP config and no context files (`context_files: false`). For a user who keeps their own `CLAUDE.md` and `AGENTS.md`.
|
|
203
|
+
|
|
204
|
+
`tool_mode` is one axis (mcp or cli) and `context_files` the other, so the MCP-only setup is the mcp tool mode without context files, not a third tool mode. `Install::Program::Setup` holds the pair.
|
|
205
|
+
|
|
206
|
+
## Unattended install
|
|
207
|
+
|
|
208
|
+
An install with every question answered on the command line, the way an AI tool runs it from an **install prompt** or a script runs it in CI. A flag answers its question (`--tools`, `--mcp`, `--cli` or `--mcp-only`, `--prune`, `--hook`), `--defaults` answers the rest with their defaults, and a flag the install cannot read stops it before anything is asked or written. A default is what the app has: the recorded tools and **setup** on a re-run, all five tools and the MCP setup on a first install. A default never removes a file; only `--prune` does. ADR-0007 records why.
|
|
209
|
+
|
|
210
|
+
## Install prompt
|
|
211
|
+
|
|
212
|
+
A message a user pastes into their AI tool so the AI tool installs, changes, removes or starts using the gem in their app. `docs/PROMPTS.md` holds them. Each names its commands outright and runs an **unattended install**, since an AI tool's shell has no one at the keyboard to answer a question.
|