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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e3129c92d99c38d7980f17c705e5b957276a29f9ad997d6679e90dc11c00749a
4
- data.tar.gz: 17d8db1739e11c246c0a2efce059682daf9cb564b6745bf4db4dcbf0750bd091
3
+ metadata.gz: 63645c29cd90be888f3a5417ecdc022404033905ec0ecef3d8da431602060931
4
+ data.tar.gz: 82365666d69092f451df32c00345ac88adac5b975987ecf3da1e55141ca06088
5
5
  SHA512:
6
- metadata.gz: f8297d9939243f9575baa725c5a10912c2def888f86a4ee918c95f54dec07516077ee55fc5e593d9ab1ee43bb7b7e9c32187db4d0d79f5e7f32abb2bb35b5e36
7
- data.tar.gz: 026cbb700cfadaf16e6d16f760456fe9d3d0a4f5486eb69406a00abe22a96789558310e044ef5ea2e791b8e730d8c21a064bb125c8d35c97e96aabc8a6835047
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
@@ -0,0 +1,3 @@
1
+ # rails-ai-context
2
+
3
+ Project instructions live in `AGENTS.md`, which is committed and shared. Read it.
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 schema: the table it holds among the parent's names and the class's own. 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.
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.