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.
Files changed (64) hide show
  1. checksums.yaml +4 -4
  2. data/.claude/commands/brainstorming-agent.md +227 -0
  3. data/.claude/commands/cli-test.md +251 -0
  4. data/.claude/commands/dev.md +234 -0
  5. data/.claude/commands/po.md +227 -0
  6. data/.claude/commands/progress.md +51 -0
  7. data/.claude/commands/uat.md +321 -0
  8. data/.rubocop.yml +9 -0
  9. data/AGENTS.md +43 -0
  10. data/CHANGELOG.md +12 -0
  11. data/CLAUDE.md +26 -3
  12. data/README.md +15 -0
  13. data/bin/dam +21 -1
  14. data/bin/jump.rb +29 -0
  15. data/bin/subtitle_processor.rb +54 -1
  16. data/bin/zsh_history.rb +846 -0
  17. data/docs/README.md +162 -69
  18. data/docs/architecture/cli/exe-bin-convention.md +434 -0
  19. data/docs/architecture/cli-patterns.md +631 -0
  20. data/docs/architecture/gpt-context/gpt-context-architecture.md +325 -0
  21. data/docs/architecture/gpt-context/gpt-context-implementation-guide.md +419 -0
  22. data/docs/architecture/gpt-context/gpt-context-vision.md +179 -0
  23. data/docs/architecture/testing/testing-patterns.md +762 -0
  24. data/docs/backlog.md +120 -0
  25. data/docs/cli-tests/FR-3-jump-location-tool.md +515 -0
  26. data/docs/specs/fr-002-gpt-context-help-system.md +265 -0
  27. data/docs/specs/fr-003-jump-location-tool.md +779 -0
  28. data/docs/specs/zsh-history-tool.md +820 -0
  29. data/docs/uat/FR-3-jump-location-tool.md +741 -0
  30. data/exe/jump +11 -0
  31. data/exe/{subtitle_manager → subtitle_processor} +1 -1
  32. data/exe/zsh_history +11 -0
  33. data/lib/appydave/tools/configuration/openai.rb +1 -1
  34. data/lib/appydave/tools/dam/file_helper.rb +28 -0
  35. data/lib/appydave/tools/dam/project_listing.rb +4 -30
  36. data/lib/appydave/tools/dam/s3_operations.rb +2 -1
  37. data/lib/appydave/tools/dam/ssd_status.rb +226 -0
  38. data/lib/appydave/tools/dam/status.rb +3 -51
  39. data/lib/appydave/tools/jump/cli.rb +561 -0
  40. data/lib/appydave/tools/jump/commands/add.rb +52 -0
  41. data/lib/appydave/tools/jump/commands/base.rb +43 -0
  42. data/lib/appydave/tools/jump/commands/generate.rb +153 -0
  43. data/lib/appydave/tools/jump/commands/remove.rb +58 -0
  44. data/lib/appydave/tools/jump/commands/report.rb +214 -0
  45. data/lib/appydave/tools/jump/commands/update.rb +42 -0
  46. data/lib/appydave/tools/jump/commands/validate.rb +54 -0
  47. data/lib/appydave/tools/jump/config.rb +233 -0
  48. data/lib/appydave/tools/jump/formatters/base.rb +48 -0
  49. data/lib/appydave/tools/jump/formatters/json_formatter.rb +19 -0
  50. data/lib/appydave/tools/jump/formatters/paths_formatter.rb +21 -0
  51. data/lib/appydave/tools/jump/formatters/table_formatter.rb +183 -0
  52. data/lib/appydave/tools/jump/location.rb +134 -0
  53. data/lib/appydave/tools/jump/path_validator.rb +47 -0
  54. data/lib/appydave/tools/jump/search.rb +230 -0
  55. data/lib/appydave/tools/subtitle_processor/transcript.rb +51 -0
  56. data/lib/appydave/tools/version.rb +1 -1
  57. data/lib/appydave/tools/zsh_history/command.rb +37 -0
  58. data/lib/appydave/tools/zsh_history/config.rb +235 -0
  59. data/lib/appydave/tools/zsh_history/filter.rb +184 -0
  60. data/lib/appydave/tools/zsh_history/formatter.rb +75 -0
  61. data/lib/appydave/tools/zsh_history/parser.rb +101 -0
  62. data/lib/appydave/tools.rb +25 -0
  63. data/package.json +1 -1
  64. 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)