appydave-tools 0.77.7 → 0.79.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/CHANGELOG.md +19 -0
- data/CLAUDE.md +14 -9
- data/CONTEXT.md +44 -0
- data/README.md +8 -5
- data/bin/{gpt_context.rb → llm_context.rb} +64 -23
- data/docs/planning/BACKLOG.md +3 -5
- data/exe/{gpt_context → llm_context} +1 -1
- data/lib/appydave/tools/jump/commands/generate.rb +1 -0
- data/lib/appydave/tools/{gpt_context → llm_context}/_doc.md +1 -1
- data/lib/appydave/tools/{gpt_context → llm_context}/file_collector.rb +33 -40
- data/lib/appydave/tools/{gpt_context → llm_context}/options.rb +5 -1
- data/lib/appydave/tools/{gpt_context → llm_context}/output_handler.rb +17 -1
- data/lib/appydave/tools/version.rb +1 -1
- data/lib/appydave/tools.rb +3 -3
- data/package.json +1 -1
- metadata +10 -10
- data/.DS_Store +0 -0
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: ec01667ec40e9b0b051f2e834800cd458c736f27107df033ddebeaf7de413823
|
|
4
|
+
data.tar.gz: 6627f68aefaf25f40cd7d55ba87e8470bd8e5c5a99146927424149b84a31b3b6
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 8e745ed73fc0f812a6275edb827df2901e5eb0b41c060b4ac68fdc27c9eff750b60b84d2244e21f2b6afb2cda98eacacc3895b6c82502673162202cb31075ddb
|
|
7
|
+
data.tar.gz: 1814d3250ecf2aebf1ccb9cf50e117fc7b9f220334c263b5b1677336848db1cd7e37f9b684df2903aba96ecc69bbad96368c1acc87fbd6addfed4086eeffe00a
|
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,22 @@
|
|
|
1
|
+
# [0.78.0](https://github.com/appydave/appydave-tools/compare/v0.77.7...v0.78.0) (2026-04-03)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Bug Fixes
|
|
5
|
+
|
|
6
|
+
* resolve rubocop block length violation in llm_context CLI ([305b65a](https://github.com/appydave/appydave-tools/commit/305b65aca92204b877ed25841a8041e9c5a08683))
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
### Features
|
|
10
|
+
|
|
11
|
+
* update gpt_gatherer to llm_gatherer ([acfbf1c](https://github.com/appydave/appydave-tools/commit/acfbf1c09d40b45d2ca211d5f3921af1127f068c))
|
|
12
|
+
|
|
13
|
+
## [0.77.7](https://github.com/appydave/appydave-tools/compare/v0.77.6...v0.77.7) (2026-03-20)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
### Bug Fixes
|
|
17
|
+
|
|
18
|
+
* parallelize git and S3 status checks in dam list (B007) ([5a6fab1](https://github.com/appydave/appydave-tools/commit/5a6fab1a9a01fda20b81315b640464e393dc1540))
|
|
19
|
+
|
|
1
20
|
## [0.77.6](https://github.com/appydave/appydave-tools/compare/v0.77.5...v0.77.6) (2026-03-20)
|
|
2
21
|
|
|
3
22
|
|
data/CLAUDE.md
CHANGED
|
@@ -27,6 +27,8 @@ Two-phase validation for the 75-commit DAM enhancement sprint (9e49668 → 4228b
|
|
|
27
27
|
- **Shareable individually** - Tools can be featured in standalone videos
|
|
28
28
|
- **Language flexible** - Currently Ruby, could be rewritten if needed
|
|
29
29
|
|
|
30
|
+
**System context**: See [CONTEXT.md](CONTEXT.md) for purpose, domain concepts, design rationale, and scope boundaries.
|
|
31
|
+
|
|
30
32
|
## Documentation Discovery Protocol
|
|
31
33
|
|
|
32
34
|
**CRITICAL: When user asks about recent changes, work completed, or project history:**
|
|
@@ -162,7 +164,7 @@ bin/console # Interactive Ruby console for experimentation
|
|
|
162
164
|
|
|
163
165
|
| Command | Gem Command | Description | Status |
|
|
164
166
|
|---------|-------------|-------------|--------|
|
|
165
|
-
| **
|
|
167
|
+
| **LLM Context** | `llm_context` | Collect project files for AI context | ⭐ PRIMARY |
|
|
166
168
|
| **YouTube Manager** | `youtube_manager` | CRUD operations on YouTube video metadata | ✅ ACTIVE |
|
|
167
169
|
| **Subtitle Processor** | `subtitle_processor` | Transform SRT files (clean/merge) | ✅ ACTIVE |
|
|
168
170
|
| **DAM (Digital Asset Management)** | `vat` | Multi-tenant video project storage orchestration | ✅ ACTIVE |
|
|
@@ -173,30 +175,33 @@ bin/console # Interactive Ruby console for experimentation
|
|
|
173
175
|
|
|
174
176
|
---
|
|
175
177
|
|
|
176
|
-
#### 1.
|
|
178
|
+
#### 1. LLM Context Gatherer (`bin/llm_context.rb`) ⭐ PRIMARY TOOL
|
|
177
179
|
Collect and organize project files for AI context:
|
|
178
180
|
|
|
179
181
|
```bash
|
|
180
182
|
# Basic usage - gather files with debug output and file output
|
|
181
|
-
bin/
|
|
183
|
+
bin/llm_context.rb -i '**/*.rb' -e 'spec/**/*' -d -o context.txt
|
|
182
184
|
|
|
183
185
|
# Multiple formats and patterns
|
|
184
|
-
bin/
|
|
186
|
+
bin/llm_context.rb -i 'lib/**/*.rb' -i 'bin/**/*.rb' -f tree,content -d
|
|
187
|
+
|
|
188
|
+
# Save to tempfile, copy path to clipboard
|
|
189
|
+
bin/llm_context.rb -i '**/*.rb' -o temp
|
|
185
190
|
|
|
186
191
|
# Advanced web project filtering
|
|
187
|
-
bin/
|
|
192
|
+
bin/llm_context.rb -i 'apps/**/*.ts' -i 'apps/**/*.tsx' -e '**/node_modules/**/*' -e '**/_generated/**/*' -d -f tree -o typescript.txt
|
|
188
193
|
|
|
189
194
|
# Tree view only for project structure
|
|
190
|
-
bin/
|
|
195
|
+
bin/llm_context.rb -i '**/*' -e '**/node_modules/**/*' -e '.git/**/*' -f tree -d
|
|
191
196
|
|
|
192
197
|
# Line-limited content gathering
|
|
193
|
-
bin/
|
|
198
|
+
bin/llm_context.rb -i '**/*.rb' -l 20 -f content -d
|
|
194
199
|
|
|
195
200
|
# Multiple output targets
|
|
196
|
-
bin/
|
|
201
|
+
bin/llm_context.rb -i 'docs/**/*' -f tree,content -o clipboard -o docs-context.txt
|
|
197
202
|
```
|
|
198
203
|
|
|
199
|
-
See detailed usage guide: [docs/usage/
|
|
204
|
+
See detailed usage guide: [docs/usage/llm-context.md](./docs/usage/llm-context.md)
|
|
200
205
|
|
|
201
206
|
#### 2. YouTube Manager (`bin/youtube_manager.rb`)
|
|
202
207
|
Manage YouTube video metadata via YouTube API:
|
data/CONTEXT.md
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
---
|
|
2
|
+
generated: 2026-04-03
|
|
3
|
+
generator: system-context
|
|
4
|
+
status: snapshot
|
|
5
|
+
sources:
|
|
6
|
+
- README.md
|
|
7
|
+
- appydave-tools.gemspec
|
|
8
|
+
- lib/appydave/tools.rb
|
|
9
|
+
- lib/appydave/tools/dam/brand_resolver.rb
|
|
10
|
+
- lib/appydave/tools/dam/project_resolver.rb
|
|
11
|
+
- lib/appydave/tools/jump/commands/generate.rb
|
|
12
|
+
- docs/dam/batch-s3-listing-requirements.md
|
|
13
|
+
- CHANGELOG.md (versions 0.76.0-0.77.7)
|
|
14
|
+
regenerate: "Run /appydave:system-context in the repo root"
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
# AppyDave Tools — System Context
|
|
18
|
+
|
|
19
|
+
## Purpose
|
|
20
|
+
Eliminate repetitive manual tasks from YouTube content creation workflows by bundling single-purpose CLI utilities that operate independently on video projects, metadata, and assets.
|
|
21
|
+
|
|
22
|
+
## Domain Concepts
|
|
23
|
+
- **Brand** — A business entity that owns video projects (AppyDave, VOZ, SupportSignal, etc.). Shortcuts (ad, joy, ss) resolve to brand keys (appydave, beauty-and-joy, supportsignal) in configs.
|
|
24
|
+
- **Project** — A discrete video deliverable. Named by pattern: FliVideo uses short codes (b65 → expands to b65-guy-monroe-marketing-plan), Storyline uses full names (boy-baker). Projects contain assets, metadata, and source files.
|
|
25
|
+
- **Digital Asset Management (DAM)** — Hybrid 3-tier storage: local working copies → S3 staging for collaboration (90-day lifecycle) → SSD archive for long-term cold storage. Orchestrates file sync and lifecycle across tiers.
|
|
26
|
+
- **Project Naming Patterns** — FliVideo: `b<num>` (short) expands to `b<num>-*` full name. Patterns like `b6*` match b60-b69. Storyline uses exact full names (no expansion).
|
|
27
|
+
- **Configuration-driven Architecture** — JSON configs (settings, channels, brands) stored in `~/.config/appydave/` per developer; secrets (.env) gitignored. Enables team collaboration: shared structure, per-dev customization.
|
|
28
|
+
- **Multi-channel YouTube Management** — Handles multiple YouTube channels (each with code, name, handle, locations). Single tool manages metadata updates across channels.
|
|
29
|
+
|
|
30
|
+
## Design Decisions
|
|
31
|
+
- **Single consolidated repository** — instead of separate gems per tool. Reduces maintenance overhead, enables code reuse, allows individual tools to be featured in standalone tutorials.
|
|
32
|
+
- **Single-purpose tools that operate independently** — each CLI does one thing (llm_context, youtube_manager, dam, etc.). Prevents feature creep, keeps coupling low, enables composition.
|
|
33
|
+
- **Configuration as data** — JSON files enable team sharing of project structure + team-specific path customization in .env. Separates secrets (API keys) from configuration (paths, channels).
|
|
34
|
+
- **Hybrid storage lifecycle** — S3 for short-term collaboration, SSD for archive. Balances cost (S3 pay-per-access), availability (local for daily work), and durability (SSD backup).
|
|
35
|
+
- **Brand/Project resolution layer** — BrandResolver + ProjectResolver decouple CLI input (shortcuts like ad, b65) from system state (config keys, full paths). Users type short codes; system maps to canonical names.
|
|
36
|
+
- **Parallel status checking** — `dam list <brand> --s3` parallelizes git and S3 status checks instead of N sequential API calls. Reduces list latency from 3-5s to <1s.
|
|
37
|
+
|
|
38
|
+
## Scope Limits
|
|
39
|
+
- Does NOT edit video files directly — only manages metadata, assets, and file organization. Video editing remains in post-production tools (Premiere, DaVinci, etc.).
|
|
40
|
+
- Does NOT provide local playback or streaming — focuses on storage, sync, and metadata. Video playback via external players or YouTube.
|
|
41
|
+
- Does NOT implement YouTube OAuth UI — wraps Google's authentication library. OAuth token generation handled by google-api-client flows, not custom UI.
|
|
42
|
+
- Does NOT manage individual files in DAM — operates on whole project directories as atomic units. Granular file operations are external (rsync, direct S3 CLI).
|
|
43
|
+
- Does NOT provide IDE integration for Jump tool — generates shell aliases and help text. IDE navigation handled by native IDE shortcuts or external plugins.
|
|
44
|
+
- Does NOT handle video versioning or branching — DAM is a flat archive. Version control (git) handles project versioning separately from media storage.
|
data/README.md
CHANGED
|
@@ -85,7 +85,7 @@ OPENAI_ACCESS_TOKEN=sk-your-actual-api-key
|
|
|
85
85
|
|
|
86
86
|
## The Tools
|
|
87
87
|
|
|
88
|
-
### 🤖
|
|
88
|
+
### 🤖 LLM Context Gatherer
|
|
89
89
|
|
|
90
90
|
**The problem:** AI assistants need context about your code, but copying files is tedious.
|
|
91
91
|
|
|
@@ -93,18 +93,21 @@ OPENAI_ACCESS_TOKEN=sk-your-actual-api-key
|
|
|
93
93
|
|
|
94
94
|
```bash
|
|
95
95
|
# Gather all Ruby files, skip tests, save to clipboard
|
|
96
|
-
|
|
96
|
+
llm_context -i '**/*.rb' -e 'spec/**/*' -d
|
|
97
97
|
|
|
98
98
|
# Get project structure as a tree
|
|
99
|
-
|
|
99
|
+
llm_context -i '**/*' -f tree -d
|
|
100
|
+
|
|
101
|
+
# Save to tempfile and copy path to clipboard
|
|
102
|
+
llm_context -i '**/*.rb' -o temp
|
|
100
103
|
|
|
101
104
|
# Multiple file types with custom output
|
|
102
|
-
|
|
105
|
+
llm_context -i 'apps/**/*.ts' -i 'apps/**/*.tsx' -e '**/node_modules/**/*' -o context.txt
|
|
103
106
|
```
|
|
104
107
|
|
|
105
108
|
**Use cases:** Working with ChatGPT, Claude, or any AI assistant on your codebase.
|
|
106
109
|
|
|
107
|
-
[Full documentation →](./docs/usage/
|
|
110
|
+
[Full documentation →](./docs/usage/llm-context.md)
|
|
108
111
|
|
|
109
112
|
---
|
|
110
113
|
|
|
@@ -5,32 +5,30 @@
|
|
|
5
5
|
# https://chatgpt.com/c/670df475-04f4-8002-a758-f5711bf433eb
|
|
6
6
|
|
|
7
7
|
# Usage:
|
|
8
|
-
# ./bin/
|
|
9
|
-
# ./bin/
|
|
8
|
+
# ./bin/llm_context.rb -d -i 'lib/openai_101/tools/**/*.rb'
|
|
9
|
+
# ./bin/llm_context.rb -d -i 'lib/openai_101/tools/**/*' -e 'node_modules/**/*' -e 'package-lock.json' -e 'lib/openai_101/tools/prompts/*.txt'
|
|
10
10
|
#
|
|
11
|
-
# Get
|
|
12
|
-
# ./bin/
|
|
11
|
+
# Get LLM Context Gatherer code
|
|
12
|
+
# ./bin/llm_context.rb -i 'bin/**/*gather*.rb' -i 'lib/openai_101/tools/**/*gather*.rb'
|
|
13
13
|
$LOAD_PATH.unshift(File.expand_path('../lib', __dir__))
|
|
14
14
|
|
|
15
15
|
require 'appydave/tools'
|
|
16
16
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
OptionParser.new do |opts|
|
|
22
|
-
opts.banner = <<~BANNER
|
|
23
|
-
GPT Context Gatherer - Collect project files for AI context
|
|
17
|
+
def build_banner
|
|
18
|
+
<<~BANNER
|
|
19
|
+
LLM Context Gatherer - Collect project files for AI context
|
|
24
20
|
|
|
25
21
|
SYNOPSIS
|
|
26
|
-
|
|
22
|
+
llm_context [options]
|
|
27
23
|
|
|
28
24
|
DESCRIPTION
|
|
29
25
|
Collects and packages codebase files for AI assistant context.
|
|
30
26
|
Outputs to clipboard (default), file, or stdout.
|
|
31
27
|
|
|
32
28
|
BANNER
|
|
29
|
+
end
|
|
33
30
|
|
|
31
|
+
def setup_options(opts, options)
|
|
34
32
|
opts.separator 'OPTIONS'
|
|
35
33
|
opts.separator ''
|
|
36
34
|
|
|
@@ -69,7 +67,7 @@ OptionParser.new do |opts|
|
|
|
69
67
|
end
|
|
70
68
|
|
|
71
69
|
opts.on('-o', '--output TARGET',
|
|
72
|
-
'Output target: clipboard, filename, or stdout',
|
|
70
|
+
'Output target: clipboard, temp, filename, or stdout',
|
|
73
71
|
'Default: clipboard. Repeatable for multiple targets.') do |target|
|
|
74
72
|
options.output_target << target
|
|
75
73
|
end
|
|
@@ -83,6 +81,12 @@ OptionParser.new do |opts|
|
|
|
83
81
|
options.show_tokens = true
|
|
84
82
|
end
|
|
85
83
|
|
|
84
|
+
opts.on('--stdin', 'Read file paths from stdin (one per line) instead of using patterns') do
|
|
85
|
+
options.stdin = true
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def setup_help_sections(opts)
|
|
86
90
|
opts.separator ''
|
|
87
91
|
opts.separator 'OUTPUT FORMATS'
|
|
88
92
|
opts.separator ' tree - Directory tree structure'
|
|
@@ -91,22 +95,39 @@ OptionParser.new do |opts|
|
|
|
91
95
|
opts.separator ' aider - Aider CLI command format (requires -p)'
|
|
92
96
|
opts.separator ' files - File paths only'
|
|
93
97
|
opts.separator ''
|
|
98
|
+
opts.separator 'OUTPUT TARGETS'
|
|
99
|
+
opts.separator ' clipboard - Copy to system clipboard (default)'
|
|
100
|
+
opts.separator ' temp - Write to system temp dir, copy path to clipboard'
|
|
101
|
+
opts.separator ' filename - Write to specified file path'
|
|
102
|
+
opts.separator ''
|
|
103
|
+
opts.separator 'INPUT MODES'
|
|
104
|
+
opts.separator ' Patterns (default): -i <glob> and -e <exclude_glob>'
|
|
105
|
+
opts.separator ' Stdin: --stdin (read file paths from stdin, one per line)'
|
|
106
|
+
opts.separator ''
|
|
94
107
|
opts.separator 'EXAMPLES'
|
|
95
108
|
opts.separator ' # Gather Ruby library code for AI context'
|
|
96
|
-
opts.separator "
|
|
109
|
+
opts.separator " llm_context -i 'lib/**/*.rb' -e 'spec/**/*' -d"
|
|
97
110
|
opts.separator ''
|
|
98
111
|
opts.separator ' # Project structure overview'
|
|
99
|
-
opts.separator "
|
|
112
|
+
opts.separator " llm_context -i '**/*' -f tree -e 'node_modules/**/*'"
|
|
100
113
|
opts.separator ''
|
|
101
114
|
opts.separator ' # Save to file with tree and content'
|
|
102
|
-
opts.separator "
|
|
115
|
+
opts.separator " llm_context -i 'src/**/*.ts' -f tree,content -o context.txt"
|
|
116
|
+
opts.separator ''
|
|
117
|
+
opts.separator ' # Write to system temp dir and copy path to clipboard'
|
|
118
|
+
opts.separator " llm_context -i 'lib/**/*.rb' -o temp"
|
|
119
|
+
opts.separator ''
|
|
120
|
+
opts.separator ' # Read file paths from stdin'
|
|
121
|
+
opts.separator " find lib -name '*.rb' | llm_context --stdin -o temp"
|
|
103
122
|
opts.separator ''
|
|
104
123
|
opts.separator ' # Generate aider command'
|
|
105
|
-
opts.separator "
|
|
124
|
+
opts.separator " llm_context -i 'lib/**/*.rb' -f aider -p 'Add logging'"
|
|
106
125
|
opts.separator ''
|
|
126
|
+
end
|
|
107
127
|
|
|
128
|
+
def setup_version_and_help(opts)
|
|
108
129
|
opts.on('-v', '--version', 'Show version') do
|
|
109
|
-
puts "
|
|
130
|
+
puts "llm_context version #{Appydave::Tools::VERSION}"
|
|
110
131
|
exit
|
|
111
132
|
end
|
|
112
133
|
|
|
@@ -114,12 +135,32 @@ OptionParser.new do |opts|
|
|
|
114
135
|
puts opts
|
|
115
136
|
exit
|
|
116
137
|
end
|
|
117
|
-
end
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
# Main execution
|
|
141
|
+
options = Appydave::Tools::LlmContext::Options.new(
|
|
142
|
+
working_directory: nil
|
|
143
|
+
)
|
|
144
|
+
|
|
145
|
+
parser = OptionParser.new do |opts|
|
|
146
|
+
opts.banner = build_banner
|
|
147
|
+
setup_options(opts, options)
|
|
148
|
+
setup_help_sections(opts)
|
|
149
|
+
setup_version_and_help(opts)
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
parser.parse!
|
|
153
|
+
|
|
154
|
+
# Handle stdin file paths
|
|
155
|
+
if options.stdin
|
|
156
|
+
options.file_paths = $stdin.readlines.map(&:chomp).reject(&:empty?)
|
|
157
|
+
options.working_directory = Dir.pwd unless options.working_directory
|
|
158
|
+
end
|
|
118
159
|
|
|
119
|
-
if options.include_patterns.empty? && options.exclude_patterns.empty?
|
|
160
|
+
if options.include_patterns.empty? && options.exclude_patterns.empty? && options.file_paths.empty?
|
|
120
161
|
script_name = File.basename($PROGRAM_NAME, File.extname($PROGRAM_NAME))
|
|
121
162
|
|
|
122
|
-
puts 'No options provided to
|
|
163
|
+
puts 'No options provided to LLM Context. Please specify patterns to include or exclude, or use --stdin.'
|
|
123
164
|
puts "For help, run: #{script_name} --help"
|
|
124
165
|
exit
|
|
125
166
|
end
|
|
@@ -133,7 +174,7 @@ pp options if options.debug == 'params'
|
|
|
133
174
|
|
|
134
175
|
options.working_directory ||= Dir.pwd
|
|
135
176
|
|
|
136
|
-
gatherer = Appydave::Tools::
|
|
177
|
+
gatherer = Appydave::Tools::LlmContext::FileCollector.new(options)
|
|
137
178
|
content = gatherer.build
|
|
138
179
|
|
|
139
180
|
if options.show_tokens
|
|
@@ -159,7 +200,7 @@ if %w[info debug].include?(options.debug)
|
|
|
159
200
|
puts '-' * 80
|
|
160
201
|
end
|
|
161
202
|
|
|
162
|
-
output_handler = Appydave::Tools::
|
|
203
|
+
output_handler = Appydave::Tools::LlmContext::OutputHandler.new(content, options)
|
|
163
204
|
output_handler.execute
|
|
164
205
|
|
|
165
206
|
pp options if options.debug == 'debug'
|
data/docs/planning/BACKLOG.md
CHANGED
|
@@ -1,16 +1,13 @@
|
|
|
1
1
|
# Project Backlog — AppyDave Tools
|
|
2
2
|
|
|
3
|
-
**Last updated**: 2026-03-20 (
|
|
4
|
-
**Total**: 41 | Pending:
|
|
3
|
+
**Last updated**: 2026-03-20 (B007 complete)
|
|
4
|
+
**Total**: 41 | Pending: 2 | Done: 38 | Deferred: 0 | Rejected: 0
|
|
5
5
|
|
|
6
6
|
---
|
|
7
7
|
|
|
8
8
|
## Pending
|
|
9
9
|
|
|
10
10
|
### Medium Priority
|
|
11
|
-
- [ ] B001 — FR-1: GPT Context token counting | Priority: medium
|
|
12
|
-
- [ ] B012 — Arch: add integration tests for brand resolution end-to-end | Priority: medium
|
|
13
|
-
- [ ] B007 — Performance: parallel git/S3 status checks for dam list | Priority: low (unblocked — B020 complete)
|
|
14
11
|
- [ ] B008 — Performance: cache git/S3 status with 5-min TTL | Priority: low
|
|
15
12
|
- [ ] B040 — Fix: ProjectResolver.resolve raises RuntimeError not typed exception (found in B012) | Priority: low
|
|
16
13
|
|
|
@@ -55,6 +52,7 @@
|
|
|
55
52
|
- [x] B010 — UX: terminal-width-aware separator lines + truncate_path in project_listing | Completed: batch-a-features (2026-03-20), v0.77.0
|
|
56
53
|
- [x] B009 — UX: progress indicators for dam S3 operations (upload, download, status, archive, sync-ssd) | Completed: batch-a-features (2026-03-20), v0.77.1
|
|
57
54
|
- [x] B020 — Arch: split S3Operations into S3Base + S3Uploader + S3Downloader + S3StatusChecker + S3Archiver; S3Operations thin facade | Completed: s3-operations-split (2026-03-20), v0.77.6
|
|
55
|
+
- [x] B007 — Performance: parallel git/S3 status checks for dam list (Thread.new per project + per check) | Completed: 2026-03-20, v0.77.7
|
|
58
56
|
|
|
59
57
|
---
|
|
60
58
|
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
module Appydave
|
|
4
4
|
module Tools
|
|
5
|
-
# Build
|
|
6
|
-
module
|
|
5
|
+
# Build LLM context from various sources
|
|
6
|
+
module LlmContext
|
|
7
7
|
# Gathers file names and content based on include and exclude patterns
|
|
8
8
|
class FileCollector
|
|
9
9
|
def initialize(options)
|
|
@@ -13,6 +13,7 @@ module Appydave
|
|
|
13
13
|
@format = options.format
|
|
14
14
|
@working_directory = File.expand_path(options.working_directory)
|
|
15
15
|
@line_limit = options.line_limit
|
|
16
|
+
@file_paths = options.file_paths
|
|
16
17
|
end
|
|
17
18
|
|
|
18
19
|
def build
|
|
@@ -23,6 +24,22 @@ module Appydave
|
|
|
23
24
|
|
|
24
25
|
private
|
|
25
26
|
|
|
27
|
+
def collect_files
|
|
28
|
+
if @file_paths.any?
|
|
29
|
+
# Use file paths directly (from stdin)
|
|
30
|
+
@file_paths.reject { |f| excluded?(f) || File.directory?(f) }
|
|
31
|
+
else
|
|
32
|
+
# Use glob patterns
|
|
33
|
+
files = []
|
|
34
|
+
@include_patterns.each do |pattern|
|
|
35
|
+
Dir.glob(pattern).each do |file_path|
|
|
36
|
+
files << file_path unless excluded?(file_path) || File.directory?(file_path)
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
files
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
26
43
|
def build_formats
|
|
27
44
|
@format.split(',').map do |fmt|
|
|
28
45
|
case fmt
|
|
@@ -38,13 +55,9 @@ module Appydave
|
|
|
38
55
|
def build_content
|
|
39
56
|
concatenated_content = []
|
|
40
57
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
content = "# file: #{file_path}\n\n#{read_file_content(file_path)}"
|
|
46
|
-
concatenated_content << content
|
|
47
|
-
end
|
|
58
|
+
collect_files.each do |file_path|
|
|
59
|
+
content = "# file: #{file_path}\n\n#{read_file_content(file_path)}"
|
|
60
|
+
concatenated_content << content
|
|
48
61
|
end
|
|
49
62
|
|
|
50
63
|
concatenated_content.join("\n\n")
|
|
@@ -60,13 +73,9 @@ module Appydave
|
|
|
60
73
|
def build_tree
|
|
61
74
|
tree_view = {}
|
|
62
75
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
path_parts = file_path.split('/')
|
|
68
|
-
insert_into_tree(tree_view, path_parts)
|
|
69
|
-
end
|
|
76
|
+
collect_files.each do |file_path|
|
|
77
|
+
path_parts = file_path.split('/')
|
|
78
|
+
insert_into_tree(tree_view, path_parts)
|
|
70
79
|
end
|
|
71
80
|
|
|
72
81
|
build_tree_pretty(tree_view).rstrip
|
|
@@ -96,22 +105,14 @@ module Appydave
|
|
|
96
105
|
'content' => []
|
|
97
106
|
}
|
|
98
107
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
next if excluded?(file_path)
|
|
108
|
+
collect_files.each do |file_path|
|
|
109
|
+
path_parts = file_path.split('/')
|
|
110
|
+
insert_into_tree(json_output['tree'], path_parts)
|
|
103
111
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
next if excluded?(file_path) || File.directory?(file_path)
|
|
109
|
-
|
|
110
|
-
json_output['content'] << {
|
|
111
|
-
'file' => file_path,
|
|
112
|
-
'content' => read_file_content(file_path)
|
|
113
|
-
}
|
|
114
|
-
end
|
|
112
|
+
json_output['content'] << {
|
|
113
|
+
'file' => file_path,
|
|
114
|
+
'content' => read_file_content(file_path)
|
|
115
|
+
}
|
|
115
116
|
end
|
|
116
117
|
|
|
117
118
|
JSON.pretty_generate(json_output)
|
|
@@ -120,15 +121,7 @@ module Appydave
|
|
|
120
121
|
def build_aider
|
|
121
122
|
return '' unless @options.prompt
|
|
122
123
|
|
|
123
|
-
files =
|
|
124
|
-
@include_patterns.each do |pattern|
|
|
125
|
-
Dir.glob(pattern).each do |file_path|
|
|
126
|
-
next if excluded?(file_path) || File.directory?(file_path)
|
|
127
|
-
|
|
128
|
-
files << file_path
|
|
129
|
-
end
|
|
130
|
-
end
|
|
131
|
-
|
|
124
|
+
files = collect_files
|
|
132
125
|
"aider --message \"#{@options.prompt}\" #{files.join(' ')}"
|
|
133
126
|
end
|
|
134
127
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
module Appydave
|
|
4
4
|
module Tools
|
|
5
|
-
module
|
|
5
|
+
module LlmContext
|
|
6
6
|
# Struct with keyword_init: true to allow named parameters
|
|
7
7
|
Options = Struct.new(
|
|
8
8
|
:include_patterns,
|
|
@@ -14,6 +14,8 @@ module Appydave
|
|
|
14
14
|
:working_directory,
|
|
15
15
|
:prompt,
|
|
16
16
|
:show_tokens,
|
|
17
|
+
:file_paths,
|
|
18
|
+
:stdin,
|
|
17
19
|
keyword_init: true
|
|
18
20
|
) do
|
|
19
21
|
def initialize(**args)
|
|
@@ -25,6 +27,8 @@ module Appydave
|
|
|
25
27
|
self.output_target ||= []
|
|
26
28
|
self.prompt ||= nil
|
|
27
29
|
self.show_tokens ||= false
|
|
30
|
+
self.file_paths ||= []
|
|
31
|
+
self.stdin ||= false
|
|
28
32
|
end
|
|
29
33
|
end
|
|
30
34
|
end
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
module Appydave
|
|
4
4
|
module Tools
|
|
5
|
-
module
|
|
5
|
+
module LlmContext
|
|
6
6
|
# OutputHandler is responsible for writing the output to the desired target
|
|
7
7
|
class OutputHandler
|
|
8
8
|
def initialize(content, options)
|
|
@@ -16,6 +16,8 @@ module Appydave
|
|
|
16
16
|
case target
|
|
17
17
|
when 'clipboard'
|
|
18
18
|
Clipboard.copy(@content)
|
|
19
|
+
when 'temp'
|
|
20
|
+
write_to_temp
|
|
19
21
|
when /^.+$/
|
|
20
22
|
write_to_file(target)
|
|
21
23
|
end
|
|
@@ -30,6 +32,20 @@ module Appydave
|
|
|
30
32
|
resolved_path = Pathname.new(target).absolute? ? target : File.join(working_directory, target)
|
|
31
33
|
File.write(resolved_path, content)
|
|
32
34
|
end
|
|
35
|
+
|
|
36
|
+
def write_to_temp
|
|
37
|
+
# Create in system temp directory with descriptive name
|
|
38
|
+
tmp_dir = Dir.tmpdir
|
|
39
|
+
timestamp = Time.now.strftime('%Y%m%d-%H%M%S-%N')[0..18] # millisecond precision
|
|
40
|
+
file_path = File.join(tmp_dir, "llm_context-#{timestamp}.txt")
|
|
41
|
+
|
|
42
|
+
# Write content to file
|
|
43
|
+
File.write(file_path, @content)
|
|
44
|
+
|
|
45
|
+
# Copy path to clipboard
|
|
46
|
+
Clipboard.copy(file_path)
|
|
47
|
+
warn "Context saved to: #{file_path}"
|
|
48
|
+
end
|
|
33
49
|
end
|
|
34
50
|
end
|
|
35
51
|
end
|
data/lib/appydave/tools.rb
CHANGED
|
@@ -33,9 +33,9 @@ require 'appydave/tools/cli_actions/prompt_completion_action'
|
|
|
33
33
|
require 'appydave/tools/cli_actions/get_video_action'
|
|
34
34
|
require 'appydave/tools/cli_actions/update_video_action'
|
|
35
35
|
|
|
36
|
-
require 'appydave/tools/
|
|
37
|
-
require 'appydave/tools/
|
|
38
|
-
require 'appydave/tools/
|
|
36
|
+
require 'appydave/tools/llm_context/options'
|
|
37
|
+
require 'appydave/tools/llm_context/file_collector'
|
|
38
|
+
require 'appydave/tools/llm_context/output_handler'
|
|
39
39
|
|
|
40
40
|
require 'appydave/tools/configuration/openai'
|
|
41
41
|
require 'appydave/tools/configuration/configurable'
|
data/package.json
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: appydave-tools
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.79.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- David Cruwys
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-03
|
|
11
|
+
date: 2026-04-03 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: activemodel
|
|
@@ -187,8 +187,8 @@ email:
|
|
|
187
187
|
executables:
|
|
188
188
|
- ad_config
|
|
189
189
|
- dam
|
|
190
|
-
- gpt_context
|
|
191
190
|
- jump
|
|
191
|
+
- llm_context
|
|
192
192
|
- prompt_tools
|
|
193
193
|
- subtitle_processor
|
|
194
194
|
- youtube_automation
|
|
@@ -197,7 +197,6 @@ executables:
|
|
|
197
197
|
extensions: []
|
|
198
198
|
extra_rdoc_files: []
|
|
199
199
|
files:
|
|
200
|
-
- ".DS_Store"
|
|
201
200
|
- ".builders/_.rb"
|
|
202
201
|
- ".builders/boot.rb"
|
|
203
202
|
- ".builders/generators/01-bootstrap.rb"
|
|
@@ -214,6 +213,7 @@ files:
|
|
|
214
213
|
- CHANGELOG.md
|
|
215
214
|
- CLAUDE.md
|
|
216
215
|
- CODE_OF_CONDUCT.md
|
|
216
|
+
- CONTEXT.md
|
|
217
217
|
- Gemfile
|
|
218
218
|
- Guardfile
|
|
219
219
|
- LICENSE.txt
|
|
@@ -225,8 +225,8 @@ files:
|
|
|
225
225
|
- bin/console
|
|
226
226
|
- bin/dam
|
|
227
227
|
- bin/generate_manifest.rb
|
|
228
|
-
- bin/gpt_context.rb
|
|
229
228
|
- bin/jump.rb
|
|
229
|
+
- bin/llm_context.rb
|
|
230
230
|
- bin/move_images.rb
|
|
231
231
|
- bin/prompt_tools.rb
|
|
232
232
|
- bin/setup
|
|
@@ -335,8 +335,8 @@ files:
|
|
|
335
335
|
- docs/uat/FR-3-jump-location-tool.md
|
|
336
336
|
- exe/ad_config
|
|
337
337
|
- exe/dam
|
|
338
|
-
- exe/gpt_context
|
|
339
338
|
- exe/jump
|
|
339
|
+
- exe/llm_context
|
|
340
340
|
- exe/prompt_tools
|
|
341
341
|
- exe/subtitle_processor
|
|
342
342
|
- exe/youtube_automation
|
|
@@ -387,10 +387,6 @@ files:
|
|
|
387
387
|
- lib/appydave/tools/dam/status.rb
|
|
388
388
|
- lib/appydave/tools/dam/sync_from_ssd.rb
|
|
389
389
|
- lib/appydave/tools/debuggable.rb
|
|
390
|
-
- lib/appydave/tools/gpt_context/_doc.md
|
|
391
|
-
- lib/appydave/tools/gpt_context/file_collector.rb
|
|
392
|
-
- lib/appydave/tools/gpt_context/options.rb
|
|
393
|
-
- lib/appydave/tools/gpt_context/output_handler.rb
|
|
394
390
|
- lib/appydave/tools/jump/cli.rb
|
|
395
391
|
- lib/appydave/tools/jump/commands/add.rb
|
|
396
392
|
- lib/appydave/tools/jump/commands/base.rb
|
|
@@ -409,6 +405,10 @@ files:
|
|
|
409
405
|
- lib/appydave/tools/jump/search.rb
|
|
410
406
|
- lib/appydave/tools/llm/models/llm_info.rb
|
|
411
407
|
- lib/appydave/tools/llm/openai_completion.rb
|
|
408
|
+
- lib/appydave/tools/llm_context/_doc.md
|
|
409
|
+
- lib/appydave/tools/llm_context/file_collector.rb
|
|
410
|
+
- lib/appydave/tools/llm_context/options.rb
|
|
411
|
+
- lib/appydave/tools/llm_context/output_handler.rb
|
|
412
412
|
- lib/appydave/tools/name_manager/_doc.md
|
|
413
413
|
- lib/appydave/tools/name_manager/project_name.rb
|
|
414
414
|
- lib/appydave/tools/prompt_tools/_doc.md
|
data/.DS_Store
DELETED
|
Binary file
|