ask-rails-harness 0.2.1 → 0.3.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: 6b7c1f9342c45ef3d4472772717fcc6ff302b35999e74806bd8964510f729f2f
4
- data.tar.gz: 017c0f1b89629f435bde77c637c96e866caffb3be86f27d99adcf6431cc79cb3
3
+ metadata.gz: 70e5e797b91144992c18866c357d73811226b3281955a208437eed7ae02b0b63
4
+ data.tar.gz: c110d660dbd193597f1bfcbae2ea5b3184f676984d4e9dc1ce9401df899d36e4
5
5
  SHA512:
6
- metadata.gz: 4a3c0d99ae4b7f7725365827e4707fc56ca680bcee0fe7d0617c03bc7aa4e8c14039ee858016ad867648e4c5dec545acaec1b1b7934f6b3ed20d72d6a9d122db
7
- data.tar.gz: 0b9c8b0b65b3baab555bde4c7e938c447b6b0527ea073a0abc3f9179d3ce8836e4f49221b601b20fd95446d33b40571f49f61bc25380baeba2cfe162a087b7bc
6
+ metadata.gz: ce9d990603fed30ed9bdf9ee20cd3087694dc7739f3751d03343f9f4d0b6a957bd9b8ba7b7146a58a45c002ef8931d26766548ed3e50aed2233acbfe16595746
7
+ data.tar.gz: 353fbc3c92ba503b3d6bb9732d9030c4d967279584814810768c32556b98c6584eaa5465b33eef3e0e00425f163e5a6466136aa040d8bb0342847a068c6a4959
data/CHANGELOG.md CHANGED
@@ -1,3 +1,15 @@
1
+ ## [0.3.0] — 2026-08-10
2
+
3
+ ### Removed
4
+
5
+ - **`ReadFile`, `SearchCodebase`, `ReadRoutes` tools removed** — generic
6
+ file-read and grep capabilities that coding agents provide natively.
7
+ `RouteInspector` fully supersedes `ReadRoutes` (parsed table vs raw file,
8
+ including `draw`-split and engine routes). The harness now ships only
9
+ Rails-aware tools: `QueryDatabase`, `ReadModel`, `ReadLog`, `RunCommand`,
10
+ `SchemaGraph`, `RouteInspector`, `RunTests`. Skills updated to use the
11
+ shell `Read` tool and `RouteInspector`.
12
+
1
13
  ## [0.2.1] — 2026-08-10
2
14
 
3
15
  ### Fixed
data/README.md CHANGED
@@ -68,15 +68,18 @@ Available settings: `default_model`, `max_turns`, `tool_concurrency`, `system_pr
68
68
 
69
69
  | Tool | What it does |
70
70
  |---|---|
71
- | `ReadFile` | Read any file relative to `Rails.root` |
72
71
  | `QueryDatabase` | Read-only SQL (non-SELECT rejected in production) |
73
72
  | `ReadModel` | Inspect an ActiveRecord model's columns, associations, validations |
74
- | `ReadRoutes` | Read `config/routes.rb` |
75
73
  | `ReadLog` | Read log files with level/search filtering |
76
- | `RunCommand` | Run shell commands in the app root |
77
- | `SearchCodebase` | Grep the codebase |
74
+ | `RunCommand` | Run shell commands in the app root, gated by permission rules |
78
75
  | `SchemaGraph` | Full schema introspection: models, tables, columns, associations |
79
76
  | `RouteInspector` | Parsed route table with filters |
77
+ | `RunTests` | Structured test results with failure reruns (minitest/rspec) |
78
+
79
+ Generic file and search capabilities (read, grep, edit) are provided by the
80
+ agent's native tools; the harness focuses on what only a Rails-aware layer
81
+ can give an agent: database access, schema/model introspection, routes,
82
+ logs, and tests — all permission-gated and audited.
80
83
 
81
84
  ## Full documentation
82
85
 
@@ -3,7 +3,7 @@
3
3
  module Ask
4
4
  module Rails
5
5
  module Harness
6
- VERSION = "0.2.1"
6
+ VERSION = "0.3.0"
7
7
  end
8
8
  end
9
9
  end
@@ -165,10 +165,7 @@ require_relative "harness/auth"
165
165
  require_relative "harness/persistence"
166
166
  require_relative "harness/service_discovery"
167
167
  require_relative "harness/tool"
168
- require_relative "harness/tools/read_file"
169
168
  require_relative "harness/tools/run_command"
170
- require_relative "harness/tools/search_codebase"
171
- require_relative "harness/tools/read_routes"
172
169
  require_relative "harness/tools/query_database"
173
170
  require_relative "harness/tools/read_model"
174
171
  require_relative "harness/tools/read_log"
@@ -184,8 +181,7 @@ end
184
181
 
185
182
  # Define after all tool files are loaded so the constants resolve
186
183
  Ask::Rails::Harness::CORE_RAILS_TOOLS = [
187
- Ask::Rails::Harness::Tools::ReadFile, Ask::Rails::Harness::Tools::RunCommand,
188
- Ask::Rails::Harness::Tools::SearchCodebase, Ask::Rails::Harness::Tools::ReadRoutes,
184
+ Ask::Rails::Harness::Tools::RunCommand,
189
185
  Ask::Rails::Harness::Tools::QueryDatabase, Ask::Rails::Harness::Tools::ReadModel,
190
186
  Ask::Rails::Harness::Tools::ReadLog, Ask::Rails::Harness::Tools::SchemaGraph,
191
187
  Ask::Rails::Harness::Tools::RouteInspector, Ask::Rails::Harness::Tools::RunTests
@@ -15,7 +15,7 @@ RunCommand.new.call(command: "bin/rails db:migrate:status | grep 'down'")
15
15
  ```
16
16
 
17
17
  If there are pending migrations:
18
- 1. Review them with `ReadFile.new.call(path: "db/migrate/<TIMESTAMP>_migration_name.rb")`
18
+ 1. Review them with `Read.new.call(path: Rails.root.join("db/migrate/<TIMESTAMP>_migration_name.rb").to_s)`
19
19
  2. Verify they're reversible: check `change`, `up`/`down`, or `reversible` blocks
20
20
  3. Check for data migrations (e.g., backfills) that should run separately
21
21
  4. Estimate execution time — large tables may need locking strategy
@@ -38,8 +38,8 @@ For importmap or esbuild/vite setups:
38
38
 
39
39
  ```ruby
40
40
  # Check build config
41
- ReadFile.new.call(path: "package.json")
42
- ReadFile.new.call(path: "vite.config.ts") if File.exist?("Rails.root.join('vite.config.ts')")
41
+ Read.new.call(path: Rails.root.join("package.json").to_s)
42
+ Read.new.call(path: Rails.root.join("vite.config.ts").to_s) if Rails.root.join("vite.config.ts").exist?
43
43
  ```
44
44
 
45
45
  ## Step 3: Review Credentials and Secrets
@@ -70,7 +70,7 @@ Glob.new.call(pattern: "app/jobs/**/*.rb")
70
70
  For any new or modified jobs:
71
71
  1. Verify the queue adapter is configured in `production.rb`
72
72
  2. Check for job retry logic that might affect rollback
73
- 3. Review `ReadFile.new.call(path: "config/sidekiq.yml")` if using Sidekiq
73
+ 3. Review `Read.new.call(path: Rails.root.join("config/sidekiq.yml").to_s)` if using Sidekiq
74
74
  4. Verify scheduled/cron jobs if using `sidekiq-cron` or `whenever`
75
75
 
76
76
  ## Step 5: Review Production Log for Pre-deploy Issues
@@ -102,10 +102,10 @@ RunCommand.new.call(command: "bundle platform")
102
102
  Verify configuration files for the target environment:
103
103
 
104
104
  ```ruby
105
- ReadFile.new.call(path: "config/environments/production.rb")
106
- ReadFile.new.call(path: "config/database.yml")
107
- ReadFile.new.call(path: "config/cable.yml") if File.exist?("config/cable.yml")
108
- ReadFile.new.call(path: "config/storage.yml") if File.exist?("config/storage.yml")
105
+ Read.new.call(path: Rails.root.join("config/environments/production.rb").to_s)
106
+ Read.new.call(path: Rails.root.join("config/database.yml").to_s)
107
+ Read.new.call(path: Rails.root.join("config/cable.yml").to_s) if Rails.root.join("config/cable.yml").exist?
108
+ Read.new.call(path: Rails.root.join("config/storage.yml").to_s) if Rails.root.join("config/storage.yml").exist?
109
109
  ```
110
110
 
111
111
  Key production checks:
@@ -6,15 +6,17 @@ description: Step-by-step methodology for debugging routing issues in Rails
6
6
  Use this skill when a route is returning 404, you're getting route matching errors,
7
7
  or routes aren't behaving as expected in a Rails application.
8
8
 
9
- ## Step 1: Read the Routes File
9
+ ## Step 1: Inspect the Route Table
10
10
 
11
- Start by examining the routes configuration:
11
+ Start by examining the parsed route table:
12
12
 
13
13
  ```ruby
14
- ReadRoutes.new.call
14
+ RouteInspector.new.call
15
15
  ```
16
16
 
17
- This reads `config/routes.rb` the source of truth for all route definitions.
17
+ This returns every route with its verb, path, controller, action, and name —
18
+ covering routes split across `draw` files and engines that a raw read of
19
+ `config/routes.rb` would miss.
18
20
 
19
21
  Look for:
20
22
  - The overall structure (namespaced, nested, shallow routes?)
@@ -82,7 +84,7 @@ error message tells you what routes were tried before failing.
82
84
  If the route exists but the controller isn't found:
83
85
 
84
86
  ```ruby
85
- ReadFile.new.call(path: "app/controllers/users_controller.rb")
87
+ Read.new.call(path: Rails.root.join("app/controllers/users_controller.rb").to_s)
86
88
  ```
87
89
 
88
90
  ## Step 5: Check Namespace and Module Nesting
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ask-rails-harness
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kaka Ruto
@@ -135,10 +135,10 @@ dependencies:
135
135
  - - "~>"
136
136
  - !ruby/object:Gem::Version
137
137
  version: '13.0'
138
- description: Rails Engine that mounts an admin AI agent at /ask. Ships 9 Rails-aware
139
- tools (ReadFile, QueryDatabase, ReadModel, ReadRoutes, RouteInspector, ReadLog,
140
- RunCommand, SearchCodebase, SchemaGraph), session persistence, audit logging, environment
141
- permissions, and service gem discovery. Previously developed as ask-rails (0.1.0–0.11.1).
138
+ description: Rails Engine that mounts an admin AI agent at /ask. Ships Rails-aware
139
+ tools (QueryDatabase, ReadModel, ReadLog, RunCommand, SchemaGraph, RouteInspector,
140
+ RunTests), session persistence, audit logging, environment permissions, and service
141
+ gem discovery. Previously developed as ask-rails (0.1.0–0.11.1).
142
142
  email:
143
143
  - kaka@myrrlabs.com
144
144
  executables: []
@@ -166,15 +166,12 @@ files:
166
166
  - lib/ask/rails/harness/service_discovery.rb
167
167
  - lib/ask/rails/harness/tool.rb
168
168
  - lib/ask/rails/harness/tools/query_database.rb
169
- - lib/ask/rails/harness/tools/read_file.rb
170
169
  - lib/ask/rails/harness/tools/read_log.rb
171
170
  - lib/ask/rails/harness/tools/read_model.rb
172
- - lib/ask/rails/harness/tools/read_routes.rb
173
171
  - lib/ask/rails/harness/tools/route_inspector.rb
174
172
  - lib/ask/rails/harness/tools/run_command.rb
175
173
  - lib/ask/rails/harness/tools/run_tests.rb
176
174
  - lib/ask/rails/harness/tools/schema_graph.rb
177
- - lib/ask/rails/harness/tools/search_codebase.rb
178
175
  - lib/ask/rails/harness/version.rb
179
176
  - lib/ask/skills/rails.db_debug/SKILL.md
180
177
  - lib/ask/skills/rails.deploy_pipeline/SKILL.md
@@ -1,23 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Ask
4
- module Rails
5
- module Harness
6
- module Tools
7
- class ReadFile < Ask::Rails::Harness::Tool
8
- description "Read a file from the Rails app. Paths are relative to Rails.root."
9
-
10
- param :path, type: :string, desc: "Relative path from Rails.root", required: true
11
-
12
- def execute(path:)
13
- full_path = rails_root.join(path)
14
- return Ask::Result.error(message: "File not found: #{path}") unless full_path.exist?
15
-
16
- content = full_path.read
17
- { path: path, content: content, size: content.length }
18
- end
19
- end
20
- end
21
- end
22
- end
23
- end
@@ -1,20 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Ask
4
- module Rails
5
- module Harness
6
- module Tools
7
- class ReadRoutes < Ask::Rails::Harness::Tool
8
- description "Read the Rails routes from config/routes.rb"
9
- def execute
10
- routes_file = rails_root.join("config", "routes.rb")
11
- return Ask::Result.error(message: "No routes file found") unless routes_file.exist?
12
-
13
- content = routes_file.read
14
- { content: content, size: content.length }
15
- end
16
- end
17
- end
18
- end
19
- end
20
- end
@@ -1,23 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Ask
4
- module Rails
5
- module Harness
6
- module Tools
7
- class SearchCodebase < Ask::Rails::Harness::Tool
8
- description "Search the Rails codebase with grep."
9
- param :pattern, type: :string, desc: "Search pattern", required: true
10
- param :path, type: :string, desc: "Subdirectory to search (optional)", required: false
11
-
12
- def execute(pattern:, path: nil)
13
- search_path = (path ? rails_root.join(path) : rails_root).to_s
14
- escaped_pattern = pattern.gsub("'", "'\\\\''")
15
- escaped_path = search_path.gsub("'", "'\\\\''")
16
- results = `cd #{rails_root} && grep -rn '#{escaped_pattern}' #{escaped_path} 2>&1 | head -50`
17
- { results: results.lines.map(&:chomp), count: results.lines.count }
18
- end
19
- end
20
- end
21
- end
22
- end
23
- end