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,779 @@
1
+ # FR-3: Jump Location Tool
2
+
3
+ **Status**: Ready for Development
4
+ **Added**: 2025-12-13
5
+ **Priority**: High - enables unified location management across terminal, Claude Code, and generated config
6
+
7
+ ---
8
+
9
+ ## Summary
10
+
11
+ A Ruby CLI tool for managing development folder locations with a single source of truth (JSON config) that serves:
12
+ - Terminal users (fuzzy search, jump aliases)
13
+ - Claude Code (via skill with JSON output)
14
+ - Generated shell configuration (aliases-jump.zsh)
15
+
16
+ ---
17
+
18
+ ## Problem Statement
19
+
20
+ Current pain points:
21
+ 1. Jump aliases (`jad`, `jss`, `jgb`) are hard to remember
22
+ 2. No single source of truth - aliases defined in one file, help documentation duplicated elsewhere
23
+ 3. In Claude Code, need to find folder paths but have no searchable system
24
+ 4. Locations organized by multiple dimensions (brand, client, type, technology) but no way to view by these dimensions
25
+ 5. Locations become stale (folders deleted/moved) with no validation
26
+
27
+ ---
28
+
29
+ ## Architecture
30
+
31
+ ```
32
+ ┌─────────────────────────────────────────────────────────────┐
33
+ │ locations.json │
34
+ │ (Single Source of Truth) │
35
+ └─────────────────────────────────────────────────────────────┘
36
+
37
+ ┌─────────────────────┼─────────────────────┐
38
+ ▼ ▼ ▼
39
+ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐
40
+ │ jump CLI │ │ Generated │ │ Claude Skill │
41
+ │ │ │ Files │ │ │
42
+ │ - search │ │ │ │ Calls CLI │
43
+ │ - add/remove │ │ aliases- │ │ with --format│
44
+ │ - validate │ │ jump.zsh │ │ json flag │
45
+ │ - reports │ │ │ │ │
46
+ │ - generate │ │ help content │ │ │
47
+ └──────────────┘ └──────────────┘ └──────────────┘
48
+
49
+
50
+ ┌──────────────┐
51
+ │ Terminal │
52
+ │ │
53
+ │ j alias │
54
+ │ ah + fzf │
55
+ └──────────────┘
56
+ ```
57
+
58
+ ---
59
+
60
+ ## File Locations
61
+
62
+ | File | Path |
63
+ |------|------|
64
+ | Tool code | `lib/appydave/tools/jump/` |
65
+ | Config file | `~/.config/appydave/locations.json` |
66
+ | Generated aliases | `~/.oh-my-zsh/custom/aliases-jump.zsh` |
67
+ | Help content | `~/.oh-my-zsh/custom/data/jump-help.txt` |
68
+ | Claude skill | `~/.claude/skills/jump-locations.md` |
69
+
70
+ **Note**: Config follows existing pattern - stored in `~/.config/appydave/` alongside `settings.json`, `channels.json`, etc. Uses the same config infrastructure with injectable paths for testing.
71
+
72
+ ---
73
+
74
+ ## Data Model
75
+
76
+ ### locations.json Structure
77
+
78
+ ```json
79
+ {
80
+ "meta": {
81
+ "version": "1.0",
82
+ "last_validated": "2025-12-13T10:00:00Z"
83
+ },
84
+ "categories": {
85
+ "type": {
86
+ "description": "Kind of location",
87
+ "values": ["brand", "client", "gem", "video", "brain", "site", "tool", "config"]
88
+ },
89
+ "technology": {
90
+ "description": "Primary language/framework",
91
+ "values": ["ruby", "javascript", "typescript", "python", "astro"]
92
+ }
93
+ },
94
+ "brands": {
95
+ "appydave": {
96
+ "aliases": ["ad", "appy", "dave"],
97
+ "description": "AppyDave brand"
98
+ },
99
+ "flivideo": {
100
+ "aliases": ["fli"],
101
+ "description": "FliVideo brand"
102
+ }
103
+ },
104
+ "clients": {
105
+ "supportsignal": {
106
+ "aliases": ["ss"],
107
+ "description": "SupportSignal client"
108
+ }
109
+ },
110
+ "locations": [
111
+ {
112
+ "key": "ad-tools",
113
+ "path": "~/dev/ad/appydave-tools",
114
+ "jump": "jad-tools",
115
+ "brand": "appydave",
116
+ "type": "tool",
117
+ "tags": ["ruby", "cli"],
118
+ "description": "AppyDave CLI tools"
119
+ }
120
+ ]
121
+ }
122
+ ```
123
+
124
+ ### Location Entry Fields
125
+
126
+ | Field | Required | Default | Description |
127
+ |-------|----------|---------|-------------|
128
+ | key | Yes | - | Unique identifier (alphanumeric + hyphens, lowercase) |
129
+ | path | Yes | - | Directory path (supports ~) |
130
+ | jump | No | `j` + key | Shell alias name |
131
+ | brand | No | - | Associated brand key |
132
+ | client | No | - | Associated client key |
133
+ | type | No | - | Category type |
134
+ | tags | No | [] | Searchable tags array |
135
+ | description | No | - | Human description |
136
+
137
+ ---
138
+
139
+ ## CLI Commands
140
+
141
+ ### Command Name
142
+
143
+ `jump` (installed via gem as `jump`)
144
+
145
+ ### Search & Retrieval
146
+
147
+ ```bash
148
+ # Fuzzy search (primary use case)
149
+ jump search <terms>
150
+ jump search appydave ruby
151
+ jump search ss app
152
+
153
+ # Get by exact key
154
+ jump get <key>
155
+ jump get ad-tools
156
+
157
+ # List all
158
+ jump list
159
+
160
+ # All commands support --format
161
+ jump search appydave --format json|table|paths
162
+ ```
163
+
164
+ ### CRUD Operations
165
+
166
+ ```bash
167
+ # Add
168
+ jump add --key <key> --path <path> [--jump alias] [--brand brand] \
169
+ [--client client] [--type type] [--tags t1,t2] [--description "desc"]
170
+
171
+ # Update
172
+ jump update <key> [--path path] [--brand brand] [--tags tags] ...
173
+
174
+ # Remove
175
+ jump remove <key>
176
+ jump remove <key> --force
177
+ ```
178
+
179
+ ### Validation
180
+
181
+ ```bash
182
+ # Validate all paths exist
183
+ jump validate
184
+
185
+ # Validate specific key
186
+ jump validate <key>
187
+ ```
188
+
189
+ **Behavior**: Report only - shows valid/invalid/missing paths. Does NOT auto-prompt for removal. User decides what to do.
190
+
191
+ ### Reports (View Data by Dimension)
192
+
193
+ ```bash
194
+ # List all categories and their values
195
+ jump report categories
196
+
197
+ # List all brands with location counts
198
+ jump report brands
199
+
200
+ # List all clients with location counts
201
+ jump report clients
202
+
203
+ # List all types with location counts
204
+ jump report types
205
+
206
+ # List all tags with location counts
207
+ jump report tags
208
+
209
+ # List locations grouped by brand
210
+ jump report by-brand
211
+ jump report by-brand appydave
212
+
213
+ # List locations grouped by client
214
+ jump report by-client
215
+
216
+ # List locations grouped by type
217
+ jump report by-type
218
+
219
+ # List locations grouped by tag
220
+ jump report by-tag ruby
221
+
222
+ # Summary overview
223
+ jump report summary
224
+ ```
225
+
226
+ ### Generation
227
+
228
+ ```bash
229
+ # Generate shell aliases (stdout by default)
230
+ jump generate aliases
231
+ jump generate aliases --output ~/.oh-my-zsh/custom/aliases-jump.zsh
232
+
233
+ # Generate help content for ah/fzf
234
+ jump generate help
235
+ jump generate help --output ~/.oh-my-zsh/custom/data/jump-help.txt
236
+
237
+ # Generate both
238
+ jump generate all
239
+ jump generate all --output-dir ~/.oh-my-zsh/custom/
240
+ ```
241
+
242
+ **Behavior**:
243
+ - Stdout by default
244
+ - Use `--output <file>` to write to file
245
+ - **Important**: Before first use, manually backup existing `aliases-jump.zsh` once
246
+
247
+ ### Info
248
+
249
+ ```bash
250
+ # Show config path, location count, last validated
251
+ jump info
252
+ ```
253
+
254
+ ---
255
+
256
+ ## Output Formats
257
+
258
+ | Format | Flag | Use Case |
259
+ |--------|------|----------|
260
+ | table | `--format table` (default) | Human terminal reading - **pretty with colors** |
261
+ | json | `--format json` | Claude skill, programmatic access |
262
+ | paths | `--format paths` | Scripting, piping |
263
+
264
+ ### JSON Response Structure
265
+
266
+ **Success**:
267
+ ```json
268
+ {
269
+ "success": true,
270
+ "count": 2,
271
+ "results": [
272
+ {
273
+ "index": 1,
274
+ "key": "ad-tools",
275
+ "path": "/Users/davidcruwys/dev/ad/appydave-tools",
276
+ "jump": "jad-tools",
277
+ "brand": "appydave",
278
+ "type": "tool",
279
+ "tags": ["ruby", "cli"],
280
+ "description": "AppyDave CLI tools",
281
+ "score": 85
282
+ }
283
+ ]
284
+ }
285
+ ```
286
+
287
+ **Error**:
288
+ ```json
289
+ {
290
+ "success": false,
291
+ "error": "Location not found",
292
+ "code": "NOT_FOUND",
293
+ "suggestion": "Did you mean: ad-tools, ad-brand?"
294
+ }
295
+ ```
296
+
297
+ ---
298
+
299
+ ## Search Algorithm
300
+
301
+ ### Fields Searched
302
+
303
+ All fields concatenated for matching:
304
+ - key, path, brand (+ aliases), client (+ aliases), type, tags, description
305
+
306
+ ### Scoring
307
+
308
+ | Match Type | Points |
309
+ |------------|--------|
310
+ | Exact key match | 100 |
311
+ | Key contains term | 50 |
312
+ | Brand/client alias match | 40 |
313
+ | Tag match | 30 |
314
+ | Type match | 20 |
315
+ | Description contains | 10 |
316
+ | Path contains | 5 |
317
+
318
+ Multiple search terms: sum scores for each matching term.
319
+
320
+ ---
321
+
322
+ ## Exit Codes
323
+
324
+ | Code | Meaning |
325
+ |------|---------|
326
+ | 0 | Success |
327
+ | 1 | Not found |
328
+ | 2 | Invalid input |
329
+ | 3 | Config error |
330
+ | 4 | Path not found |
331
+
332
+ ---
333
+
334
+ ## Defensive Coding Requirements
335
+
336
+ ### Input Validation
337
+
338
+ - **Keys**: alphanumeric + hyphens only, lowercase
339
+ - **Paths**: must start with `~` or `/`, no shell metacharacters
340
+ - **Tags**: lowercase, alphanumeric + hyphens
341
+ - **All strings**: strip whitespace, reasonable length limits
342
+
343
+ ### Error Handling
344
+
345
+ - Never crash on bad input
346
+ - Always return structured response (success/error)
347
+ - Include suggestions on NOT_FOUND (fuzzy match alternatives)
348
+
349
+ ### Config Safety
350
+
351
+ - Backup before writes (timestamped backup files)
352
+ - Atomic writes (temp file then rename)
353
+ - Handle missing/corrupt config (create defaults)
354
+ - Validate JSON structure on load
355
+
356
+ ---
357
+
358
+ ## Claude Skill Specification
359
+
360
+ **File**: `~/.claude/skills/jump-locations.md`
361
+
362
+ ```markdown
363
+ # Jump - Location Finder
364
+
365
+ Find and manage development folder locations. Use when user asks
366
+ "where is", "find folder", "path to", "jump to", or needs to
367
+ locate project/brand/client directories.
368
+
369
+ ## Prerequisites
370
+
371
+ Tool must be installed at ~/dev/ad/appydave-tools
372
+
373
+ ## Commands
374
+
375
+ ### Search for locations
376
+ jump search <terms> --format json
377
+
378
+ Returns ranked matches. Terms are fuzzy matched against all fields.
379
+
380
+ ### Get specific location
381
+ jump get <key> --format json
382
+
383
+ Returns single location by exact key.
384
+
385
+ ### List all locations
386
+ jump list --format json
387
+
388
+ ### Add new location
389
+ jump add --key <key> --path <path> [options] --format json
390
+
391
+ Options:
392
+ --jump <alias> Jump alias (default: j + key)
393
+ --brand <brand> Associated brand
394
+ --client <client> Associated client
395
+ --type <type> Location type
396
+ --tags <t1,t2,t3> Comma-separated tags
397
+ --description <desc> Human description
398
+
399
+ ### Remove location
400
+ jump remove <key> --force --format json
401
+
402
+ ### Validate locations
403
+ jump validate --format json
404
+
405
+ ### Reports
406
+ jump report brands --format json
407
+ jump report clients --format json
408
+ jump report types --format json
409
+ jump report tags --format json
410
+ jump report by-brand [brand] --format json
411
+ jump report summary --format json
412
+
413
+ ## Natural Language Mappings
414
+
415
+ | User Says | Command |
416
+ |-----------|---------|
417
+ | "Where are the appydave tools?" | jump search appydave tools --format json |
418
+ | "Show me all client folders" | jump report by-client --format json |
419
+ | "What brands do I have?" | jump report brands --format json |
420
+ | "Add a location for xyz at ~/dev/xyz" | jump add --key xyz --path ~/dev/xyz --format json |
421
+ | "Is the ss folder still valid?" | jump validate ss --format json |
422
+ | "What ruby projects do I have?" | jump search ruby --format json |
423
+ | "Show me supportsignal locations" | jump search supportsignal --format json |
424
+ | "Remove old-project" | jump remove old-project --force --format json |
425
+ | "What types of locations exist?" | jump report types --format json |
426
+ | "Show all locations grouped by brand" | jump report by-brand --format json |
427
+
428
+ ## Response Handling
429
+
430
+ All JSON responses have:
431
+ - success: boolean
432
+ - For lists: count + results array
433
+ - For single: result object
434
+ - On error: error message + code + suggestion
435
+
436
+ ## Error Recovery
437
+
438
+ 1. NOT_FOUND: Check suggestion field for alternatives
439
+ 2. INVALID_INPUT: Report validation issue to user
440
+ 3. PATH_NOT_FOUND: Ask user to verify path exists
441
+ ```
442
+
443
+ ---
444
+
445
+ ## Testing Architecture
446
+
447
+ ### The Problem
448
+
449
+ The `locations.json` config contains real filesystem paths (e.g., `~/dev/ad/appydave-tools`) that:
450
+ - Exist on David's development machine
451
+ - Won't exist in CI environment
452
+ - Are unique to each developer's system
453
+
454
+ We need to test search, validation, reports, and generation without depending on real filesystem paths.
455
+
456
+ ### Solution: Dependency Injection
457
+
458
+ Use dependency injection for filesystem operations, following the existing codebase pattern where `spec_helper.rb` uses `Dir.mktmpdir` for config paths.
459
+
460
+ #### Config Path Injection (Existing Pattern)
461
+
462
+ ```ruby
463
+ # spec_helper.rb - already established pattern
464
+ Appydave::Tools::Configuration::Config.set_default do |config|
465
+ config.config_path = Dir.mktmpdir
466
+ end
467
+ ```
468
+
469
+ The Jump tool's config (`~/.config/appydave/locations.json`) follows this same pattern - config path is injectable.
470
+
471
+ #### Path Validator Injection (New for Jump)
472
+
473
+ Inject a `PathValidator` dependency that can be swapped for testing:
474
+
475
+ **Production implementation**:
476
+ ```ruby
477
+ # lib/appydave/tools/jump/path_validator.rb
478
+ module Appydave
479
+ module Tools
480
+ module Jump
481
+ class PathValidator
482
+ def exists?(path)
483
+ File.directory?(File.expand_path(path))
484
+ end
485
+
486
+ def expand(path)
487
+ File.expand_path(path)
488
+ end
489
+ end
490
+ end
491
+ end
492
+ end
493
+ ```
494
+
495
+ **Test implementation**:
496
+ ```ruby
497
+ # spec/support/jump_test_helpers.rb
498
+ class TestPathValidator
499
+ def initialize(valid_paths: [])
500
+ @valid_paths = valid_paths.map { |p| File.expand_path(p) }
501
+ end
502
+
503
+ def exists?(path)
504
+ expanded = File.expand_path(path)
505
+ @valid_paths.include?(expanded)
506
+ end
507
+
508
+ def expand(path)
509
+ File.expand_path(path)
510
+ end
511
+ end
512
+ ```
513
+
514
+ #### Usage in Classes
515
+
516
+ Classes that need filesystem access accept validator as dependency:
517
+
518
+ ```ruby
519
+ # lib/appydave/tools/jump/commands/validate.rb
520
+ module Appydave
521
+ module Tools
522
+ module Jump
523
+ module Commands
524
+ class Validate
525
+ def initialize(config, path_validator: PathValidator.new)
526
+ @config = config
527
+ @path_validator = path_validator
528
+ end
529
+
530
+ def run
531
+ @config.locations.map do |location|
532
+ {
533
+ key: location.key,
534
+ path: location.path,
535
+ valid: @path_validator.exists?(location.path)
536
+ }
537
+ end
538
+ end
539
+ end
540
+ end
541
+ end
542
+ end
543
+ end
544
+ ```
545
+
546
+ #### Test Example
547
+
548
+ ```ruby
549
+ # spec/appydave/tools/jump/commands/validate_spec.rb
550
+ RSpec.describe Appydave::Tools::Jump::Commands::Validate do
551
+ let(:config) { build_test_config(locations: test_locations) }
552
+ let(:path_validator) { TestPathValidator.new(valid_paths: ['~/real-path']) }
553
+
554
+ subject { described_class.new(config, path_validator: path_validator) }
555
+
556
+ let(:test_locations) do
557
+ [
558
+ { key: 'valid-loc', path: '~/real-path' },
559
+ { key: 'invalid-loc', path: '~/does-not-exist' }
560
+ ]
561
+ end
562
+
563
+ it 'identifies valid and invalid paths' do
564
+ results = subject.run
565
+
566
+ expect(results.find { |r| r[:key] == 'valid-loc' }[:valid]).to be true
567
+ expect(results.find { |r| r[:key] == 'invalid-loc' }[:valid]).to be false
568
+ end
569
+ end
570
+ ```
571
+
572
+ ### What Gets Injected
573
+
574
+ | Dependency | Production | Test |
575
+ |------------|------------|------|
576
+ | Config path | `~/.config/appydave/` | `Dir.mktmpdir` |
577
+ | Path validator | `PathValidator` (real filesystem) | `TestPathValidator` (mock valid paths) |
578
+ | Output stream | `$stdout` | `StringIO` (capture output) |
579
+
580
+ ### What Doesn't Need Injection
581
+
582
+ These can be tested directly without mocking:
583
+ - **Search algorithm** - operates on in-memory data
584
+ - **Scoring logic** - pure functions
585
+ - **JSON formatting** - string transformation
586
+ - **Config parsing** - uses test fixture files
587
+ - **Report aggregation** - operates on config data
588
+
589
+ ### Test Fixture Strategy
590
+
591
+ ```
592
+ spec/fixtures/jump/
593
+ ├── locations_basic.json # Simple config for unit tests
594
+ ├── locations_full.json # Complete config with all fields
595
+ ├── locations_empty.json # Edge case: no locations
596
+ ├── locations_invalid.json # Malformed JSON for error handling
597
+ └── examples.yml # Data-driven test cases
598
+ ```
599
+
600
+ ### CI Compatibility
601
+
602
+ With this approach:
603
+ - No real filesystem dependencies in tests
604
+ - All paths validated against mock validator
605
+ - Config loaded from temp directories with fixture data
606
+ - Tests run identically on dev machines and CI
607
+
608
+ ---
609
+
610
+ ## Test Strategy
611
+
612
+ ### Data-Driven Testing
613
+
614
+ Tests use YAML fixtures for easy maintenance. See `spec/fixtures/jump/examples.yml`.
615
+
616
+ **Test categories**:
617
+ - Search examples (by brand, alias, tag, multiple terms, no matches)
618
+ - Get examples (exact key, non-existent, suggestions)
619
+ - Add examples (minimal, all fields, invalid input, duplicate)
620
+ - Validate examples (existing paths, missing paths, mixed)
621
+ - Report examples (brands, clients, tags, by-brand filtered)
622
+ - Generate examples (alias lines, help lines, default jump)
623
+ - Edge cases (empty query, special characters, paths with spaces, unicode)
624
+
625
+ ### Test Runner Pattern
626
+
627
+ ```ruby
628
+ # spec/appydave/tools/jump/search_spec.rb
629
+ RSpec.describe Appydave::Tools::Jump::Search do
630
+ examples = YAML.load_file('spec/fixtures/jump_examples.yml')
631
+
632
+ examples['search_examples'].each do |example|
633
+ it example['name'] do
634
+ config = build_test_config(example['given'])
635
+ searcher = described_class.new(config)
636
+ result = searcher.search(example['given']['query'])
637
+
638
+ expect(result[:success]).to eq(example['expect']['success'])
639
+ # ... additional assertions
640
+ end
641
+ end
642
+ end
643
+ ```
644
+
645
+ ---
646
+
647
+ ## Seed Data Task
648
+
649
+ Before the tool is useful, `locations.json` needs initial data.
650
+
651
+ ### Source
652
+
653
+ Current `~/.oh-my-zsh/custom/aliases-jump.zsh`
654
+
655
+ ### Process
656
+
657
+ 1. Parse existing alias lines: `alias jfoo="cd ~/path"`
658
+ 2. Extract key (remove `j` prefix), path, jump alias
659
+ 3. Infer brand from path (`/ad/` → appydave, `/clients/supportsignal` → supportsignal)
660
+ 4. Infer type from path patterns
661
+ 5. Validate all paths exist
662
+ 6. Generate initial `locations.json`
663
+
664
+ ### Implementation
665
+
666
+ Could be:
667
+ - One-time migration script
668
+ - `jump import <file>` command (preferred - reusable)
669
+
670
+ ---
671
+
672
+ ## Phase 2 (Future, Not MVP)
673
+
674
+ Design should accommodate but NOT implement:
675
+
676
+ - **DAM integration**: Dynamic video project folders
677
+ - **FliHub integration**: Active/pinned project status
678
+ - **Watch mode**: Auto-regenerate on config change
679
+ - **Computed filters**: `--active` flag from external sources
680
+
681
+ ---
682
+
683
+ ## Acceptance Criteria
684
+
685
+ ### Core Functionality
686
+
687
+ - [ ] `jump search <terms>` returns fuzzy-matched results with scores
688
+ - [ ] `jump get <key>` returns single location or error with suggestion
689
+ - [ ] `jump list` shows all locations
690
+ - [ ] `jump add` creates new location with validation
691
+ - [ ] `jump update` modifies existing location
692
+ - [ ] `jump remove` deletes location (with `--force` for no prompt)
693
+ - [ ] `jump validate` checks all paths exist, reports results
694
+
695
+ ### Reports
696
+
697
+ - [ ] `jump report brands/clients/types/tags` shows counts
698
+ - [ ] `jump report by-brand/by-client/by-type/by-tag` groups locations
699
+ - [ ] `jump report summary` shows overview
700
+
701
+ ### Generation
702
+
703
+ - [ ] `jump generate aliases` outputs shell alias format
704
+ - [ ] `jump generate help` outputs fzf-friendly help format
705
+ - [ ] `--output <file>` writes to file instead of stdout
706
+
707
+ ### Output Formats
708
+
709
+ - [ ] `--format table` shows colored, pretty output (default)
710
+ - [ ] `--format json` returns structured JSON
711
+ - [ ] `--format paths` returns one path per line
712
+
713
+ ### Error Handling
714
+
715
+ - [ ] Invalid input returns structured error with code
716
+ - [ ] NOT_FOUND includes fuzzy suggestions
717
+ - [ ] Config errors handled gracefully (create defaults if missing)
718
+ - [ ] Exit codes match specification
719
+
720
+ ### Claude Skill
721
+
722
+ - [ ] Skill file generated and installable
723
+ - [ ] All commands work with `--format json`
724
+ - [ ] Error responses include recovery suggestions
725
+
726
+ ---
727
+
728
+ ## Deliverables Checklist
729
+
730
+ | Deliverable | Description |
731
+ |-------------|-------------|
732
+ | Data model | `locations.json` with meta, categories, brands, clients, locations |
733
+ | CLI commands | search, get, list, add, update, remove, validate, generate, report, info |
734
+ | Output formats | table (colored), json, paths |
735
+ | Search algorithm | Fuzzy match with weighted scoring |
736
+ | Reports | By brand, client, type, tag, summary |
737
+ | Generation | aliases-jump.zsh, help content (stdout default) |
738
+ | Claude skill | Skill file with command mappings and examples |
739
+ | Test fixtures | YAML-driven test cases |
740
+ | Seed data | Import from existing aliases-jump.zsh |
741
+ | Defensive coding | Input validation, error handling, config safety |
742
+
743
+ ---
744
+
745
+ ## Implementation Notes
746
+
747
+ ### CLI Pattern
748
+
749
+ This is a **Pattern 4: Method Dispatch (Full)** tool per the CLI patterns guide:
750
+ - 10+ commands
751
+ - Hierarchical help system (`jump help search`, `jump help report`)
752
+ - Complex argument parsing per command
753
+
754
+ ### Module Structure
755
+
756
+ ```
757
+ lib/appydave/tools/jump/
758
+ ├── cli.rb # Command routing and help
759
+ ├── config.rb # Load/save locations.json
760
+ ├── search.rb # Search algorithm
761
+ ├── location.rb # Location model/validation
762
+ ├── commands/
763
+ │ ├── add.rb
764
+ │ ├── update.rb
765
+ │ ├── remove.rb
766
+ │ ├── validate.rb
767
+ │ ├── generate.rb
768
+ │ └── report.rb
769
+ ├── formatters/
770
+ │ ├── table.rb # Colored table output
771
+ │ ├── json.rb
772
+ │ └── paths.rb
773
+ └── importers/
774
+ └── alias_file.rb # Import from aliases-jump.zsh
775
+ ```
776
+
777
+ ---
778
+
779
+ **Last updated**: 2025-12-13