cf-mcp 0.18.0 → 0.19.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: 4161d3091e34024cc73f40437b755e9c08b9ed4679e642caf3578dbf24e4eae0
4
- data.tar.gz: 7ca49f9aba9d0cb13e9cfd1c738848792a162a1fb2d97c1413bd713eb9e268a6
3
+ metadata.gz: 8503e2b733dd80a28ab4e44b5435ce8ca334ba25a0bd34a3751c2b986beea8dc
4
+ data.tar.gz: f4b986ddb96f77b7bc97c5b56384b6aaae88ee73f1f030a184409e64c78cd317
5
5
  SHA512:
6
- metadata.gz: 40f8ce2d39d0816d8e0acdd75922a7cf77935dccf4c4a8be3e14084e9cb09ef21ea73beb6ff8d454eae372a22ec542e557137d5e539a8e2671f291f88d8ba005
7
- data.tar.gz: 271d54107c00a36dc2bb2245265d22709752bed02ae5388dc6c8e5ed98ed09f2ba400d070f58d2f5f111ad5c24c6d3c83dde655c84b621bb6f99044aa0ab90e8
6
+ metadata.gz: e408e0273973b658e8eb883946d350b25a899d901e5f0940bbb4e9cec4e64e3d21287461fdf17141ba21b33e9b03016d4375635115b490b143476c0a5e142554
7
+ data.tar.gz: 7878980a0bb69c7038055106a803ee68032840ffb9fb37c684ddc99353797c133133c1485405f8342ae98052d974b7771d2e17258cf1474e27df1b90592a6dcf
data/CHANGELOG.md CHANGED
@@ -5,7 +5,20 @@ 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
- ## [Unreleased]
8
+ ## [0.19.0] - 2026-09-15
9
+
10
+ ### Added
11
+
12
+ - Show the Cute Framework revision (git commit SHA) being served at startup and on the dashboard, linked to the commit on GitHub
13
+ - Print progress while parsing header files, when running in a terminal
14
+
15
+ ### Changed
16
+
17
+ - Updated dependencies, including `mcp` from 0.22.0 to 0.25.0
18
+
19
+ ### Fixed
20
+
21
+ - `--root` now accepts a Cute Framework project root (as documented) and auto-descends into its `include/` directory; previously this scanned unrelated files and skipped topic indexing entirely
9
22
 
10
23
  ## [0.17.2] - 2026-02-10
11
24
 
@@ -293,6 +306,7 @@ This version was prepared but never released. Changes rolled into 0.17.2.
293
306
  - `cf_list_category` - List items by category
294
307
  - `cf_get_details` - Get full documentation by name
295
308
 
309
+ [0.19.0]: https://github.com/pusewicz/cf-mcp/compare/v0.18.0...v0.19.0
296
310
  [0.17.2]: https://github.com/pusewicz/cf-mcp/compare/v0.17.0...v0.17.2
297
311
  [0.17.1]: https://github.com/pusewicz/cf-mcp/compare/v0.17.0...v0.17.1
298
312
  [0.17.0]: https://github.com/pusewicz/cf-mcp/compare/v0.16.2...v0.17.0
data/Manifest.txt CHANGED
@@ -6,7 +6,6 @@ Rakefile
6
6
  config.ru
7
7
  config/puma.rb
8
8
  exe/cf-mcp
9
- exe/cf-mcp-wrapper
10
9
  lib/cf/mcp.rb
11
10
  lib/cf/mcp/cli.rb
12
11
  lib/cf/mcp/downloader.rb
data/Rakefile CHANGED
@@ -9,7 +9,7 @@ require "standard/rake"
9
9
 
10
10
  desc "Generate Manifest.txt from git ls-files"
11
11
  task :manifest do
12
- ignore_patterns = %w[bin/ Gemfile .gitignore test/ .github/ .standard.yml cf-mcp.gemspec .ruby-version CLAUDE.md AGENTS.md fly.toml Procfile Dockerfile .dockerignore .claude/ .mcp.json]
12
+ ignore_patterns = %w[bin/ Gemfile .gitignore test/ .github/ .standard.yml cf-mcp.gemspec .ruby-version CLAUDE.md AGENTS.md fly.toml Procfile Dockerfile .dockerignore .claude/ .mcp.json .serena/]
13
13
 
14
14
  files = IO.popen(%w[git ls-files -z], chdir: __dir__, err: IO::NULL) do |ls|
15
15
  ls.readlines("\x0", chomp: true)
data/lib/cf/mcp/cli.rb CHANGED
@@ -97,8 +97,9 @@ module CF
97
97
  warn "Indexed #{count} topics from: #{path}" if event == :topics_indexed
98
98
  end
99
99
  warn "Indexed #{index.stats[:total]} items (#{index.stats[:functions]} functions, #{index.stats[:structs]} structs, #{index.stats[:enums]} enums)"
100
+ warn "Cute Framework revision: #{builder.revision}" if builder.revision
100
101
 
101
- server = Server.new(index)
102
+ server = Server.new(index, revision: builder.revision)
102
103
  server.run_stdio
103
104
  end
104
105
 
@@ -15,6 +15,8 @@ module CF
15
15
 
16
16
  class DownloadError < StandardError; end
17
17
 
18
+ attr_reader :sha
19
+
18
20
  def initialize(download_dir: DEFAULT_DOWNLOAD_DIR)
19
21
  @download_dir = download_dir
20
22
  end
@@ -30,6 +32,7 @@ module CF
30
32
  # Check if cache is valid
31
33
  stored_sha = read_sha_metadata(sha_file)
32
34
  latest_sha = fetch_latest_sha
35
+ @sha = latest_sha
33
36
 
34
37
  if stored_sha && latest_sha && stored_sha == latest_sha
35
38
  if File.directory?(include_path) && !Dir.empty?(include_path)
@@ -1,11 +1,13 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "open3"
4
+
3
5
  module CF
4
6
  module MCP
5
7
  class IndexBuilder
6
8
  DEFAULT_HEADERS_PATH = File.expand_path("~/Work/GitHub/pusewicz/cute_framework/include")
7
9
 
8
- attr_reader :headers_path
10
+ attr_reader :headers_path, :revision
9
11
 
10
12
  def initialize(root: nil, download: false)
11
13
  @headers_path = resolve_headers_path(root: root, download: download)
@@ -41,20 +43,45 @@ module CF
41
43
  private
42
44
 
43
45
  def resolve_headers_path(root:, download:)
44
- return root if root
45
- return ENV["CF_HEADERS_PATH"] if ENV["CF_HEADERS_PATH"]
46
+ if root
47
+ @revision = detect_git_revision(root)
48
+ nested_include = File.join(root, "include")
49
+ return File.directory?(nested_include) ? nested_include : root
50
+ end
51
+
52
+ if (env_path = ENV["CF_HEADERS_PATH"])
53
+ @revision = detect_git_revision(env_path)
54
+ return env_path
55
+ end
46
56
 
47
57
  if download
48
58
  warn "Downloading Cute Framework headers from GitHub..."
49
59
  downloader = Downloader.new
50
60
  path = downloader.download_and_extract
61
+ @revision = downloader.sha
51
62
  warn "Downloaded headers to: #{path}"
52
63
  return path
53
64
  end
54
65
 
66
+ @revision = detect_git_revision(DEFAULT_HEADERS_PATH)
55
67
  DEFAULT_HEADERS_PATH
56
68
  end
57
69
 
70
+ # Detects the current git commit SHA for a local Cute Framework checkout.
71
+ # `path` may be the repo root or any subdirectory within it (e.g. include/) -
72
+ # git walks up to find the enclosing repository either way.
73
+ def detect_git_revision(path)
74
+ return nil unless File.directory?(path)
75
+
76
+ stdout, _stderr, status = Open3.capture3("git", "-C", path, "rev-parse", "--short", "HEAD")
77
+ return nil unless status.success?
78
+
79
+ sha = stdout.strip
80
+ sha.empty? ? nil : sha
81
+ rescue Errno::ENOENT
82
+ nil
83
+ end
84
+
58
85
  def find_topics_path(headers_path)
59
86
  # If headers_path is .../cute_framework/include, topics is at .../cute_framework/docs/topics
60
87
  base = File.dirname(headers_path)
data/lib/cf/mcp/parser.rb CHANGED
@@ -32,6 +32,7 @@ module CF
32
32
  def parse_directory(path)
33
33
  items = []
34
34
  Dir.glob(File.join(path, "**/*.h")).each do |header_file|
35
+ warn "Parsing #{header_file}" if $stderr.isatty
35
36
  items.concat(parse_file(header_file))
36
37
  end
37
38
  items
data/lib/cf/mcp/server.rb CHANGED
@@ -5,7 +5,9 @@ require "mcp"
5
5
  module CF
6
6
  module MCP
7
7
  class Server
8
- attr_reader :server, :index
8
+ attr_reader :server, :index, :revision
9
+
10
+ CUTE_FRAMEWORK_COMMIT_URL_TEMPLATE = "https://github.com/RandyGaul/cute_framework/commit/%{revision}"
9
11
 
10
12
  CORS_HEADERS = {
11
13
  "access-control-allow-origin" => "*",
@@ -30,16 +32,18 @@ module CF
30
32
  warn "Indexed #{count} topics from: #{path}" if event == :topics_indexed
31
33
  end
32
34
  warn "Indexed #{index.stats[:total]} items (#{index.stats[:functions]} functions, #{index.stats[:structs]} structs, #{index.stats[:enums]} enums)"
35
+ warn "Cute Framework revision: #{builder.revision}" if builder.revision
33
36
 
34
- new(index).rack_app
37
+ new(index, revision: builder.revision).rack_app
35
38
  end
36
39
 
37
40
  PROTOCOL_VERSION = "2025-03-26"
38
41
  WEBSITE_URL = ENV.fetch("FLY_APP_NAME", nil) ? "https://#{ENV["FLY_APP_NAME"]}.fly.dev" : "https://cf-mcp.fly.dev"
39
42
  PUBLIC_DIR = File.join(__dir__, "public")
40
43
 
41
- def initialize(index)
44
+ def initialize(index, revision: nil)
42
45
  @index = index
46
+ @revision = revision
43
47
 
44
48
  configuration = ::MCP::Configuration.new(protocol_version: PROTOCOL_VERSION)
45
49
  @server = ::MCP::Server.new(
@@ -190,6 +194,8 @@ module CF
190
194
  context = TemplateContext.new(
191
195
  version: CF::MCP::VERSION,
192
196
  protocol_version: PROTOCOL_VERSION,
197
+ revision: @revision,
198
+ revision_url: @revision && format(CUTE_FRAMEWORK_COMMIT_URL_TEMPLATE, revision: @revision),
193
199
  stats: index.stats,
194
200
  categories: index.categories.sort,
195
201
  topics: index.topics_ordered.map { |t| {name: t.name, brief: t.brief} },
@@ -213,11 +219,13 @@ module CF
213
219
  class TemplateContext
214
220
  TEMPLATES_DIR = File.join(__dir__, "templates")
215
221
 
216
- attr_reader :version, :protocol_version, :stats, :categories, :topics, :tools, :tool_schemas_json
222
+ attr_reader :version, :protocol_version, :revision, :revision_url, :stats, :categories, :topics, :tools, :tool_schemas_json
217
223
 
218
- def initialize(version:, protocol_version:, stats:, categories:, topics:, tools:, tool_schemas_json:)
224
+ def initialize(version:, protocol_version:, revision:, revision_url:, stats:, categories:, topics:, tools:, tool_schemas_json:)
219
225
  @version = version
220
226
  @protocol_version = protocol_version
227
+ @revision = revision
228
+ @revision_url = revision_url
221
229
  @stats = stats
222
230
  @categories = categories
223
231
  @topics = topics
@@ -55,6 +55,12 @@
55
55
  <th>Protocol Version</th>
56
56
  <td><%= protocol_version %></td>
57
57
  </tr>
58
+ <% if revision %>
59
+ <tr>
60
+ <th>Cute Framework Revision</th>
61
+ <td><a href="<%= h(revision_url) %>"><%= h(revision) %></a></td>
62
+ </tr>
63
+ <% end %>
58
64
  </table>
59
65
 
60
66
  <h2>Endpoints</h2>
@@ -2,6 +2,6 @@
2
2
 
3
3
  module CF
4
4
  module MCP
5
- VERSION = "0.18.0"
5
+ VERSION = "0.19.0"
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cf-mcp
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.18.0
4
+ version: 0.19.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Piotr Usewicz
@@ -29,14 +29,14 @@ dependencies:
29
29
  requirements:
30
30
  - - "~>"
31
31
  - !ruby/object:Gem::Version
32
- version: '0.6'
32
+ version: '0.25'
33
33
  type: :runtime
34
34
  prerelease: false
35
35
  version_requirements: !ruby/object:Gem::Requirement
36
36
  requirements:
37
37
  - - "~>"
38
38
  - !ruby/object:Gem::Version
39
- version: '0.6'
39
+ version: '0.25'
40
40
  - !ruby/object:Gem::Dependency
41
41
  name: puma
42
42
  requirement: !ruby/object:Gem::Requirement
@@ -99,7 +99,6 @@ email:
99
99
  - piotr@layer22.com
100
100
  executables:
101
101
  - cf-mcp
102
- - cf-mcp-wrapper
103
102
  extensions: []
104
103
  extra_rdoc_files: []
105
104
  files:
@@ -111,7 +110,6 @@ files:
111
110
  - config.ru
112
111
  - config/puma.rb
113
112
  - exe/cf-mcp
114
- - exe/cf-mcp-wrapper
115
113
  - lib/cf/mcp.rb
116
114
  - lib/cf/mcp/cli.rb
117
115
  - lib/cf/mcp/downloader.rb
@@ -170,7 +168,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
170
168
  - !ruby/object:Gem::Version
171
169
  version: '0'
172
170
  requirements: []
173
- rubygems_version: 4.0.3
171
+ rubygems_version: 4.0.12
174
172
  specification_version: 4
175
173
  summary: MCP server providing documentation tools for Cute Framework
176
174
  test_files: []
data/exe/cf-mcp-wrapper DELETED
@@ -1,8 +0,0 @@
1
- #!/bin/bash
2
- source /opt/homebrew/share/chruby/chruby.sh
3
-
4
- PROJECT_DIR="$(cd "$(dirname "$0")/.." && pwd)"
5
- chruby "$(cat "$PROJECT_DIR/.ruby-version")"
6
-
7
- export BUNDLE_GEMFILE="$PROJECT_DIR/Gemfile"
8
- exec "$PROJECT_DIR/exe/cf-mcp" "$@"