Skip to content

Commit b301f18

Browse files
committed
reorganize to be consistent with the new mcp sdk style
1 parent 620afb3 commit b301f18

21 files changed

+270
-309
lines changed

Gemfile.lock

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ PATH
55
mcp (~> 0.1)
66
query_packwerk (~> 0.1)
77
sorbet-runtime
8-
thor (~> 1.2)
8+
thor
9+
zeitwerk
910

1011
GEM
1112
remote: https://rubygems.org/

MCP.md

Lines changed: 0 additions & 81 deletions
This file was deleted.

chatwerk.gemspec

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,5 +36,6 @@ Gem::Specification.new do |spec|
3636
spec.add_dependency 'mcp', '~> 0.1'
3737
spec.add_dependency 'query_packwerk', '~> 0.1'
3838
spec.add_dependency 'sorbet-runtime'
39-
spec.add_dependency 'thor', '~> 1.2'
39+
spec.add_dependency 'thor'
40+
spec.add_dependency 'zeitwerk'
4041
end

lib/chatwerk.rb

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,16 @@
11
# typed: strict
22
# frozen_string_literal: true
33

4+
require 'zeitwerk'
45
require 'query_packwerk'
56
require 'sorbet-runtime'
7+
require 'chatwerk/version'
8+
9+
loader = Zeitwerk::Loader.for_gem
10+
loader.setup
611

712
# Chatwerk provides integration between QueryPackwerk and AI tools
813
# via the Model Context Protocol (MCP) server.
914
module Chatwerk
10-
extend T::Sig
11-
12-
autoload :API, 'chatwerk/api'
13-
autoload :CLI, 'chatwerk/cli'
14-
autoload :Error, 'chatwerk/error'
15-
autoload :Helpers, 'chatwerk/helpers'
16-
autoload :Mcp, 'chatwerk/mcp'
17-
autoload :Views, 'chatwerk/views'
18-
autoload :VERSION, 'chatwerk/version'
19-
2015
class NotFoundError < Error; end
2116
end

lib/chatwerk/api.rb

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,9 @@
22
# frozen_string_literal: true
33

44
require 'yaml'
5-
require_relative 'views'
65

76
module Chatwerk
8-
module API
7+
module Api
98
class << self
109
def print_env
1110
msg = <<~MESSAGE

lib/chatwerk/cli.rb

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@
22
# frozen_string_literal: true
33

44
require 'thor'
5-
require 'chatwerk'
6-
require 'chatwerk/api'
75

86
module Chatwerk
97
# CLI interface for Chatwerk using Thor
@@ -25,27 +23,27 @@ def inspect(working_directory = nil)
2523

2624
desc 'print_env', 'Show current environment details'
2725
def print_env
28-
puts API.print_env
26+
puts Api.print_env
2927
end
3028

3129
desc 'packages [PACKAGE_PATH]', 'List all valid packwerk packages, optionally filtered by package path'
3230
def packages(package_path = nil)
33-
puts API.packages(package_path:)
31+
puts Api.packages(package_path:)
3432
end
3533

3634
desc 'package PACKAGE_PATH', 'Show details for a specific package'
3735
def package(package_path)
38-
puts API.package(package_path:)
36+
puts Api.package(package_path:)
3937
end
4038

4139
desc 'package_todos PACKAGE_PATH [CONSTANT_NAME]', 'Show dependency violations FROM this package TO others'
4240
def package_todos(package_path, constant_name = nil)
43-
puts API.package_todos(package_path:, constant_name:)
41+
puts Api.package_todos(package_path:, constant_name:)
4442
end
4543

4644
desc 'package_violations PACKAGE_PATH [CONSTANT_NAME]', 'Show dependency violations TO this package FROM others'
4745
def package_violations(package_path, constant_name = nil)
48-
puts API.package_violations(package_path:, constant_name:)
46+
puts Api.package_violations(package_path:, constant_name:)
4947
end
5048

5149
desc 'version', 'Display Chatwerk version'

lib/chatwerk/mcp.rb

Lines changed: 5 additions & 188 deletions
Original file line numberDiff line numberDiff line change
@@ -1,189 +1,6 @@
11
require 'mcp'
2-
require 'query_packwerk'
3-
require 'parse_packwerk'
4-
require 'yaml'
5-
require_relative 'views'
6-
require_relative 'api'
7-
require_relative 'helpers'
82

93
module Chatwerk
10-
# Print environment information tool
11-
class PrintEnvTool < MCP::Tool
12-
description 'Get the current working directory and environment path of the MCP server, ensuring correct directory context'
13-
14-
input_schema(
15-
properties: {},
16-
required: []
17-
)
18-
19-
class << self
20-
def call(server_context:)
21-
msg = <<~MESSAGE
22-
Relay these exact details to the user:
23-
Current Directory: #{Dir.pwd}
24-
Environment: #{ENV.fetch('PWD', nil)}
25-
MESSAGE
26-
Helpers.chdir do
27-
msg << "Chdir'd to #{Helpers.pwd}\n"
28-
end
29-
msg << ENV.to_h.map { |key, value| "#{key}=#{value}" }.join("\n")
30-
31-
MCP::Tool::Response.new([{
32-
type: 'text',
33-
text: msg
34-
}])
35-
end
36-
end
37-
end
38-
39-
# List packages tool
40-
class PackagesTool < MCP::Tool
41-
description <<~DESC
42-
List all valid packwerk packages (aka packs) in the project.
43-
Use this to find or list packages, optionally matching a substring of the package_path.
44-
DESC
45-
46-
input_schema(
47-
properties: {
48-
package_path: {
49-
type: 'string',
50-
description: "A partial package path name to constrain the results (e.g. 'packs/product_services/payments/banks' or 'payments/banks')."
51-
}
52-
},
53-
required: []
54-
)
55-
56-
class << self
57-
def call(server_context:, package_path: nil)
58-
result = API.packages(package_path: package_path)
59-
60-
MCP::Tool::Response.new([{
61-
type: 'text',
62-
text: result
63-
}])
64-
end
65-
end
66-
end
67-
68-
# Show package details tool
69-
class PackageTool < MCP::Tool
70-
description <<~DESC
71-
Show the details for a specific package.
72-
73-
Output format:
74-
- Package details, including dependencies and configuration
75-
DESC
76-
77-
input_schema(
78-
properties: {
79-
package_path: {
80-
type: 'string',
81-
description: "A full relative package path (e.g. 'packs/product_services/payments/banks')."
82-
}
83-
},
84-
required: ['package_path']
85-
)
86-
87-
class << self
88-
def call(package_path:, server_context:)
89-
Helpers.chdir
90-
result = API.package(package_path: package_path)
91-
92-
MCP::Tool::Response.new([{
93-
type: 'text',
94-
text: result
95-
}])
96-
end
97-
end
98-
end
99-
100-
# Package todos (violations FROM this package) tool
101-
class PackageTodosTool < MCP::Tool
102-
description <<~DESC
103-
Find code that violates dependency boundaries FROM this package TO other packages.
104-
105-
Output formats:
106-
- Without constant_name: List of violated constants with counts
107-
Example: "::OtherPackage::SomeClass # 3 violations"
108-
- With constant_name: Detailed examples and locations
109-
Example:
110-
::OtherPackage::SomeClass
111-
example: OtherPackage::SomeClass.new
112-
files:
113-
- app/services/my_service.rb
114-
DESC
115-
116-
input_schema(
117-
properties: {
118-
package_path: {
119-
type: 'string',
120-
description: "The relative path of a directory containing a package.yml file (e.g. 'packs/product_services/payments/origination_banks')."
121-
},
122-
constant_name: {
123-
type: 'string',
124-
description: "The name of a constant to filter the results by. If provided, a more detailed list of code usage examples will be returned. (e.g. '::OtherPackage::SomeClass')"
125-
}
126-
},
127-
required: ['package_path']
128-
)
129-
130-
class << self
131-
def call(package_path:, server_context:, constant_name: nil)
132-
Helpers.chdir
133-
result = API.package_todos(package_path: package_path, constant_name: constant_name)
134-
135-
MCP::Tool::Response.new([{
136-
type: 'text',
137-
text: result
138-
}])
139-
end
140-
end
141-
end
142-
143-
# Package violations (violations TO this package) tool
144-
class PackageViolationsTool < MCP::Tool
145-
description <<~DESC
146-
Find code that violates dependency boundaries TO this package FROM other packages.
147-
148-
Output formats:
149-
- Without constant_name: List of violated constants with counts
150-
Example: "::ThisPackage::SomeClass: 3 violations"
151-
- With constant_name: Detailed examples and locations
152-
Example:
153-
# Constant `::ThisPackage::SomeClass`
154-
## Example:
155-
ThisPackage::SomeClass.new
156-
### Files:
157-
app/services/other_service.rb
158-
DESC
159-
160-
input_schema(
161-
properties: {
162-
package_path: {
163-
type: 'string',
164-
description: "The relative path of a directory containing a package.yml file (e.g. 'packs/product_services/payments/origination_banks'). AKA a 'pack' or 'package'."
165-
},
166-
constant_name: {
167-
type: 'string',
168-
description: 'The name of a constant to filter the results by. If provided, a more detailed list of code usage examples will be returned.'
169-
}
170-
},
171-
required: ['package_path']
172-
)
173-
174-
class << self
175-
def call(package_path:, server_context:, constant_name: nil)
176-
Helpers.chdir
177-
result = API.package_violations(package_path: package_path, constant_name: constant_name)
178-
179-
MCP::Tool::Response.new([{
180-
type: 'text',
181-
text: result
182-
}])
183-
end
184-
end
185-
end
186-
1874
# MCP Server setup
1885
class Mcp
1896
def self.server
@@ -192,11 +9,11 @@ def self.server
1929
name: name,
19310
version: Chatwerk::VERSION,
19411
tools: [
195-
PrintEnvTool,
196-
PackagesTool,
197-
PackageTool,
198-
PackageTodosTool,
199-
PackageViolationsTool
12+
Tools::PrintEnvTool,
13+
Tools::PackagesTool,
14+
Tools::PackageTool,
15+
Tools::PackageTodosTool,
16+
Tools::PackageViolationsTool
20017
]
20118
)
20219
end

0 commit comments

Comments
 (0)