appydave-tools 0.20.1 → 0.21.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.
@@ -0,0 +1,693 @@
1
+ # PRD: Client Sharing with Pre-Signed URLs
2
+
3
+ **Status:** Draft
4
+ **Author:** David Cruwys
5
+ **Created:** 2025-11-10
6
+ **Priority:** Phase 5 Enhancement
7
+
8
+ ---
9
+
10
+ ## Overview
11
+
12
+ Content creators frequently need to share video files with clients, collaborators, and team members who don't have AWS access. Currently, this requires manual workflows through the S3 console or making files public. DAM should provide a simple, secure way to generate shareable links directly from the command line.
13
+
14
+ ### Current State
15
+
16
+ **Problem:** Sharing videos with clients is cumbersome
17
+
18
+ **Current workflows:**
19
+ 1. **Manual S3 Console** - Log in → Navigate → Select file → Generate pre-signed URL → Copy → Email
20
+ 2. **Public S3 Files** - Make bucket/file public (security risk, permanent access)
21
+ 3. **Download & Re-upload** - Download from S3 → Upload to file sharing service
22
+ 4. **Email attachment** - Download → Compress → Email (limited by file size)
23
+
24
+ **Pain points:**
25
+ - Time-consuming multi-step process
26
+ - Requires AWS console access
27
+ - No expiry management
28
+ - No HTML embed support
29
+ - Manual copy-paste prone to errors
30
+
31
+ ### Proposed State
32
+
33
+ **Unified DAM Interface:**
34
+ ```bash
35
+ # Basic: Share single video (7-day expiry default)
36
+ dam share appydave b70 video.mp4
37
+
38
+ # Advanced: Custom expiry and HTML embed
39
+ dam share appydave b70 video.mp4 --expires 14d --html
40
+
41
+ # Multiple files: Generate shareable index page
42
+ dam share appydave b70 *.mp4 --expires 3d --index
43
+ ```
44
+
45
+ **Output:**
46
+ ```
47
+ 📤 Shareable link (expires in 7 days):
48
+ https://appydave-video-projects.s3.ap-southeast-1.amazonaws.com/staging/v-appydave/b70/video.mp4?X-Amz-Signature=...&X-Amz-Expires=604800
49
+
50
+ 📋 Copied to clipboard!
51
+
52
+ 🎬 HTML embed code:
53
+ <video controls width="800">
54
+ <source src="https://..." type="video/mp4">
55
+ </video>
56
+ ```
57
+
58
+ ---
59
+
60
+ ## Goals
61
+
62
+ ### Primary Goals
63
+
64
+ 1. **One-Command Sharing** - Generate shareable URL with single command
65
+ 2. **Clipboard Integration** - Automatic clipboard copy for quick pasting
66
+ 3. **Secure by Default** - Time-limited pre-signed URLs (no permanent public access)
67
+ 4. **Client-Friendly** - No AWS account required for recipients
68
+
69
+ ### Secondary Goals
70
+
71
+ 5. **HTML Embed Support** - Generate embed code for video players
72
+ 6. **Multiple File Support** - Share entire project or filtered files
73
+ 7. **Customizable Expiry** - Flexible time windows (hours to days)
74
+ 8. **Index Generation** - Create HTML page listing multiple videos
75
+
76
+ ### Non-Goals
77
+
78
+ - **CloudFront integration** - Not implementing CDN (future enhancement)
79
+ - **Upload via share** - Only sharing existing files, not upload workflows
80
+ - **Authentication** - Pre-signed URLs are authentication (no additional login)
81
+ - **Analytics tracking** - Not tracking who viewed/downloaded
82
+
83
+ ---
84
+
85
+ ## User Stories
86
+
87
+ ### Story 1: Share Single Video with Client (Primary Use Case)
88
+
89
+ **As a content creator,**
90
+ **I want to share a video file with a client quickly,**
91
+ **So they can review it without needing AWS access.**
92
+
93
+ **Workflow:**
94
+ ```bash
95
+ # From anywhere
96
+ dam share appydave b70 final-edit.mp4
97
+
98
+ # Output copied to clipboard automatically
99
+ # Paste into email/Slack and send
100
+ ```
101
+
102
+ **Acceptance criteria:**
103
+ - ✅ Generates pre-signed URL with 7-day default expiry
104
+ - ✅ Copies URL to system clipboard automatically
105
+ - ✅ Shows expiry date/time clearly
106
+ - ✅ Client can view video in browser (no download required)
107
+ - ✅ Works from any directory (uses brand/project resolution)
108
+
109
+ ---
110
+
111
+ ### Story 2: Share with Custom Expiry Time
112
+
113
+ **As a content creator,**
114
+ **I want to control how long the shared link remains valid,**
115
+ **So I can match client review timelines.**
116
+
117
+ **Workflow:**
118
+ ```bash
119
+ # Quick review (24 hours)
120
+ dam share appydave b70 draft.mp4 --expires 24h
121
+
122
+ # Extended review (2 weeks)
123
+ dam share appydave b70 final.mp4 --expires 14d
124
+ ```
125
+
126
+ **Acceptance criteria:**
127
+ - ✅ Supports hours (h), days (d) suffixes
128
+ - ✅ Minimum: 1 hour
129
+ - ✅ Maximum: 7 days (S3 pre-signed URL limit)
130
+ - ✅ Shows expiry timestamp in output
131
+ - ✅ Clear error if expiry exceeds limits
132
+
133
+ ---
134
+
135
+ ### Story 3: Generate HTML Embed Code
136
+
137
+ **As a content creator,**
138
+ **I want to embed videos in HTML pages,**
139
+ **So clients can view them in custom review portals.**
140
+
141
+ **Workflow:**
142
+ ```bash
143
+ dam share appydave b70 video.mp4 --html
144
+ ```
145
+
146
+ **Output:**
147
+ ```html
148
+ 📤 Shareable link (expires in 7 days):
149
+ https://...
150
+
151
+ 📋 Copied to clipboard!
152
+
153
+ 🎬 HTML embed code:
154
+ <video controls width="800" preload="metadata">
155
+ <source src="https://..." type="video/mp4">
156
+ Your browser does not support the video tag.
157
+ </video>
158
+ ```
159
+
160
+ **Acceptance criteria:**
161
+ - ✅ Generates complete `<video>` tag
162
+ - ✅ Includes responsive width
163
+ - ✅ Includes fallback message
164
+ - ✅ Copies HTML to clipboard when --html flag used
165
+ - ✅ Works with common video formats (mp4, mov, webm)
166
+
167
+ ---
168
+
169
+ ### Story 4: Share Multiple Files
170
+
171
+ **As a content creator,**
172
+ **I want to share multiple video files at once,**
173
+ **So clients can review all deliverables together.**
174
+
175
+ **Workflow:**
176
+ ```bash
177
+ # Share all MP4s in project
178
+ dam share appydave b70 *.mp4 --expires 3d
179
+ ```
180
+
181
+ **Output:**
182
+ ```
183
+ 📤 Sharing 3 files (expires in 3 days):
184
+
185
+ 1. intro.mp4
186
+ https://...
187
+
188
+ 2. main-content.mp4
189
+ https://...
190
+
191
+ 3. outro.mp4
192
+ https://...
193
+
194
+ 📋 All links copied to clipboard!
195
+ ```
196
+
197
+ **Acceptance criteria:**
198
+ - ✅ Supports glob patterns (*.mp4, video-*.mov)
199
+ - ✅ Generates individual URLs for each file
200
+ - ✅ Copies all URLs to clipboard (newline-separated)
201
+ - ✅ Shows count of files shared
202
+ - ✅ Consistent expiry across all files
203
+
204
+ ---
205
+
206
+ ### Story 5: Generate Shareable Index Page
207
+
208
+ **As a content creator,**
209
+ **I want to create an HTML page with all videos,**
210
+ **So clients have a single link to view all deliverables.**
211
+
212
+ **Workflow:**
213
+ ```bash
214
+ dam share appydave b70 *.mp4 --index --expires 7d
215
+ ```
216
+
217
+ **Output:**
218
+ ```
219
+ 📤 Generated shareable index (expires in 7 days):
220
+ /Users/davidcruwys/dev/video-projects/v-appydave/b70-project/share-index.html
221
+
222
+ 🌐 Index URL:
223
+ https://appydave-video-projects.s3.ap-southeast-1.amazonaws.com/staging/v-appydave/b70/share-index.html?...
224
+
225
+ 📋 Copied to clipboard!
226
+
227
+ Index includes:
228
+ - intro.mp4 (125 MB)
229
+ - main-content.mp4 (2.3 GB)
230
+ - outro.mp4 (89 MB)
231
+ ```
232
+
233
+ **Acceptance criteria:**
234
+ - ✅ Generates HTML file with embedded video players
235
+ - ✅ Shows file names, sizes, and thumbnails
236
+ - ✅ Includes all videos with individual pre-signed URLs
237
+ - ✅ Uploads index.html to S3 with pre-signed URL
238
+ - ✅ Mobile-responsive design
239
+ - ✅ Single link for client (just share index URL)
240
+
241
+ ---
242
+
243
+ ## Technical Design
244
+
245
+ ### Architecture
246
+
247
+ **Command Structure:**
248
+ ```ruby
249
+ # bin/dam
250
+ def share_command(args)
251
+ options = parse_share_args(args)
252
+ share_ops = Appydave::Tools::Dam::ShareOperations.new(options[:brand], options[:project])
253
+ share_ops.generate_links(
254
+ files: options[:files],
255
+ expires: options[:expires],
256
+ html: options[:html],
257
+ index: options[:index]
258
+ )
259
+ end
260
+ ```
261
+
262
+ **New Module:**
263
+ ```ruby
264
+ # lib/appydave/tools/dam/share_operations.rb
265
+ module Appydave::Tools::Dam
266
+ class ShareOperations
267
+ def initialize(brand, project)
268
+ @brand = brand
269
+ @project = project
270
+ @config = load_brand_config(brand)
271
+ @s3_client = setup_s3_client
272
+ end
273
+
274
+ def generate_links(files:, expires: '7d', html: false, index: false)
275
+ # 1. Resolve file paths
276
+ # 2. Generate pre-signed URLs (using AWS SDK)
277
+ # 3. Copy to clipboard
278
+ # 4. Generate HTML if requested
279
+ # 5. Create index page if requested
280
+ end
281
+ end
282
+ end
283
+ ```
284
+
285
+ ### AWS SDK Integration
286
+
287
+ **Pre-signed URL generation:**
288
+ ```ruby
289
+ def generate_presigned_url(s3_key, expires_in_seconds)
290
+ presigner = Aws::S3::Presigner.new(client: @s3_client)
291
+ presigner.presigned_url(
292
+ :get_object,
293
+ bucket: @config.aws.s3_bucket,
294
+ key: s3_key,
295
+ expires_in: expires_in_seconds
296
+ )
297
+ end
298
+ ```
299
+
300
+ ### Clipboard Integration
301
+
302
+ **Cross-platform clipboard support:**
303
+ ```ruby
304
+ require 'clipboard' # Already in gemspec
305
+
306
+ def copy_to_clipboard(text)
307
+ Clipboard.copy(text)
308
+ puts "📋 Copied to clipboard!"
309
+ rescue StandardError => e
310
+ puts "⚠️ Could not copy to clipboard: #{e.message}"
311
+ puts " (URL shown above for manual copy)"
312
+ end
313
+ ```
314
+
315
+ ### Expiry Parsing
316
+
317
+ **Human-friendly time parsing:**
318
+ ```ruby
319
+ def parse_expiry(expiry_string)
320
+ # Examples: "24h", "7d", "2d", "48h"
321
+ case expiry_string
322
+ when /^(\d+)h$/
323
+ hours = $1.to_i
324
+ raise "Expiry must be at least 1 hour" if hours < 1
325
+ raise "Expiry cannot exceed 168 hours (7 days)" if hours > 168
326
+ hours * 3600
327
+ when /^(\d+)d$/
328
+ days = $1.to_i
329
+ raise "Expiry must be at least 1 day" if days < 1
330
+ raise "Expiry cannot exceed 7 days" if days > 7
331
+ days * 86400
332
+ else
333
+ raise "Invalid expiry format. Use: 24h, 7d, etc."
334
+ end
335
+ end
336
+ ```
337
+
338
+ ### HTML Generation
339
+
340
+ **Basic embed template:**
341
+ ```html
342
+ <video controls width="800" preload="metadata" style="max-width: 100%;">
343
+ <source src="{PRESIGNED_URL}" type="video/mp4">
344
+ Your browser does not support the video tag.
345
+ </video>
346
+ ```
347
+
348
+ **Index page template:**
349
+ ```html
350
+ <!DOCTYPE html>
351
+ <html>
352
+ <head>
353
+ <title>Video Review - {PROJECT_NAME}</title>
354
+ <meta name="viewport" content="width=device-width, initial-scale=1">
355
+ <style>
356
+ body { font-family: system-ui; max-width: 1200px; margin: 2rem auto; padding: 0 1rem; }
357
+ video { width: 100%; max-width: 800px; display: block; margin: 1rem 0; }
358
+ .video-item { margin: 2rem 0; padding: 1rem; border: 1px solid #ddd; border-radius: 8px; }
359
+ .filename { font-size: 1.2rem; font-weight: bold; }
360
+ .filesize { color: #666; }
361
+ .expiry { color: #c00; font-style: italic; }
362
+ </style>
363
+ </head>
364
+ <body>
365
+ <h1>Video Review: {PROJECT_NAME}</h1>
366
+ <p class="expiry">⚠️ Links expire: {EXPIRY_DATE}</p>
367
+
368
+ {VIDEO_ITEMS}
369
+ </body>
370
+ </html>
371
+ ```
372
+
373
+ ---
374
+
375
+ ## Command Reference
376
+
377
+ ### Basic Usage
378
+
379
+ ```bash
380
+ # Share single file (7-day default)
381
+ dam share <brand> <project> <file>
382
+
383
+ # Examples
384
+ dam share appydave b70 final-edit.mp4
385
+ dam share voz boy-baker scene-01.mov
386
+ ```
387
+
388
+ ### With Options
389
+
390
+ ```bash
391
+ # Custom expiry
392
+ dam share appydave b70 video.mp4 --expires 24h
393
+ dam share appydave b70 video.mp4 --expires 14d
394
+
395
+ # Generate HTML embed code
396
+ dam share appydave b70 video.mp4 --html
397
+
398
+ # Multiple files
399
+ dam share appydave b70 *.mp4
400
+ dam share appydave b70 scene-*.mov --expires 3d
401
+
402
+ # Generate index page
403
+ dam share appydave b70 *.mp4 --index
404
+ dam share appydave b70 *.mp4 --index --html --expires 7d
405
+ ```
406
+
407
+ ### Auto-Detection
408
+
409
+ ```bash
410
+ # From project directory
411
+ cd ~/dev/video-projects/v-appydave/b70-project
412
+ dam share video.mp4
413
+ dam share *.mp4 --index
414
+ ```
415
+
416
+ ### Help
417
+
418
+ ```bash
419
+ dam help share
420
+ dam share --help
421
+ ```
422
+
423
+ ---
424
+
425
+ ## Implementation Plan
426
+
427
+ ### Phase 1: Basic Pre-Signed URLs (MVP)
428
+
429
+ **Scope:**
430
+ - Single file sharing
431
+ - 7-day default expiry
432
+ - Clipboard integration
433
+ - Basic error handling
434
+
435
+ **Commands:**
436
+ ```bash
437
+ dam share appydave b70 video.mp4
438
+ ```
439
+
440
+ **Estimated effort:** 4-6 hours
441
+
442
+ **Files to create:**
443
+ - `lib/appydave/tools/dam/share_operations.rb`
444
+ - `spec/appydave/tools/dam/share_operations_spec.rb`
445
+
446
+ **Files to modify:**
447
+ - `bin/dam` (add share_command)
448
+
449
+ ---
450
+
451
+ ### Phase 2: Advanced Options
452
+
453
+ **Scope:**
454
+ - Custom expiry (hours/days)
455
+ - HTML embed code generation
456
+ - Multiple file support
457
+ - Auto-detection from PWD
458
+
459
+ **Commands:**
460
+ ```bash
461
+ dam share appydave b70 video.mp4 --expires 24h --html
462
+ dam share appydave b70 *.mp4 --expires 3d
463
+ ```
464
+
465
+ **Estimated effort:** 3-4 hours
466
+
467
+ **New features:**
468
+ - Expiry parsing (`parse_expiry`)
469
+ - HTML template generation
470
+ - Glob pattern support
471
+
472
+ ---
473
+
474
+ ### Phase 3: Index Generation
475
+
476
+ **Scope:**
477
+ - HTML index page creation
478
+ - Multiple video embedding
479
+ - File size display
480
+ - Upload index to S3
481
+
482
+ **Commands:**
483
+ ```bash
484
+ dam share appydave b70 *.mp4 --index --expires 7d
485
+ ```
486
+
487
+ **Estimated effort:** 4-5 hours
488
+
489
+ **New features:**
490
+ - Index HTML template
491
+ - Upload index.html to S3
492
+ - Generate pre-signed URL for index
493
+ - Responsive design
494
+
495
+ ---
496
+
497
+ ## Testing Strategy
498
+
499
+ ### Unit Tests
500
+
501
+ ```ruby
502
+ # spec/appydave/tools/dam/share_operations_spec.rb
503
+ describe ShareOperations do
504
+ describe '#generate_presigned_url' do
505
+ it 'generates valid S3 pre-signed URL'
506
+ it 'includes correct expiry time'
507
+ it 'uses correct S3 bucket and key'
508
+ end
509
+
510
+ describe '#parse_expiry' do
511
+ it 'parses hours (24h → 86400 seconds)'
512
+ it 'parses days (7d → 604800 seconds)'
513
+ it 'raises error for invalid format'
514
+ it 'raises error for expiry > 7 days'
515
+ end
516
+
517
+ describe '#generate_html_embed' do
518
+ it 'generates valid video tag'
519
+ it 'includes presigned URL'
520
+ it 'handles different video formats'
521
+ end
522
+ end
523
+ ```
524
+
525
+ ### Integration Tests
526
+
527
+ ```bash
528
+ # Manual testing checklist
529
+ 1. Share single MP4 file (verify URL works in browser)
530
+ 2. Share with 24h expiry (verify expires_in parameter)
531
+ 3. Generate HTML embed (verify renders in browser)
532
+ 4. Share multiple files (verify all URLs generated)
533
+ 5. Generate index page (verify uploads to S3 and renders)
534
+ 6. Auto-detect from project directory
535
+ 7. Error handling (missing file, invalid expiry)
536
+ ```
537
+
538
+ ---
539
+
540
+ ## Security Considerations
541
+
542
+ ### Pre-Signed URL Security
543
+
544
+ **✅ Secure by default:**
545
+ - Time-limited access (1 hour to 7 days)
546
+ - URL includes cryptographic signature
547
+ - No permanent public access
548
+ - Revocable (delete S3 file = broken link)
549
+
550
+ **⚠️ Considerations:**
551
+ - Anyone with URL can access (don't share publicly)
552
+ - URLs can be forwarded (client could share with others)
553
+ - No view tracking or analytics
554
+
555
+ **Best practices:**
556
+ - Use shortest expiry needed for use case
557
+ - Share via secure channels (email, Slack, not public forums)
558
+ - Delete S3 file if early revocation needed
559
+
560
+ ### S3 Bucket Permissions
561
+
562
+ **Required permissions:**
563
+ ```json
564
+ {
565
+ "Version": "2012-10-17",
566
+ "Statement": [
567
+ {
568
+ "Effect": "Allow",
569
+ "Action": [
570
+ "s3:GetObject",
571
+ "s3:PutObject"
572
+ ],
573
+ "Resource": "arn:aws:s3:::appydave-video-projects/staging/*"
574
+ }
575
+ ]
576
+ }
577
+ ```
578
+
579
+ ---
580
+
581
+ ## Documentation Updates
582
+
583
+ ### Help System
584
+
585
+ **Add to `dam help`:**
586
+ ```
587
+ Share Commands:
588
+ dam share <brand> <project> <file> Generate shareable URL
589
+ dam share <brand> <project> <file> --html Generate HTML embed code
590
+ dam share <brand> <project> *.mp4 --index Create shareable index page
591
+ ```
592
+
593
+ **New help page:**
594
+ ```bash
595
+ dam help share
596
+ # Shows: Full usage, examples, expiry options, HTML generation
597
+ ```
598
+
599
+ ### Usage Guide
600
+
601
+ **Update `docs/dam/usage.md`:**
602
+ - Add "Client Sharing" section
603
+ - Include examples for all use cases
604
+ - Document security best practices
605
+ - Explain pre-signed URL limitations
606
+
607
+ ### Testing Plan
608
+
609
+ **Update `docs/dam/dam-testing-plan.md`:**
610
+ - Add Phase 5 tests for share command
611
+ - Include test cases for each story
612
+ - Manual verification steps for URLs
613
+
614
+ ---
615
+
616
+ ## Success Metrics
617
+
618
+ **Adoption:**
619
+ - 70% of content creators use `dam share` within 2 weeks
620
+ - Reduced time from "need to share" to "link sent" from 5 minutes to 30 seconds
621
+
622
+ **Usability:**
623
+ - Zero reported issues with clipboard integration
624
+ - Positive feedback on HTML embed generation
625
+ - Client satisfaction (no AWS access required)
626
+
627
+ **Technical:**
628
+ - 90%+ test coverage for ShareOperations
629
+ - Zero security incidents (no accidental public files)
630
+ - Expiry times respected (no premature/late expirations)
631
+
632
+ ---
633
+
634
+ ## Future Enhancements (Phase 6+)
635
+
636
+ ### CloudFront Integration
637
+ - Faster delivery via CDN
638
+ - Custom domain (share.appydave.com)
639
+ - Longer expiry times (CloudFront signed URLs can last years)
640
+
641
+ ### Analytics Tracking
642
+ - View count per video
643
+ - Geographic distribution of viewers
644
+ - Watch duration metrics
645
+
646
+ ### Password Protection
647
+ - Optional password for sensitive videos
648
+ - Client enters password to unlock video
649
+
650
+ ### Batch Operations
651
+ - Share entire project with one command
652
+ - Generate weekly review packages
653
+ - Scheduled expiry reminders
654
+
655
+ ### Team Collaboration
656
+ - Share internally within team (different expiry rules)
657
+ - Comment/feedback integration
658
+ - Version comparison views
659
+
660
+ ---
661
+
662
+ ## Appendix
663
+
664
+ ### Related Commands
665
+
666
+ **Existing DAM commands that share uses:**
667
+ - `dam s3-up` - Must upload file to S3 before sharing
668
+ - `dam s3-status` - Check if file exists in S3
669
+ - `dam list` - Discover available files to share
670
+
671
+ **Workflow integration:**
672
+ ```bash
673
+ # Complete workflow: upload and share
674
+ dam s3-up appydave b70 final-edit.mp4
675
+ dam share appydave b70 final-edit.mp4 --expires 7d --html
676
+ ```
677
+
678
+ ### References
679
+
680
+ **AWS Documentation:**
681
+ - [S3 Pre-Signed URLs](https://docs.aws.amazon.com/AmazonS3/latest/userguide/ShareObjectPreSignedURL.html)
682
+ - [AWS SDK for Ruby - S3 Presigner](https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/S3/Presigner.html)
683
+
684
+ **Similar Tools:**
685
+ - Dropbox (share links with expiry)
686
+ - Google Drive (shareable links)
687
+ - Frame.io (video review platform)
688
+
689
+ ---
690
+
691
+ **Document Version:** 1.0
692
+ **Status:** Ready for Implementation
693
+ **Next Steps:** Review with team → Implement Phase 1 MVP → User testing
@@ -0,0 +1,40 @@
1
+ # Windows Documentation
2
+
3
+ Documentation for setting up and using AppyDave Tools on Windows.
4
+
5
+ ## Installation
6
+
7
+ **[installation.md](./installation.md)** - Complete Windows setup guide
8
+
9
+ Covers:
10
+ - Installing Ruby (via RubyInstaller)
11
+ - Installing AppyDave Tools gem
12
+ - Configuration setup
13
+ - AWS CLI installation (optional, for S3 features)
14
+ - Troubleshooting common Windows issues
15
+
16
+ **Time required:** 20-30 minutes
17
+
18
+ ---
19
+
20
+ ## Testing
21
+
22
+ Once installation is complete, see:
23
+
24
+ **[../dam/dam-testing-plan-windows-powershell.md](../dam/dam-testing-plan-windows-powershell.md)** - DAM-specific Windows testing
25
+
26
+ Covers:
27
+ - 30+ Windows-specific test scenarios
28
+ - Path handling tests (C:/ vs C:\\)
29
+ - All DAM commands
30
+ - Performance benchmarks
31
+
32
+ ---
33
+
34
+ ## Support
35
+
36
+ **Ruby versions tested:** 3.3.x, 3.4.x
37
+ **Windows versions:** Windows 10, Windows 11
38
+ **Status:** ✅ Ready for testing
39
+
40
+ **Issues:** https://github.com/appydave/appydave-tools/issues