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,434 @@
1
+ # exe/ vs bin/ Directory Convention
2
+
3
+ This document explains the convention for organizing CLI executables in appydave-tools, following standard RubyGems practices.
4
+
5
+ ## Table of Contents
6
+
7
+ - [Overview](#overview)
8
+ - [Directory Purposes](#directory-purposes)
9
+ - [How It Works](#how-it-works)
10
+ - [File Structure Examples](#file-structure-examples)
11
+ - [Creating New CLI Tools](#creating-new-cli-tools)
12
+ - [Gemspec Configuration](#gemspec-configuration)
13
+ - [Development vs Installation](#development-vs-installation)
14
+ - [Why This Pattern?](#why-this-pattern)
15
+
16
+ ---
17
+
18
+ ## Overview
19
+
20
+ The project uses two directories for executables:
21
+
22
+ | Directory | Purpose | File Extension | When Used |
23
+ |-----------|---------|----------------|-----------|
24
+ | `bin/` | Full CLI implementation | `.rb` | Development |
25
+ | `exe/` | Thin wrapper for gem installation | None | Gem users |
26
+
27
+ This follows the standard RubyGems convention where:
28
+ - **`bin/`** contains development scripts and the full CLI implementation
29
+ - **`exe/`** contains the executables that get installed when users run `gem install`
30
+
31
+ ---
32
+
33
+ ## Directory Purposes
34
+
35
+ ### bin/ Directory
36
+
37
+ **Purpose:** Contains the actual CLI implementation code.
38
+
39
+ **Contents:**
40
+ - Full Ruby scripts with CLI classes
41
+ - OptionParser configuration
42
+ - Command routing logic
43
+ - All CLI-specific code
44
+
45
+ **File naming:** `tool_name.rb` (with `.rb` extension)
46
+
47
+ **Example:**
48
+ ```
49
+ bin/
50
+ ├── subtitle_processor.rb # Full 200-line CLI implementation
51
+ ├── gpt_context.rb # Full CLI implementation
52
+ ├── youtube_manager.rb # Full CLI implementation
53
+ └── console # IRB console for development
54
+ ```
55
+
56
+ ### exe/ Directory
57
+
58
+ **Purpose:** Contains thin wrapper scripts that get installed as system commands.
59
+
60
+ **Contents:**
61
+ - Minimal Ruby scripts (typically 3-7 lines)
62
+ - Just loads the corresponding `bin/` file
63
+ - No business logic
64
+
65
+ **File naming:** `tool_name` (NO `.rb` extension)
66
+
67
+ **Example:**
68
+ ```
69
+ exe/
70
+ ├── subtitle_processor # Wrapper → loads bin/subtitle_processor.rb
71
+ ├── gpt_context # Wrapper → loads bin/gpt_context.rb
72
+ ├── youtube_manager # Wrapper → loads bin/youtube_manager.rb
73
+ └── ad_config # Wrapper → loads bin/configuration.rb
74
+ ```
75
+
76
+ ---
77
+
78
+ ## How It Works
79
+
80
+ ### The Wrapper Pattern
81
+
82
+ Each `exe/` file is a thin wrapper that loads its corresponding `bin/` implementation:
83
+
84
+ ```ruby
85
+ #!/usr/bin/env ruby
86
+ # frozen_string_literal: true
87
+
88
+ require 'appydave/tools'
89
+
90
+ load File.expand_path('../bin/subtitle_processor.rb', __dir__)
91
+ ```
92
+
93
+ ### Flow Diagram
94
+
95
+ ```
96
+ User runs: subtitle_processor clean -f input.srt -o output.srt
97
+
98
+
99
+ ┌─────────────────────────────────────────────────────────┐
100
+ │ exe/subtitle_processor (installed in PATH) │
101
+ │ ├── require 'appydave/tools' │
102
+ │ └── load '../bin/subtitle_processor.rb' │
103
+ └─────────────────────────────────────────────────────────┘
104
+
105
+
106
+ ┌─────────────────────────────────────────────────────────┐
107
+ │ bin/subtitle_processor.rb (full implementation) │
108
+ │ ├── class SubtitleProcessorCLI │
109
+ │ ├── def clean_subtitles(args) │
110
+ │ ├── def join_subtitles(args) │
111
+ │ └── SubtitleProcessorCLI.new.run │
112
+ └─────────────────────────────────────────────────────────┘
113
+
114
+
115
+ ┌─────────────────────────────────────────────────────────┐
116
+ │ lib/appydave/tools/subtitle_processor/clean.rb │
117
+ │ (business logic) │
118
+ └─────────────────────────────────────────────────────────┘
119
+ ```
120
+
121
+ ---
122
+
123
+ ## File Structure Examples
124
+
125
+ ### Complete Example: subtitle_processor
126
+
127
+ **exe/subtitle_processor** (7 lines - wrapper):
128
+ ```ruby
129
+ #!/usr/bin/env ruby
130
+ # frozen_string_literal: true
131
+
132
+ require 'appydave/tools'
133
+
134
+ load File.expand_path('../bin/subtitle_processor.rb', __dir__)
135
+ ```
136
+
137
+ **bin/subtitle_processor.rb** (200+ lines - full implementation):
138
+ ```ruby
139
+ #!/usr/bin/env ruby
140
+ # frozen_string_literal: true
141
+
142
+ require 'optparse'
143
+
144
+ $LOAD_PATH.unshift(File.expand_path('../lib', __dir__))
145
+
146
+ require 'appydave/tools'
147
+
148
+ class SubtitleProcessorCLI
149
+ def initialize
150
+ @commands = {
151
+ 'clean' => method(:clean_subtitles),
152
+ 'join' => method(:join_subtitles),
153
+ 'transcript' => method(:transcript_subtitles)
154
+ }
155
+ end
156
+
157
+ def run
158
+ command, *args = ARGV
159
+ # ... command routing
160
+ end
161
+
162
+ private
163
+
164
+ def clean_subtitles(args)
165
+ # ... 50 lines of option parsing and execution
166
+ end
167
+
168
+ def join_subtitles(args)
169
+ # ... 50 lines of option parsing and execution
170
+ end
171
+
172
+ # ... more methods
173
+ end
174
+
175
+ SubtitleProcessorCLI.new.run
176
+ ```
177
+
178
+ ### Example: gpt_context
179
+
180
+ **exe/gpt_context**:
181
+ ```ruby
182
+ #!/usr/bin/env ruby
183
+ # frozen_string_literal: true
184
+
185
+ require 'appydave/tools'
186
+
187
+ load File.expand_path('../bin/gpt_context.rb', __dir__)
188
+ ```
189
+
190
+ ### Example: ad_config (different naming)
191
+
192
+ Sometimes the exe/ name differs from bin/ name:
193
+
194
+ **exe/ad_config** → **bin/configuration.rb**:
195
+ ```ruby
196
+ #!/usr/bin/env ruby
197
+ # frozen_string_literal: true
198
+
199
+ require 'appydave/tools'
200
+
201
+ load File.expand_path('../bin/configuration.rb', __dir__)
202
+ ```
203
+
204
+ ---
205
+
206
+ ## Creating New CLI Tools
207
+
208
+ ### Step 1: Create the bin/ Implementation
209
+
210
+ ```bash
211
+ touch bin/my_tool.rb
212
+ chmod +x bin/my_tool.rb
213
+ ```
214
+
215
+ **bin/my_tool.rb:**
216
+ ```ruby
217
+ #!/usr/bin/env ruby
218
+ # frozen_string_literal: true
219
+
220
+ require 'optparse'
221
+
222
+ $LOAD_PATH.unshift(File.expand_path('../lib', __dir__))
223
+
224
+ require 'appydave/tools'
225
+
226
+ class MyToolCLI
227
+ def run
228
+ # Full CLI implementation here
229
+ end
230
+ end
231
+
232
+ MyToolCLI.new.run
233
+ ```
234
+
235
+ ### Step 2: Create the exe/ Wrapper
236
+
237
+ ```bash
238
+ touch exe/my_tool
239
+ chmod +x exe/my_tool
240
+ ```
241
+
242
+ **exe/my_tool:**
243
+ ```ruby
244
+ #!/usr/bin/env ruby
245
+ # frozen_string_literal: true
246
+
247
+ require 'appydave/tools'
248
+
249
+ load File.expand_path('../bin/my_tool.rb', __dir__)
250
+ ```
251
+
252
+ ### Step 3: Verify in Gemspec
253
+
254
+ The gemspec automatically includes all `exe/` files:
255
+
256
+ ```ruby
257
+ # appydave-tools.gemspec
258
+ spec.bindir = 'exe'
259
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
260
+ ```
261
+
262
+ ### Step 4: Test Both Ways
263
+
264
+ **Development (from project directory):**
265
+ ```bash
266
+ bin/my_tool.rb --help
267
+ ```
268
+
269
+ **After gem install:**
270
+ ```bash
271
+ my_tool --help
272
+ ```
273
+
274
+ ---
275
+
276
+ ## Gemspec Configuration
277
+
278
+ The gemspec defines how executables are installed:
279
+
280
+ ```ruby
281
+ # appydave-tools.gemspec
282
+
283
+ Gem::Specification.new do |spec|
284
+ # ...
285
+
286
+ # The directory containing executables
287
+ spec.bindir = 'exe'
288
+
289
+ # Automatically find all files in exe/ directory
290
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
291
+
292
+ # ...
293
+ end
294
+ ```
295
+
296
+ ### What This Means
297
+
298
+ 1. **`spec.bindir = 'exe'`** - Tells RubyGems to look in `exe/` for executables
299
+ 2. **`spec.executables = ...`** - Lists all files in `exe/` as installable commands
300
+ 3. **No `.rb` extension** - Files in `exe/` don't have extensions, so `exe/gpt_context` becomes the `gpt_context` command
301
+
302
+ ### Verification
303
+
304
+ ```bash
305
+ # List what will be installed as executables
306
+ ruby -e "puts Gem::Specification.load('appydave-tools.gemspec').executables"
307
+ ```
308
+
309
+ Expected output:
310
+ ```
311
+ gpt_context
312
+ youtube_manager
313
+ prompt_tools
314
+ youtube_automation
315
+ ad_config
316
+ dam
317
+ subtitle_processor
318
+ zsh_history
319
+ ```
320
+
321
+ ---
322
+
323
+ ## Development vs Installation
324
+
325
+ ### During Development
326
+
327
+ Run tools directly from `bin/` with the `.rb` extension:
328
+
329
+ ```bash
330
+ # From project root
331
+ bin/subtitle_processor.rb clean -f input.srt -o output.srt
332
+
333
+ # Or make it executable and run directly
334
+ chmod +x bin/subtitle_processor.rb
335
+ ./bin/subtitle_processor.rb clean -f input.srt -o output.srt
336
+ ```
337
+
338
+ **Why use bin/ during development:**
339
+ - No gem installation needed
340
+ - Changes take effect immediately
341
+ - `$LOAD_PATH` is set to use local `lib/`
342
+
343
+ ### After Gem Installation
344
+
345
+ Users run the command without extension:
346
+
347
+ ```bash
348
+ # After: gem install appydave-tools
349
+ subtitle_processor clean -f input.srt -o output.srt
350
+ ```
351
+
352
+ **What happens:**
353
+ 1. Shell finds `subtitle_processor` in PATH (installed by gem)
354
+ 2. That's actually `exe/subtitle_processor`
355
+ 3. Which loads `bin/subtitle_processor.rb` from the installed gem
356
+ 4. Which uses `lib/appydave/tools/` from the installed gem
357
+
358
+ ---
359
+
360
+ ## Why This Pattern?
361
+
362
+ ### 1. Separation of Concerns
363
+
364
+ | Directory | Responsibility |
365
+ |-----------|----------------|
366
+ | `exe/` | Entry point (what gets installed) |
367
+ | `bin/` | CLI implementation |
368
+ | `lib/` | Business logic |
369
+
370
+ ### 2. Standard RubyGems Convention
371
+
372
+ This follows how most Ruby gems organize executables:
373
+ - Rails uses `exe/rails` → internal implementation
374
+ - Bundler uses `exe/bundler` → internal implementation
375
+ - RuboCop uses `exe/rubocop` → internal implementation
376
+
377
+ ### 3. Clean Installation
378
+
379
+ Users get clean command names without `.rb` extension:
380
+ ```bash
381
+ # Clean
382
+ subtitle_processor clean -f input.srt
383
+
384
+ # Not
385
+ subtitle_processor.rb clean -f input.srt
386
+ ```
387
+
388
+ ### 4. Development Flexibility
389
+
390
+ Developers can:
391
+ - Run `bin/*.rb` directly during development
392
+ - Test changes without reinstalling gem
393
+ - Keep development scripts (like `bin/console`) separate from installed commands
394
+
395
+ ### 5. Single Source of Truth
396
+
397
+ The `exe/` wrappers just load `bin/` files, so:
398
+ - Only one place to edit CLI code (`bin/`)
399
+ - No duplication between development and installed versions
400
+ - Easy to maintain
401
+
402
+ ---
403
+
404
+ ## Current exe/ Files
405
+
406
+ | exe/ file | Loads | Command |
407
+ |-----------|-------|---------|
408
+ | `exe/gpt_context` | `bin/gpt_context.rb` | `gpt_context` |
409
+ | `exe/youtube_manager` | `bin/youtube_manager.rb` | `youtube_manager` |
410
+ | `exe/prompt_tools` | `bin/prompt_tools.rb` | `prompt_tools` |
411
+ | `exe/youtube_automation` | `bin/youtube_automation.rb` | `youtube_automation` |
412
+ | `exe/ad_config` | `bin/configuration.rb` | `ad_config` |
413
+ | `exe/dam` | `bin/dam` | `dam` |
414
+ | `exe/subtitle_processor` | `bin/subtitle_processor.rb` | `subtitle_processor` |
415
+ | `exe/zsh_history` | `bin/zsh_history.rb` | `zsh_history` |
416
+
417
+ ---
418
+
419
+ ## Summary
420
+
421
+ | Aspect | bin/ | exe/ |
422
+ |--------|------|------|
423
+ | **Purpose** | Full CLI implementation | Thin wrapper for installation |
424
+ | **Extension** | `.rb` | None |
425
+ | **Size** | 50-500+ lines | 3-7 lines |
426
+ | **Contains** | OptionParser, routing, CLI classes | Just `require` and `load` |
427
+ | **Used during** | Development | After gem install |
428
+ | **Edited** | Frequently | Rarely (only when adding new tools) |
429
+
430
+ **Key takeaway:** Edit `bin/`, don't touch `exe/` unless adding a new tool.
431
+
432
+ ---
433
+
434
+ **Last updated:** 2025-12-13