admin_suite 0.5.0 → 0.6.2
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/.gitignore +7 -0
- data/CHANGELOG.md +78 -11
- data/CONTRIBUTING.md +9 -4
- data/Gemfile +1 -0
- data/README.md +25 -5
- data/app/controllers/admin_suite/application_controller.rb +12 -11
- data/app/controllers/admin_suite/mcp_controller.rb +36 -0
- data/app/controllers/admin_suite/resources_controller.rb +7 -78
- data/app/views/admin_suite/resources/index.html.erb +1 -0
- data/config/routes.rb +5 -0
- data/lib/admin/base/resource.rb +7 -29
- data/lib/admin_suite/auth/host_user.rb +42 -0
- data/lib/admin_suite/auth/strategy.rb +1 -1
- data/lib/admin_suite/auth.rb +15 -0
- data/lib/admin_suite/authorization_context.rb +28 -0
- data/lib/admin_suite/configuration.rb +56 -2
- data/lib/admin_suite/mcp/authorization.rb +68 -0
- data/lib/admin_suite/mcp/serializer.rb +138 -0
- data/lib/admin_suite/mcp/tools/aggregate.rb +55 -0
- data/lib/admin_suite/mcp/tools/describe_resources.rb +63 -0
- data/lib/admin_suite/mcp/tools/get_record.rb +41 -0
- data/lib/admin_suite/mcp/tools/list_records.rb +67 -0
- data/lib/admin_suite/mcp.rb +53 -0
- data/lib/admin_suite/query.rb +71 -0
- data/lib/admin_suite/ui/show_value_formatter.rb +2 -2
- data/lib/admin_suite/version.rb +1 -1
- data/lib/admin_suite.rb +14 -9
- data/lib/generators/admin_suite/install/templates/admin_suite.rb +5 -2
- data/test/archspec/enforcement_test.rb +115 -0
- data/test/controllers/resources_controller_test.rb +19 -13
- data/test/dummy/config/environments/development.rb +9 -6
- data/test/dummy_boot_test.rb +21 -0
- data/test/integration/authentication_test.rb +10 -0
- data/test/integration/authorization_test.rb +20 -3
- data/test/integration/index_query_characterization_test.rb +229 -0
- data/test/integration/mcp_aggregate_test.rb +44 -0
- data/test/integration/mcp_authorization_test.rb +102 -0
- data/test/integration/mcp_endpoint_test.rb +89 -0
- data/test/integration/mcp_get_record_test.rb +62 -0
- data/test/integration/mcp_instrumentation_test.rb +107 -0
- data/test/integration/mcp_list_records_test.rb +75 -0
- data/test/integration/mcp_parity_test.rb +155 -0
- data/test/integration/mcp_release_test.rb +131 -0
- data/test/integration/read_only_resource_test.rb +128 -2
- data/test/integration/searchable_select_search_test.rb +5 -4
- data/test/lib/action_executor_test.rb +17 -9
- data/test/lib/auth_host_user_test.rb +52 -0
- data/test/lib/auth_http_basic_test.rb +10 -0
- data/test/lib/auth_test.rb +20 -3
- data/test/lib/authorization_context_test.rb +127 -0
- data/test/lib/engine_defaults_test.rb +1 -2
- data/test/lib/mcp_serializer_test.rb +107 -0
- data/test/lib/query_test.rb +91 -0
- data/test/lib/removed_deprecations_test.rb +16 -0
- data/test/publish_workflow_test.rb +63 -0
- data/test/test_helper.rb +26 -0
- metadata +44 -5
- data/lib/admin_suite/renderers/legacy_gleania.rb +0 -232
- data/test/lib/legacy_renderer_deprecation_test.rb +0 -42
- data/test/lib/resource_exportable_deprecation_test.rb +0 -47
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "test_helper"
|
|
4
|
+
|
|
5
|
+
class McpSerializerTest < ActiveSupport::TestCase
|
|
6
|
+
Column = Data.define(:name)
|
|
7
|
+
Index = Data.define(:columns_list)
|
|
8
|
+
Config = Data.define(:index_config)
|
|
9
|
+
|
|
10
|
+
test "emits only the resource's declared columns" do
|
|
11
|
+
record = Struct.new(:id, :name, :secret_token).new(1, "Widget", "sh-hh")
|
|
12
|
+
config = Config.new(Index.new([Column.new(:id), Column.new(:name)]))
|
|
13
|
+
|
|
14
|
+
row = AdminSuite::Mcp::Serializer.index_row(record, config)
|
|
15
|
+
|
|
16
|
+
assert_equal %w[id name], row.keys.map(&:to_s).sort
|
|
17
|
+
refute_includes row.keys.map(&:to_s), "secret_token"
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
test "a raising accessor degrades that cell, not the row" do
|
|
21
|
+
record = Object.new
|
|
22
|
+
def record.id = 1
|
|
23
|
+
def record.name = raise("boom")
|
|
24
|
+
config = Config.new(Index.new([Column.new(:id), Column.new(:name)]))
|
|
25
|
+
|
|
26
|
+
row = AdminSuite::Mcp::Serializer.index_row(record, config)
|
|
27
|
+
|
|
28
|
+
assert_equal 1, row[:id]
|
|
29
|
+
assert_nil row[:name]
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
test "association panels return bounded rows containing only declared columns" do
|
|
33
|
+
show = Admin::Base::Resource::ShowConfig.new
|
|
34
|
+
show.panel :children, association: :children, columns: [:name], limit: 500
|
|
35
|
+
config = Struct.new(:show_config).new(show)
|
|
36
|
+
child = Struct.new(:name, :secret_token).new("Visible", "private")
|
|
37
|
+
record = Struct.new(:children).new(Array.new(150, child))
|
|
38
|
+
|
|
39
|
+
payload = AdminSuite::Mcp::Serializer.associations_payload(record, config, max_rows: 100)
|
|
40
|
+
assert_equal 100, payload.fetch(:children).fetch(:rows).size
|
|
41
|
+
assert_equal({ name: "Visible" }, payload.fetch(:children).fetch(:rows).first)
|
|
42
|
+
assert_equal 100, payload.fetch(:children).fetch(:applied_limit)
|
|
43
|
+
refute_includes JSON.generate(payload), "private"
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
test "association panels without declared columns do not serialize model attributes" do
|
|
47
|
+
show = Admin::Base::Resource::ShowConfig.new
|
|
48
|
+
show.panel :children, association: :children
|
|
49
|
+
config = Struct.new(:show_config).new(show)
|
|
50
|
+
record = Object.new
|
|
51
|
+
def record.children = raise("must not load an undeclared field set")
|
|
52
|
+
|
|
53
|
+
assert_empty AdminSuite::Mcp::Serializer.associations_payload(record, config, max_rows: 100)
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
test "a content lambda serializes the proc result, not a missing attribute" do
|
|
57
|
+
record = Struct.new(:id).new(1)
|
|
58
|
+
column = Admin::Base::Resource::ColumnDefinition.new(name: :listings_count, content: ->(_r) { 42 })
|
|
59
|
+
config = Config.new(Index.new([column]))
|
|
60
|
+
|
|
61
|
+
assert_equal 42, AdminSuite::Mcp::Serializer.index_row(record, config)[:listings_count]
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
test "a label lambda serializes the proc result" do
|
|
65
|
+
record = Struct.new(:id).new(1)
|
|
66
|
+
column = Admin::Base::Resource::ColumnDefinition.new(name: :status, content: ->(_r) { "active" }, type: :label)
|
|
67
|
+
config = Config.new(Index.new([column]))
|
|
68
|
+
|
|
69
|
+
assert_equal "active", AdminSuite::Mcp::Serializer.index_row(record, config)[:status]
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
test "declared times and associations serialize as parseable primitives, not heap dumps" do
|
|
73
|
+
created_at = Time.utc(2026, 9, 10, 12, 0, 0)
|
|
74
|
+
application = SerializerApplication.new(id: 7, name: "Acme")
|
|
75
|
+
record = Struct.new(:created_at, :application, :blob).new(created_at, application, SerializerOpaque.new)
|
|
76
|
+
config = Config.new(Index.new([Column.new(:created_at), Column.new(:application), Column.new(:blob)]))
|
|
77
|
+
|
|
78
|
+
row = AdminSuite::Mcp::Serializer.index_row(record, config)
|
|
79
|
+
text = AdminSuite::Mcp::Serializer.dump(row)
|
|
80
|
+
|
|
81
|
+
assert_equal "2026-09-10T12:00:00Z", row[:created_at]
|
|
82
|
+
assert_equal created_at, Time.iso8601(row[:created_at])
|
|
83
|
+
assert_equal "Acme", row[:application]
|
|
84
|
+
refute_match(/#<|0x[0-9a-f]+/i, text)
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
test "a missing association panel degrades that panel instead of raising" do
|
|
88
|
+
show = Admin::Base::Resource::ShowConfig.new
|
|
89
|
+
show.panel :children, association: :missing_kids, columns: [:name]
|
|
90
|
+
config = Struct.new(:show_config).new(show)
|
|
91
|
+
|
|
92
|
+
payload = AdminSuite::Mcp::Serializer.associations_payload(Object.new, config, max_rows: 100)
|
|
93
|
+
|
|
94
|
+
assert_equal [], payload.fetch(:children).fetch(:rows)
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
class SerializerApplication < ActiveRecord::Base
|
|
98
|
+
attr_reader :id, :name
|
|
99
|
+
|
|
100
|
+
def initialize(id:, name:)
|
|
101
|
+
@id = id
|
|
102
|
+
@name = name
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
class SerializerOpaque; end
|
|
107
|
+
end
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "test_helper"
|
|
4
|
+
|
|
5
|
+
class QueryTest < ActiveSupport::TestCase
|
|
6
|
+
Config = Struct.new(:model_class, :index_config)
|
|
7
|
+
IndexConfig = Struct.new(
|
|
8
|
+
:per_page,
|
|
9
|
+
:includes_list,
|
|
10
|
+
:searchable_fields,
|
|
11
|
+
:filters_list,
|
|
12
|
+
:default_sort,
|
|
13
|
+
:sortable_fields,
|
|
14
|
+
:default_sort_direction
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
class RaisingIncludesRelation < ReadOnlyResourceFixtures::Relation
|
|
18
|
+
def includes(*)
|
|
19
|
+
raise ArgumentError, "bad association"
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
class Model
|
|
24
|
+
class << self
|
|
25
|
+
attr_accessor :relation
|
|
26
|
+
|
|
27
|
+
def all = relation
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
test "per_page falls back to the DSL value when no param is given" do
|
|
32
|
+
query = AdminSuite::Query.new(resource_config: config_with(per_page: 30), params: {})
|
|
33
|
+
|
|
34
|
+
assert_equal 30, query.per_page
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
test "per_page honours the param" do
|
|
38
|
+
query = AdminSuite::Query.new(resource_config: config_with(per_page: 30), params: { per_page: "50" })
|
|
39
|
+
|
|
40
|
+
assert_equal 50, query.per_page
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
test "per_page clamps to MAX_PAGE_SIZE" do
|
|
44
|
+
query = AdminSuite::Query.new(resource_config: config_with(per_page: 30), params: { per_page: "999999" })
|
|
45
|
+
|
|
46
|
+
assert_equal AdminSuite::Query::MAX_PAGE_SIZE, query.per_page
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
test "per_page falls back for junk and non-positive values" do
|
|
50
|
+
["abc", "0", "-5", nil, "", [], true].each do |value|
|
|
51
|
+
query = AdminSuite::Query.new(resource_config: config_with(per_page: 30), params: { per_page: value })
|
|
52
|
+
|
|
53
|
+
assert_equal 30, query.per_page, "per_page: #{value.inspect} must fall back to the DSL value"
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
test "the cap applies to DSL defaults as well as explicit page sizes" do
|
|
58
|
+
[nil, "", "bad", 0, -1, [], true, 5000].each do |value|
|
|
59
|
+
query = AdminSuite::Query.new(resource_config: config_with(per_page: 500),
|
|
60
|
+
params: { per_page: value }, max_page_size: 40)
|
|
61
|
+
assert_equal 40, query.per_page, "per_page=#{value.inspect}"
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
test "per_page remains a positive integer when max_page_size is below 1" do
|
|
66
|
+
[0, -5, nil].each do |cap|
|
|
67
|
+
query = AdminSuite::Query.new(
|
|
68
|
+
resource_config: config_with(per_page: 30),
|
|
69
|
+
params: { per_page: "10" },
|
|
70
|
+
max_page_size: cap
|
|
71
|
+
)
|
|
72
|
+
|
|
73
|
+
assert_kind_of Integer, query.per_page, "max_page_size=#{cap.inspect}"
|
|
74
|
+
assert_operator query.per_page, :>, 0, "max_page_size=#{cap.inspect}"
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
test "a raising includes degrades to the unoptimized scope instead of raising" do
|
|
79
|
+
relation = RaisingIncludesRelation.new([])
|
|
80
|
+
Model.relation = relation
|
|
81
|
+
query = AdminSuite::Query.new(resource_config: config_with(per_page: 25, includes: [:nope]), params: {})
|
|
82
|
+
|
|
83
|
+
assert_same relation, query.scope
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
private
|
|
87
|
+
|
|
88
|
+
def config_with(per_page:, includes: [])
|
|
89
|
+
Config.new(Model, IndexConfig.new(per_page, includes, [], [], nil, [], :asc))
|
|
90
|
+
end
|
|
91
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "test_helper"
|
|
4
|
+
|
|
5
|
+
class RemovedDeprecationsTest < ActiveSupport::TestCase
|
|
6
|
+
test "the gem has no legacy Gleania renderer implementations or defaults" do
|
|
7
|
+
refute defined?(AdminSuite::Renderers::LegacyGleania)
|
|
8
|
+
%i[prompt_template_preview messages_preview tool_args_preview turn_messages_preview].each do |key|
|
|
9
|
+
assert_nil AdminSuite::RendererRegistry.lookup_default(key)
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
test "exportable is no longer a resource DSL method" do
|
|
14
|
+
refute Admin::Base::Resource.respond_to?(:exportable)
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "minitest/autorun"
|
|
4
|
+
require "yaml"
|
|
5
|
+
|
|
6
|
+
class PublishWorkflowTest < Minitest::Test
|
|
7
|
+
WORKFLOW_PATH = File.expand_path("../.github/workflows/publish.yml", __dir__)
|
|
8
|
+
|
|
9
|
+
def setup
|
|
10
|
+
@source = File.read(WORKFLOW_PATH)
|
|
11
|
+
@workflow = YAML.load_file(WORKFLOW_PATH)
|
|
12
|
+
@job = @workflow.fetch("jobs").fetch("publish")
|
|
13
|
+
@steps = @job.fetch("steps")
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def test_publishing_uses_the_release_environment_and_job_scoped_oidc
|
|
17
|
+
assert_equal "release", @job["environment"]
|
|
18
|
+
assert_equal "write", @job.fetch("permissions")["id-token"]
|
|
19
|
+
assert_equal "write", @job.fetch("permissions")["contents"]
|
|
20
|
+
refute @workflow.fetch("permissions", {}).key?("id-token")
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def test_automatic_publishing_requires_successful_main_push_ci
|
|
24
|
+
condition = @job.fetch("if")
|
|
25
|
+
assert_includes condition, "github.repository == 'techwright-lab/admin_suite'"
|
|
26
|
+
assert_includes condition, "github.event_name == 'workflow_run'"
|
|
27
|
+
assert_includes condition, "github.event.workflow_run.conclusion == 'success'"
|
|
28
|
+
assert_includes condition, "github.event.workflow_run.event == 'push'"
|
|
29
|
+
assert_includes condition, "github.event.workflow_run.head_branch == 'main'"
|
|
30
|
+
assert_includes condition, "github.event.workflow_run.head_repository.full_name == github.repository"
|
|
31
|
+
assert_includes condition, "github.event_name == 'workflow_dispatch' && github.ref == 'refs/heads/main'"
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def test_credentials_are_pinned_conditional_and_before_the_push
|
|
35
|
+
credentials_index = @steps.index { |step| step["name"] == "Configure RubyGems trusted publishing" }
|
|
36
|
+
refute_nil credentials_index
|
|
37
|
+
credentials = @steps.fetch(credentials_index)
|
|
38
|
+
push_index = @steps.index { |step| step["name"] == "Publish to RubyGems" }
|
|
39
|
+
push = @steps.fetch(push_index)
|
|
40
|
+
|
|
41
|
+
assert_equal "rubygems/configure-rubygems-credentials@dc5a8d8553e6ee01fc26761a49e99e733d17954a", credentials["uses"]
|
|
42
|
+
assert_equal "steps.version_check.outputs.should_publish == 'true'", credentials["if"]
|
|
43
|
+
assert_equal credentials["if"], push["if"]
|
|
44
|
+
assert_operator credentials_index, :<, push_index
|
|
45
|
+
refute_includes @source, "secrets.RUBYGEMS_API_KEY"
|
|
46
|
+
refute_includes @source, "GEM_HOST_API_KEY:"
|
|
47
|
+
refute_includes @source, "~/.gem/credentials"
|
|
48
|
+
assert_includes push.fetch("run"), "gem push"
|
|
49
|
+
assert_includes push.fetch("run"), "--host https://rubygems.org"
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def test_releases_preserve_tested_sha_and_serialization
|
|
53
|
+
checkout = @steps.find { |step| step.fetch("uses", "").start_with?("actions/checkout@") }
|
|
54
|
+
assert_equal "${{ github.event.workflow_run.head_sha || github.sha }}", checkout.fetch("with")["ref"]
|
|
55
|
+
assert_equal false, @workflow.fetch("concurrency")["cancel-in-progress"]
|
|
56
|
+
assert_includes @source, "different contents. Bump the gem version before publishing."
|
|
57
|
+
push_index = @steps.index { |step| step["name"] == "Publish to RubyGems" }
|
|
58
|
+
tag_index = @steps.index { |step| step["name"] == "Create Git tag" }
|
|
59
|
+
release_index = @steps.index { |step| step["name"] == "Create GitHub Release" }
|
|
60
|
+
assert_operator push_index, :<, tag_index
|
|
61
|
+
assert_operator tag_index, :<, release_index
|
|
62
|
+
end
|
|
63
|
+
end
|
data/test/test_helper.rb
CHANGED
|
@@ -16,6 +16,15 @@ if ENV["COVERAGE"]
|
|
|
16
16
|
end
|
|
17
17
|
|
|
18
18
|
require_relative "dummy/config/environment"
|
|
19
|
+
|
|
20
|
+
# Auth strategies are process-global. Tests that register temporary strategies
|
|
21
|
+
# can restore a snapshot with this helper to avoid cross-file registry leakage.
|
|
22
|
+
def with_auth_registry_snapshot
|
|
23
|
+
registry = AdminSuite::Auth.instance_variable_get(:@registry).dup
|
|
24
|
+
yield
|
|
25
|
+
ensure
|
|
26
|
+
AdminSuite::Auth.instance_variable_set(:@registry, registry)
|
|
27
|
+
end
|
|
19
28
|
require "minitest/autorun"
|
|
20
29
|
require "active_support/test_case"
|
|
21
30
|
require "action_dispatch/testing/integration"
|
|
@@ -23,6 +32,14 @@ require "action_dispatch/testing/integration"
|
|
|
23
32
|
# Ensure the engine is loaded (and its initializers run).
|
|
24
33
|
require "admin_suite"
|
|
25
34
|
|
|
35
|
+
def with_authorize(hook)
|
|
36
|
+
previous = AdminSuite.config.authorize
|
|
37
|
+
AdminSuite.config.authorize = hook
|
|
38
|
+
yield
|
|
39
|
+
ensure
|
|
40
|
+
AdminSuite.config.authorize = previous
|
|
41
|
+
end
|
|
42
|
+
|
|
26
43
|
# The dummy app is intentionally database-free, while the generic controller
|
|
27
44
|
# supports Active Record hosts. Supply only the exception type its lookup path
|
|
28
45
|
# rescues so show-page behavior can be exercised with an in-memory fixture.
|
|
@@ -181,3 +198,12 @@ module Admin
|
|
|
181
198
|
end
|
|
182
199
|
end
|
|
183
200
|
end
|
|
201
|
+
|
|
202
|
+
# MCP never permits anonymous callers, including in the development escape hatch.
|
|
203
|
+
class McpIntegrationTest < ActionDispatch::IntegrationTest
|
|
204
|
+
setup do
|
|
205
|
+
@previous_mcp_actor_resolver = AdminSuite.config.current_actor
|
|
206
|
+
AdminSuite.config.current_actor = ->(_) { "test-operator" }
|
|
207
|
+
end
|
|
208
|
+
teardown { AdminSuite.config.current_actor = @previous_mcp_actor_resolver }
|
|
209
|
+
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: admin_suite
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.6.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- TechWright Labs
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-
|
|
11
|
+
date: 2026-10-03 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: rails
|
|
@@ -50,6 +50,20 @@ dependencies:
|
|
|
50
50
|
- - "<"
|
|
51
51
|
- !ruby/object:Gem::Version
|
|
52
52
|
version: '10'
|
|
53
|
+
- !ruby/object:Gem::Dependency
|
|
54
|
+
name: mcp
|
|
55
|
+
requirement: !ruby/object:Gem::Requirement
|
|
56
|
+
requirements:
|
|
57
|
+
- - "~>"
|
|
58
|
+
- !ruby/object:Gem::Version
|
|
59
|
+
version: '1.1'
|
|
60
|
+
type: :runtime
|
|
61
|
+
prerelease: false
|
|
62
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
63
|
+
requirements:
|
|
64
|
+
- - "~>"
|
|
65
|
+
- !ruby/object:Gem::Version
|
|
66
|
+
version: '1.1'
|
|
53
67
|
- !ruby/object:Gem::Dependency
|
|
54
68
|
name: turbo-rails
|
|
55
69
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -152,6 +166,7 @@ files:
|
|
|
152
166
|
- app/controllers/admin_suite/application_controller.rb
|
|
153
167
|
- app/controllers/admin_suite/dashboard_controller.rb
|
|
154
168
|
- app/controllers/admin_suite/docs_controller.rb
|
|
169
|
+
- app/controllers/admin_suite/mcp_controller.rb
|
|
155
170
|
- app/controllers/admin_suite/portals_controller.rb
|
|
156
171
|
- app/controllers/admin_suite/resources_controller.rb
|
|
157
172
|
- app/helpers/admin_suite/base_helper.rb
|
|
@@ -205,8 +220,10 @@ files:
|
|
|
205
220
|
- lib/admin_suite.rb
|
|
206
221
|
- lib/admin_suite/auth.rb
|
|
207
222
|
- lib/admin_suite/auth/host_hook.rb
|
|
223
|
+
- lib/admin_suite/auth/host_user.rb
|
|
208
224
|
- lib/admin_suite/auth/http_basic.rb
|
|
209
225
|
- lib/admin_suite/auth/strategy.rb
|
|
226
|
+
- lib/admin_suite/authorization_context.rb
|
|
210
227
|
- lib/admin_suite/configuration.rb
|
|
211
228
|
- lib/admin_suite/definition_loader.rb
|
|
212
229
|
- lib/admin_suite/deprecation.rb
|
|
@@ -214,14 +231,21 @@ files:
|
|
|
214
231
|
- lib/admin_suite/host_autoload_policy.rb
|
|
215
232
|
- lib/admin_suite/legacy_custom_renderer_procs.rb
|
|
216
233
|
- lib/admin_suite/markdown_renderer.rb
|
|
234
|
+
- lib/admin_suite/mcp.rb
|
|
235
|
+
- lib/admin_suite/mcp/authorization.rb
|
|
236
|
+
- lib/admin_suite/mcp/serializer.rb
|
|
237
|
+
- lib/admin_suite/mcp/tools/aggregate.rb
|
|
238
|
+
- lib/admin_suite/mcp/tools/describe_resources.rb
|
|
239
|
+
- lib/admin_suite/mcp/tools/get_record.rb
|
|
240
|
+
- lib/admin_suite/mcp/tools/list_records.rb
|
|
217
241
|
- lib/admin_suite/portal_definition.rb
|
|
218
242
|
- lib/admin_suite/portal_registry.rb
|
|
243
|
+
- lib/admin_suite/query.rb
|
|
219
244
|
- lib/admin_suite/renderer.rb
|
|
220
245
|
- lib/admin_suite/renderer_registry.rb
|
|
221
246
|
- lib/admin_suite/renderers/code_renderer.rb
|
|
222
247
|
- lib/admin_suite/renderers/json_renderer.rb
|
|
223
248
|
- lib/admin_suite/renderers/key_value_renderer.rb
|
|
224
|
-
- lib/admin_suite/renderers/legacy_gleania.rb
|
|
225
249
|
- lib/admin_suite/renderers/table_from_renderer.rb
|
|
226
250
|
- lib/admin_suite/section_definition.rb
|
|
227
251
|
- lib/admin_suite/theme_palette.rb
|
|
@@ -238,6 +262,7 @@ files:
|
|
|
238
262
|
- lib/generators/admin_suite/scaffold/scaffold_generator.rb
|
|
239
263
|
- lib/tasks/admin_suite_tailwind.rake
|
|
240
264
|
- lib/tasks/admin_suite_test.rake
|
|
265
|
+
- test/archspec/enforcement_test.rb
|
|
241
266
|
- test/controllers/resources_controller_test.rb
|
|
242
267
|
- test/dummy/Gemfile
|
|
243
268
|
- test/dummy/README.md
|
|
@@ -281,6 +306,7 @@ files:
|
|
|
281
306
|
- test/dummy/public/icon.svg
|
|
282
307
|
- test/dummy/public/robots.txt
|
|
283
308
|
- test/dummy/test/test_helper.rb
|
|
309
|
+
- test/dummy_boot_test.rb
|
|
284
310
|
- test/fixtures/docs/progress/PROGRESS_REPORT.md
|
|
285
311
|
- test/integration/association_linking_test.rb
|
|
286
312
|
- test/integration/authentication_test.rb
|
|
@@ -288,8 +314,17 @@ files:
|
|
|
288
314
|
- test/integration/chart_panel_test.rb
|
|
289
315
|
- test/integration/dashboard_test.rb
|
|
290
316
|
- test/integration/docs_test.rb
|
|
317
|
+
- test/integration/index_query_characterization_test.rb
|
|
291
318
|
- test/integration/index_table_test.rb
|
|
292
319
|
- test/integration/layout_assets_test.rb
|
|
320
|
+
- test/integration/mcp_aggregate_test.rb
|
|
321
|
+
- test/integration/mcp_authorization_test.rb
|
|
322
|
+
- test/integration/mcp_endpoint_test.rb
|
|
323
|
+
- test/integration/mcp_get_record_test.rb
|
|
324
|
+
- test/integration/mcp_instrumentation_test.rb
|
|
325
|
+
- test/integration/mcp_list_records_test.rb
|
|
326
|
+
- test/integration/mcp_parity_test.rb
|
|
327
|
+
- test/integration/mcp_release_test.rb
|
|
293
328
|
- test/integration/navigation_sections_test.rb
|
|
294
329
|
- test/integration/pagination_and_stats_test.rb
|
|
295
330
|
- test/integration/read_only_resource_test.rb
|
|
@@ -299,23 +334,27 @@ files:
|
|
|
299
334
|
- test/integration/toggle_test.rb
|
|
300
335
|
- test/lib/action_executor_redirect_test.rb
|
|
301
336
|
- test/lib/action_executor_test.rb
|
|
337
|
+
- test/lib/auth_host_user_test.rb
|
|
302
338
|
- test/lib/auth_http_basic_test.rb
|
|
303
339
|
- test/lib/auth_resolution_test.rb
|
|
304
340
|
- test/lib/auth_test.rb
|
|
341
|
+
- test/lib/authorization_context_test.rb
|
|
305
342
|
- test/lib/builtin_renderers_test.rb
|
|
306
343
|
- test/lib/definition_loader_test.rb
|
|
307
344
|
- test/lib/engine_defaults_test.rb
|
|
308
345
|
- test/lib/form_field_renderer_test.rb
|
|
309
346
|
- test/lib/format_table_cell_test.rb
|
|
310
347
|
- test/lib/index_includes_test.rb
|
|
311
|
-
- test/lib/legacy_renderer_deprecation_test.rb
|
|
312
348
|
- test/lib/markdown_renderer_test.rb
|
|
349
|
+
- test/lib/mcp_serializer_test.rb
|
|
350
|
+
- test/lib/query_test.rb
|
|
351
|
+
- test/lib/removed_deprecations_test.rb
|
|
313
352
|
- test/lib/renderer_test.rb
|
|
314
|
-
- test/lib/resource_exportable_deprecation_test.rb
|
|
315
353
|
- test/lib/resource_observability_extensions_test.rb
|
|
316
354
|
- test/lib/show_value_formatter_test.rb
|
|
317
355
|
- test/lib/theme_palette_test.rb
|
|
318
356
|
- test/lib/zeitwerk_integration_test.rb
|
|
357
|
+
- test/publish_workflow_test.rb
|
|
319
358
|
- test/test_helper.rb
|
|
320
359
|
homepage: https://github.com/techwright-lab/admin_suite
|
|
321
360
|
licenses:
|