ffast 0.2.4 → 0.2.6

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: 4b5b5e27292bfe589236ccf40952b5da73f4dfc4b35df85220d9beebae7c725e
4
- data.tar.gz: 6c4466b554e164c447cfb02760c5b6cd262c0f904f7ea8c35897288efa4668ec
3
+ metadata.gz: 95125c92ee4201a508f422f041be2a63aebe3a92a19ca303d85b1be98ab6f1e0
4
+ data.tar.gz: 137a7d81790b9f51aaeea271d4d803b6b33a158f7f4b9f4c8a007a23131e6f05
5
5
  SHA512:
6
- metadata.gz: 0f8ccd9bcd621b69847fd1092b0fa08cada32258a2ec1f6b04654744c8930718628955698673577e4431a6fe6146da744bcb6aafdada442aa08bfe8e5ba32780
7
- data.tar.gz: 263b032df9ed1ea5b8d7cd71e1bd613dc781c53fc1dd10cb8bedbe526d904543e1331bb43f345679954e7ebc404b0bdfb5f965dffd35b74c454038ba7ae0fb31
6
+ metadata.gz: 9b1cb25bf21ef812530856cd778b8d875df7498bc9aaa6576c215964c75dc189131f8fdb539b18eec54b8c44fc3033099b74d457135f77feeff6d5f1ebb34405
7
+ data.tar.gz: 256b3549dd55c412ad1a5d2d84b7d284f4fb94f10096f56a02391ae4e67f4e40894ad1816ab997f7dd08b99b36aa90b9eb68ce3101fa8bba0fb0ba7185329761
data/fast.gemspec CHANGED
@@ -17,7 +17,8 @@ Gem::Specification.new do |spec|
17
17
  spec.license = 'MIT'
18
18
 
19
19
  spec.files = `git ls-files -z`.split("\x0").reject do |f|
20
- f.match(%r{^(test|spec|experiments|examples|features|docs|assets|stylesheets|site)/})
20
+ f.match(%r{^(test|spec|experiments|examples|features|docs|assets|stylesheets|site)/}) ||
21
+ f.match(%r{^(\.git|\.github|\.travis|\.sourcelevel|\.rubocop|\.projections|\.rspec|Gemfile|Rakefile|Guardfile|mkdocs|requirements-docs|TODO|ideia_blog_post)})
21
22
  end
22
23
 
23
24
  spec.post_install_message = <<~THANKS
@@ -39,8 +40,8 @@ Gem::Specification.new do |spec|
39
40
  THANKS
40
41
 
41
42
  spec.bindir = 'bin'
42
- spec.executables = %w[fast fast-experiment]
43
- spec.require_paths = %w[lib experiments]
43
+ spec.executables = %w[fast fast-experiment fast-mcp]
44
+ spec.require_paths = %w[lib]
44
45
 
45
46
  spec.add_dependency 'coderay'
46
47
  spec.add_dependency 'parallel'
data/lib/fast/cli.rb CHANGED
@@ -106,8 +106,23 @@ module Fast
106
106
  args = args.dup
107
107
  args = replace_args_with_shortcut(args) if shortcut_name_from(args)
108
108
  @colorize = STDOUT.isatty
109
- option_parser.parse! args
109
+ @headless = false
110
+ @bodyless = false
111
+ @captures = false
112
+ @parallel = false
113
+ @debug = false
114
+ @sql = false
115
+ @level = nil
116
+ @show_sexp = false
117
+ @help = false
118
+ @similar = false
119
+ @from_code = false
120
+ @show_link = false
121
+ @show_permalink = false
122
+ @files = []
123
+ option_parser.parse!(args)
110
124
  @pattern, @files = extract_pattern_and_files(args)
125
+ puts "DEBUG: pattern=#{@pattern.inspect} files=#{@files.inspect}" if @debug
111
126
 
112
127
  @sql ||= @files.any? && @files.all? { |file| file.end_with?('.sql') }
113
128
  require 'fast/sql' if @sql
@@ -146,7 +161,7 @@ module Fast
146
161
  @sql = true
147
162
  end
148
163
 
149
- opts.on('--captures', 'Print only captures of the patterns and skip node results') do
164
+ opts.on('-c', '--captures', 'Print only captures of the patterns and skip node results') do
150
165
  @captures = true
151
166
  end
152
167
 
data/lib/fast/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Fast
4
- VERSION = '0.2.4'
4
+ VERSION = '0.2.6'
5
5
  end
data/lib/fast.rb CHANGED
@@ -548,7 +548,6 @@ module Fast
548
548
  case expression
549
549
  when Proc then expression.call(node)
550
550
  when Find then expression.match?(node)
551
- when Symbol then compare_symbol_or_head(expression, node)
552
551
  when Enumerable
553
552
  if expression.last == :'...' || expression.last.is_a?(Find) && expression.last.token == '...'
554
553
  expression[0...-1].each_with_index.all? do |exp, i|
@@ -774,7 +773,7 @@ module Fast
774
773
  # Fast.expression("{int float}")
775
774
  class Any < Find
776
775
  def match?(node)
777
- token.any? { |expression| Fast.match?(expression, node) }
776
+ token.any? { |expression| !!Fast.match?(expression, node) }
778
777
  end
779
778
 
780
779
  def to_s
@@ -785,7 +784,7 @@ module Fast
785
784
  # Intersect expressions. Works like a **AND** operator.
786
785
  class All < Find
787
786
  def match?(node)
788
- token.all? { |expression| expression.match?(node) }
787
+ token.all? { |expression| !!expression.match?(node) }
789
788
  end
790
789
 
791
790
  def to_s
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ffast
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.4
4
+ version: 0.2.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jônatas Davi Paganini
@@ -240,33 +240,21 @@ email:
240
240
  executables:
241
241
  - fast
242
242
  - fast-experiment
243
+ - fast-mcp
243
244
  extensions: []
244
245
  extra_rdoc_files: []
245
246
  files:
246
247
  - ".agents/fast-pattern-expert/SKILL.md"
247
- - ".github/workflows/release.yml"
248
- - ".github/workflows/ruby.yml"
249
- - ".gitignore"
250
- - ".projections.json"
251
- - ".rspec"
252
- - ".rubocop.yml"
253
- - ".sourcelevel.yml"
254
- - ".travis.yml"
255
248
  - CODE_OF_CONDUCT.md
256
249
  - Fastfile
257
- - Gemfile
258
- - Guardfile
259
250
  - LICENSE.txt
260
251
  - README.md
261
- - Rakefile
262
- - TODO.md
263
252
  - bin/console
264
253
  - bin/fast
265
254
  - bin/fast-experiment
266
255
  - bin/fast-mcp
267
256
  - bin/setup
268
257
  - fast.gemspec
269
- - ideia_blog_post.md
270
258
  - lib/fast.rb
271
259
  - lib/fast/cli.rb
272
260
  - lib/fast/experiment.rb
@@ -283,8 +271,6 @@ files:
283
271
  - lib/fast/sql/rewriter.rb
284
272
  - lib/fast/summary.rb
285
273
  - lib/fast/version.rb
286
- - mkdocs.yml
287
- - requirements-docs.txt
288
274
  homepage: https://jonatas.github.io/fast/
289
275
  licenses:
290
276
  - MIT
@@ -308,7 +294,6 @@ post_install_message: |2+
308
294
  rdoc_options: []
309
295
  require_paths:
310
296
  - lib
311
- - experiments
312
297
  required_ruby_version: !ruby/object:Gem::Requirement
313
298
  requirements:
314
299
  - - ">="
@@ -1,27 +0,0 @@
1
- name: Release Gem
2
-
3
- on:
4
- push:
5
- tags:
6
- - 'v*' # Triggers when a new tag like v0.2.0 is pushed
7
-
8
- jobs:
9
- release:
10
- name: Build and Release
11
- runs-on: ubuntu-22.04
12
- permissions:
13
- contents: read # Required to checkout the code
14
- id-token: write # Required for RubyGems Trusted Publishing
15
-
16
- steps:
17
- - name: Checkout code
18
- uses: actions/checkout@v4
19
-
20
- - name: Set up Ruby
21
- uses: ruby/setup-ruby@v1
22
- with:
23
- ruby-version: '3.3'
24
- bundler-cache: true
25
-
26
- - name: Publish to RubyGems
27
- uses: rubygems/release-gem@v1
@@ -1,34 +0,0 @@
1
- # This workflow uses actions that are not certified by GitHub.
2
- # They are provided by a third-party and are governed by
3
- # separate terms of service, privacy policy, and support
4
- # documentation.
5
- # This workflow will download a prebuilt Ruby version, install dependencies and run tests with Rake
6
- # For more information see: https://github.com/marketplace/actions/setup-ruby-jruby-and-truffleruby
7
-
8
- name: Ruby
9
-
10
- on:
11
- push:
12
- branches: [ "master" ]
13
- pull_request:
14
- branches: [ "master" ]
15
-
16
- permissions:
17
- contents: read
18
-
19
- jobs:
20
- test:
21
- runs-on: ubuntu-22.04
22
- strategy:
23
- matrix:
24
- ruby-version: ['3.0', '3.1', '3.2', '3.3']
25
-
26
- steps:
27
- - uses: actions/checkout@v4
28
- - name: Set up Ruby
29
- uses: ruby/setup-ruby@v1
30
- with:
31
- ruby-version: ${{ matrix.ruby-version }}
32
- bundler-cache: true
33
- - name: Run tests
34
- run: bundle exec rake
data/.gitignore DELETED
@@ -1,14 +0,0 @@
1
- /.bundle/
2
- /.yardoc
3
- /Gemfile.lock
4
- /_yardoc/
5
- /coverage/
6
- /doc/
7
- /pkg/
8
- /site/
9
- /spec/reports/
10
- /tmp/
11
- .venv/
12
-
13
- # rspec failure tracking
14
- .rspec_status
data/.projections.json DELETED
@@ -1,4 +0,0 @@
1
- {
2
- "README.md": { "type": "readme" },
3
- "lib/*.rb": { "type": "lib", "alternate": "spec/{}_spec.rb" }
4
- }
data/.rspec DELETED
@@ -1,2 +0,0 @@
1
- --format documentation
2
- --color
data/.rubocop.yml DELETED
@@ -1,160 +0,0 @@
1
- # This is the configuration used to check the rubocop source code.
2
-
3
- require:
4
- - rubocop-rspec
5
- - rubocop-performance
6
-
7
- AllCops:
8
- Exclude:
9
- - 'tmp/**/*'
10
- - 'examples/*'
11
- TargetRubyVersion: 2.6
12
-
13
- Layout/LineLength:
14
- Enabled: false
15
-
16
- Layout/EmptyLinesAroundAttributeAccessor:
17
- Enabled: false
18
-
19
- Layout/SpaceAroundMethodCallOperator:
20
- Enabled: false
21
-
22
- Lint/BinaryOperatorWithIdenticalOperands:
23
- Enabled: true
24
-
25
- Lint/DuplicateElsifCondition:
26
- Enabled: false
27
-
28
- Lint/DuplicateRescueException:
29
- Enabled: false
30
-
31
- Lint/EmptyConditionalBody:
32
- Enabled: false
33
-
34
- Lint/FloatComparison:
35
- Enabled: false
36
-
37
- Lint/MissingSuper:
38
- Enabled: false
39
-
40
- Lint/OutOfRangeRegexpRef:
41
- Enabled: false
42
-
43
- Lint/SelfAssignment:
44
- Enabled: false
45
-
46
- Lint/TopLevelReturnWithArgument:
47
- Enabled: false
48
-
49
- Lint/UnreachableLoop:
50
- Enabled: false
51
-
52
-
53
- Lint/DeprecatedOpenSSLConstant:
54
- Enabled: false
55
-
56
- Lint/MixedRegexpCaptureTypes:
57
- Enabled: false
58
-
59
- Lint/RaiseException:
60
- Enabled: true
61
-
62
- Lint/StructNewOverride:
63
- Enabled: true
64
-
65
- Style/AccessorGrouping:
66
- Enabled: false
67
-
68
- Style/ArrayCoercion:
69
- Enabled: false
70
-
71
- Style/BisectedAttrAccessor:
72
- Enabled: true
73
-
74
- Style/CaseLikeIf:
75
- Enabled: true
76
-
77
- Style/ExplicitBlockArgument:
78
- Enabled: false
79
-
80
- Style/ExponentialNotation:
81
- Enabled: true
82
-
83
- Style/GlobalStdStream:
84
- Enabled: false
85
-
86
- Style/HashAsLastArrayItem:
87
- Enabled: false
88
-
89
- Style/HashLikeCase:
90
- Enabled: true
91
-
92
- Style/OptionalBooleanParameter:
93
- Enabled: true
94
-
95
- Style/RedundantAssignment:
96
- Enabled: true
97
-
98
- Style/RedundantFetchBlock:
99
- Enabled: true
100
-
101
- Style/RedundantFileExtensionInRequire:
102
- Enabled: true
103
-
104
- Style/SingleArgumentDig:
105
- Enabled: true
106
-
107
- Style/StringConcatenation:
108
- Enabled: true
109
-
110
- Style/RedundantRegexpCharacterClass:
111
- Enabled: false
112
-
113
- Style/RedundantRegexpEscape:
114
- Enabled: false
115
-
116
- Style/SlicingWithRange:
117
- Enabled: true
118
-
119
- Metrics/BlockLength:
120
- Exclude:
121
- - 'spec/**/*'
122
- - 'fast.gemspec'
123
-
124
- Lint/InterpolationCheck:
125
- Exclude:
126
- - 'spec/**/*'
127
-
128
- Metrics/MethodLength:
129
- CountComments: false # count full line comments?
130
- Max: 12
131
-
132
- Metrics/ModuleLength:
133
- Enabled: false
134
-
135
- Layout/MultilineMethodCallIndentation:
136
- EnforcedStyle: 'indented'
137
-
138
- RSpec/NestedGroups:
139
- Max: 4
140
-
141
- RSpec/ExampleLength:
142
- Max: 20
143
-
144
- RSpec/MultipleExpectations:
145
- Enabled: false
146
-
147
- RSpec/DescribedClass:
148
- Enabled: false
149
-
150
- RSpec/ImplicitSubject:
151
- Enabled: false
152
-
153
- Style/HashEachMethods:
154
- Enabled: true
155
-
156
- Style/HashTransformKeys:
157
- Enabled: true
158
-
159
- Style/HashTransformValues:
160
- Enabled: true
data/.sourcelevel.yml DELETED
@@ -1,2 +0,0 @@
1
- pull_requests:
2
- comments: false
data/.travis.yml DELETED
@@ -1,18 +0,0 @@
1
- sudo: false
2
- language: ruby
3
- env:
4
- global:
5
- - CC_TEST_REPORTER_ID=cf3977cb8c335147723d765c91877e0506ba43e56a22a0dc5b83d7fb969cf5e4
6
- rvm:
7
- - 2.6.3
8
- before_install:
9
- gem install bundler -v 2.1.4
10
- before_script:
11
- - curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter
12
- - chmod +x ./cc-test-reporter
13
- - ./cc-test-reporter before-build
14
- after_script:
15
- - ./cc-test-reporter after-build -t simplecov --exit-code $TRAVIS_TEST_RESULT
16
- script:
17
- - bundle exec rubocop --fail-level warning --display-only-fail-level-offenses
18
- - bundle exec rspec
data/Gemfile DELETED
@@ -1,6 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- source 'https://rubygems.org'
4
-
5
- # Specify your gem's dependencies in fast.gemspec
6
- gemspec
data/Guardfile DELETED
@@ -1,39 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # A sample Guardfile
4
- # More info at https://github.com/guard/guard#readme
5
-
6
- ## Uncomment and set this to only include directories you want to watch
7
- # directories %w(app lib config test spec features) \
8
- # .select{|d| Dir.exists?(d) ? d : UI.warning("Directory #{d} does not exist")}
9
-
10
- ## Note: if you are using the `directories` clause above and you are not
11
- ## watching the project directory ('.'), then you will want to move
12
- ## the Guardfile to a watched dir and symlink it back, e.g.
13
- #
14
- # $ mkdir config
15
- # $ mv Guardfile config/
16
- # $ ln -s config/Guardfile .
17
- #
18
- # and, you'll have to watch "config/Guardfile" instead of "Guardfile"
19
-
20
- guard 'livereload' do
21
- watch(%r{lib/.+\.rb$})
22
- end
23
-
24
- guard :rspec, cmd: 'bundle exec rspec' do
25
- require 'guard/rspec/dsl'
26
- dsl = Guard::RSpec::Dsl.new(self)
27
-
28
- # Feel free to open issues for suggestions and improvements
29
-
30
- # RSpec files
31
- rspec = dsl.rspec
32
- watch(rspec.spec_helper) { rspec.spec_dir }
33
- watch(rspec.spec_support) { rspec.spec_dir }
34
- watch(rspec.spec_files)
35
-
36
- # Ruby files
37
- ruby = dsl.ruby
38
- dsl.watch_spec_files_for(ruby.lib_files)
39
- end
data/Rakefile DELETED
@@ -1,8 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'bundler/gem_tasks'
4
- require 'rspec/core/rake_task'
5
-
6
- RSpec::Core::RakeTask.new(:spec)
7
-
8
- task default: :spec
data/TODO.md DELETED
@@ -1,3 +0,0 @@
1
- - [ ] Add matcher diagnostics. Allow check details of each matcher in the three
2
- - [ ] Split stuff into files and add tests for each class
3
- - [ ] Validate expressions and raise errors for invalid expressions
data/ideia_blog_post.md DELETED
@@ -1,36 +0,0 @@
1
- # Empowering LLM Agents with Natural Language to Fast Patterns
2
-
3
- Today I'm excited to announce a significant set of improvements to `fast`, specifically designed to bridge the gap between human reasoning (and LLM agents) and the technical precision of Ruby AST searching.
4
-
5
- ## The Problem: AST Patterns are Hard
6
-
7
- Searching through code using AST patterns is incredibly powerful, but constructing the right S-expression can be daunting. Whether you're a human or an AI agent, getting the syntax just right—especially for complex queries—often involves a lot of trial and error.
8
-
9
- ## The Solution: NL-to-Fast Translation
10
-
11
- We've introduced three new tools to solve this:
12
-
13
- 1. **The `fast-pattern-expert` Skill**: A specialized Gemini CLI skill that provides deep guidance, syntax references, and few-shot examples for translating structural descriptions of Ruby code into valid `Fast` patterns.
14
- 2. **`validate_fast_pattern` MCP Tool**: A new tool for our Model Context Protocol (MCP) server that allows agents to verify their generated patterns before executing them.
15
- 3. **`--validate-pattern` CLI Flag**: A quick way for humans to check if their pattern syntax is correct, checking for balanced nesting and valid token types.
16
-
17
- ### Example in Action:
18
- **Query:** "Find all classes that inherit from `BaseService` and have a `call` method."
19
- **Pattern:** `[(class _ (const nil BaseService)) (def call)]`
20
-
21
- ## Robustness and Precision
22
-
23
- We've also beefed up the core of `fast`:
24
- - **Stricter Validation**: The `ExpressionParser` now tracks nesting levels and unconsumed tokens, providing helpful error messages instead of silently failing or returning partial matches.
25
- - **Improved `...` Matcher**: The `...` literal now acts as a "rest-of-children" matcher when used at the end of a pattern, making it much easier to match methods with any number of arguments.
26
- - **Graceful Degradation**: Multi-file scans (`.scan`) now degrade gracefully if a single file fails to parse, ensuring your reconnaissance isn't aborted by one unsupported syntax node.
27
-
28
- ## A Safer Release Workflow
29
-
30
- On the operational side, I'm moving our gem release process to **GitHub Actions**. By releasing from a clean CI sandbox instead of my local machine, we ensure a much higher level of security and reproducibility. This move minimizes the risk of local environment contamination and provides a transparent, auditable path from source to RubyGems.
31
-
32
- ## Release 0.2.4
33
-
34
- To celebrate these features, we are releasing version `0.2.4` today!
35
-
36
- Happy searching!
data/mkdocs.yml DELETED
@@ -1,51 +0,0 @@
1
- site_name: Fast
2
- repo_url: https://github.com/jonatas/fast
3
- edit_uri: edit/master/docs/
4
-
5
- extra:
6
- analytics:
7
- provider: google
8
- property: G-YKZDZDNRG2
9
-
10
- theme:
11
- name: material
12
- palette:
13
- primary: indigo
14
- accent: pink
15
- logo: assets/logo.png
16
- favicon: assets/favicon.png
17
- extra_css:
18
- - stylesheets/custom.css
19
-
20
- plugins:
21
- - search
22
-
23
- markdown_extensions:
24
- - admonition
25
- - pymdownx.details
26
- - pymdownx.superfences
27
- - pymdownx.tabbed:
28
- alternate_style: true
29
- - toc:
30
- permalink: true
31
- nav:
32
- - Introduction: index.md
33
- - Walkthrough: walkthrough.md
34
- - Syntax: syntax.md
35
- - Command Line: command_line.md
36
- - Experiments: experiments.md
37
- - Shortcuts: shortcuts.md
38
- - Git Integration: git.md
39
- - Fast for LLMs and Agents: agents.md
40
- - MCP Server Tutorial: mcp_tutorial.md
41
- - Code Similarity: similarity_tutorial.md
42
- - LLM/Agent Feature TODOs: llm_features.md
43
- - Pry Integration: pry-integration.md
44
- - Editors' Integration: editors-integration.md
45
- - Research: research.md
46
- - Ideas: ideas.md
47
- - Videos: videos.md
48
- - SQL:
49
- - Intro: sql/index.md
50
- - Shortcuts: sql/shortcuts.md
51
- - About: sql-support.md
@@ -1,3 +0,0 @@
1
- mkdocs>=1.6,<2.0
2
- mkdocs-material>=9.5,<10.0
3
- pymdown-extensions>=10.0,<11.0