appydave-tools 0.83.0 → 0.84.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7b1472f59045694d5411b4112d3c66c04dfa724197ff9a6caa6fe8dde4437a6a
4
- data.tar.gz: 9088a3cc358367481e06602912df404694af78d5271d2b90458e08ee63dc272c
3
+ metadata.gz: bbde49937db92444ee47416c1fbd53d0cd3ca6c99bc65b30e30a58cf2490facc
4
+ data.tar.gz: 1807239701f53c00bd7e692c51e6792056b2e951d0b71720059fdd5c5fbd4414
5
5
  SHA512:
6
- metadata.gz: 9dd76f56f7e9886dbd88b8ab9a2a4e026abd1ddaad935046c61a9fc7a9b72cbf316edb8fcb3d81889a55833cca273c3e09abee6d066bad035b7337afa823aab5
7
- data.tar.gz: 1c32c5827d8b838d9c4f723ecfc0c4695c6d5189fc0f19401b365ca9c9888f3e57de8a167fdc9ba67edb4dc56d3519207e19df95c3382f9f7d50b3af5eef85c7
6
+ metadata.gz: be1b84a9fb1b45b7377c8cc0e0371f234b5b56e96f23a44f1733e6face17c489a288bd3f8128a5e8548eb09247ff3deffd38144eb6480214b5ba8401406bf022
7
+ data.tar.gz: e3cffdedb85686158bc251361f04b0b2ea44f354f472968efd92bf84c165dd1aa69ca37aa0e1105c191b5f84d70ccccbf0ed7e9418e0e194dbf1a1dceca0bfd8
data/CHANGELOG.md CHANGED
@@ -1,3 +1,15 @@
1
+ # [0.83.0](https://github.com/appydave/appydave-tools/compare/v0.82.0...v0.83.0) (2026-04-04)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * rename format_tokens param n to count to satisfy Naming/MethodParameterName ([e49d615](https://github.com/appydave/appydave-tools/commit/e49d61517a89b05f6c21bd4c5852a3ec59a74a55))
7
+
8
+
9
+ ### Features
10
+
11
+ * add --smart flag for auto-routing output by token size ([a9466e0](https://github.com/appydave/appydave-tools/commit/a9466e059b5164a83902580bbfac5031e3a2dfe3))
12
+
1
13
  # [0.82.0](https://github.com/appydave/appydave-tools/compare/v0.81.0...v0.82.0) (2026-04-04)
2
14
 
3
15
 
@@ -0,0 +1,142 @@
1
+ # FR-NEW: Query Location & App Registry Integration
2
+
3
+ **Status**: Proposed
4
+ **Priority**: Medium
5
+ **Created**: 2026-04-05
6
+ **Relates to**: `query_brain`, `llm_context` pipeline; `locations.json`, `apps.json`
7
+
8
+ ---
9
+
10
+ ## Problem
11
+
12
+ `query_brain` and `llm_context` work well for brain files but have no way to resolve project paths from the existing registries. When a user says "package the FliVideo project for LLM research", there is no single command that:
13
+ 1. Looks up the project path from `locations.json` or `apps.json`
14
+ 2. Knows which file groupings are relevant (docs, code, prompts, tests)
15
+ 3. Feeds those paths directly into `llm_context`
16
+
17
+ Instead, the user must manually look up the path and write the `llm_context` invocation by hand every time.
18
+
19
+ ---
20
+
21
+ ## Proposed Solution
22
+
23
+ ### Option A — `query_location` CLI (preferred)
24
+
25
+ New binary `bin/query_location.rb` that queries `~/.config/appydave/locations.json` and `~/.config/appydave/apps.json` by key, name, type, or brand.
26
+
27
+ ```bash
28
+ # Find a project by key or name
29
+ query_location --find flivideo
30
+ query_location --find ss-prompt
31
+
32
+ # List all products
33
+ query_location --type product
34
+
35
+ # Get path only (for piping)
36
+ query_location --find flivideo --path-only
37
+
38
+ # Get JSON metadata
39
+ query_location --find flivideo --meta
40
+
41
+ # List all apps from apps.json
42
+ query_location --apps
43
+ query_location --apps --status active
44
+ ```
45
+
46
+ Output modes:
47
+ - Default: path on a single line (pipeable to `llm_context`)
48
+ - `--meta`: JSON with key, path, description, type, status
49
+ - `--path-only`: bare path string
50
+
51
+ ### Option B — Extend `jump.rb` with a query subcommand
52
+
53
+ Add `jump.rb query --find flivideo` rather than a new binary. Lower overhead, shares existing location-loading code.
54
+
55
+ **Recommendation**: Option B — reuse `jump.rb` infrastructure, add a `query` subcommand that outputs path/meta. Less surface area, same capability.
56
+
57
+ ---
58
+
59
+ ## File Groupings (Phase 2)
60
+
61
+ Once location lookup works, the second gap is "which files within a project are relevant for LLM research?" Today the user must specify patterns manually.
62
+
63
+ **Proposed**: A `.llm-groups.yaml` sidecar file at the project root declaring named groupings:
64
+
65
+ ```yaml
66
+ # .llm-groups.yaml
67
+ groups:
68
+ docs:
69
+ - "docs/**/*.md"
70
+ - "README.md"
71
+ - "CLAUDE.md"
72
+ code:
73
+ - "lib/**/*.rb"
74
+ - "bin/**/*.rb"
75
+ tests:
76
+ - "spec/**/*.rb"
77
+ prompts:
78
+ - "poem/**/*.json"
79
+ - "poem/**/*.yaml"
80
+ ```
81
+
82
+ Then:
83
+ ```bash
84
+ # Package docs group for LLM
85
+ query_location --find appydave-tools --path-only | xargs -I{} llm_context -b {} --groups docs
86
+
87
+ # Or inline
88
+ llm_context -b ~/dev/ad/appydave-tools --groups docs,code
89
+ ```
90
+
91
+ `llm_context` would read `.llm-groups.yaml` if present and expand the named groupings into `-i` patterns.
92
+
93
+ ---
94
+
95
+ ## Pipeline Vision (Full)
96
+
97
+ ```bash
98
+ # Today (manual, fragile)
99
+ llm_context -b ~/dev/ad/flivideo -i 'lib/**/*.rb' -i 'docs/**/*.md' -f content -o clipboard
100
+
101
+ # After this feature (location-aware)
102
+ query_location --find flivideo --path-only | xargs -I{} llm_context -b {} --groups docs,code -f content -o clipboard
103
+
104
+ # Or shorthand once groups file exists
105
+ llm_context --project flivideo --groups docs -o clipboard
106
+ ```
107
+
108
+ ---
109
+
110
+ ## Acceptance Criteria
111
+
112
+ - [ ] `jump.rb query --find <term>` returns matching location path(s)
113
+ - [ ] `jump.rb query --find <term> --meta` returns JSON with key, path, description, type
114
+ - [ ] `jump.rb query --type product` lists all product locations
115
+ - [ ] Output is pipeable to `llm_context -b`
116
+ - [ ] Apps from `apps.json` are also queryable (or a separate `--apps` flag)
117
+ - [ ] Spec coverage for new query subcommand
118
+
119
+ ### Phase 2 (separate backlog item)
120
+ - [ ] `llm_context` reads `.llm-groups.yaml` and expands `--groups` flag into `-i` patterns
121
+ - [ ] `.llm-groups.yaml` standard defined and documented
122
+ - [ ] At least 3 projects have `.llm-groups.yaml` files (appydave-tools, flivideo, ss-prompt)
123
+
124
+ ---
125
+
126
+ ## Related Systems
127
+
128
+ - `~/.config/appydave/locations.json` — 70+ project locations (source of truth for `jump`)
129
+ - `~/.config/appydave/apps.json` — app registry with ports, start scripts, status
130
+ - `query_brain` — parallel tool for brain files; this is the project equivalent
131
+ - `llm_context` — the consumer; needs paths to operate
132
+ - `system-comprehension-pattern.md` — the pattern that produces the mental model; needs groupings to be useful at scale
133
+ - `appydave:system-context` skill — MISSING skill that generates `CONTEXT.md` per project; relates to Phase 2 groupings
134
+
135
+ ---
136
+
137
+ ## Notes
138
+
139
+ - Do NOT create a separate JSON registry — `locations.json` is already the source of truth
140
+ - The `jump` skill already knows about `locations.json`; extending `jump.rb` keeps things consistent
141
+ - Phase 2 (`.llm-groups.yaml`) is the real value unlock — Phase 1 is just plumbing
142
+ - This feature is what enables the "package project X for LLM research" workflow without manual path lookup every time
@@ -0,0 +1,107 @@
1
+ # Gap Analysis: system-context vs system-comprehension-pattern
2
+
3
+ **Context**: The `CONTEXT.md` file in this repo was generated by `/appydave:system-context` — a skill
4
+ that doesn't yet exist in appydave-plugins. This note compares what that skill *produced* (the output)
5
+ against the `system-comprehension-pattern.md` in the prompt-patterns brain to assess the gap.
6
+
7
+ **Created**: 2026-04-05
8
+
9
+ ---
10
+
11
+ ## What system-context Produced (CONTEXT.md output)
12
+
13
+ Looking at `CONTEXT.md` (generated 2026-04-03), the skill produced:
14
+
15
+ ```yaml
16
+ # Frontmatter
17
+ generated: 2026-04-03
18
+ generator: system-context
19
+ status: snapshot
20
+ sources: [README.md, gemspec, lib/tools.rb, brand_resolver.rb, project_resolver.rb, jump/commands/generate.rb, docs/dam/batch-s3-listing-requirements.md, CHANGELOG.md (versions 0.76.0-0.77.7)]
21
+ regenerate: "Run /appydave:system-context in the repo root"
22
+ ```
23
+
24
+ Sections produced:
25
+ 1. **Purpose** — one sentence
26
+ 2. **Domain Concepts** — key vocabulary (Brand, Project, DAM, Project Naming, Configuration, Multi-channel)
27
+ 3. **Design Decisions** — 6 decisions with rationale
28
+ 4. **Scope Limits** — 6 explicit "does NOT" statements
29
+
30
+ ---
31
+
32
+ ## What system-comprehension-pattern Produces (Level 1)
33
+
34
+ The 8-dimension Level 1 prompt produces:
35
+
36
+ 1. REAL PURPOSE — pain solved, world without it
37
+ 2. MENTAL MODEL — central metaphor or abstraction
38
+ 3. CORE ABSTRACTIONS — 3-5 building blocks and how they relate
39
+ 4. KEY WORKFLOWS — 2-4 end-to-end workflows (intent → outcome, not API calls)
40
+ 5. DESIGN DECISIONS — why it's built this way, alternatives considered
41
+ 6. NON-OBVIOUS CONSTRAINTS — things that look like they should work but don't
42
+ 7. EXPERT VS BEGINNER — mental shift from competent to expert
43
+ 8. SCOPE LIMITS — explicit non-scope + what handles those things instead
44
+
45
+ ---
46
+
47
+ ## Gap Analysis
48
+
49
+ | Dimension | system-context | system-comprehension Level 1 |
50
+ |-----------|---------------|------------------------------|
51
+ | Purpose / Real problem | ✅ One sentence | ✅ Full explanation + "world without it" |
52
+ | Domain concepts / Core abstractions | ✅ Reasonable depth | ✅ Richer — explains relationships between concepts |
53
+ | Mental model / Central metaphor | ❌ Not present | ✅ The central "how does the system think?" question |
54
+ | Key workflows | ❌ Not present | ✅ End-to-end workflows (intent → outcome) |
55
+ | Design decisions | ✅ Good — 6 decisions with rationale | ✅ Same coverage + alternatives considered |
56
+ | Non-obvious constraints | ❌ Not present | ✅ The "looks like it should work but doesn't" list |
57
+ | Expert vs beginner mental shift | ❌ Not present | ✅ The hardest thing to get from docs |
58
+ | Scope limits | ✅ Good — 6 explicit "does NOT" statements | ✅ Same + what handles those things instead |
59
+
60
+ **Score: system-context covers ~4/8 dimensions well. Missing the 4 that are hardest to get from docs.**
61
+
62
+ ---
63
+
64
+ ## The Core Gap
65
+
66
+ `system-context` is essentially an **automated documentation snapshot** — it reads source files and
67
+ produces a structured summary. It does this well and efficiently (no LLM needed, or minimal).
68
+
69
+ `system-comprehension-pattern` Level 1 is a **mental model prompt** — it produces reasoning about the
70
+ system, not just facts about it. The 4 missing dimensions (mental model, key workflows, non-obvious
71
+ constraints, expert vs beginner) are precisely the things that make a reasoning partner vs a fact retriever.
72
+
73
+ **Practical implication**: `CONTEXT.md` is useful as orientation context for an LLM session. But an LLM
74
+ given only `CONTEXT.md` would produce competent-but-generic answers. An LLM given the Level 1
75
+ comprehension output would produce expert-level, system-aware answers.
76
+
77
+ ---
78
+
79
+ ## What This Means for the system-context Skill (when built)
80
+
81
+ When `/appydave:system-context` is built as a proper skill, it should:
82
+
83
+ 1. **Keep what works**: automated extraction of purpose, domain concepts, design decisions, scope limits
84
+ (these come from README, gemspec, source files — no deep reasoning needed)
85
+
86
+ 2. **Add what's missing**: either
87
+ - Prompt the LLM to produce the missing 4 dimensions as part of the generation
88
+ - Or leave a `## Pending Comprehension` section flagging that Level 1 comprehension hasn't been run
89
+
90
+ 3. **Add a query_brain groupings block** — this is the new gap not in either system:
91
+ ```yaml
92
+ llm_groups:
93
+ docs: ["docs/**/*.md", "README.md", "CLAUDE.md"]
94
+ code: ["lib/**/*.rb", "bin/**/*.rb"]
95
+ tests: ["spec/**/*.rb"]
96
+ ```
97
+ So that `llm_context --project appydave-tools --groups docs` works without manual pattern entry.
98
+
99
+ ---
100
+
101
+ ## Recommendation
102
+
103
+ - **`system-context` as-is**: Good for quick onboarding context. Use it.
104
+ - **Before deep work**: Also run Level 1 comprehension from `system-comprehension-pattern.md` and append
105
+ the output to `CONTEXT.md` or keep it in a separate `COMPREHENSION.md`.
106
+ - **Long-term**: Build the `system-context` skill to include LLM-driven comprehension + groupings block.
107
+ The skill that produces `CONTEXT.md` should be the same skill that makes the project queryable.
@@ -54,6 +54,8 @@ module Appydave
54
54
  run_remove(args)
55
55
  when 'validate'
56
56
  run_validate(args)
57
+ when 'query'
58
+ run_query(args)
57
59
  when 'report'
58
60
  run_report(args)
59
61
  when 'generate'
@@ -128,6 +130,35 @@ module Appydave
128
130
  exit_code_for(result)
129
131
  end
130
132
 
133
+ def run_query(args)
134
+ meta_mode = args.delete('--meta')
135
+
136
+ find_terms = extract_multi_option(args, '--find')
137
+ type_filter = extract_option(args, '--type')
138
+ brand_filter = extract_option(args, '--brand')
139
+ args.delete('--path-only')
140
+
141
+ cmd = Commands::Query.new(
142
+ load_config,
143
+ find: find_terms,
144
+ type: type_filter,
145
+ brand: brand_filter
146
+ )
147
+ result = cmd.run
148
+
149
+ if result[:success]
150
+ if meta_mode
151
+ format_output(result, 'json')
152
+ else
153
+ format_output(result, 'paths')
154
+ end
155
+ else
156
+ warn result[:error]
157
+ end
158
+
159
+ exit_code_for(result)
160
+ end
161
+
131
162
  def run_get(args)
132
163
  format = format_option(args)
133
164
  key = args.first
@@ -350,6 +381,20 @@ module Appydave
350
381
  attrs
351
382
  end
352
383
 
384
+ def extract_multi_option(args, flag)
385
+ values = []
386
+ loop do
387
+ index = args.index(flag)
388
+ break unless index
389
+
390
+ value = args[index + 1]
391
+ args.delete_at(index + 1)
392
+ args.delete_at(index)
393
+ values << value if value
394
+ end
395
+ values
396
+ end
397
+
353
398
  def extract_option(args, flag)
354
399
  index = args.index(flag)
355
400
  return nil unless index
@@ -407,6 +452,7 @@ module Appydave
407
452
  search <terms> Fuzzy search across all location metadata
408
453
  get <key> Get location by exact key
409
454
  list List all locations
455
+ query Scriptable location lookup (pipeline-friendly)
410
456
 
411
457
  CRUD Operations:
412
458
  add Add a new location
@@ -445,6 +491,8 @@ module Appydave
445
491
  topic = args.first
446
492
 
447
493
  case topic
494
+ when 'query'
495
+ show_query_help
448
496
  when 'search'
449
497
  show_search_help
450
498
  when 'add'
@@ -464,6 +512,36 @@ module Appydave
464
512
  end
465
513
  end
466
514
 
515
+ def show_query_help
516
+ output.puts <<~HELP
517
+ jump query - Scriptable location lookup (pipeline-friendly)
518
+
519
+ Usage: jump query [--find <term>] [--type <type>] [--brand <brand>] [--path-only|--meta]
520
+
521
+ Filters (all are AND-combined):
522
+ --find <term> Match term against key, name, brand, type, tags, description
523
+ Repeat for AND logic: --find appydave --find ruby
524
+ --type <type> Filter by location type (e.g. tool, gem, product)
525
+ --brand <brand> Filter by brand (e.g. appydave, flivideo)
526
+
527
+ Output modes:
528
+ (default) One path per line — pipeable (same as --path-only)
529
+ --path-only Explicit path-per-line mode
530
+ --meta JSON array with key, path, description, type, brand, status
531
+
532
+ Exit codes:
533
+ 0 Matches found
534
+ 1 No matches (NOT_FOUND)
535
+
536
+ Examples:
537
+ jump query --find flivideo
538
+ jump query --find flivideo --meta
539
+ jump query --type tool
540
+ jump query --find appydave --type tool
541
+ jump query --find flivideo | xargs llm_context -b
542
+ HELP
543
+ end
544
+
467
545
  def show_search_help
468
546
  output.puts <<~HELP
469
547
  jump search - Fuzzy search locations
@@ -0,0 +1,112 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Appydave
4
+ module Tools
5
+ module Jump
6
+ module Commands
7
+ # Query command provides scriptable location lookup
8
+ #
9
+ # Designed for pipeline use — default output is bare paths, one per line.
10
+ # Use --meta for structured JSON output.
11
+ #
12
+ # @example Find by term
13
+ # cmd = Commands::Query.new(config, find: ['flivideo'])
14
+ # result = cmd.run
15
+ # result[:results] # => Array of matching location hashes
16
+ #
17
+ # @example Filter by type
18
+ # cmd = Commands::Query.new(config, type: 'product')
19
+ # result = cmd.run
20
+ class Query < Base
21
+ attr_reader :find_terms, :type_filter, :brand_filter
22
+
23
+ def initialize(config, **options)
24
+ super
25
+ @find_terms = Array(options[:find]).map { |t| t.to_s.downcase.strip }.reject(&:empty?)
26
+ @type_filter = normalize_option(options[:type])
27
+ @brand_filter = normalize_option(options[:brand])
28
+ end
29
+
30
+ def run
31
+ matches = config.locations.select { |loc| matches?(loc) }
32
+
33
+ if matches.empty?
34
+ return error_result(
35
+ 'No locations found matching the given criteria',
36
+ code: 'NOT_FOUND'
37
+ )
38
+ end
39
+
40
+ results = matches.map.with_index(1) do |location, index|
41
+ location_to_result(location, index)
42
+ end
43
+
44
+ success_result(
45
+ count: results.size,
46
+ results: results
47
+ )
48
+ end
49
+
50
+ private
51
+
52
+ def matches?(location)
53
+ return false if type_filter && location.type&.downcase != type_filter
54
+ return false if brand_filter && location.brand&.downcase != brand_filter
55
+ return false unless find_terms_match?(location)
56
+
57
+ true
58
+ end
59
+
60
+ def find_terms_match?(location)
61
+ return true if find_terms.empty?
62
+
63
+ # All find terms must match (AND logic) — each term matches if it appears
64
+ # in any of the searchable fields of the location
65
+ find_terms.all? { |term| term_matches_location?(term, location) }
66
+ end
67
+
68
+ def term_matches_location?(term, location)
69
+ fields = [
70
+ location.key,
71
+ location.type,
72
+ location.brand,
73
+ location.client,
74
+ location.description,
75
+ location.path
76
+ ].compact.map(&:downcase)
77
+
78
+ tag_fields = location.tags.map(&:downcase)
79
+
80
+ fields.any? { |f| f.include?(term) } || tag_fields.any? { |t| t.include?(term) }
81
+ end
82
+
83
+ def normalize_option(value)
84
+ return nil unless value
85
+
86
+ value.to_s.downcase.strip
87
+ end
88
+
89
+ def location_to_result(location, index)
90
+ {
91
+ index: index,
92
+ key: location.key,
93
+ path: expand_path(location.path),
94
+ description: location.description,
95
+ type: location.type,
96
+ brand: location.brand,
97
+ client: location.client,
98
+ tags: location.tags,
99
+ status: 'active'
100
+ }.compact
101
+ end
102
+
103
+ def expand_path(path)
104
+ return path unless path
105
+
106
+ File.expand_path(path)
107
+ end
108
+ end
109
+ end
110
+ end
111
+ end
112
+ end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Appydave
4
4
  module Tools
5
- VERSION = '0.83.0'
5
+ VERSION = '0.84.0'
6
6
  end
7
7
  end
@@ -109,6 +109,7 @@ require 'appydave/tools/jump/commands/remove'
109
109
  require 'appydave/tools/jump/commands/validate'
110
110
  require 'appydave/tools/jump/commands/report'
111
111
  require 'appydave/tools/jump/commands/generate'
112
+ require 'appydave/tools/jump/commands/query'
112
113
  require 'appydave/tools/jump/cli'
113
114
 
114
115
  require 'appydave/tools/youtube_manager/models/youtube_details'
data/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "appydave-tools",
3
- "version": "0.83.0",
3
+ "version": "0.84.0",
4
4
  "description": "AppyDave YouTube Automation Tools",
5
5
  "scripts": {
6
6
  "release": "semantic-release"
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.83.0
4
+ version: 0.84.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-04-04 00:00:00.000000000 Z
11
+ date: 2026-04-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activemodel
@@ -329,6 +329,8 @@ files:
329
329
  - docs/planning/micro-cleanup/AGENTS.md
330
330
  - docs/planning/micro-cleanup/IMPLEMENTATION_PLAN.md
331
331
  - docs/planning/micro-cleanup/assessment.md
332
+ - docs/planning/query-location-feature/IMPLEMENTATION_PLAN.md
333
+ - docs/planning/query-location-feature/system-context-gap-analysis.md
332
334
  - docs/planning/s3-operations-split/AGENTS.md
333
335
  - docs/planning/s3-operations-split/IMPLEMENTATION_PLAN.md
334
336
  - docs/planning/test-coverage-gaps/AGENTS.md
@@ -404,6 +406,7 @@ files:
404
406
  - lib/appydave/tools/jump/commands/add.rb
405
407
  - lib/appydave/tools/jump/commands/base.rb
406
408
  - lib/appydave/tools/jump/commands/generate.rb
409
+ - lib/appydave/tools/jump/commands/query.rb
407
410
  - lib/appydave/tools/jump/commands/remove.rb
408
411
  - lib/appydave/tools/jump/commands/report.rb
409
412
  - lib/appydave/tools/jump/commands/update.rb