appydave-tools 0.15.0 → 0.17.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/.rubocop.yml +6 -0
- data/AGENTS.md +22 -0
- data/CHANGELOG.md +19 -0
- data/CLAUDE.md +318 -79
- data/README.md +390 -81
- data/bin/archive_project.rb +249 -0
- data/bin/configuration.rb +21 -1
- data/bin/generate_manifest.rb +357 -0
- data/bin/subtitle_manager.rb +18 -12
- data/bin/subtitle_processor.rb +158 -0
- data/bin/sync_from_ssd.rb +236 -0
- data/bin/vat +623 -0
- data/docs/README.md +169 -0
- data/docs/archive/codebase-audit-2025-01.md +424 -0
- data/docs/archive/documentation-framework-proposal.md +808 -0
- data/docs/archive/purpose-and-philosophy.md +110 -0
- data/docs/archive/test-coverage-quick-wins.md +342 -0
- data/docs/archive/tool-discovery.md +199 -0
- data/docs/archive/tool-documentation-analysis.md +592 -0
- data/docs/configuration/.env.example +19 -0
- data/docs/configuration/README.md +394 -0
- data/docs/configuration/channels.example.json +26 -0
- data/docs/configuration/settings.example.json +6 -0
- data/docs/development/CODEX-recommendations.md +123 -0
- data/docs/development/README.md +100 -0
- data/docs/development/cli-architecture-patterns.md +1604 -0
- data/docs/development/pattern-comparison.md +284 -0
- data/docs/prd-unified-brands-configuration.md +792 -0
- data/docs/project-brand-systems-analysis.md +934 -0
- data/docs/tools/bank-reconciliation.md +269 -0
- data/docs/tools/cli-actions.md +444 -0
- data/docs/tools/configuration.md +329 -0
- data/docs/{usage → tools}/gpt-context.md +118 -7
- data/docs/tools/index.md +324 -0
- data/docs/tools/move-images.md +295 -0
- data/docs/tools/name-manager.md +322 -0
- data/docs/tools/prompt-tools.md +209 -0
- data/docs/tools/subtitle-processor.md +242 -0
- data/docs/tools/youtube-automation.md +258 -0
- data/docs/tools/youtube-manager.md +248 -0
- data/docs/vat/dam-vision.md +123 -0
- data/docs/vat/session-summary-2025-11-09.md +297 -0
- data/docs/vat/usage.md +508 -0
- data/docs/vat/vat-testing-plan.md +801 -0
- data/lib/appydave/tools/configuration/models/brands_config.rb +238 -0
- data/lib/appydave/tools/configuration/models/config_base.rb +7 -0
- data/lib/appydave/tools/configuration/models/settings_config.rb +4 -0
- data/lib/appydave/tools/{subtitle_manager → subtitle_processor}/clean.rb +1 -1
- data/lib/appydave/tools/{subtitle_manager → subtitle_processor}/join.rb +5 -2
- data/lib/appydave/tools/vat/config.rb +153 -0
- data/lib/appydave/tools/vat/config_loader.rb +91 -0
- data/lib/appydave/tools/vat/manifest_generator.rb +239 -0
- data/lib/appydave/tools/vat/project_listing.rb +198 -0
- data/lib/appydave/tools/vat/project_resolver.rb +132 -0
- data/lib/appydave/tools/vat/s3_operations.rb +560 -0
- data/lib/appydave/tools/version.rb +1 -1
- data/lib/appydave/tools.rb +11 -5
- data/package.json +1 -1
- metadata +85 -14
- data/docs/dam/overview.md +0 -28
- data/lib/mj-paste-test/main.rb +0 -35
- data/lib/mj-paste-test/prompts.txt +0 -18
- data/lib/mj-paste-test/readme-leonardo.md +0 -0
- /data/lib/appydave/tools/{subtitle_manager → subtitle_processor}/_doc-clean.md +0 -0
- /data/lib/appydave/tools/{subtitle_manager → subtitle_processor}/_doc-join.md +0 -0
- /data/lib/appydave/tools/{subtitle_manager → subtitle_processor}/_doc-todo.md +0 -0
|
@@ -0,0 +1,394 @@
|
|
|
1
|
+
# AppyDave Tools Configuration Guide
|
|
2
|
+
|
|
3
|
+
This guide explains how to configure AppyDave Tools for your environment.
|
|
4
|
+
|
|
5
|
+
## Table of Contents
|
|
6
|
+
|
|
7
|
+
- [Quick Start](#quick-start)
|
|
8
|
+
- [Configuration Files](#configuration-files)
|
|
9
|
+
- [settings.json](#settingsjson)
|
|
10
|
+
- [channels.json](#channelsjson)
|
|
11
|
+
- [.env](#env)
|
|
12
|
+
- [Configuration Commands](#configuration-commands)
|
|
13
|
+
- [Migration from Legacy Config](#migration-from-legacy-config)
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## Quick Start
|
|
18
|
+
|
|
19
|
+
### 1. Create Default Configuration Files
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
ad_config -c
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
This creates empty configuration files at `~/.config/appydave/`:
|
|
26
|
+
- `settings.json` - Paths and preferences
|
|
27
|
+
- `channels.json` - YouTube channel definitions
|
|
28
|
+
- `youtube-automation.json` - Automation workflows
|
|
29
|
+
|
|
30
|
+
### 2. Option A: Copy Example Files
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
# Copy examples to your config directory
|
|
34
|
+
cp docs/configuration/settings.example.json ~/.config/appydave/settings.json
|
|
35
|
+
cp docs/configuration/channels.example.json ~/.config/appydave/channels.json
|
|
36
|
+
|
|
37
|
+
# Copy .env to project root
|
|
38
|
+
cp docs/configuration/.env.example .env
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Then edit each file and replace placeholders with your actual values.
|
|
42
|
+
|
|
43
|
+
### 2. Option B: Edit Directly in VS Code
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
ad_config -e
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Opens `~/.config/appydave/` in VS Code for editing.
|
|
50
|
+
|
|
51
|
+
### 3. Add Your Values
|
|
52
|
+
|
|
53
|
+
Update the configuration files with your specific paths and settings.
|
|
54
|
+
|
|
55
|
+
**Required for VAT (Video Asset Tools):**
|
|
56
|
+
```json
|
|
57
|
+
{
|
|
58
|
+
"video-projects-root": "/path/to/your/video-projects"
|
|
59
|
+
}
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
**Required for OpenAI tools:**
|
|
63
|
+
```bash
|
|
64
|
+
OPENAI_ACCESS_TOKEN=sk-your-actual-api-key
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
---
|
|
68
|
+
|
|
69
|
+
## Configuration Files
|
|
70
|
+
|
|
71
|
+
### `settings.json`
|
|
72
|
+
|
|
73
|
+
**Location:** `~/.config/appydave/settings.json`
|
|
74
|
+
|
|
75
|
+
**Purpose:** Stores paths and preferences (non-secret configuration)
|
|
76
|
+
|
|
77
|
+
**Example:**
|
|
78
|
+
```json
|
|
79
|
+
{
|
|
80
|
+
"video-projects-root": "/Users/yourname/dev/video-projects",
|
|
81
|
+
"ecamm-recording-folder": "/Users/yourname/ecamm",
|
|
82
|
+
"download-folder": "/Users/yourname/Downloads",
|
|
83
|
+
"download-image-folder": "/Users/yourname/Downloads/images"
|
|
84
|
+
}
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
**Settings Reference:**
|
|
88
|
+
|
|
89
|
+
| Key | Purpose | Used By | Required |
|
|
90
|
+
|-----|---------|---------|----------|
|
|
91
|
+
| `video-projects-root` | Root directory for all video projects | VAT commands | ✅ For VAT |
|
|
92
|
+
| `ecamm-recording-folder` | Where Ecamm Live saves recordings | Move Images | Optional |
|
|
93
|
+
| `download-folder` | General downloads directory | Move Images | Optional |
|
|
94
|
+
| `download-image-folder` | Image downloads (defaults to `download-folder`) | Move Images | Optional |
|
|
95
|
+
|
|
96
|
+
**Safe to:**
|
|
97
|
+
- ✅ Version control (after removing personal paths)
|
|
98
|
+
- ✅ Share with team (as template)
|
|
99
|
+
- ✅ Commit to git (as `.example` file)
|
|
100
|
+
|
|
101
|
+
---
|
|
102
|
+
|
|
103
|
+
### `channels.json`
|
|
104
|
+
|
|
105
|
+
**Location:** `~/.config/appydave/channels.json`
|
|
106
|
+
|
|
107
|
+
**Purpose:** Defines YouTube channels and their project locations
|
|
108
|
+
|
|
109
|
+
**Example:**
|
|
110
|
+
```json
|
|
111
|
+
{
|
|
112
|
+
"channels": {
|
|
113
|
+
"appydave": {
|
|
114
|
+
"code": "ad",
|
|
115
|
+
"name": "AppyDave",
|
|
116
|
+
"youtube_handle": "@appydave",
|
|
117
|
+
"locations": {
|
|
118
|
+
"content_projects": "/path/to/content",
|
|
119
|
+
"video_projects": "/Users/yourname/dev/video-projects/v-appydave",
|
|
120
|
+
"published_projects": "/path/to/published",
|
|
121
|
+
"abandoned_projects": "/path/to/abandoned"
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
**Channel Properties:**
|
|
129
|
+
|
|
130
|
+
| Property | Description | Example |
|
|
131
|
+
|----------|-------------|---------|
|
|
132
|
+
| `key` | Internal identifier (object key) | `"appydave"` |
|
|
133
|
+
| `code` | Short code for project naming | `"ad"` |
|
|
134
|
+
| `name` | Display name | `"AppyDave"` |
|
|
135
|
+
| `youtube_handle` | YouTube @ handle | `"@appydave"` |
|
|
136
|
+
|
|
137
|
+
**Location Properties:**
|
|
138
|
+
|
|
139
|
+
| Location | Purpose | Can Use "NOT-SET" |
|
|
140
|
+
|----------|---------|-------------------|
|
|
141
|
+
| `content_projects` | Content planning/scripts | ✅ Yes |
|
|
142
|
+
| `video_projects` | Active video projects | ❌ No (required) |
|
|
143
|
+
| `published_projects` | Published video archives | ✅ Yes |
|
|
144
|
+
| `abandoned_projects` | Abandoned projects | ✅ Yes |
|
|
145
|
+
|
|
146
|
+
**Using "NOT-SET":**
|
|
147
|
+
|
|
148
|
+
If you don't have a location configured yet, use `"NOT-SET"` as a placeholder:
|
|
149
|
+
|
|
150
|
+
```json
|
|
151
|
+
"content_projects": "NOT-SET"
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
This makes it clear that the value needs to be configured later.
|
|
155
|
+
|
|
156
|
+
**Safe to:**
|
|
157
|
+
- ✅ Version control structure (remove personal paths first)
|
|
158
|
+
- ⚠️ Each developer customizes paths locally
|
|
159
|
+
- ✅ Share channel definitions (codes, names, handles)
|
|
160
|
+
|
|
161
|
+
---
|
|
162
|
+
|
|
163
|
+
### `.env`
|
|
164
|
+
|
|
165
|
+
**Location:** `.env` (project root directory)
|
|
166
|
+
|
|
167
|
+
**Purpose:** Stores secrets and API keys
|
|
168
|
+
|
|
169
|
+
**⚠️ CRITICAL: This file is gitignored and should NEVER be committed!**
|
|
170
|
+
|
|
171
|
+
**Example:**
|
|
172
|
+
```bash
|
|
173
|
+
# OpenAI API Configuration
|
|
174
|
+
OPENAI_ACCESS_TOKEN=sk-your-actual-api-key-here
|
|
175
|
+
OPENAI_ORGANIZATION_ID=org-your-actual-org-id
|
|
176
|
+
|
|
177
|
+
# Optional: Enable OpenAI tools
|
|
178
|
+
TOOLS_ENABLED=true
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
**Environment Variables:**
|
|
182
|
+
|
|
183
|
+
| Variable | Purpose | Required For | Secret? |
|
|
184
|
+
|----------|---------|--------------|---------|
|
|
185
|
+
| `OPENAI_ACCESS_TOKEN` | OpenAI API key | prompt_tools, youtube_automation | ✅ SECRET |
|
|
186
|
+
| `OPENAI_ORGANIZATION_ID` | OpenAI org ID | prompt_tools, youtube_automation | ✅ SECRET |
|
|
187
|
+
| `TOOLS_ENABLED` | Enable OpenAI configuration | Optional | ❌ No |
|
|
188
|
+
|
|
189
|
+
**Getting API Keys:**
|
|
190
|
+
- OpenAI: https://platform.openai.com/api-keys
|
|
191
|
+
|
|
192
|
+
**Safe to:**
|
|
193
|
+
- ❌ NEVER version control
|
|
194
|
+
- ❌ NEVER share
|
|
195
|
+
- ❌ NEVER commit to git
|
|
196
|
+
- ✅ Keep local only
|
|
197
|
+
- ✅ Share `.env.example` template
|
|
198
|
+
|
|
199
|
+
---
|
|
200
|
+
|
|
201
|
+
## Configuration Commands
|
|
202
|
+
|
|
203
|
+
### List All Configurations
|
|
204
|
+
|
|
205
|
+
```bash
|
|
206
|
+
ad_config -l
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
Shows which configuration files exist and their paths.
|
|
210
|
+
|
|
211
|
+
**Example Output:**
|
|
212
|
+
```
|
|
213
|
+
NAME | EXISTS | PATH
|
|
214
|
+
-------------------|--------|------------------------------------------------------------
|
|
215
|
+
settings | true | /Users/yourname/.config/appydave/settings.json
|
|
216
|
+
channels | true | /Users/yourname/.config/appydave/channels.json
|
|
217
|
+
youtube_automation | true | /Users/yourname/.config/appydave/youtube-automation.json
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
### Create Missing Configurations
|
|
221
|
+
|
|
222
|
+
```bash
|
|
223
|
+
ad_config -c
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
Creates any configuration files that don't exist yet.
|
|
227
|
+
|
|
228
|
+
**Safety:** This command will NOT overwrite existing files. It only creates missing ones.
|
|
229
|
+
|
|
230
|
+
### Print Configuration Values
|
|
231
|
+
|
|
232
|
+
```bash
|
|
233
|
+
# Print all configurations
|
|
234
|
+
ad_config -p
|
|
235
|
+
|
|
236
|
+
# Print specific configurations
|
|
237
|
+
ad_config -p settings
|
|
238
|
+
ad_config -p channels
|
|
239
|
+
ad_config -p settings,channels
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
Shows the current values in your configuration files.
|
|
243
|
+
|
|
244
|
+
### Edit in VS Code
|
|
245
|
+
|
|
246
|
+
```bash
|
|
247
|
+
ad_config -e
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
Opens the configuration directory (`~/.config/appydave/`) in Visual Studio Code.
|
|
251
|
+
|
|
252
|
+
---
|
|
253
|
+
|
|
254
|
+
## Migration from Legacy Config
|
|
255
|
+
|
|
256
|
+
### From `~/.vat-config` (Deprecated)
|
|
257
|
+
|
|
258
|
+
If you have an old `~/.vat-config` file, migrate to `settings.json`:
|
|
259
|
+
|
|
260
|
+
**Old format** (`~/.vat-config`):
|
|
261
|
+
```
|
|
262
|
+
VIDEO_PROJECTS_ROOT=/Users/yourname/dev/video-projects
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
**New format** (`~/.config/appydave/settings.json`):
|
|
266
|
+
```json
|
|
267
|
+
{
|
|
268
|
+
"video-projects-root": "/Users/yourname/dev/video-projects"
|
|
269
|
+
}
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
**Migration steps:**
|
|
273
|
+
|
|
274
|
+
1. Check your current VAT config:
|
|
275
|
+
```bash
|
|
276
|
+
cat ~/.vat-config
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
2. Add the value to settings.json:
|
|
280
|
+
```bash
|
|
281
|
+
ad_config -e
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
3. In `settings.json`, add:
|
|
285
|
+
```json
|
|
286
|
+
"video-projects-root": "/your/path/from/vat/config"
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
4. Test that VAT still works:
|
|
290
|
+
```bash
|
|
291
|
+
vat list
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
5. Delete the old file:
|
|
295
|
+
```bash
|
|
296
|
+
rm ~/.vat-config
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
**Note:** The `vat init` command is deprecated. Use `ad_config` instead.
|
|
300
|
+
|
|
301
|
+
---
|
|
302
|
+
|
|
303
|
+
## Backup & Recovery
|
|
304
|
+
|
|
305
|
+
### Automatic Backups
|
|
306
|
+
|
|
307
|
+
Every time you save a configuration, a timestamped backup is created automatically:
|
|
308
|
+
|
|
309
|
+
```
|
|
310
|
+
~/.config/appydave/settings.json.backup.20251109-203015
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
**Backup format:** `filename.backup.YYYYMMDD-HHMMSS`
|
|
314
|
+
|
|
315
|
+
### Restoring from Backup
|
|
316
|
+
|
|
317
|
+
```bash
|
|
318
|
+
# List available backups
|
|
319
|
+
ls -la ~/.config/appydave/*.backup.*
|
|
320
|
+
|
|
321
|
+
# Restore from backup
|
|
322
|
+
cp ~/.config/appydave/settings.json.backup.20251109-203015 \
|
|
323
|
+
~/.config/appydave/settings.json
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
---
|
|
327
|
+
|
|
328
|
+
## Troubleshooting
|
|
329
|
+
|
|
330
|
+
### "VIDEO_PROJECTS_ROOT not configured" Error
|
|
331
|
+
|
|
332
|
+
**Problem:** VAT commands fail with configuration error.
|
|
333
|
+
|
|
334
|
+
**Solution:**
|
|
335
|
+
```bash
|
|
336
|
+
ad_config -e
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
Add to `settings.json`:
|
|
340
|
+
```json
|
|
341
|
+
{
|
|
342
|
+
"video-projects-root": "/path/to/your/video-projects"
|
|
343
|
+
}
|
|
344
|
+
```
|
|
345
|
+
|
|
346
|
+
### Configuration Files Missing
|
|
347
|
+
|
|
348
|
+
**Problem:** Configuration files don't exist.
|
|
349
|
+
|
|
350
|
+
**Solution:**
|
|
351
|
+
```bash
|
|
352
|
+
ad_config -c
|
|
353
|
+
```
|
|
354
|
+
|
|
355
|
+
This creates default empty configuration files.
|
|
356
|
+
|
|
357
|
+
### OpenAI API Errors
|
|
358
|
+
|
|
359
|
+
**Problem:** "OpenAI API key not configured"
|
|
360
|
+
|
|
361
|
+
**Solution:**
|
|
362
|
+
|
|
363
|
+
1. Create `.env` file in project root:
|
|
364
|
+
```bash
|
|
365
|
+
cp docs/configuration/.env.example .env
|
|
366
|
+
```
|
|
367
|
+
|
|
368
|
+
2. Add your API key:
|
|
369
|
+
```bash
|
|
370
|
+
OPENAI_ACCESS_TOKEN=sk-your-actual-key
|
|
371
|
+
OPENAI_ORGANIZATION_ID=org-your-org-id
|
|
372
|
+
TOOLS_ENABLED=true
|
|
373
|
+
```
|
|
374
|
+
|
|
375
|
+
3. Never commit `.env` to git (it's gitignored by default)
|
|
376
|
+
|
|
377
|
+
---
|
|
378
|
+
|
|
379
|
+
## Best Practices
|
|
380
|
+
|
|
381
|
+
1. **Use `ad_config -c` for initialization** - It's safe and won't overwrite existing files
|
|
382
|
+
2. **Use "NOT-SET" for unconfigured paths** - Makes it clear what needs to be set
|
|
383
|
+
3. **Keep secrets in `.env`** - Never put API keys in `settings.json`
|
|
384
|
+
4. **Backup before major changes** - Automatic backups are created, but you can manually backup too
|
|
385
|
+
5. **Use `ad_config -p` to verify** - Check your configuration values are correct
|
|
386
|
+
6. **Share examples, not actual configs** - Use `.example` files for team sharing
|
|
387
|
+
|
|
388
|
+
---
|
|
389
|
+
|
|
390
|
+
## Need Help?
|
|
391
|
+
|
|
392
|
+
- Check CLAUDE.md for project-specific configuration
|
|
393
|
+
- Run `ad_config --help` for command options
|
|
394
|
+
- See example files in `docs/configuration/`
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
{
|
|
2
|
+
"channels": {
|
|
3
|
+
"your-channel-key": {
|
|
4
|
+
"code": "yc",
|
|
5
|
+
"name": "Your Channel Name",
|
|
6
|
+
"youtube_handle": "@yourhandle",
|
|
7
|
+
"locations": {
|
|
8
|
+
"content_projects": "/path/to/content/projects",
|
|
9
|
+
"video_projects": "/path/to/video/projects",
|
|
10
|
+
"published_projects": "/path/to/published/projects",
|
|
11
|
+
"abandoned_projects": "/path/to/abandoned/projects"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"second-channel": {
|
|
15
|
+
"code": "sc",
|
|
16
|
+
"name": "Second Channel",
|
|
17
|
+
"youtube_handle": "@secondchannel",
|
|
18
|
+
"locations": {
|
|
19
|
+
"content_projects": "NOT-SET",
|
|
20
|
+
"video_projects": "/path/to/video-projects/v-second-channel",
|
|
21
|
+
"published_projects": "NOT-SET",
|
|
22
|
+
"abandoned_projects": "NOT-SET"
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
# CODEX Recommendations
|
|
2
|
+
|
|
3
|
+
> Last updated: 2025-11-09 13:36:08 UTC
|
|
4
|
+
> Maintenance note: whenever files outside this document change, review them and reflect any new patterns/risks here so the recommendations stay authoritative.
|
|
5
|
+
|
|
6
|
+
Guide created by Codex (GPT-5) to capture near-term cleanups and deeper refactors that will make `appydave-tools` easier to extend and test.
|
|
7
|
+
|
|
8
|
+
## Snapshot
|
|
9
|
+
|
|
10
|
+
- **Primary friction**: global configuration access makes VAT objects hard to test, forcing `allow_any_instance_of` overrides in specs such as `spec/appydave/tools/vat/config_spec.rb:6`.
|
|
11
|
+
- **Secondary friction**: command classes mix terminal IO with core logic (see `lib/appydave/tools/vat/project_resolver.rb:19-50`), which complicates automation and reuse.
|
|
12
|
+
- **Tooling debt**: RuboCop is configured (`.rubocop.yml`) but not enforced; the current run emits 108 offenses (93 auto-correctable per Claude logs) and engineers silence cops instead of resolving root causes.
|
|
13
|
+
|
|
14
|
+
## Priority Map
|
|
15
|
+
|
|
16
|
+
| Order | Theme | Why it matters |
|
|
17
|
+
| --- | --- | --- |
|
|
18
|
+
| P0 | Make configuration/services injectable | Unlocks clean tests, eliminates global stubs, and keeps future CLIs composable. |
|
|
19
|
+
| P1 | Re-enable effective lint/test automation | 93 auto-fixes are “free”; the remaining 15 surface real architecture problems that deserve explicit debt tracking. |
|
|
20
|
+
| P2 | Separate IO from business logic in CLI helpers | Enables automation agents (Claude) and humans to reuse services without TTY prompts. |
|
|
21
|
+
| P3 | Standardize filesystem fixtures | Reduces the bespoke `Dir.mktmpdir` + `FileUtils` boilerplate sprinkled through VAT specs; faster, safer tests. |
|
|
22
|
+
|
|
23
|
+
## Detailed Recommendations
|
|
24
|
+
|
|
25
|
+
### 1. Introduce configuration adapters
|
|
26
|
+
|
|
27
|
+
- **Problem**: `Appydave::Tools::Vat::Config.projects_root` reaches directly into `Configuration::Config.settings` (`lib/appydave/tools/vat/config.rb:13-21`), so specs must stub *every* `SettingsConfig` instance (`spec/appydave/tools/vat/config_spec.rb:14`).
|
|
28
|
+
- **Action**:
|
|
29
|
+
1. Create a lightweight `SettingsProvider` (duck-typed or interface module) that exposes `video_projects_root`.
|
|
30
|
+
2. Update VAT entry points to accept `settings:` or `config:` keyword args defaulting to the singleton, e.g. `def projects_root(settings: default_settings)`.
|
|
31
|
+
3. Provide a `Config.with_settings(temp_settings) { ... }` helper for specs and CLI overrides.
|
|
32
|
+
- **Impact**: RSpec can inject fakes without `allow_any_instance_of`; RuboCop warning disappears with no cop disable required.
|
|
33
|
+
|
|
34
|
+
### 2. Capture the remaining RuboCop debt deliberately
|
|
35
|
+
|
|
36
|
+
- **Problem**: Engineers currently choose between “ignore 108 offenses” or “disable cops,” which erodes lint value. `.rubocop.yml` already sets generous limits (200-char lines, spec exclusions), so remaining issues are meaningful.
|
|
37
|
+
- **Action plan**:
|
|
38
|
+
1. Run `bundle exec rubocop --auto-correct` and commit format-only fixes (expect ~93 files touched).
|
|
39
|
+
2. For the 15 blocking offenses, open a short-lived spreadsheet (or GH issue tracker) that records *cop → file → fix owner*. This keeps the queue visible without blocking merges.
|
|
40
|
+
3. Add a CI step (GitHub Action or Circle job) that executes `bundle exec rubocop` plus `bundle exec rake spec`, failing PRs that reintroduce offenses.
|
|
41
|
+
- **Fallback**: If any `allow_any_instance_of` remains after Step 1, convert it to the adapter pattern described above; avoid new `rubocop:disable` directives unless there’s a written justification beside them.
|
|
42
|
+
|
|
43
|
+
### 3. Decouple terminal IO from VAT services
|
|
44
|
+
|
|
45
|
+
- **Problem**: `ProjectResolver.resolve` blends filesystem globbing with interactive prompts (`puts`/`$stdin.gets`, `lib/appydave/tools/vat/project_resolver.rb:41-48`). These prompts block automation agents, and the logic cannot be reused inside other CLIs or tests without stubbing global IO.
|
|
46
|
+
- **Action**:
|
|
47
|
+
1. Extract the pure resolution logic so it always returns a result set (possibly multi-match) and never prints.
|
|
48
|
+
2. Create an `InteractiveResolver` (or CLI layer) that takes `io_in:`/`io_out:` and handles messaging/selection.
|
|
49
|
+
3. Update `bin/vat` commands to use the interactive wrapper; specs can cover both the pure resolver and the IO adapter with deterministic streams.
|
|
50
|
+
- **Bonus**: While refactoring, move the repeated `Dir.glob` filtering into a shared helper (e.g., `Projects::Scanner`) so CLAUDE/Code agents can reuse it for listing commands.
|
|
51
|
+
|
|
52
|
+
### 4. Standardize filesystem fixtures
|
|
53
|
+
|
|
54
|
+
- **Observation**: VAT specs repeatedly open temp dirs, `mkdir_p` brand/project skeletons, and remember to clean up (see blocks at `spec/appydave/tools/vat/config_spec.rb:22-178` and `spec/appydave/tools/vat/project_resolver_spec.rb:9-70`). Minor mistakes (missing cleanup, duplicated brand shortcuts) cause flaky tests locally.
|
|
55
|
+
- **Action**:
|
|
56
|
+
1. Add `spec/support/filesystem_helpers.rb` with helpers like `with_projects_root(brands: %w[appydave]) { |root| ... }`.
|
|
57
|
+
2. Include the helper in `spec/spec_helper.rb`, then convert VAT specs to the helper to remove boilerplate and centralize cleanup.
|
|
58
|
+
3. Consider shipping seeded sample trees under `spec/samples/video-projects` for regression-style tests that need deeper structures.
|
|
59
|
+
|
|
60
|
+
### 5. Harden `Configuration::Config`
|
|
61
|
+
|
|
62
|
+
- **Problem**: `Configuration::Config` uses `method_missing` to expose registered configs (`lib/appydave/tools/configuration/config.rb:31-39`), which hides failures until runtime and complicates auto-complete.
|
|
63
|
+
- **Action**:
|
|
64
|
+
1. Replace `method_missing` with explicit reader methods or `Forwardable`, or at minimum raise descriptive errors that list the registered keys (`configurations.keys`).
|
|
65
|
+
2. Expose a `fetch(:settings)` API that returns nil-friendly values for easier dependency injection.
|
|
66
|
+
3. Document the registration flow in `docs/development/cli-architecture-patterns.md` so new tools follow the same adapter approach.
|
|
67
|
+
|
|
68
|
+
### 6. Bake the plan into docs & automation
|
|
69
|
+
|
|
70
|
+
- Add a **Claude Impact** note whenever a CLI behavior changes (per `AGENTS.md`), and link back to this file so the agent knows why tests may require new prompts.
|
|
71
|
+
- Create a short checklist in `docs/development/README.md` (“Before merging VAT changes: run rubocop, run VAT specs, update configuration adapters”) to keep the recommendations visible.
|
|
72
|
+
|
|
73
|
+
## Architecture-Wide Opportunities
|
|
74
|
+
|
|
75
|
+
### CLI boundaries & shared ergonomics
|
|
76
|
+
|
|
77
|
+
- `bin/gpt_context.rb:15-88` hand-rolls its `OptionParser` setup even though `lib/appydave/tools/cli_actions/base_action.rb:8-44` already codifies a reusable CLI contract. Promote `BaseAction` to the default entrypoint for every CLI (gpt_context, prompt_tools, subtitle_processor, Ito/AI-TLDR helpers) so options, `-h`, and validation logic stay consistent.
|
|
78
|
+
- Extract a `Cli::Runner` that discovers actions via naming (`Appydave::Tools::<Tool>::Cli::<Command>`) and wire it into each `bin/*` – this keeps future tools (Hey Ito, BMAD, etc.) aligned without duplicating boilerplate.
|
|
79
|
+
- Add smoke specs that exercise each executable via `CLIHelpers.run('bin/gpt_context.rb --help')` to catch option regressions and ensure Guard/Claude can rely on deterministic output.
|
|
80
|
+
|
|
81
|
+
### GptContext as a reusable service
|
|
82
|
+
|
|
83
|
+
- `lib/appydave/tools/gpt_context/file_collector.rb:12-77` mutates global process state with `FileUtils.cd` and prints the working directory from inside the constructor. Replace this with `Dir.chdir(working_dir) { … }` blocks and pass a logger so the class can run quietly when invoked programmatically.
|
|
84
|
+
- The collector silently reads every match into memory; for large worktrees (Ito + AppyDave), the CLI will thrash. Consider yielding per-file chunks to a stream-aware `OutputHandler` so future AI agents can request incremental context.
|
|
85
|
+
- Normalize include/exclude matching by compiling glob patterns once (e.g., using `File::FNM_EXTGLOB`) to avoid repeated `Dir.glob` passes, and consider exposing a dry-run mode that returns candidate file lists for Claude prompt generation.
|
|
86
|
+
|
|
87
|
+
### Subtitle pipeline robustness
|
|
88
|
+
|
|
89
|
+
- `lib/appydave/tools/subtitle_processor/clean.rb:9-95` combines parsing, normalization, and IO side-effects. Break this into (1) a pure parser that operates on enumerables, (2) a formatter that emits SRT or VTT, and (3) a CLI wrapper for file IO. Doing so makes it easier to add BMAD-specific filters (emoji stripping, custom timelines) without forking the entire class.
|
|
90
|
+
- Add quick fuzz tests that feed malformed SRT snippets to ensure the parser fails fast instead of silently swallowing lines.
|
|
91
|
+
- Document the workflow in `docs/tools/subtitle_processor.md` (currently absent) so collaborators understand how to integrate Hey Ito or AI-TLDR narration scripts.
|
|
92
|
+
|
|
93
|
+
### YouTube automation hardening
|
|
94
|
+
|
|
95
|
+
- `lib/appydave/tools/youtube_manager/youtube_base.rb:8-17` constructs a Google API client on every command invocation. Cache the service in a memoized factory or inject it so tests can supply a fake client.
|
|
96
|
+
- `lib/appydave/tools/youtube_manager/authorization.rb:9-54` shells out a WEBrick server and prints instructions; wrap this interaction in a strategy object so Claude can be told “launch headless auth” versus “prompt operator David Cruwys.”
|
|
97
|
+
- Build retries and quota awareness around `@service.update_video` (`lib/appydave/tools/youtube_manager/update_video.rb:31-43`) so Ito/BMAD batch jobs can recover from `Google::Apis::RateLimitError` instead of crashing half-way through.
|
|
98
|
+
|
|
99
|
+
### Configuration & type safety
|
|
100
|
+
|
|
101
|
+
- `lib/appydave/tools/types/base_model.rb` + siblings provide a mini ActiveModel alternative but many tools now depend directly on `ActiveModel` (see `appydave-tools.gemspec:28-34`). Decide whether to lean fully into ActiveModel validations (Ruby 3-ready) or keep the custom types. If the latter, add coercion specs to lock down behavior for indifferent hashes (useful for AI ingestion).
|
|
102
|
+
- Expose typed settings objects per feature (`VatSettings`, `YoutubeSettings`) that wrap `SettingsConfig` so each CLI only sees the keys it needs. This makes future schema evolution (e.g., extra Ito endpoints) less risky.
|
|
103
|
+
|
|
104
|
+
### Testing & observability
|
|
105
|
+
|
|
106
|
+
- `spec/spec_helper.rb:5-41` always bootstraps SimpleCov/WebMock, which slows down iterative TDD. Guard these with ENV flags (`COVERAGE=true`, `ALLOW_NET=true`) so developers can opt into faster loops when needed.
|
|
107
|
+
- Add contract tests for each CLI that ensure stdout/stderr remain machine-readable—critical for Claude pipelines documented in `CLAUDE.md`. Snapshot testing (via `rspec-snapshot`) works well for command help text.
|
|
108
|
+
- Extend logging: `k_log` is only used inside configuration; wire it into VAT, GPT Context, and YouTube workflows so all tools share the same structured logging style. Include context like `brand=appydave` or `persona=Hey Ito` to help when multiple personas (Ito, AI-TLDR, AppyDave, BMAD) run jobs concurrently.
|
|
109
|
+
|
|
110
|
+
### Platform & dependency strategy
|
|
111
|
+
|
|
112
|
+
- `appydave-tools.gemspec:11-37` still declares `required_ruby_version >= 2.7`, but dependencies such as `activemodel ~> 8` and `google-api-client` are already Ruby 3-first. Move the baseline to Ruby 3.2 (or 3.3) so pattern matching, numbered parameters, and improved GC become available.
|
|
113
|
+
- Once on Ruby 3.2+, enable YJIT in local scripts (document via `docs/development/README.md`) to speed up large jobs like GPT context scans.
|
|
114
|
+
- Create a `Dependabot` (or Renovate) config so gem bumps don’t surprise automation—Ito and Hey Ito will benefit from predictable upgrade cadences. Pair this with a changelog checklist entry reminding you to note **Claude Impact** when APIs change.
|
|
115
|
+
|
|
116
|
+
## Suggested Next Steps
|
|
117
|
+
|
|
118
|
+
1. **Week 1**: Implement the configuration adapter + filesystem helper, convert VAT specs, and remove the `RSpec/AnyInstance` disable comment.
|
|
119
|
+
2. **Week 2**: Run RuboCop auto-correct, triage the residual offenses, and wire RuboCop/spec runs into CI.
|
|
120
|
+
3. **Week 3**: Refactor `ProjectResolver` IO separation and document the new contract for CLI callers.
|
|
121
|
+
4. **Week 4**: Revisit other CLIs (`youtube_manager`, `subtitle_processor`) and apply the same adapter/IO patterns once VAT proves the approach.
|
|
122
|
+
|
|
123
|
+
Ping Codex if you’d like guidance on scoping or sequencing—happy to help break these down into actionable tickets.
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
# Development Documentation
|
|
2
|
+
|
|
3
|
+
This directory contains comprehensive guides for developing and extending appydave-tools.
|
|
4
|
+
|
|
5
|
+
## Quick Links
|
|
6
|
+
|
|
7
|
+
### Architecture Guides
|
|
8
|
+
- [CLI Architecture Patterns](./cli-architecture-patterns.md) - **START HERE** when creating new tools
|
|
9
|
+
|
|
10
|
+
## Quick Pattern Selection
|
|
11
|
+
|
|
12
|
+
When creating a new CLI tool, use this quick reference:
|
|
13
|
+
|
|
14
|
+
### Single Operation Tool → Pattern 1
|
|
15
|
+
**Use when:** Tool performs ONE operation with various options
|
|
16
|
+
|
|
17
|
+
**Examples:** `gpt_context`, `move_images`
|
|
18
|
+
|
|
19
|
+
**Key files:**
|
|
20
|
+
```
|
|
21
|
+
bin/tool_name.rb # CLI executable
|
|
22
|
+
lib/appydave/tools/tool_name/
|
|
23
|
+
├── options.rb # Options struct
|
|
24
|
+
└── main_logic.rb # Business logic
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
**Read:** [Pattern 1 Details](./cli-architecture-patterns.md#pattern-1-single-command-tools)
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
### 2-5 Commands → Pattern 2
|
|
32
|
+
**Use when:** Tool has 2-5 related commands with simple routing
|
|
33
|
+
|
|
34
|
+
**Examples:** `subtitle_processor`, `configuration`
|
|
35
|
+
|
|
36
|
+
**Key files:**
|
|
37
|
+
```
|
|
38
|
+
bin/tool_name.rb # CLI with inline routing
|
|
39
|
+
lib/appydave/tools/tool_name/
|
|
40
|
+
├── command_one.rb # Command implementation
|
|
41
|
+
└── command_two.rb # Command implementation
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
**Read:** [Pattern 2 Details](./cli-architecture-patterns.md#pattern-2-multi-command-with-inline-routing)
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
### 6+ Commands or Shared Patterns → Pattern 3
|
|
49
|
+
**Use when:** Tool has many commands OR commands share validation/execution patterns
|
|
50
|
+
|
|
51
|
+
**Examples:** `youtube_manager`
|
|
52
|
+
|
|
53
|
+
**Key files:**
|
|
54
|
+
```
|
|
55
|
+
bin/tool_name.rb # CLI with BaseAction routing
|
|
56
|
+
lib/appydave/tools/
|
|
57
|
+
├── cli_actions/
|
|
58
|
+
│ ├── base_action.rb # Shared base (already exists)
|
|
59
|
+
│ ├── tool_cmd_one_action.rb # Command as Action class
|
|
60
|
+
│ └── tool_cmd_two_action.rb
|
|
61
|
+
└── tool_name/
|
|
62
|
+
└── service.rb # Business logic
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
**Read:** [Pattern 3 Details](./cli-architecture-patterns.md#pattern-3-multi-command-with-baseaction)
|
|
66
|
+
|
|
67
|
+
---
|
|
68
|
+
|
|
69
|
+
## Common Tasks
|
|
70
|
+
|
|
71
|
+
### Adding a New Tool
|
|
72
|
+
1. Choose pattern using [Decision Tree](./cli-architecture-patterns.md#decision-tree)
|
|
73
|
+
2. Follow [Migration Guide](./cli-architecture-patterns.md#migration-guide)
|
|
74
|
+
3. Register in `appydave-tools.gemspec`
|
|
75
|
+
4. Document in `CLAUDE.md`
|
|
76
|
+
|
|
77
|
+
### Understanding Existing Code
|
|
78
|
+
- See [Directory Structure](./cli-architecture-patterns.md#directory-structure)
|
|
79
|
+
- Review [Best Practices](./cli-architecture-patterns.md#best-practices)
|
|
80
|
+
|
|
81
|
+
### Writing Tests
|
|
82
|
+
- Read [Testing Approach](./cli-architecture-patterns.md#testing-approach)
|
|
83
|
+
- No `require` statements in specs (handled by `spec_helper`)
|
|
84
|
+
- Test business logic, not CLI executables
|
|
85
|
+
|
|
86
|
+
---
|
|
87
|
+
|
|
88
|
+
## Philosophy
|
|
89
|
+
|
|
90
|
+
AppyDave Tools follows a **consolidated toolkit philosophy**:
|
|
91
|
+
- Multiple independent tools in one repository
|
|
92
|
+
- Each tool solves one specific problem
|
|
93
|
+
- Clear separation between CLI and business logic
|
|
94
|
+
- Business logic can be used programmatically (no CLI dependencies in `lib/`)
|
|
95
|
+
|
|
96
|
+
**Full Philosophy:** [Purpose and Philosophy](../purpose-and-philosophy.md)
|
|
97
|
+
|
|
98
|
+
---
|
|
99
|
+
|
|
100
|
+
**Last updated:** 2025-11-08
|