stimulus_plumbers_mcp 0.4.5 → 0.4.8

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.
Files changed (42) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +34 -24
  3. data/lib/stimulus_plumbers/mcp/loaders/aria_loader.rb +31 -0
  4. data/lib/stimulus_plumbers/mcp/loaders/component_docs_loader.rb +38 -0
  5. data/lib/stimulus_plumbers/mcp/loaders/component_requirements.rb +41 -0
  6. data/lib/stimulus_plumbers/mcp/loaders/component_schema_loader.rb +49 -0
  7. data/lib/stimulus_plumbers/mcp/loaders/component_theme_loader.rb +41 -0
  8. data/lib/stimulus_plumbers/mcp/loaders/controller_docs_loader.rb +31 -0
  9. data/lib/stimulus_plumbers/mcp/loaders/controller_schema_loader.rb +49 -0
  10. data/lib/stimulus_plumbers/mcp/loaders/guide.md +48 -0
  11. data/lib/stimulus_plumbers/mcp/loaders/guide_loader.rb +40 -4
  12. data/lib/stimulus_plumbers/mcp/loaders/icons_loader.rb +34 -0
  13. data/lib/stimulus_plumbers/mcp/loaders/support/docs_table_parser.rb +112 -0
  14. data/lib/stimulus_plumbers/mcp/loaders/support/gem_vendor_path.rb +18 -0
  15. data/lib/stimulus_plumbers/mcp/loaders/tailwind_loader.rb +35 -0
  16. data/lib/stimulus_plumbers/mcp/loaders/versions_loader.rb +110 -0
  17. data/lib/stimulus_plumbers/mcp/plugins/aria.rb +34 -0
  18. data/lib/stimulus_plumbers/mcp/plugins/base.rb +40 -31
  19. data/lib/stimulus_plumbers/mcp/plugins/component_docs.rb +96 -0
  20. data/lib/stimulus_plumbers/mcp/plugins/component_schema.rb +133 -0
  21. data/lib/stimulus_plumbers/mcp/plugins/component_theme.rb +90 -0
  22. data/lib/stimulus_plumbers/mcp/plugins/controller_docs.rb +91 -0
  23. data/lib/stimulus_plumbers/mcp/plugins/controller_schema.rb +81 -0
  24. data/lib/stimulus_plumbers/mcp/plugins/guide.rb +70 -16
  25. data/lib/stimulus_plumbers/mcp/plugins/icons.rb +42 -0
  26. data/lib/stimulus_plumbers/mcp/plugins/tailwind.rb +69 -45
  27. data/lib/stimulus_plumbers/mcp/plugins/versions.rb +44 -0
  28. data/lib/stimulus_plumbers/mcp/server.rb +26 -9
  29. data/lib/stimulus_plumbers/mcp/version.rb +1 -1
  30. data/lib/stimulus_plumbers_mcp.rb +31 -11
  31. metadata +22 -12
  32. data/lib/stimulus_plumbers/mcp/loaders/component_controller_map.rb +0 -38
  33. data/lib/stimulus_plumbers/mcp/loaders/docs_loader.rb +0 -129
  34. data/lib/stimulus_plumbers/mcp/loaders/guide/overview.md +0 -48
  35. data/lib/stimulus_plumbers/mcp/loaders/schema_loader.rb +0 -45
  36. data/lib/stimulus_plumbers/mcp/loaders/stimulus_manifest.rb +0 -47
  37. data/lib/stimulus_plumbers/mcp/loaders/tailwind_theme_loader.rb +0 -29
  38. data/lib/stimulus_plumbers/mcp/loaders/theme_loader.rb +0 -97
  39. data/lib/stimulus_plumbers/mcp/plugins/docs.rb +0 -82
  40. data/lib/stimulus_plumbers/mcp/plugins/schema.rb +0 -110
  41. data/lib/stimulus_plumbers/mcp/plugins/stimulus.rb +0 -66
  42. data/lib/stimulus_plumbers/mcp/plugins/theme.rb +0 -66
@@ -0,0 +1,81 @@
1
+ # frozen_string_literal: true
2
+
3
+ module StimulusPlumbers
4
+ module MCP
5
+ module Plugins
6
+ class ControllerSchema < Base
7
+ class << self
8
+ def loader_key = :controller_schema
9
+
10
+ def loader = ControllerSchemaLoader
11
+
12
+ def static_resources
13
+ [
14
+ ::MCP::Resource.new(
15
+ uri: "controller://index",
16
+ name: "controllers-index",
17
+ description: "Index of all Stimulus controller identifiers in @stimulus-plumbers/controllers",
18
+ mime_type: "application/json"
19
+ )
20
+ ].freeze
21
+ end
22
+
23
+ def dynamic_resource_templates
24
+ [
25
+ ::MCP::ResourceTemplate.new(
26
+ uri_template: "controller://{name}/schema",
27
+ name: "controller-schema",
28
+ description: "Targets, values, outlets, and classes for a Stimulus controller",
29
+ mime_type: "application/json"
30
+ )
31
+ ].freeze
32
+ end
33
+
34
+ def read(uri, store)
35
+ controllers = store[:controller_schema]
36
+
37
+ case uri
38
+ when "controller://index"
39
+ json_resource(uri, controllers.keys)
40
+ when %r{\Acontroller://([^/]+)/schema\z}
41
+ identifier = Regexp.last_match(1)
42
+ json_resource(uri, controllers[identifier] || { error: "unknown controller: #{identifier}" })
43
+ end
44
+ end
45
+
46
+ def register_tools(server, store)
47
+ controllers = store[:controller_schema]
48
+
49
+ register_list_controllers(server, controllers)
50
+ register_get_controller_schema(server, controllers)
51
+ end
52
+
53
+ private
54
+
55
+ def register_list_controllers(server, controllers)
56
+ text_tool(
57
+ server,
58
+ name: "list_controllers",
59
+ description: "Lists all Stimulus controller identifiers provided by @stimulus-plumbers/controllers"
60
+ ) do
61
+ JSON.generate(controllers.keys)
62
+ end
63
+ end
64
+
65
+ def register_get_controller_schema(server, controllers)
66
+ text_tool(
67
+ server,
68
+ name: "get_controller_schema",
69
+ description: "Returns targets, values (with types and defaults), outlets, and classes for a " \
70
+ "Stimulus controller. For narrative usage docs use get_controller_docs",
71
+ input_schema: { properties: { name: { type: "string" } }, required: ["name"] }
72
+ ) do |name:|
73
+ data = controllers[name]
74
+ data ? JSON.generate(data) : not_found("unknown controller: #{name}")
75
+ end
76
+ end
77
+ end
78
+ end
79
+ end
80
+ end
81
+ end
@@ -3,27 +3,81 @@
3
3
  module StimulusPlumbers
4
4
  module MCP
5
5
  module Plugins
6
- module Guide
7
- extend Base
6
+ class Guide < Base
7
+ GUIDE_NAMES = %w[component controller tailwind theme].freeze
8
8
 
9
- LOADER_KEY = :guide
10
- LOADER = GuideLoader
9
+ class << self
10
+ def loader_key = :guide
11
11
 
12
- STATIC_RESOURCES = [
13
- ::MCP::Resource.new(
14
- uri: "guide://overview",
15
- name: "overview",
16
- description: "Start here — how to build views and forms with stimulus-plumbers, with pointers to every tool/resource",
17
- mime_type: "text/markdown"
18
- )
19
- ].freeze
12
+ def loader = GuideLoader
20
13
 
21
- DYNAMIC_RESOURCE_TEMPLATES = [].freeze
14
+ def static_resources
15
+ [
16
+ ::MCP::Resource.new(
17
+ uri: "guide://overview",
18
+ name: "overview",
19
+ description: "Start here — how to build views and forms with stimulus-plumbers, with pointers " \
20
+ "to every tool/resource",
21
+ mime_type: "text/markdown"
22
+ )
23
+ ].freeze
24
+ end
22
25
 
23
- def self.read(uri, store)
24
- return unless uri == "guide://overview"
26
+ def dynamic_resource_templates
27
+ [
28
+ ::MCP::ResourceTemplate.new(
29
+ uri_template: "guide://{name}",
30
+ name: "guide",
31
+ description: "Per-package usage guide: component (Rails forms/views), controller " \
32
+ "(plain-JS/non-Rails setup), tailwind (Tailwind install/theming), theme " \
33
+ "(custom theme integration contract)",
34
+ mime_type: "text/markdown"
35
+ )
36
+ ].freeze
37
+ end
25
38
 
26
- text_resource(uri, "text/markdown", store[:guide])
39
+ def read(uri, store)
40
+ guide = store[:guide]
41
+
42
+ case uri
43
+ when "guide://overview"
44
+ text_resource(uri, "text/markdown", guide[:overview])
45
+ when %r{\Aguide://(#{GUIDE_NAMES.join("|")})\z}
46
+ text_resource(uri, "text/markdown", guide[Regexp.last_match(1).to_sym])
47
+ end
48
+ end
49
+
50
+ def register_tools(server, store)
51
+ guide = store[:guide]
52
+
53
+ register_list_guides(server)
54
+ register_get_guide(server, guide)
55
+ end
56
+
57
+ private
58
+
59
+ def register_list_guides(server)
60
+ text_tool(
61
+ server,
62
+ name: "list_guides",
63
+ description: "Lists available per-package usage guides — see guide://overview for the full map"
64
+ ) do
65
+ JSON.generate(GUIDE_NAMES)
66
+ end
67
+ end
68
+
69
+ def register_get_guide(server, guide)
70
+ text_tool(
71
+ server,
72
+ name: "get_guide",
73
+ description: "Returns a per-package usage guide: component (Rails forms/views), controller " \
74
+ "(plain-JS/non-Rails setup), tailwind (Tailwind install/theming), theme (custom " \
75
+ "theme integration contract)",
76
+ input_schema: { properties: { name: { type: "string", enum: GUIDE_NAMES } }, required: ["name"] }
77
+ ) do |name:|
78
+ guide[name.to_sym] || not_found("unknown guide: #{name}")
79
+ end
80
+ end
27
81
  end
28
82
  end
29
83
  end
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ module StimulusPlumbers
4
+ module MCP
5
+ module Plugins
6
+ class Icons < Base
7
+ class << self
8
+ def loader_key = :icons
9
+
10
+ def loader = IconsLoader
11
+
12
+ def static_resources
13
+ [
14
+ ::MCP::Resource.new(
15
+ uri: "component://icons",
16
+ name: "icons",
17
+ description: "All available icon names bundled with the Tailwind theme",
18
+ mime_type: "application/json"
19
+ )
20
+ ].freeze
21
+ end
22
+
23
+ def read(uri, store)
24
+ return unless uri == "component://icons"
25
+
26
+ json_resource(uri, store[:icons])
27
+ end
28
+
29
+ def register_tools(server, store)
30
+ text_tool(
31
+ server,
32
+ name: "list_icons",
33
+ description: "Lists all available icon names bundled with the Tailwind theme"
34
+ ) do
35
+ JSON.generate(store[:icons])
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -3,53 +3,77 @@
3
3
  module StimulusPlumbers
4
4
  module MCP
5
5
  module Plugins
6
- module Tailwind
7
- extend Base
8
-
9
- LOADER_KEY = :tailwind
10
- LOADER = TailwindThemeLoader
11
-
12
- STATIC_RESOURCES = [
13
- ::MCP::Resource.new(
14
- uri: "tailwind://components",
15
- name: "tailwind-components-index",
16
- description: "Index of component keys implemented by the stimulus-plumbers Tailwind theme",
17
- mime_type: "application/json"
18
- )
19
- ].freeze
20
-
21
- DYNAMIC_RESOURCE_TEMPLATES = [
22
- ::MCP::ResourceTemplate.new(
23
- uri_template: "tailwind://components/{name}",
24
- name: "tailwind-component-classes",
25
- description: "Tailwind CSS utility classes emitted per variant for a component",
26
- mime_type: "application/json"
27
- )
28
- ].freeze
29
-
30
- def self.read(uri, store)
31
- tailwind = store[:tailwind]
32
-
33
- case uri
34
- when "tailwind://components"
35
- json_resource(uri, tailwind.keys)
36
- when %r{\Atailwind://components/(.+)\z}
37
- key = Regexp.last_match(1).to_sym
38
- json_resource(uri, tailwind[key] || { error: "unknown component: #{key}" })
6
+ class Tailwind < Base
7
+ class << self
8
+ def loader_key = :tailwind
9
+
10
+ def loader = TailwindLoader
11
+
12
+ def static_resources
13
+ [
14
+ ::MCP::Resource.new(
15
+ uri: "component://tailwind",
16
+ name: "component-tailwind-index",
17
+ description: "Index of component keys implemented by the stimulus-plumbers Tailwind theme",
18
+ mime_type: "application/json"
19
+ )
20
+ ].freeze
21
+ end
22
+
23
+ def dynamic_resource_templates
24
+ [
25
+ ::MCP::ResourceTemplate.new(
26
+ uri_template: "component://{name}/tailwind",
27
+ name: "component-tailwind-classes",
28
+ description: "Tailwind CSS utility classes emitted per variant for a component",
29
+ mime_type: "application/json"
30
+ )
31
+ ].freeze
32
+ end
33
+
34
+ def read(uri, store)
35
+ tailwind = store[:tailwind]
36
+
37
+ case uri
38
+ when "component://tailwind"
39
+ json_resource(uri, tailwind.keys)
40
+ when %r{\Acomponent://([^/]+)/tailwind\z}
41
+ key = Regexp.last_match(1).to_sym
42
+ json_resource(uri, tailwind[key] || { error: "unknown component: #{key}" })
43
+ end
44
+ end
45
+
46
+ def register_tools(server, store)
47
+ tailwind = store[:tailwind]
48
+
49
+ register_list_component_tailwind(server, tailwind)
50
+ register_get_component_tailwind(server, tailwind)
51
+ end
52
+
53
+ private
54
+
55
+ def register_list_component_tailwind(server, tailwind)
56
+ text_tool(
57
+ server,
58
+ name: "list_component_tailwind",
59
+ description: "Lists component keys implemented by the stimulus-plumbers Tailwind theme"
60
+ ) do
61
+ JSON.generate(tailwind.keys)
62
+ end
39
63
  end
40
- end
41
64
 
42
- def self.register_tools(server, store)
43
- tailwind = store[:tailwind]
44
-
45
- text_tool(
46
- server,
47
- name: "get_tailwind_classes",
48
- description: "Returns Tailwind CSS utility classes emitted per variant for a component",
49
- input_schema: { properties: { component: { type: "string" } }, required: ["component"] }
50
- ) do |component:|
51
- data = tailwind[component.to_sym]
52
- data ? JSON.generate(data) : not_found("unknown component: #{component}")
65
+ def register_get_component_tailwind(server, tailwind)
66
+ text_tool(
67
+ server,
68
+ name: "get_component_tailwind",
69
+ description: "Returns Tailwind CSS utility classes emitted per variant for a component. " \
70
+ "For themed params/controllers use get_component_schema; for the Rails helper " \
71
+ "surface use get_component_helper",
72
+ input_schema: { properties: { name: { type: "string" } }, required: ["name"] }
73
+ ) do |name:|
74
+ data = tailwind[name.to_sym]
75
+ data ? JSON.generate(data) : not_found("unknown component: #{name}")
76
+ end
53
77
  end
54
78
  end
55
79
  end
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ module StimulusPlumbers
4
+ module MCP
5
+ module Plugins
6
+ class Versions < Base
7
+ class << self
8
+ def loader_key = :versions
9
+
10
+ def loader = VersionsLoader
11
+
12
+ def static_resources
13
+ [
14
+ ::MCP::Resource.new(
15
+ uri: "versions://sources",
16
+ name: "source-versions",
17
+ description: "Resolved version (and resolution path, for stimulus) of each gem/package " \
18
+ "backing this server's data — use to spot version drift between sources",
19
+ mime_type: "application/json"
20
+ )
21
+ ].freeze
22
+ end
23
+
24
+ def read(uri, store)
25
+ return unless uri == "versions://sources"
26
+
27
+ json_resource(uri, store[:versions])
28
+ end
29
+
30
+ def register_tools(server, store)
31
+ text_tool(
32
+ server,
33
+ name: "get_source_versions",
34
+ description: "Returns the resolved version (and resolution path, for stimulus) of each " \
35
+ "gem/package backing this server's data — use to spot version drift between sources"
36
+ ) do
37
+ JSON.generate(store[:versions])
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
@@ -4,12 +4,19 @@ module StimulusPlumbers
4
4
  module MCP
5
5
  module Server
6
6
  PLUGINS = [
7
+ Plugins::ComponentDocs,
8
+ Plugins::ComponentSchema,
9
+ Plugins::ComponentTheme,
10
+
11
+ Plugins::ControllerDocs,
12
+ Plugins::ControllerSchema,
13
+
14
+ Plugins::Icons,
15
+ Plugins::Tailwind,
16
+
17
+ Plugins::Aria,
7
18
  Plugins::Guide,
8
- Plugins::Schema,
9
- Plugins::Docs,
10
- Plugins::Stimulus,
11
- Plugins::Theme,
12
- Plugins::Tailwind
19
+ Plugins::Versions
13
20
  ].freeze
14
21
 
15
22
  INSTRUCTIONS = "Use these resources and tools for accurate API references when " \
@@ -17,24 +24,34 @@ module StimulusPlumbers
17
24
  "Read guide://overview first for a map of the form/view/stimulus API."
18
25
 
19
26
  def self.build
20
- store = PLUGINS.to_h { |plugin| [plugin::LOADER_KEY, plugin::LOADER.call] }
27
+ store = build_store
21
28
  report_sources(store)
22
29
 
23
30
  server = new_server
24
31
  server.resources_read_handler do |params|
25
- PLUGINS.lazy.filter_map { |plugin| plugin.read(params[:uri], store) }.first || []
32
+ PLUGINS.lazy.filter_map { |plugin| plugin.read(params[:uri], store) }.first ||
33
+ unknown_resource(params[:uri])
26
34
  end
27
35
  PLUGINS.each { |plugin| plugin.register_tools(server, store) }
28
36
  server
29
37
  end
30
38
 
39
+ def self.build_store
40
+ PLUGINS.to_h { |plugin| [plugin.loader_key, plugin.loader.call] }
41
+ end
42
+
43
+ def self.unknown_resource(uri)
44
+ message = "unknown resource: #{uri} — read guide://overview for a map of available resources"
45
+ [{ uri: uri, mimeType: "application/json", text: JSON.generate(error: message) }]
46
+ end
47
+
31
48
  def self.new_server
32
49
  ::MCP::Server.new(
33
50
  name: "stimulus-plumbers",
34
51
  version: StimulusPlumbers::MCP::VERSION,
35
52
  instructions: INSTRUCTIONS,
36
- resources: PLUGINS.flat_map { |p| p::STATIC_RESOURCES },
37
- resource_templates: PLUGINS.flat_map { |p| p::DYNAMIC_RESOURCE_TEMPLATES }
53
+ resources: PLUGINS.flat_map(&:static_resources),
54
+ resource_templates: PLUGINS.flat_map(&:dynamic_resource_templates)
38
55
  )
39
56
  end
40
57
 
@@ -2,6 +2,6 @@
2
2
 
3
3
  module StimulusPlumbers
4
4
  module MCP
5
- VERSION = "0.4.5"
5
+ VERSION = "0.4.8"
6
6
  end
7
7
  end
@@ -9,19 +9,39 @@ require "stimulus_plumbers"
9
9
  require "stimulus_plumbers_tailwind"
10
10
 
11
11
  require_relative "stimulus_plumbers/mcp/version"
12
+ require_relative "stimulus_plumbers/mcp/loaders/support/docs_table_parser"
13
+ require_relative "stimulus_plumbers/mcp/loaders/support/gem_vendor_path"
14
+
15
+ require_relative "stimulus_plumbers/mcp/loaders/component_docs_loader"
16
+ require_relative "stimulus_plumbers/mcp/loaders/component_requirements"
17
+ require_relative "stimulus_plumbers/mcp/loaders/component_schema_loader"
18
+ require_relative "stimulus_plumbers/mcp/loaders/component_theme_loader"
19
+
20
+ require_relative "stimulus_plumbers/mcp/loaders/controller_docs_loader"
21
+ require_relative "stimulus_plumbers/mcp/loaders/controller_schema_loader"
22
+
23
+ require_relative "stimulus_plumbers/mcp/loaders/icons_loader"
24
+ require_relative "stimulus_plumbers/mcp/loaders/tailwind_loader"
25
+
26
+ require_relative "stimulus_plumbers/mcp/loaders/aria_loader"
12
27
  require_relative "stimulus_plumbers/mcp/loaders/guide_loader"
13
- require_relative "stimulus_plumbers/mcp/loaders/schema_loader"
14
- require_relative "stimulus_plumbers/mcp/loaders/docs_loader"
15
- require_relative "stimulus_plumbers/mcp/loaders/stimulus_manifest"
16
- require_relative "stimulus_plumbers/mcp/loaders/component_controller_map"
17
- require_relative "stimulus_plumbers/mcp/loaders/theme_loader"
18
- require_relative "stimulus_plumbers/mcp/loaders/tailwind_theme_loader"
28
+ require_relative "stimulus_plumbers/mcp/loaders/versions_loader"
29
+
19
30
  require_relative "stimulus_plumbers/mcp/plugins/base"
20
- require_relative "stimulus_plumbers/mcp/plugins/guide"
21
- require_relative "stimulus_plumbers/mcp/plugins/schema"
22
- require_relative "stimulus_plumbers/mcp/plugins/docs"
23
- require_relative "stimulus_plumbers/mcp/plugins/stimulus"
24
- require_relative "stimulus_plumbers/mcp/plugins/theme"
31
+
32
+ require_relative "stimulus_plumbers/mcp/plugins/component_docs"
33
+ require_relative "stimulus_plumbers/mcp/plugins/component_schema"
34
+ require_relative "stimulus_plumbers/mcp/plugins/component_theme"
35
+
36
+ require_relative "stimulus_plumbers/mcp/plugins/controller_docs"
37
+ require_relative "stimulus_plumbers/mcp/plugins/controller_schema"
38
+
39
+ require_relative "stimulus_plumbers/mcp/plugins/icons"
25
40
  require_relative "stimulus_plumbers/mcp/plugins/tailwind"
41
+
42
+ require_relative "stimulus_plumbers/mcp/plugins/aria"
43
+ require_relative "stimulus_plumbers/mcp/plugins/guide"
44
+ require_relative "stimulus_plumbers/mcp/plugins/versions"
45
+
26
46
  require_relative "stimulus_plumbers/mcp/server"
27
47
  require_relative "stimulus_plumbers/mcp/cli"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: stimulus_plumbers_mcp
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.5
4
+ version: 0.4.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ryan Chang
@@ -80,21 +80,31 @@ files:
80
80
  - bin/server
81
81
  - bin/stimulus-plumbers-mcp
82
82
  - lib/stimulus_plumbers/mcp/cli.rb
83
- - lib/stimulus_plumbers/mcp/loaders/component_controller_map.rb
84
- - lib/stimulus_plumbers/mcp/loaders/docs_loader.rb
85
- - lib/stimulus_plumbers/mcp/loaders/guide/overview.md
83
+ - lib/stimulus_plumbers/mcp/loaders/aria_loader.rb
84
+ - lib/stimulus_plumbers/mcp/loaders/component_docs_loader.rb
85
+ - lib/stimulus_plumbers/mcp/loaders/component_requirements.rb
86
+ - lib/stimulus_plumbers/mcp/loaders/component_schema_loader.rb
87
+ - lib/stimulus_plumbers/mcp/loaders/component_theme_loader.rb
88
+ - lib/stimulus_plumbers/mcp/loaders/controller_docs_loader.rb
89
+ - lib/stimulus_plumbers/mcp/loaders/controller_schema_loader.rb
90
+ - lib/stimulus_plumbers/mcp/loaders/guide.md
86
91
  - lib/stimulus_plumbers/mcp/loaders/guide_loader.rb
87
- - lib/stimulus_plumbers/mcp/loaders/schema_loader.rb
88
- - lib/stimulus_plumbers/mcp/loaders/stimulus_manifest.rb
89
- - lib/stimulus_plumbers/mcp/loaders/tailwind_theme_loader.rb
90
- - lib/stimulus_plumbers/mcp/loaders/theme_loader.rb
92
+ - lib/stimulus_plumbers/mcp/loaders/icons_loader.rb
93
+ - lib/stimulus_plumbers/mcp/loaders/support/docs_table_parser.rb
94
+ - lib/stimulus_plumbers/mcp/loaders/support/gem_vendor_path.rb
95
+ - lib/stimulus_plumbers/mcp/loaders/tailwind_loader.rb
96
+ - lib/stimulus_plumbers/mcp/loaders/versions_loader.rb
97
+ - lib/stimulus_plumbers/mcp/plugins/aria.rb
91
98
  - lib/stimulus_plumbers/mcp/plugins/base.rb
92
- - lib/stimulus_plumbers/mcp/plugins/docs.rb
99
+ - lib/stimulus_plumbers/mcp/plugins/component_docs.rb
100
+ - lib/stimulus_plumbers/mcp/plugins/component_schema.rb
101
+ - lib/stimulus_plumbers/mcp/plugins/component_theme.rb
102
+ - lib/stimulus_plumbers/mcp/plugins/controller_docs.rb
103
+ - lib/stimulus_plumbers/mcp/plugins/controller_schema.rb
93
104
  - lib/stimulus_plumbers/mcp/plugins/guide.rb
94
- - lib/stimulus_plumbers/mcp/plugins/schema.rb
95
- - lib/stimulus_plumbers/mcp/plugins/stimulus.rb
105
+ - lib/stimulus_plumbers/mcp/plugins/icons.rb
96
106
  - lib/stimulus_plumbers/mcp/plugins/tailwind.rb
97
- - lib/stimulus_plumbers/mcp/plugins/theme.rb
107
+ - lib/stimulus_plumbers/mcp/plugins/versions.rb
98
108
  - lib/stimulus_plumbers/mcp/server.rb
99
109
  - lib/stimulus_plumbers/mcp/version.rb
100
110
  - lib/stimulus_plumbers_mcp.rb
@@ -1,38 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module StimulusPlumbers
4
- module MCP
5
- class ComponentControllerMap
6
- def self.call
7
- Components.constants
8
- .map { |c| Components.const_get(c) }
9
- .grep(Class)
10
- .to_h { |klass| [component_key(klass), controllers_for(klass).uniq] }
11
- end
12
-
13
- # Controllers from a component class plus its nested sub-components (e.g. Combobox::Date),
14
- # keyed to the top-level component. Skips references to sibling components.
15
- def self.controllers_for(mod)
16
- mod.constants(false).flat_map do |const|
17
- value = mod.const_get(const)
18
- if const.to_s.end_with?("CONTROLLER")
19
- Array(value).grep(String).flat_map(&:split)
20
- elsif nested?(mod, value)
21
- controllers_for(value)
22
- else
23
- []
24
- end
25
- end
26
- end
27
-
28
- def self.nested?(mod, value)
29
- value.is_a?(Module) && !value.name.nil? && value.name.start_with?("#{mod.name}::")
30
- end
31
-
32
- def self.component_key(klass)
33
- klass.name.demodulize.underscore.to_sym
34
- end
35
- private_class_method :controllers_for, :nested?, :component_key
36
- end
37
- end
38
- end