appydave-tools 0.70.0 → 0.71.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 +4 -4
- data/.claude/commands/brainstorming-agent.md +227 -0
- data/.claude/commands/cli-test.md +251 -0
- data/.claude/commands/dev.md +234 -0
- data/.claude/commands/po.md +227 -0
- data/.claude/commands/progress.md +51 -0
- data/.claude/commands/uat.md +321 -0
- data/.rubocop.yml +9 -0
- data/AGENTS.md +43 -0
- data/CHANGELOG.md +12 -0
- data/CLAUDE.md +26 -3
- data/README.md +15 -0
- data/bin/dam +21 -1
- data/bin/jump.rb +29 -0
- data/bin/subtitle_processor.rb +54 -1
- data/bin/zsh_history.rb +846 -0
- data/docs/README.md +162 -69
- data/docs/architecture/cli/exe-bin-convention.md +434 -0
- data/docs/architecture/cli-patterns.md +631 -0
- data/docs/architecture/gpt-context/gpt-context-architecture.md +325 -0
- data/docs/architecture/gpt-context/gpt-context-implementation-guide.md +419 -0
- data/docs/architecture/gpt-context/gpt-context-vision.md +179 -0
- data/docs/architecture/testing/testing-patterns.md +762 -0
- data/docs/backlog.md +120 -0
- data/docs/cli-tests/FR-3-jump-location-tool.md +515 -0
- data/docs/specs/fr-002-gpt-context-help-system.md +265 -0
- data/docs/specs/fr-003-jump-location-tool.md +779 -0
- data/docs/specs/zsh-history-tool.md +820 -0
- data/docs/uat/FR-3-jump-location-tool.md +741 -0
- data/exe/jump +11 -0
- data/exe/{subtitle_manager → subtitle_processor} +1 -1
- data/exe/zsh_history +11 -0
- data/lib/appydave/tools/configuration/openai.rb +1 -1
- data/lib/appydave/tools/dam/file_helper.rb +28 -0
- data/lib/appydave/tools/dam/project_listing.rb +4 -30
- data/lib/appydave/tools/dam/s3_operations.rb +2 -1
- data/lib/appydave/tools/dam/ssd_status.rb +226 -0
- data/lib/appydave/tools/dam/status.rb +3 -51
- data/lib/appydave/tools/jump/cli.rb +561 -0
- data/lib/appydave/tools/jump/commands/add.rb +52 -0
- data/lib/appydave/tools/jump/commands/base.rb +43 -0
- data/lib/appydave/tools/jump/commands/generate.rb +153 -0
- data/lib/appydave/tools/jump/commands/remove.rb +58 -0
- data/lib/appydave/tools/jump/commands/report.rb +214 -0
- data/lib/appydave/tools/jump/commands/update.rb +42 -0
- data/lib/appydave/tools/jump/commands/validate.rb +54 -0
- data/lib/appydave/tools/jump/config.rb +233 -0
- data/lib/appydave/tools/jump/formatters/base.rb +48 -0
- data/lib/appydave/tools/jump/formatters/json_formatter.rb +19 -0
- data/lib/appydave/tools/jump/formatters/paths_formatter.rb +21 -0
- data/lib/appydave/tools/jump/formatters/table_formatter.rb +183 -0
- data/lib/appydave/tools/jump/location.rb +134 -0
- data/lib/appydave/tools/jump/path_validator.rb +47 -0
- data/lib/appydave/tools/jump/search.rb +230 -0
- data/lib/appydave/tools/subtitle_processor/transcript.rb +51 -0
- data/lib/appydave/tools/version.rb +1 -1
- data/lib/appydave/tools/zsh_history/command.rb +37 -0
- data/lib/appydave/tools/zsh_history/config.rb +235 -0
- data/lib/appydave/tools/zsh_history/filter.rb +184 -0
- data/lib/appydave/tools/zsh_history/formatter.rb +75 -0
- data/lib/appydave/tools/zsh_history/parser.rb +101 -0
- data/lib/appydave/tools.rb +25 -0
- data/package.json +1 -1
- metadata +51 -4
|
@@ -0,0 +1,419 @@
|
|
|
1
|
+
# GPT Context Gatherer - Implementation Guide
|
|
2
|
+
|
|
3
|
+
**For developers** working on or extending the GPT Context module.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## File Structure
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
lib/appydave/tools/gpt_context/
|
|
11
|
+
├── _doc.md # Legacy internal notes
|
|
12
|
+
├── options.rb # Options struct definition
|
|
13
|
+
├── file_collector.rb # Core file gathering logic
|
|
14
|
+
└── output_handler.rb # Output delivery (clipboard/file)
|
|
15
|
+
|
|
16
|
+
bin/
|
|
17
|
+
└── gpt_context.rb # CLI entry point
|
|
18
|
+
|
|
19
|
+
spec/appydave/tools/gpt_context/
|
|
20
|
+
├── file_collector_spec.rb
|
|
21
|
+
├── options_spec.rb
|
|
22
|
+
└── output_handler_spec.rb
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## Component Details
|
|
28
|
+
|
|
29
|
+
### Options Struct
|
|
30
|
+
|
|
31
|
+
**Location**: `lib/appydave/tools/gpt_context/options.rb:7-27`
|
|
32
|
+
|
|
33
|
+
```ruby
|
|
34
|
+
Options = Struct.new(
|
|
35
|
+
:include_patterns,
|
|
36
|
+
:exclude_patterns,
|
|
37
|
+
:format,
|
|
38
|
+
:line_limit,
|
|
39
|
+
:debug,
|
|
40
|
+
:output_target,
|
|
41
|
+
:working_directory,
|
|
42
|
+
:prompt,
|
|
43
|
+
keyword_init: true
|
|
44
|
+
) do
|
|
45
|
+
def initialize(**args)
|
|
46
|
+
super
|
|
47
|
+
self.include_patterns ||= []
|
|
48
|
+
self.exclude_patterns ||= []
|
|
49
|
+
self.format ||= 'tree,content'
|
|
50
|
+
self.debug ||= 'none'
|
|
51
|
+
self.output_target ||= []
|
|
52
|
+
self.prompt ||= nil
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
**Key implementation notes**:
|
|
58
|
+
|
|
59
|
+
1. **Struct with keyword_init** - Enables `Options.new(format: 'json')` syntax
|
|
60
|
+
2. **Mutable defaults** - Arrays are initialized in `initialize`, not in Struct definition (avoids shared state)
|
|
61
|
+
3. **No validation** - Relies on CLI layer for validation
|
|
62
|
+
|
|
63
|
+
### FileCollector
|
|
64
|
+
|
|
65
|
+
**Location**: `lib/appydave/tools/gpt_context/file_collector.rb:8-146`
|
|
66
|
+
|
|
67
|
+
#### Constructor
|
|
68
|
+
|
|
69
|
+
```ruby
|
|
70
|
+
def initialize(options)
|
|
71
|
+
@options = options
|
|
72
|
+
@include_patterns = options.include_patterns
|
|
73
|
+
@exclude_patterns = options.exclude_patterns
|
|
74
|
+
@format = options.format
|
|
75
|
+
@working_directory = File.expand_path(options.working_directory)
|
|
76
|
+
@line_limit = options.line_limit
|
|
77
|
+
end
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
**Note**: `File.expand_path` converts relative paths to absolute.
|
|
81
|
+
|
|
82
|
+
#### Main Entry Point
|
|
83
|
+
|
|
84
|
+
```ruby
|
|
85
|
+
def build
|
|
86
|
+
FileUtils.cd(@working_directory) if @working_directory && Dir.exist?(@working_directory)
|
|
87
|
+
|
|
88
|
+
formats = @format.split(',')
|
|
89
|
+
result = formats.map do |fmt|
|
|
90
|
+
case fmt
|
|
91
|
+
when 'tree' then build_tree
|
|
92
|
+
when 'content' then build_content
|
|
93
|
+
when 'json' then build_json
|
|
94
|
+
when 'aider' then build_aider
|
|
95
|
+
else ''
|
|
96
|
+
end
|
|
97
|
+
end.join("\n\n")
|
|
98
|
+
|
|
99
|
+
FileUtils.cd(Dir.home) if @working_directory
|
|
100
|
+
|
|
101
|
+
result
|
|
102
|
+
end
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
**Key points**:
|
|
106
|
+
- Changes to working directory for relative pattern matching
|
|
107
|
+
- Supports comma-separated formats
|
|
108
|
+
- Returns to home directory (not original pwd) after - potential improvement opportunity
|
|
109
|
+
|
|
110
|
+
#### Tree Building Algorithm
|
|
111
|
+
|
|
112
|
+
```ruby
|
|
113
|
+
def build_tree
|
|
114
|
+
tree_view = {}
|
|
115
|
+
|
|
116
|
+
@include_patterns.each do |pattern|
|
|
117
|
+
Dir.glob(pattern).each do |file_path|
|
|
118
|
+
next if excluded?(file_path)
|
|
119
|
+
|
|
120
|
+
path_parts = file_path.split('/')
|
|
121
|
+
insert_into_tree(tree_view, path_parts)
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
build_tree_pretty(tree_view).rstrip
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
def insert_into_tree(tree, path_parts)
|
|
129
|
+
node = tree
|
|
130
|
+
path_parts.each do |part|
|
|
131
|
+
node[part] ||= {}
|
|
132
|
+
node = node[part]
|
|
133
|
+
end
|
|
134
|
+
end
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
**Algorithm**:
|
|
138
|
+
1. Build nested hash from file paths
|
|
139
|
+
2. Each path segment becomes a key
|
|
140
|
+
3. Empty hash `{}` represents leaf nodes (files)
|
|
141
|
+
|
|
142
|
+
#### Tree Rendering
|
|
143
|
+
|
|
144
|
+
```ruby
|
|
145
|
+
def build_tree_pretty(node, prefix: '', is_last: true, output: ''.dup)
|
|
146
|
+
node.each_with_index do |(part, child), index|
|
|
147
|
+
connector = is_last && index == node.size - 1 ? '└' : '├'
|
|
148
|
+
output << "#{prefix}#{connector}─ #{part}\n"
|
|
149
|
+
next_prefix = is_last && index == node.size - 1 ? ' ' : '│ '
|
|
150
|
+
build_tree_pretty(child,
|
|
151
|
+
prefix: "#{prefix}#{next_prefix}",
|
|
152
|
+
is_last: child.empty? || index == node.size - 1,
|
|
153
|
+
output: output)
|
|
154
|
+
end
|
|
155
|
+
output
|
|
156
|
+
end
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
**Box-drawing characters**:
|
|
160
|
+
- `├` - branch with siblings below
|
|
161
|
+
- `└` - last branch (no siblings below)
|
|
162
|
+
- `│` - vertical continuation
|
|
163
|
+
- `─` - horizontal line
|
|
164
|
+
|
|
165
|
+
#### Content Building
|
|
166
|
+
|
|
167
|
+
```ruby
|
|
168
|
+
def build_content
|
|
169
|
+
concatenated_content = []
|
|
170
|
+
|
|
171
|
+
@include_patterns.each do |pattern|
|
|
172
|
+
Dir.glob(pattern).each do |file_path|
|
|
173
|
+
next if excluded?(file_path) || File.directory?(file_path)
|
|
174
|
+
|
|
175
|
+
content = "# file: #{file_path}\n\n#{read_file_content(file_path)}"
|
|
176
|
+
concatenated_content << content
|
|
177
|
+
end
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
concatenated_content.join("\n\n")
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
def read_file_content(file_path)
|
|
184
|
+
lines = File.readlines(file_path)
|
|
185
|
+
return lines.first(@line_limit).join if @line_limit
|
|
186
|
+
|
|
187
|
+
lines.join
|
|
188
|
+
end
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
**Format**: Each file gets a header `# file: path/to/file.rb` followed by content.
|
|
192
|
+
|
|
193
|
+
#### Exclusion Logic
|
|
194
|
+
|
|
195
|
+
```ruby
|
|
196
|
+
def excluded?(file_path)
|
|
197
|
+
@exclude_patterns.any? do |pattern|
|
|
198
|
+
File.fnmatch(pattern, file_path, File::FNM_PATHNAME | File::FNM_DOTMATCH)
|
|
199
|
+
end
|
|
200
|
+
end
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
**Flags**:
|
|
204
|
+
- `FNM_PATHNAME` - `*` won't match `/` (so `*.rb` won't match `lib/foo.rb`)
|
|
205
|
+
- `FNM_DOTMATCH` - `*` will match dotfiles
|
|
206
|
+
|
|
207
|
+
### OutputHandler
|
|
208
|
+
|
|
209
|
+
**Location**: `lib/appydave/tools/gpt_context/output_handler.rb:7-36`
|
|
210
|
+
|
|
211
|
+
```ruby
|
|
212
|
+
class OutputHandler
|
|
213
|
+
def initialize(content, options)
|
|
214
|
+
@content = content
|
|
215
|
+
@output_targets = options.output_target
|
|
216
|
+
@working_directory = options.working_directory
|
|
217
|
+
end
|
|
218
|
+
|
|
219
|
+
def execute
|
|
220
|
+
@output_targets.each do |target|
|
|
221
|
+
case target
|
|
222
|
+
when 'clipboard'
|
|
223
|
+
Clipboard.copy(@content)
|
|
224
|
+
when /^.+$/
|
|
225
|
+
write_to_file(target)
|
|
226
|
+
end
|
|
227
|
+
end
|
|
228
|
+
end
|
|
229
|
+
|
|
230
|
+
private
|
|
231
|
+
|
|
232
|
+
def write_to_file(target)
|
|
233
|
+
resolved_path = Pathname.new(target).absolute? ? target : File.join(working_directory, target)
|
|
234
|
+
File.write(resolved_path, content)
|
|
235
|
+
end
|
|
236
|
+
end
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
**Key points**:
|
|
240
|
+
- Supports multiple output targets (can write to clipboard AND files)
|
|
241
|
+
- Relative paths resolved against working directory
|
|
242
|
+
- Uses `Pathname#absolute?` for path detection
|
|
243
|
+
|
|
244
|
+
---
|
|
245
|
+
|
|
246
|
+
## CLI Implementation
|
|
247
|
+
|
|
248
|
+
**Location**: `bin/gpt_context.rb`
|
|
249
|
+
|
|
250
|
+
### Option Parsing
|
|
251
|
+
|
|
252
|
+
```ruby
|
|
253
|
+
options = Appydave::Tools::GptContext::Options.new(working_directory: nil)
|
|
254
|
+
|
|
255
|
+
OptionParser.new do |opts|
|
|
256
|
+
opts.on('-i', '--include PATTERN', 'Pattern or file to include') do |pattern|
|
|
257
|
+
options.include_patterns << pattern
|
|
258
|
+
end
|
|
259
|
+
# ... more options
|
|
260
|
+
end.parse!
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
**Pattern**: Direct mutation of Options struct during parsing.
|
|
264
|
+
|
|
265
|
+
### Default Application
|
|
266
|
+
|
|
267
|
+
```ruby
|
|
268
|
+
if options.output_target.empty?
|
|
269
|
+
puts 'No output target provided. Will default to `clipboard`.'
|
|
270
|
+
options.output_target << 'clipboard'
|
|
271
|
+
end
|
|
272
|
+
|
|
273
|
+
options.working_directory ||= Dir.pwd
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
### Execution Flow
|
|
277
|
+
|
|
278
|
+
```ruby
|
|
279
|
+
gatherer = Appydave::Tools::GptContext::FileCollector.new(options)
|
|
280
|
+
content = gatherer.build
|
|
281
|
+
|
|
282
|
+
if %w[info debug].include?(options.debug)
|
|
283
|
+
puts '-' * 80
|
|
284
|
+
puts content
|
|
285
|
+
puts '-' * 80
|
|
286
|
+
end
|
|
287
|
+
|
|
288
|
+
output_handler = Appydave::Tools::GptContext::OutputHandler.new(content, options)
|
|
289
|
+
output_handler.execute
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
---
|
|
293
|
+
|
|
294
|
+
## Testing Strategy
|
|
295
|
+
|
|
296
|
+
### Unit Tests
|
|
297
|
+
|
|
298
|
+
Each component should be tested in isolation:
|
|
299
|
+
|
|
300
|
+
```ruby
|
|
301
|
+
# Options
|
|
302
|
+
describe Appydave::Tools::GptContext::Options do
|
|
303
|
+
it 'initializes with defaults' do
|
|
304
|
+
options = described_class.new
|
|
305
|
+
expect(options.include_patterns).to eq([])
|
|
306
|
+
expect(options.format).to eq('tree,content')
|
|
307
|
+
end
|
|
308
|
+
end
|
|
309
|
+
|
|
310
|
+
# FileCollector
|
|
311
|
+
describe Appydave::Tools::GptContext::FileCollector do
|
|
312
|
+
let(:options) { Appydave::Tools::GptContext::Options.new(...) }
|
|
313
|
+
let(:collector) { described_class.new(options) }
|
|
314
|
+
|
|
315
|
+
it 'builds tree format' do
|
|
316
|
+
# Test with fixture files
|
|
317
|
+
end
|
|
318
|
+
end
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
### Integration Tests
|
|
322
|
+
|
|
323
|
+
Test full CLI flow:
|
|
324
|
+
|
|
325
|
+
```ruby
|
|
326
|
+
describe 'gpt_context CLI' do
|
|
327
|
+
it 'gathers files and outputs to clipboard' do
|
|
328
|
+
# Shell out to bin/gpt_context.rb
|
|
329
|
+
# Verify clipboard contents
|
|
330
|
+
end
|
|
331
|
+
end
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
### Fixture Files
|
|
335
|
+
|
|
336
|
+
Use `spec/fixtures/gpt-content-gatherer/` for test files.
|
|
337
|
+
|
|
338
|
+
---
|
|
339
|
+
|
|
340
|
+
## Extension Points
|
|
341
|
+
|
|
342
|
+
### Adding a New Format
|
|
343
|
+
|
|
344
|
+
1. Add format name to Options validation (if any)
|
|
345
|
+
2. Add case in `FileCollector#build`:
|
|
346
|
+
|
|
347
|
+
```ruby
|
|
348
|
+
when 'my_format'
|
|
349
|
+
build_my_format
|
|
350
|
+
```
|
|
351
|
+
|
|
352
|
+
3. Implement `build_my_format` method:
|
|
353
|
+
|
|
354
|
+
```ruby
|
|
355
|
+
def build_my_format
|
|
356
|
+
# Return string
|
|
357
|
+
end
|
|
358
|
+
```
|
|
359
|
+
|
|
360
|
+
### Adding a New Output Target
|
|
361
|
+
|
|
362
|
+
1. Add case in `OutputHandler#execute`:
|
|
363
|
+
|
|
364
|
+
```ruby
|
|
365
|
+
when 'my_target'
|
|
366
|
+
handle_my_target
|
|
367
|
+
```
|
|
368
|
+
|
|
369
|
+
2. Implement handler method:
|
|
370
|
+
|
|
371
|
+
```ruby
|
|
372
|
+
def handle_my_target
|
|
373
|
+
# Do something with @content
|
|
374
|
+
end
|
|
375
|
+
```
|
|
376
|
+
|
|
377
|
+
### Adding CLI Options
|
|
378
|
+
|
|
379
|
+
1. Add property to Options struct
|
|
380
|
+
2. Add `opts.on` in CLI
|
|
381
|
+
3. Use property in appropriate component
|
|
382
|
+
|
|
383
|
+
---
|
|
384
|
+
|
|
385
|
+
## Known Limitations
|
|
386
|
+
|
|
387
|
+
### Current Issues
|
|
388
|
+
|
|
389
|
+
1. **Working directory handling** - Returns to `Dir.home` instead of original pwd
|
|
390
|
+
2. **No error handling** - File read errors propagate as exceptions
|
|
391
|
+
3. **Memory usage** - All content loaded into memory (no streaming)
|
|
392
|
+
4. **Debug output** - `puts` statements in production code
|
|
393
|
+
|
|
394
|
+
### Improvement Opportunities
|
|
395
|
+
|
|
396
|
+
1. **Token counting** - Add estimated token count for LLM context limits
|
|
397
|
+
2. **Caching** - Cache file listings for repeated runs
|
|
398
|
+
3. **Parallel reading** - Read files in parallel for large codebases
|
|
399
|
+
4. **Streaming output** - Stream to file instead of building in memory
|
|
400
|
+
|
|
401
|
+
---
|
|
402
|
+
|
|
403
|
+
## Code Quality Checklist
|
|
404
|
+
|
|
405
|
+
When modifying GPT Context code:
|
|
406
|
+
|
|
407
|
+
- [ ] All files start with `# frozen_string_literal: true`
|
|
408
|
+
- [ ] RuboCop passes with no offenses
|
|
409
|
+
- [ ] Specs pass for all components
|
|
410
|
+
- [ ] No `puts` or `pp` in library code (only CLI)
|
|
411
|
+
- [ ] Options struct remains backward-compatible
|
|
412
|
+
- [ ] Documentation updated if API changes
|
|
413
|
+
|
|
414
|
+
---
|
|
415
|
+
|
|
416
|
+
**Related Documentation**:
|
|
417
|
+
- [Vision & Strategy](./gpt-context-vision.md)
|
|
418
|
+
- [Architecture & Data Flow](./gpt-context-architecture.md)
|
|
419
|
+
- [Usage Guide](../../guides/tools/gpt-context.md)
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
# GPT Context Gatherer - Vision & Strategy
|
|
2
|
+
|
|
3
|
+
**Purpose**: Enable AI-assisted development by efficiently packaging codebase context for Large Language Models.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## What Problem Does This Solve?
|
|
8
|
+
|
|
9
|
+
When working with AI assistants (Claude, ChatGPT, Copilot, Cursor), the quality of AI output directly correlates with the quality of context provided. Developers face these challenges:
|
|
10
|
+
|
|
11
|
+
1. **Manual file copying is tedious** - Selecting, opening, copying dozens of files wastes time
|
|
12
|
+
2. **Context limits are real** - LLMs have token limits; you can't feed entire codebases
|
|
13
|
+
3. **Relevance matters** - AI needs focused, relevant context, not noise
|
|
14
|
+
4. **Format affects comprehension** - AI understands structured input better than random dumps
|
|
15
|
+
|
|
16
|
+
**GPT Context Gatherer** solves these by automating intelligent context collection.
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## Core Philosophy
|
|
21
|
+
|
|
22
|
+
### Single Purpose
|
|
23
|
+
|
|
24
|
+
GPT Context does ONE thing well: **gather project files into AI-ready format**.
|
|
25
|
+
|
|
26
|
+
It is NOT:
|
|
27
|
+
- A code search tool (use grep, ripgrep, Glob)
|
|
28
|
+
- A file manager (use Finder, ls)
|
|
29
|
+
- An AI assistant (use Claude, ChatGPT)
|
|
30
|
+
- A documentation generator (use YARD, RDoc)
|
|
31
|
+
|
|
32
|
+
### Developer-Centric Design
|
|
33
|
+
|
|
34
|
+
- **Command-line first** - Integrates with existing dev workflows
|
|
35
|
+
- **Pattern-based** - Uses familiar glob patterns developers already know
|
|
36
|
+
- **Clipboard-friendly** - Default output to clipboard for immediate paste
|
|
37
|
+
- **Composable** - Works with other tools (aider, scripts, pipelines)
|
|
38
|
+
|
|
39
|
+
### Format Flexibility
|
|
40
|
+
|
|
41
|
+
Different AI tasks need different context formats:
|
|
42
|
+
|
|
43
|
+
| Task | Best Format | Why |
|
|
44
|
+
|------|-------------|-----|
|
|
45
|
+
| Understanding structure | `tree` | Visual hierarchy |
|
|
46
|
+
| Code review | `content` | Full source code |
|
|
47
|
+
| API documentation | `json` | Structured data |
|
|
48
|
+
| AI-assisted coding | `aider` | Tool-specific format |
|
|
49
|
+
|
|
50
|
+
---
|
|
51
|
+
|
|
52
|
+
## Target Workflows
|
|
53
|
+
|
|
54
|
+
### Primary: AI-Assisted Development
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
# Quick context for Claude/ChatGPT question
|
|
58
|
+
gpt_context -i 'lib/auth/**/*.rb' -d
|
|
59
|
+
|
|
60
|
+
# Paste into AI chat, ask: "How does authentication work?"
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### Secondary: aider Integration
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
# Generate aider command with files and prompt
|
|
67
|
+
gpt_context -i 'lib/api/**/*.rb' -f aider -p "Add rate limiting to these endpoints"
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### Tertiary: Documentation & Onboarding
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
# Generate codebase overview for new team member
|
|
74
|
+
gpt_context -i 'lib/**/*.rb' -e 'spec/**/*' -f tree -o codebase-overview.txt
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
---
|
|
78
|
+
|
|
79
|
+
## Design Principles
|
|
80
|
+
|
|
81
|
+
### 1. Reasonable Defaults
|
|
82
|
+
|
|
83
|
+
- **Default output**: `clipboard` (most common use case)
|
|
84
|
+
- **Default format**: `tree,content` (structure + code)
|
|
85
|
+
- **Default debug**: `none` (quiet operation)
|
|
86
|
+
|
|
87
|
+
Users shouldn't need to specify common options.
|
|
88
|
+
|
|
89
|
+
### 2. Explicit Over Implicit
|
|
90
|
+
|
|
91
|
+
- Patterns are explicit (`'lib/**/*.rb'`), not magic
|
|
92
|
+
- Include patterns are additive, exclude patterns are subtractive
|
|
93
|
+
- Output targets are specified, not guessed
|
|
94
|
+
|
|
95
|
+
### 3. Non-Destructive
|
|
96
|
+
|
|
97
|
+
- Never modifies source files
|
|
98
|
+
- Clipboard is the only "destructive" default (overwrites previous clipboard)
|
|
99
|
+
- File output requires explicit `-o` flag
|
|
100
|
+
|
|
101
|
+
### 4. Transparent Operation
|
|
102
|
+
|
|
103
|
+
- Debug modes show exactly what's happening
|
|
104
|
+
- `params` shows configuration
|
|
105
|
+
- `info` shows collected content
|
|
106
|
+
- `debug` shows everything
|
|
107
|
+
|
|
108
|
+
---
|
|
109
|
+
|
|
110
|
+
## Relationship to Other Tools
|
|
111
|
+
|
|
112
|
+
### vs. DAM (Digital Asset Management)
|
|
113
|
+
|
|
114
|
+
| Aspect | GPT Context | DAM |
|
|
115
|
+
|--------|-------------|-----|
|
|
116
|
+
| **Purpose** | Collect code for AI context | Manage video project storage |
|
|
117
|
+
| **Input** | Source code files | Video assets (MP4, SRT, etc.) |
|
|
118
|
+
| **Output** | Text (clipboard/file) | Cloud/SSD storage |
|
|
119
|
+
| **Pattern** | Glob patterns | Brand/project structure |
|
|
120
|
+
| **State** | Stateless | Stateful (sync tracking) |
|
|
121
|
+
| **External services** | None | AWS S3 |
|
|
122
|
+
|
|
123
|
+
### vs. Built-in Tools
|
|
124
|
+
|
|
125
|
+
| Need | Use This |
|
|
126
|
+
|------|----------|
|
|
127
|
+
| Find files by name | `Glob`, `find` |
|
|
128
|
+
| Search file contents | `Grep`, `rg` |
|
|
129
|
+
| Package files for AI | **GPT Context** |
|
|
130
|
+
| Read single file | `Read`, `cat` |
|
|
131
|
+
|
|
132
|
+
---
|
|
133
|
+
|
|
134
|
+
## Evolution Roadmap
|
|
135
|
+
|
|
136
|
+
### Current State (v1.x)
|
|
137
|
+
|
|
138
|
+
- ✅ Pattern-based file collection
|
|
139
|
+
- ✅ Multiple output formats (tree, content, json, aider)
|
|
140
|
+
- ✅ Multiple output targets (clipboard, files)
|
|
141
|
+
- ✅ Line limiting for large files
|
|
142
|
+
- ✅ Base directory support
|
|
143
|
+
|
|
144
|
+
### Potential Enhancements
|
|
145
|
+
|
|
146
|
+
These are ideas, not commitments:
|
|
147
|
+
|
|
148
|
+
1. **Token counting** - Show estimated token count for context
|
|
149
|
+
2. **Smart truncation** - Automatically fit within token limits
|
|
150
|
+
3. **Preset patterns** - Named pattern sets (e.g., `--preset ruby-lib`)
|
|
151
|
+
4. **History** - Remember recent patterns per project
|
|
152
|
+
5. **MCP integration** - Expose as Model Context Protocol server
|
|
153
|
+
|
|
154
|
+
### Non-Goals
|
|
155
|
+
|
|
156
|
+
These will NOT be added:
|
|
157
|
+
|
|
158
|
+
- File editing capabilities
|
|
159
|
+
- Version control integration (that's git's job)
|
|
160
|
+
- Remote file access (that's DAM's job)
|
|
161
|
+
- AI inference (that's the AI's job)
|
|
162
|
+
|
|
163
|
+
---
|
|
164
|
+
|
|
165
|
+
## Success Metrics
|
|
166
|
+
|
|
167
|
+
GPT Context is successful when:
|
|
168
|
+
|
|
169
|
+
1. **Time saved** - Faster than manual file selection
|
|
170
|
+
2. **Context quality** - AI produces better responses with gathered context
|
|
171
|
+
3. **Adoption** - Becomes natural part of AI-assisted workflow
|
|
172
|
+
4. **Simplicity** - Learned in minutes, remembered for months
|
|
173
|
+
|
|
174
|
+
---
|
|
175
|
+
|
|
176
|
+
**Related Documentation**:
|
|
177
|
+
- [Architecture & Data Flow](./gpt-context-architecture.md)
|
|
178
|
+
- [Implementation Guide](./gpt-context-implementation-guide.md)
|
|
179
|
+
- [Usage Guide](../../guides/tools/gpt-context.md)
|