appydave-tools 0.11.0 → 0.11.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +19 -0
- data/README.md +1 -2
- data/docs/usage/gpt-context.md +195 -0
- data/lib/appydave/tools/subtitle_master/_doc.md +6 -1
- data/lib/appydave/tools/version.rb +1 -1
- data/package-lock.json +2 -2
- data/package.json +1 -1
- metadata +2 -2
- data/a.json +0 -60
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ff3f53496b7bcef356d2b26a3983b9edc374e7f8f1e51e8568eb046c92ffd8f5
|
4
|
+
data.tar.gz: 49d5940949d4f12c23a4da97e005ece228ede5ed4fa3143b9ffe276748da6f3a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ad766554742121c77732c469de4789595585143ffc91e5671211ec00bc00aaafd578bfe3f27180ebc41d37e88a2bc8450efe99a5d869a5433095165d2ffd239a
|
7
|
+
data.tar.gz: 3248e609f4f6749e432c61fc26f56dc350c0991c9f25aa416d0124660c095a2366ee3432fdb07155c3c1b3b0a64a71753826e0a9128dff4e10efe3b9bf806ec4
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,22 @@
|
|
1
|
+
## [0.11.1](https://github.com/klueless-io/appydave-tools/compare/v0.11.0...v0.11.1) (2024-10-16)
|
2
|
+
|
3
|
+
|
4
|
+
### Bug Fixes
|
5
|
+
|
6
|
+
* gpt context documentation ([808fccd](https://github.com/klueless-io/appydave-tools/commit/808fccdea10c472522da02c8af7f9a2c9eaf361a))
|
7
|
+
|
8
|
+
# [0.11.0](https://github.com/klueless-io/appydave-tools/compare/v0.10.4...v0.11.0) (2024-10-16)
|
9
|
+
|
10
|
+
|
11
|
+
### Bug Fixes
|
12
|
+
|
13
|
+
* gpt context improvements ([1a1db97](https://github.com/klueless-io/appydave-tools/commit/1a1db976317d1b6056d14e226a5635c3b7dea83d))
|
14
|
+
|
15
|
+
|
16
|
+
### Features
|
17
|
+
|
18
|
+
* gpt_context has improved options, this may break some previous calls ([21c984a](https://github.com/klueless-io/appydave-tools/commit/21c984a61d215da93783a3df55f10301cae55e1c))
|
19
|
+
|
1
20
|
## [0.10.4](https://github.com/klueless-io/appydave-tools/compare/v0.10.3...v0.10.4) (2024-10-09)
|
2
21
|
|
3
22
|
|
data/README.md
CHANGED
@@ -0,0 +1,195 @@
|
|
1
|
+
# GPT Context Usage Guide
|
2
|
+
|
3
|
+
This guide provides a comprehensive reference for using the `gpt_context` tool. Below you'll find examples of different use cases and command line invocations to help you effectively use `gpt_context` for gathering and organizing your project files. These examples will help you remember how to leverage various options available in `gpt_context`.
|
4
|
+
|
5
|
+
## Overview
|
6
|
+
|
7
|
+
`gpt_context` is a command line utility designed to collect, filter, and organize context from different files within a project. It allows for gathering files based on include and exclude patterns, visualizing the project structure, and exporting collected information in multiple formats, such as content, tree, or JSON.
|
8
|
+
|
9
|
+
### Common Options
|
10
|
+
- **`-i` or `--include`**: Specify patterns or files to include (multiple entries allowed).
|
11
|
+
- **`-e` or `--exclude`**: Specify patterns or files to exclude (multiple entries allowed).
|
12
|
+
- **`-f` or `--format`**: Define output format (`content`, `tree`, or `json`). If not provided, then `tree` followed by `content` is used by default.
|
13
|
+
- **`-d` or `--debug`**: Enable debug mode (e.g., `info`, `params`, `debug`). The default is `info` and this is how output to console is invoked. (Yes, I know, it should be part of the `--output` option as well).
|
14
|
+
- **`-o` or `--output`**: Set the output target (`clipboard` or a file path). The default is `clipboard` (I know this is potentially destructive).
|
15
|
+
- **`-l` or `--line-limit`**: Limit the number of lines included from each file.
|
16
|
+
- **`-b` or `--base-dir`**: Set the base directory to gather files from. Current working directory is used if not supplied.
|
17
|
+
|
18
|
+
## Usage Examples
|
19
|
+
|
20
|
+
### 1. Gathering File Contents
|
21
|
+
To gather the content of specific files and print it to the console, you can use the `-f content` format option:
|
22
|
+
|
23
|
+
```sh
|
24
|
+
$ gpt_context -i "**/gpt_context.rb" -i "**/gpt_context/*.rb" -d -f content
|
25
|
+
```
|
26
|
+
**Explanation**: This command collects the content of all Ruby files matching the specified patterns (`gpt_context.rb` and files in the `gpt_context` directory). It includes debug output (`-d`) to log the content to the console during execution. The result is stored in the clipboard in content format.
|
27
|
+
|
28
|
+
### 2. Displaying Directory Structure as a Tree
|
29
|
+
To visualize the structure of the included files as a tree, use the `-f tree` option:
|
30
|
+
|
31
|
+
```sh
|
32
|
+
$ gpt_context -i "**/gpt_context.rb" -i "**/gpt_context/*.rb" -d -f tree
|
33
|
+
```
|
34
|
+
**Explanation**: This command collects files based on the patterns and using the `-d` prints them in a tree-like structure. The tree is also loaded into the clipboard by default. This is useful for understanding the overall organization of files within the project.
|
35
|
+
|
36
|
+
### 3. Exporting File Data as JSON
|
37
|
+
You can export the gathered file data as JSON by using the `-f json` format option, along with specifying an output file:
|
38
|
+
|
39
|
+
```sh
|
40
|
+
$ gpt_context -i "**/gpt_context.rb" -i "**/gpt_context/*.rb" -f json -o somefile.json
|
41
|
+
```
|
42
|
+
**Explanation**: This command collects files and outputs the gathered data in JSON format. The result is saved to `somefile.json` (`-o somefile.json`). There is no `-d` so there will be no console output; also, the `-o` will replace the default which is `clipboard` and so the only output in this case is the file which will go into the working directory. This is helpful when you need a structured representation of your project files, such as for further processing or analysis.
|
43
|
+
|
44
|
+
### 4. Combining Multiple Formats
|
45
|
+
You can generate multiple formats at once by specifying them in a comma-separated list:
|
46
|
+
|
47
|
+
```sh
|
48
|
+
$ gpt_context -i "**/gpt_context.rb" -i "**/gpt_context/*.rb" -f tree,content
|
49
|
+
```
|
50
|
+
**Explanation**: This command gathers the files and produces both a tree view and concatenated content output. The combined output can help visualize both the structure and content of your project files. This would be the default if you did not use `-f`, but interestingly, you can reverse them `-f content,tree` if you want the tree at the bottom of the concatenated output.
|
51
|
+
|
52
|
+
### 5. Limiting the Number of Lines Collected
|
53
|
+
To limit the number of lines collected from each file, use the `-l` option:
|
54
|
+
|
55
|
+
```sh
|
56
|
+
$ gpt_context -i "**/*.rb" -l 10
|
57
|
+
```
|
58
|
+
**Explanation**: This command gathers the first 10 lines from each Ruby file in the current directory and its subdirectories. This can be useful for getting an overview without including complete files.
|
59
|
+
|
60
|
+
### 6. Setting the Working Directory
|
61
|
+
You can specify a base directory to gather files from by using the `-b` option:
|
62
|
+
|
63
|
+
```sh
|
64
|
+
$ gpt_context -b "lib/" -i "**/*.rb" -f tree
|
65
|
+
```
|
66
|
+
**Explanation**: This command sets the base directory to `lib/` and gathers all Ruby files within it, displaying the output in a tree format. This helps scope your collection to a specific part of your project.
|
67
|
+
|
68
|
+
## Debugging Tips
|
69
|
+
- **Debugging Mode**: The `-d` option can be followed by levels like `info`, `params`, or `debug` to control the verbosity of debug output.
|
70
|
+
- `params`: Prints out the parameters being used.
|
71
|
+
- `debug`: Provides detailed output, which can be helpful for troubleshooting issues.
|
72
|
+
|
73
|
+
Example:
|
74
|
+
```sh
|
75
|
+
$ gpt_context -i "**/*.rb" -d debug -f content
|
76
|
+
```
|
77
|
+
This will provide detailed debug output while collecting file contents.
|
78
|
+
|
79
|
+
## Output Targets
|
80
|
+
- **Clipboard**: By default, if no output target is specified, the content is copied to the clipboard.
|
81
|
+
- **File Output**: Use the `-o` option with a file path to save the output to a file.
|
82
|
+
|
83
|
+
Example:
|
84
|
+
```sh
|
85
|
+
$ gpt_context -i "**/*.rb" -o output.txt
|
86
|
+
```
|
87
|
+
This saves the gathered content to `output.txt`.
|
88
|
+
|
89
|
+
## Summary
|
90
|
+
The `gpt_context` tool is versatile for gathering, visualizing, and exporting project context in various formats. Whether you need a structured view of your files, a quick JSON export, or just the content concatenated, these examples should help you remember how to leverage the tool's full capabilities effectively.
|
91
|
+
|
92
|
+
Feel free to expand this guide with more examples as you explore new ways to use `gpt_context`!
|
93
|
+
|
94
|
+
## Class-Level Usage Examples
|
95
|
+
|
96
|
+
In addition to the command line interface, the `gpt_context` tool provides classes that can be used directly in Ruby code for greater flexibility. Here are some examples of how to use the main classes involved in `gpt_context`.
|
97
|
+
|
98
|
+
### 1. Using `FileCollector`
|
99
|
+
The `FileCollector` class can be used to gather files programmatically. Below is an example of how to instantiate and use the `FileCollector` class.
|
100
|
+
|
101
|
+
```ruby
|
102
|
+
require 'appydave/tools'
|
103
|
+
|
104
|
+
# Set up options for FileCollector
|
105
|
+
options = Appydave::Tools::GptContext::Options.new(
|
106
|
+
include_patterns: ['**/*.rb'],
|
107
|
+
exclude_patterns: ['spec/**/*'],
|
108
|
+
format: 'content',
|
109
|
+
line_limit: 20,
|
110
|
+
working_directory: Dir.pwd
|
111
|
+
)
|
112
|
+
|
113
|
+
# Create a new FileCollector instance
|
114
|
+
collector = Appydave::Tools::GptContext::FileCollector.new(options)
|
115
|
+
|
116
|
+
# Gather the file content
|
117
|
+
content = collector.build
|
118
|
+
|
119
|
+
# Output the collected content
|
120
|
+
puts content
|
121
|
+
```
|
122
|
+
**Explanation**: This script sets up `Options` with specific parameters (including which files to include/exclude and the format), and then creates a `FileCollector` instance to gather the content. The gathered content is printed to the console.
|
123
|
+
|
124
|
+
### 2. Setting Up `Options`
|
125
|
+
The `Options` class is crucial for configuring how the `FileCollector` behaves. Here’s how you can use the `Options` class:
|
126
|
+
|
127
|
+
```ruby
|
128
|
+
require 'appydave/tools'
|
129
|
+
|
130
|
+
# Create options with specific settings
|
131
|
+
options = Appydave::Tools::GptContext::Options.new(
|
132
|
+
include_patterns: ['lib/**/*.rb'],
|
133
|
+
exclude_patterns: ['lib/excluded/**/*.rb'],
|
134
|
+
format: 'tree,content',
|
135
|
+
line_limit: 10,
|
136
|
+
debug: 'info',
|
137
|
+
output_target: ['clipboard'],
|
138
|
+
working_directory: 'lib'
|
139
|
+
)
|
140
|
+
|
141
|
+
# Display options
|
142
|
+
pp options
|
143
|
+
```
|
144
|
+
**Explanation**: The `Options` class provides named parameters to specify how files should be gathered. This script creates an `Options` instance, which can then be used by `FileCollector` or other components of the tool.
|
145
|
+
|
146
|
+
### 3. Using `OutputHandler`
|
147
|
+
The `OutputHandler` class is responsible for handling the output after files are gathered. Here is how to use it:
|
148
|
+
|
149
|
+
```ruby
|
150
|
+
require 'appydave/tools'
|
151
|
+
|
152
|
+
# Create options and gather content using FileCollector
|
153
|
+
options = Appydave::Tools::GptContext::Options.new(
|
154
|
+
include_patterns: ['**/*.rb'],
|
155
|
+
format: 'content',
|
156
|
+
output_target: ['output.txt']
|
157
|
+
)
|
158
|
+
|
159
|
+
collector = Appydave::Tools::GptContext::FileCollector.new(options)
|
160
|
+
content = collector.build
|
161
|
+
|
162
|
+
# Handle output using OutputHandler
|
163
|
+
output_handler = Appydave::Tools::GptContext::OutputHandler.new(content, options)
|
164
|
+
output_handler.execute
|
165
|
+
```
|
166
|
+
**Explanation**: This script collects content using `FileCollector` and then uses `OutputHandler` to save the gathered content to `output.txt`. The `OutputHandler` manages different output targets, such as clipboard or files, based on the specified options.
|
167
|
+
|
168
|
+
### 4. Combining Classes for Complete Workflow
|
169
|
+
Here’s an example of combining `Options`, `FileCollector`, and `OutputHandler` to automate the entire workflow:
|
170
|
+
|
171
|
+
```ruby
|
172
|
+
require 'appydave/tools'
|
173
|
+
|
174
|
+
# Step 1: Create Options
|
175
|
+
options = Appydave::Tools::GptContext::Options.new(
|
176
|
+
include_patterns: ['**/*.rb'],
|
177
|
+
exclude_patterns: ['**/test/**/*.rb'],
|
178
|
+
format: 'json',
|
179
|
+
output_target: ['output.json'],
|
180
|
+
debug: 'params'
|
181
|
+
)
|
182
|
+
|
183
|
+
# Step 2: Gather Files using FileCollector
|
184
|
+
collector = Appydave::Tools::GptContext::FileCollector.new(options)
|
185
|
+
content = collector.build
|
186
|
+
|
187
|
+
# Step 3: Output Results using OutputHandler
|
188
|
+
output_handler = Appydave::Tools::GptContext::OutputHandler.new(content, options)
|
189
|
+
output_handler.execute
|
190
|
+
```
|
191
|
+
**Explanation**: This complete example demonstrates how to use `Options` to configure the gathering process, `FileCollector` to collect the files, and `OutputHandler` to manage the output. This approach can be useful for programmatically automating context collection tasks in more complex workflows.
|
192
|
+
|
193
|
+
## References
|
194
|
+
|
195
|
+
- [ChatGPT Documentation](https://chatgpt.com/c/670f2150-08b4-8002-b2d7-04aff6fe304f)
|
@@ -1,6 +1,11 @@
|
|
1
1
|
# Subtitle Master
|
2
2
|
|
3
|
-
|
3
|
+
Older Chat
|
4
|
+
- https://chatgpt.com/c/f80dfca5-8168-4561-b5c6-8efed8672a88
|
5
|
+
|
6
|
+
New Features
|
7
|
+
- https://chatgpt.com/c/670470b8-a0c4-8002-9678-d4d69c680481
|
8
|
+
|
4
9
|
|
5
10
|
## SubtitleMaster - Clean Component
|
6
11
|
|
data/package-lock.json
CHANGED
@@ -1,12 +1,12 @@
|
|
1
1
|
{
|
2
2
|
"name": "appydave-tools",
|
3
|
-
"version": "0.11.
|
3
|
+
"version": "0.11.2",
|
4
4
|
"lockfileVersion": 3,
|
5
5
|
"requires": true,
|
6
6
|
"packages": {
|
7
7
|
"": {
|
8
8
|
"name": "appydave-tools",
|
9
|
-
"version": "0.11.
|
9
|
+
"version": "0.11.2",
|
10
10
|
"devDependencies": {
|
11
11
|
"@klueless-js/semantic-release-rubygem": "github:klueless-js/semantic-release-rubygem",
|
12
12
|
"@semantic-release/changelog": "^6.0.3",
|
data/package.json
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: appydave-tools
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.11.
|
4
|
+
version: 0.11.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- David Cruwys
|
@@ -156,7 +156,6 @@ files:
|
|
156
156
|
- LICENSE.txt
|
157
157
|
- README.md
|
158
158
|
- Rakefile
|
159
|
-
- a.json
|
160
159
|
- bin/bank_reconciliation.rb
|
161
160
|
- bin/configuration.rb
|
162
161
|
- bin/console
|
@@ -166,6 +165,7 @@ files:
|
|
166
165
|
- bin/subtitle_master.rb
|
167
166
|
- bin/youtube_automation.rb
|
168
167
|
- bin/youtube_manager.rb
|
168
|
+
- docs/usage/gpt-context.md
|
169
169
|
- images.log
|
170
170
|
- lib/appydave/tools.rb
|
171
171
|
- lib/appydave/tools/cli_actions/_doc.md
|
data/a.json
DELETED
@@ -1,60 +0,0 @@
|
|
1
|
-
{
|
2
|
-
"tree": {
|
3
|
-
"bin": {
|
4
|
-
"gpt_context.rb": {
|
5
|
-
}
|
6
|
-
},
|
7
|
-
"lib": {
|
8
|
-
"appydave": {
|
9
|
-
"tools": {
|
10
|
-
"gpt_context": {
|
11
|
-
"file_collector.rb": {
|
12
|
-
},
|
13
|
-
"options.rb": {
|
14
|
-
},
|
15
|
-
"output_handler.rb": {
|
16
|
-
}
|
17
|
-
}
|
18
|
-
}
|
19
|
-
}
|
20
|
-
},
|
21
|
-
"spec": {
|
22
|
-
"appydave": {
|
23
|
-
"tools": {
|
24
|
-
"gpt_context": {
|
25
|
-
"file_collector_spec.rb": {
|
26
|
-
},
|
27
|
-
"output_handler_spec.rb": {
|
28
|
-
}
|
29
|
-
}
|
30
|
-
}
|
31
|
-
}
|
32
|
-
}
|
33
|
-
},
|
34
|
-
"content": [
|
35
|
-
{
|
36
|
-
"file": "bin/gpt_context.rb",
|
37
|
-
"content": "#!/usr/bin/env ruby\n# frozen_string_literal: true\n\n# GPT Chats:\n# https://chatgpt.com/c/670df475-04f4-8002-a758-f5711bf433eb\n\n# Usage:\n# ./bin/gpt_context.rb -d -i 'lib/openai_101/tools/**/*.rb'\n# ./bin/gpt_context.rb -d -i 'lib/openai_101/tools/**/*' -e 'node_modules/**/*' -e 'package-lock.json' -e 'lib/openai_101/tools/prompts/*.txt'\n#\n# Get GPT Context Gatherer code\n# ./bin/gpt_context.rb -i 'bin/**/*gather*.rb' -i 'lib/openai_101/tools/**/*gather*.rb'\n$LOAD_PATH.unshift(File.expand_path('../lib', __dir__))\n\nrequire 'appydave/tools'\nrequire 'appydave/tools/gpt_context/options'\nrequire 'json'\nrequire 'optparse'\nrequire 'clipboard'\nrequire 'pathname'\n\noptions = Appydave::Tools::GptContext::Options.new(\n working_directory: nil\n)\n\nOptionParser.new do |opts|\n opts.banner = 'Usage: gather_content.rb [options]'\n\n opts.on('-i', '--include PATTERN', 'Pattern or file to include (can be used multiple times)') do |pattern|\n options.include_patterns << pattern\n end\n\n opts.on('-e', '--exclude PATTERN', 'Pattern or file to exclude (can be used multiple times)') do |pattern|\n options.exclude_patterns << pattern\n end\n\n opts.on('-f', '--format FORMAT', 'Output format: content, tree, or json, if not provided then both are used') do |format|\n options.format = format\n end\n\n opts.on('-l', '--line-limit LIMIT', 'Limit the number of lines included from each file') do |limit|\n options.line_limit = limit.to_i\n end\n\n # New option for specifying base directory\n opts.on('-b', '--base-dir DIRECTORY', 'Set the base directory to gather files from') do |directory|\n options.working_directory = directory\n end\n\n # Debug output options\n opts.on('-d', '--debug [MODE]', 'Enable debug mode [none, info, params, debug]', 'none', 'info', 'params', 'debug') do |debug|\n options.debug = debug || 'info'\n end\n\n # Output targets: clipboard or file\n opts.on('-o', '--output TARGET', 'Output target: clipboard, or a file path (can be used multiple times)') do |target|\n options.output_target << target\n end\n\n opts.on_tail('-h', '--help', 'Show this message') do\n puts opts\n puts \"\\nExamples:\"\n puts \" #{File.basename($PROGRAM_NAME)} -i 'lib/**/*.rb' -e 'lib/excluded/**/*.rb' -d\"\n puts \" #{File.basename($PROGRAM_NAME)} --include 'src/**/*.js' --exclude 'src/vendor/**/*.js'\"\n\n puts ''\n puts ' # Get GPT Context Gatherer code that is found in any folder (bin, lib & spec)'\n puts \" #{File.basename($PROGRAM_NAME)} -i '**/*gather*.rb'\"\n exit\n end\nend.parse!\n\nif options.include_patterns.empty? && options.exclude_patterns.empty? && options.format.nil?\n script_name = File.basename($PROGRAM_NAME, File.extname($PROGRAM_NAME))\n\n puts 'No options provided to GPT Context. Please specify patterns to include or exclude.'\n puts \"For help, run: #{script_name} --help\"\n exit\nend\n\nif options.output_target.empty?\n puts 'No output target provided. Will default to `clipboard`. You can set the output target using -o'\n options.output_target << 'clipboard'\nend\n\npp options if options.debug == 'params'\n\noptions.working_directory ||= Dir.pwd\n\ngatherer = Appydave::Tools::GptContext::FileCollector.new(options)\ncontent = gatherer.build\n\nif %w[info debug].include?(options.debug)\n puts '-' * 80\n puts content\n puts '-' * 80\nend\n\noutput_handler = Appydave::Tools::GptContext::OutputHandler.new(content, options)\noutput_handler.execute\n\npp options if options.debug == 'debug'\n"
|
38
|
-
},
|
39
|
-
{
|
40
|
-
"file": "lib/appydave/tools/gpt_context/file_collector.rb",
|
41
|
-
"content": "# frozen_string_literal: true\n\nmodule Appydave\n module Tools\n # Build GPT context from various sources\n module GptContext\n # Gathers file names and content based on include and exclude patterns\n class FileCollector\n def initialize(options)\n @options = options\n @include_patterns = options.include_patterns\n @exclude_patterns = options.exclude_patterns\n @format = options.format\n @working_directory = options.working_directory\n @line_limit = options.line_limit\n end\n\n def build\n FileUtils.cd(@working_directory) if @working_directory && Dir.exist?(@working_directory)\n\n formats = @format.split(',')\n result = formats.map do |fmt|\n case fmt\n when 'tree'\n build_tree\n when 'content'\n build_content\n when 'json'\n build_json\n else\n ''\n end\n end.join(\"\\n\\n\")\n\n FileUtils.cd(Dir.home) if @working_directory\n\n result\n end\n\n private\n\n def build_content\n concatenated_content = []\n\n @include_patterns.each do |pattern|\n Dir.glob(pattern).each do |file_path|\n next if excluded?(file_path) || File.directory?(file_path)\n\n content = \"# file: #{file_path}\\n\\n#{read_file_content(file_path)}\"\n concatenated_content << content\n end\n end\n\n concatenated_content.join(\"\\n\\n\")\n end\n\n def read_file_content(file_path)\n lines = File.readlines(file_path)\n return lines.first(@line_limit).join if @line_limit\n\n lines.join\n end\n\n def build_tree\n tree_view = {}\n\n @include_patterns.each do |pattern|\n Dir.glob(pattern).each do |file_path|\n next if excluded?(file_path)\n\n path_parts = file_path.split('/')\n insert_into_tree(tree_view, path_parts)\n end\n end\n\n build_tree_pretty(tree_view).rstrip\n end\n\n def insert_into_tree(tree, path_parts)\n node = tree\n path_parts.each do |part|\n node[part] ||= {}\n node = node[part]\n end\n end\n\n def build_tree_pretty(node, prefix: '', is_last: true, output: ''.dup)\n node.each_with_index do |(part, child), index|\n connector = is_last && index == node.size - 1 ? '└' : '├'\n output << \"#{prefix}#{connector}─ #{part}\\n\"\n next_prefix = is_last && index == node.size - 1 ? ' ' : '│ '\n build_tree_pretty(child, prefix: \"#{prefix}#{next_prefix}\", is_last: child.empty? || index == node.size - 1, output: output)\n end\n output\n end\n\n def build_json\n json_output = {\n 'tree' => {},\n 'content' => []\n }\n\n # Building tree structure in JSON\n @include_patterns.each do |pattern|\n Dir.glob(pattern).each do |file_path|\n next if excluded?(file_path)\n\n path_parts = file_path.split('/')\n insert_into_tree(json_output['tree'], path_parts)\n end\n end\n\n # Building content structure in JSON\n @include_patterns.each do |pattern|\n Dir.glob(pattern).each do |file_path|\n next if excluded?(file_path) || File.directory?(file_path)\n\n json_output['content'] << {\n 'file' => file_path,\n 'content' => read_file_content(file_path)\n }\n end\n end\n\n JSON.pretty_generate(json_output)\n end\n\n def excluded?(file_path)\n @exclude_patterns.any? { |pattern| File.fnmatch(pattern, file_path, File::FNM_PATHNAME | File::FNM_DOTMATCH) }\n end\n end\n end\n end\nend\n"
|
42
|
-
},
|
43
|
-
{
|
44
|
-
"file": "lib/appydave/tools/gpt_context/options.rb",
|
45
|
-
"content": "# frozen_string_literal: true\n\nmodule Appydave\n module Tools\n module GptContext\n # Struct with keyword_init: true to allow named parameters\n Options = Struct.new(\n :include_patterns,\n :exclude_patterns,\n :format,\n :line_limit,\n :debug,\n :output_target,\n :working_directory,\n keyword_init: true\n ) do\n def initialize(**args)\n super\n self.include_patterns ||= []\n self.exclude_patterns ||= []\n self.format ||= 'tree,content'\n self.debug ||= 'none'\n self.output_target ||= []\n end\n end\n end\n end\nend\n"
|
46
|
-
},
|
47
|
-
{
|
48
|
-
"file": "lib/appydave/tools/gpt_context/output_handler.rb",
|
49
|
-
"content": "# frozen_string_literal: true\n\nmodule Appydave\n module Tools\n module GptContext\n class OutputHandler\n def initialize(content, options)\n @content = content\n @output_targets = options.output_target\n @working_directory = options.working_directory\n end\n\n def execute\n @output_targets.each do |target|\n case target\n when 'clipboard'\n Clipboard.copy(@content)\n when /^.+$/\n write_to_file(target)\n end\n end\n end\n\n private\n\n attr_reader :content, :output_targets, :working_directory\n\n def write_to_file(target)\n resolved_path = Pathname.new(target).absolute? ? target : File.join(working_directory, target)\n File.write(resolved_path, content)\n end\n end\n end\n end\nend\n"
|
50
|
-
},
|
51
|
-
{
|
52
|
-
"file": "spec/appydave/tools/gpt_context/file_collector_spec.rb",
|
53
|
-
"content": "# frozen_string_literal: true\n\nRSpec.describe Appydave::Tools::GptContext::FileCollector do\n describe '#build' do\n subject { described_class.new(include_patterns: include_patterns, exclude_patterns: exclude_patterns, format: format, line_limit: line_limit) }\n\n let(:include_patterns) { ['spec/fixtures/gpt-content-gatherer/**/*.txt'] }\n let(:exclude_patterns) { ['spec/fixtures/gpt-content-gatherer/excluded/*.txt', '**/deep/**/*'] }\n let(:format) { 'content' }\n let(:line_limit) { nil }\n\n context 'when gathering content' do\n it 'concatenates content from files matching include patterns' do\n expect(subject.build).to include('File 1 content', 'File 2 content')\n end\n\n it 'excludes content from files matching exclude patterns' do\n expect(subject.build).not_to include('Excluded file content')\n expect(subject.build).not_to include('Deep 1')\n expect(subject.build).not_to include('Deep 1')\n end\n\n it 'includes file paths as headers in the gathered content' do\n expect(subject.build)\n .to include('# file: spec/fixtures/gpt-content-gatherer/included/file1.txt')\n .and include('# file: spec/fixtures/gpt-content-gatherer/included/file2.txt')\n end\n end\n\n context 'when line limit is set' do\n let(:line_limit) { 1 }\n\n it 'limits the number of lines included from each file' do\n expect(subject.build).not_to include('Line #2')\n end\n end\n end\n\n describe '#build with tree format' do\n subject { described_class.new(include_patterns: include_patterns, exclude_patterns: exclude_patterns, format: 'tree') }\n\n let(:include_patterns) { ['spec/fixtures/gpt-content-gatherer/**/*'] }\n let(:exclude_patterns) { [] }\n\n before do\n allow(Dir).to receive(:glob).and_return(\n [\n 'spec/fixtures/gpt-content-gatherer/included/file1.txt',\n 'spec/fixtures/gpt-content-gatherer/included/file2.txt',\n 'spec/fixtures/gpt-content-gatherer/included/subdir/file3.txt'\n ]\n )\n allow(File).to receive(:directory?).and_return(false)\n end\n\n it 'prints a tree view of the included files and directories with improved ASCII art' do\n expected_output = <<~TREE\n └─ spec\n └─ fixtures\n └─ gpt-content-gatherer\n └─ included\n ├─ file1.txt\n ├─ file2.txt\n └─ subdir\n └─ file3.txt\n TREE\n\n expect(subject.build.strip).to eq(expected_output.strip)\n end\n end\n\n describe '#build with both formats' do\n subject { described_class.new(include_patterns: include_patterns, exclude_patterns: exclude_patterns, format: 'tree,content') }\n\n let(:include_patterns) { ['spec/fixtures/gpt-content-gatherer/**/*'] }\n let(:exclude_patterns) { [] }\n\n before do\n allow(Dir).to receive(:glob).and_return(\n [\n 'spec/fixtures/gpt-content-gatherer/included/file1.txt',\n 'spec/fixtures/gpt-content-gatherer/included/file2.txt',\n 'spec/fixtures/gpt-content-gatherer/included/subdir/file3.txt'\n ]\n )\n allow(File).to receive(:directory?).and_return(false)\n end\n\n it 'prints both a tree view and the file contents' do\n expected_output_tree = <<~TREE\n └─ spec\n └─ fixtures\n └─ gpt-content-gatherer\n └─ included\n ├─ file1.txt\n ├─ file2.txt\n └─ subdir\n └─ file3.txt\n TREE\n\n expected_output_content = <<~CONTENT\n # file: spec/fixtures/gpt-content-gatherer/included/file1.txt\n\n File 1 content\n Line #2\n\n # file: spec/fixtures/gpt-content-gatherer/included/file2.txt\n\n File 2 content\n Line #2\n\n # file: spec/fixtures/gpt-content-gatherer/included/subdir/file3.txt\n\n File 3 content\n Line #2\n CONTENT\n\n expect(subject.build).to include(expected_output_tree.strip)\n expect(subject.build).to include(expected_output_content.strip)\n end\n end\nend\n"
|
54
|
-
},
|
55
|
-
{
|
56
|
-
"file": "spec/appydave/tools/gpt_context/output_handler_spec.rb",
|
57
|
-
"content": "# frozen_string_literal: true\n\nRSpec.describe Appydave::Tools::GptContext::OutputHandler do\n subject { described_class.new(content, options) }\n\n let(:content) { 'Sample content' }\n let(:options) { double('Options', output_target: ['clipboard'], working_directory: Dir.pwd) }\n\n describe '#execute' do\n it 'copies content to clipboard when output target is clipboard' do\n expect(Clipboard).to receive(:copy).with(content)\n subject.execute\n end\n\n context 'when output target is a file' do\n let(:options) { double('Options', output_target: ['output.txt'], working_directory: Dir.pwd) }\n\n it 'writes content to the specified file' do\n expect(File).to receive(:write).with(File.join(Dir.pwd, 'output.txt'), content)\n subject.execute\n end\n end\n\n context 'when multiple output targets are specified' do\n let(:options) { double('Options', output_target: ['clipboard', 'output.txt'], working_directory: Dir.pwd) }\n\n it 'copies content to clipboard and writes to file' do\n expect(Clipboard).to receive(:copy).with(content)\n expect(File).to receive(:write).with(File.join(Dir.pwd, 'output.txt'), content)\n subject.execute\n end\n end\n end\nend\n"
|
58
|
-
}
|
59
|
-
]
|
60
|
-
}
|