appydave-tools 0.79.0 → 0.80.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 +7 -0
- data/bin/query_brain.rb +65 -0
- data/bin/query_omi.rb +71 -0
- data/exe/query_brain +7 -0
- data/exe/query_omi +7 -0
- data/lib/appydave/tools/brain_context/brain_finder.rb +165 -0
- data/lib/appydave/tools/brain_context/omi_finder.rb +153 -0
- data/lib/appydave/tools/brain_context/options.rb +57 -0
- data/lib/appydave/tools/version.rb +1 -1
- data/lib/appydave/tools.rb +4 -0
- data/package.json +1 -1
- metadata +10 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: cb0b711e430f2082be55712eb0c3e630726bcc77628dc8ab144d72f27fc05bd7
|
|
4
|
+
data.tar.gz: 8fc9be5413601f6da5cccd649d324578df676efb842b138623998a1f6dd7b676
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: d7527c25930ba5fb35206e6321fea074f12593a9188ed4b7d51f1f832f01f60a9929336b8670bf48bea0f68eeba0df150ecb542ea244be899334781ef432a7a1
|
|
7
|
+
data.tar.gz: 051f6c24d48fa6caa2ac342436a1105403d7524e871ee248996b772e0e16aafde612cd33386d4b6bba92b5f1f0c2e2f6cf61406e9f76db5a42e55d367031c642
|
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
# [0.79.0](https://github.com/appydave/appydave-tools/compare/v0.78.0...v0.79.0) (2026-04-03)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Features
|
|
5
|
+
|
|
6
|
+
* add --stdin support to llm_context for piping file paths ([8890cfe](https://github.com/appydave/appydave-tools/commit/8890cfebb80cfda81b679da3e52a185bbb1c9141))
|
|
7
|
+
|
|
1
8
|
# [0.78.0](https://github.com/appydave/appydave-tools/compare/v0.77.7...v0.78.0) (2026-04-03)
|
|
2
9
|
|
|
3
10
|
|
data/bin/query_brain.rb
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
$LOAD_PATH.unshift(File.expand_path('../lib', __dir__))
|
|
5
|
+
require 'appydave/tools'
|
|
6
|
+
|
|
7
|
+
options = Appydave::Tools::BrainContextOptions.new
|
|
8
|
+
|
|
9
|
+
def setup_options(options)
|
|
10
|
+
OptionParser.new do |opts| # rubocop:disable Metrics/BlockLength
|
|
11
|
+
opts.banner = 'Usage: query_brain [options]'
|
|
12
|
+
|
|
13
|
+
opts.on('--brain NAME', 'Query brain by name, alias, or fuzzy match') do |name|
|
|
14
|
+
options.brain_names << name
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
opts.on('--tag TAG', 'Query brains by tag') do |tag|
|
|
18
|
+
options.tags << tag
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
opts.on('--category CAT', 'Query all brains in category') do |cat|
|
|
22
|
+
options.categories << cat
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
opts.on('--activity-min LEVEL', %w[high medium low none],
|
|
26
|
+
'Filter brains by minimum activity level') do |level|
|
|
27
|
+
options.activity_levels << level
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
opts.on('--status STATUS', %w[active stable deprecated],
|
|
31
|
+
'Filter brains by status (default: exclude deprecated)') do |status|
|
|
32
|
+
options.status = status
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
opts.on('--files-only', 'Exclude INDEX.md, only include content files') do
|
|
36
|
+
options.include_index = false
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
opts.on('-d', '--debug [MODE]', %w[none info params debug],
|
|
40
|
+
'Debug output level') do |level|
|
|
41
|
+
options.debug_level = level || 'info'
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
opts.on('-v', '--version', 'Show version') do
|
|
45
|
+
puts "query_brain v#{Appydave::Tools::VERSION}"
|
|
46
|
+
exit 0
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
opts.on('-h', '--help', 'Show this message') do
|
|
50
|
+
puts opts
|
|
51
|
+
exit 0
|
|
52
|
+
end
|
|
53
|
+
end.parse!
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
setup_options(options)
|
|
57
|
+
|
|
58
|
+
# Query
|
|
59
|
+
finder = Appydave::Tools::BrainQuery.new(options)
|
|
60
|
+
paths = finder.find
|
|
61
|
+
|
|
62
|
+
# Output file paths, one per line
|
|
63
|
+
paths.each { |p| puts p }
|
|
64
|
+
|
|
65
|
+
exit 0
|
data/bin/query_omi.rb
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
$LOAD_PATH.unshift(File.expand_path('../lib', __dir__))
|
|
5
|
+
require 'appydave/tools'
|
|
6
|
+
|
|
7
|
+
options = Appydave::Tools::BrainContextOptions.new
|
|
8
|
+
options.omi = true
|
|
9
|
+
|
|
10
|
+
def setup_options(options)
|
|
11
|
+
OptionParser.new do |opts| # rubocop:disable Metrics/BlockLength
|
|
12
|
+
opts.banner = 'Usage: query_omi [options]'
|
|
13
|
+
|
|
14
|
+
opts.on('--signal SIGNAL', %w[work life ambient],
|
|
15
|
+
'Filter by signal') do |signal|
|
|
16
|
+
options.omi_signals << signal
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
opts.on('--routing ROUTING',
|
|
20
|
+
'Filter by routing (brain-update, todo-item, personal, til, archive; pipe-delimited)') do |routing|
|
|
21
|
+
options.omi_routings.concat(routing.split('|').map(&:strip))
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
opts.on('--activity ACTIVITY',
|
|
25
|
+
'Filter by activity (planning, reviewing, learning, debugging, etc.; pipe-delimited)') do |activity|
|
|
26
|
+
options.omi_activities.concat(activity.split('|').map(&:strip))
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
opts.on('--date-from DATE', 'Include files from date (YYYY-MM-DD)') do |date|
|
|
30
|
+
options.date_from = date
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
opts.on('--date-to DATE', 'Include files up to date (YYYY-MM-DD)') do |date|
|
|
34
|
+
options.date_to = date
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
opts.on('--enriched-only', 'Skip raw (non-enriched) transcripts') do
|
|
38
|
+
options.enriched_only = true
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
opts.on('--brain NAME', 'Find OMI files mentioning this brain') do |name|
|
|
42
|
+
options.brain_names << name
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
opts.on('-d', '--debug [MODE]', %w[none info params debug],
|
|
46
|
+
'Debug output level') do |level|
|
|
47
|
+
options.debug_level = level || 'info'
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
opts.on('-v', '--version', 'Show version') do
|
|
51
|
+
puts "query_omi v#{Appydave::Tools::VERSION}"
|
|
52
|
+
exit 0
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
opts.on('-h', '--help', 'Show this message') do
|
|
56
|
+
puts opts
|
|
57
|
+
exit 0
|
|
58
|
+
end
|
|
59
|
+
end.parse!
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
setup_options(options)
|
|
63
|
+
|
|
64
|
+
# Query
|
|
65
|
+
finder = Appydave::Tools::OmiQuery.new(options)
|
|
66
|
+
paths = finder.find
|
|
67
|
+
|
|
68
|
+
# Output file paths, one per line
|
|
69
|
+
paths.each { |p| puts p }
|
|
70
|
+
|
|
71
|
+
exit 0
|
data/exe/query_brain
ADDED
data/exe/query_omi
ADDED
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'json'
|
|
4
|
+
|
|
5
|
+
module Appydave
|
|
6
|
+
module Tools
|
|
7
|
+
# Queries brains-index.json to find brain files
|
|
8
|
+
class BrainQuery
|
|
9
|
+
def initialize(options)
|
|
10
|
+
@options = options
|
|
11
|
+
@index = nil
|
|
12
|
+
@alias_map = nil
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def find
|
|
16
|
+
return [] unless @options.brain_query?
|
|
17
|
+
|
|
18
|
+
load_index!
|
|
19
|
+
paths = []
|
|
20
|
+
|
|
21
|
+
# Handle brain name queries
|
|
22
|
+
@options.brain_names.each do |name|
|
|
23
|
+
paths.concat(find_by_name(name))
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# Handle tag queries
|
|
27
|
+
@options.tags.each do |tag|
|
|
28
|
+
paths.concat(find_by_tag(tag))
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# Handle category queries
|
|
32
|
+
@options.categories.each do |category|
|
|
33
|
+
paths.concat(find_by_category(category))
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# Handle activity level filters
|
|
37
|
+
paths.select! { |p| matches_activity_level?(p) } if @options.activity_levels.any?
|
|
38
|
+
|
|
39
|
+
# Remove duplicates and return
|
|
40
|
+
paths.uniq.sort
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
private
|
|
44
|
+
|
|
45
|
+
def load_index!
|
|
46
|
+
return if @index
|
|
47
|
+
|
|
48
|
+
index_path = @options.brains_index_path
|
|
49
|
+
unless File.exist?(index_path)
|
|
50
|
+
raise "brains-index.json not found at #{index_path}. Run: python ~/dev/ad/brains/.claude/skills/brain-librarian/scripts/build_brain_index.py build --all ~/dev/ad/brains"
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
@index = JSON.parse(File.read(index_path))
|
|
54
|
+
build_alias_map!
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def build_alias_map!
|
|
58
|
+
@alias_map = {}
|
|
59
|
+
@index['alias_index']&.each { |alias_name, brain_name| @alias_map[alias_name.downcase] = brain_name }
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def find_by_name(name)
|
|
63
|
+
load_index!
|
|
64
|
+
|
|
65
|
+
# Step 1: Exact match on brain key
|
|
66
|
+
brain_entry = find_brain_in_index(name)
|
|
67
|
+
return brain_entries_to_paths([brain_entry]) if brain_entry
|
|
68
|
+
|
|
69
|
+
# Step 2: Alias match
|
|
70
|
+
if @alias_map && @alias_map[name.downcase]
|
|
71
|
+
brain_name = @alias_map[name.downcase]
|
|
72
|
+
brain_entry = find_brain_in_index(brain_name)
|
|
73
|
+
return brain_entries_to_paths([brain_entry]) if brain_entry
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
# Step 3: Substring match on brain key (case-insensitive)
|
|
77
|
+
matches = []
|
|
78
|
+
@index['categories'].each_value do |category_data|
|
|
79
|
+
category_data['brains'].each do |brain_name, brain_data|
|
|
80
|
+
matches << brain_data if brain_name.downcase.include?(name.downcase)
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
return brain_entries_to_paths(matches) if matches.length == 1
|
|
84
|
+
return brain_entries_to_paths(matches) if matches.any?
|
|
85
|
+
|
|
86
|
+
# Not found
|
|
87
|
+
[]
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def find_by_tag(tag)
|
|
91
|
+
load_index!
|
|
92
|
+
tag = tag.downcase.gsub('_', '-')
|
|
93
|
+
|
|
94
|
+
brain_names = @index['tag_index']&.[](tag) || []
|
|
95
|
+
brain_entries = []
|
|
96
|
+
|
|
97
|
+
brain_names.each do |brain_name|
|
|
98
|
+
entry = find_brain_in_index(brain_name)
|
|
99
|
+
brain_entries << entry if entry
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
brain_entries_to_paths(brain_entries)
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
def find_by_category(category)
|
|
106
|
+
load_index!
|
|
107
|
+
category_data = @index['categories'][category] || @index['categories'][category.downcase]
|
|
108
|
+
|
|
109
|
+
return [] unless category_data
|
|
110
|
+
|
|
111
|
+
brain_entries = category_data['brains'].values
|
|
112
|
+
brain_entries_to_paths(brain_entries)
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
def find_brain_in_index(brain_name)
|
|
116
|
+
@index['categories'].each_value do |category_data|
|
|
117
|
+
return category_data['brains'][brain_name] if category_data['brains'][brain_name]
|
|
118
|
+
end
|
|
119
|
+
nil
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
def brain_entries_to_paths(brain_entries)
|
|
123
|
+
paths = []
|
|
124
|
+
|
|
125
|
+
brain_entries.each do |entry|
|
|
126
|
+
next unless entry
|
|
127
|
+
|
|
128
|
+
# Add files from files[] array
|
|
129
|
+
entry['files']&.each do |file|
|
|
130
|
+
# File entry is relative to the brain directory
|
|
131
|
+
brain_name = extract_brain_name(entry)
|
|
132
|
+
full_path = File.join(@options.brains_root, brain_name, file)
|
|
133
|
+
paths << full_path if File.exist?(full_path)
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
# Add INDEX.md if requested
|
|
137
|
+
if @options.include_index
|
|
138
|
+
index_path = File.join(@options.brains_root, entry['index_path'])
|
|
139
|
+
paths << index_path if File.exist?(index_path)
|
|
140
|
+
end
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
paths
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
def extract_brain_name(entry)
|
|
147
|
+
# index_path is like "brain-name/INDEX.md"
|
|
148
|
+
entry['index_path'].split('/')[0]
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
def matches_activity_level?(file_path)
|
|
152
|
+
# Extract brain name from path
|
|
153
|
+
brain_name = file_path.match(%r{#{Regexp.escape(@options.brains_root)}/([^/]+)})&.[](1)
|
|
154
|
+
return false unless brain_name
|
|
155
|
+
|
|
156
|
+
# Find the brain entry
|
|
157
|
+
entry = find_brain_in_index(brain_name)
|
|
158
|
+
return false unless entry
|
|
159
|
+
|
|
160
|
+
# Check if activity level matches filter
|
|
161
|
+
@options.activity_levels.include?(entry['activity_level'])
|
|
162
|
+
end
|
|
163
|
+
end
|
|
164
|
+
end
|
|
165
|
+
end
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'date'
|
|
4
|
+
|
|
5
|
+
module Appydave
|
|
6
|
+
module Tools
|
|
7
|
+
# Queries OMI transcript directory by enriched frontmatter
|
|
8
|
+
class OmiQuery
|
|
9
|
+
def initialize(options)
|
|
10
|
+
@options = options
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def find
|
|
14
|
+
return [] unless @options.omi_query?
|
|
15
|
+
|
|
16
|
+
paths = []
|
|
17
|
+
|
|
18
|
+
Dir.glob(File.join(@options.omi_dir, '*.md')).each do |file_path|
|
|
19
|
+
next unless include_file?(file_path)
|
|
20
|
+
|
|
21
|
+
paths << file_path
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
paths.sort
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
private
|
|
28
|
+
|
|
29
|
+
def include_file?(file_path)
|
|
30
|
+
frontmatter = extract_frontmatter(file_path)
|
|
31
|
+
return false unless frontmatter
|
|
32
|
+
|
|
33
|
+
# If enriched-only requested, skip raw files
|
|
34
|
+
return false if @options.enriched_only && (!frontmatter['signal'] || !frontmatter['extraction_summary'])
|
|
35
|
+
|
|
36
|
+
# Apply filters
|
|
37
|
+
return false unless signal_matches?(frontmatter)
|
|
38
|
+
return false unless routing_matches?(frontmatter)
|
|
39
|
+
return false unless activity_matches?(frontmatter)
|
|
40
|
+
return false unless date_matches?(frontmatter)
|
|
41
|
+
return false unless brain_matches?(frontmatter)
|
|
42
|
+
|
|
43
|
+
true
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def extract_frontmatter(file_path)
|
|
47
|
+
content = File.read(file_path, encoding: 'utf-8')
|
|
48
|
+
lines = content.split("\n")
|
|
49
|
+
|
|
50
|
+
return nil unless lines[0] == '---'
|
|
51
|
+
|
|
52
|
+
frontmatter = {}
|
|
53
|
+
i = 1
|
|
54
|
+
while i < lines.length
|
|
55
|
+
line = lines[i]
|
|
56
|
+
break if line == '---'
|
|
57
|
+
|
|
58
|
+
# Parse YAML-like: key: value
|
|
59
|
+
if line.match?(/^[a-z_]+:/)
|
|
60
|
+
key, value = parse_yaml_line(line)
|
|
61
|
+
frontmatter[key] = value
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
i += 1
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
frontmatter.empty? ? nil : frontmatter
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def parse_yaml_line(line)
|
|
71
|
+
# Handle simple cases: key: value, key: [a, b, c]
|
|
72
|
+
match = line.match(/^([a-z_]+):\s*(.*)$/)
|
|
73
|
+
return [nil, nil] unless match
|
|
74
|
+
|
|
75
|
+
key = match[1]
|
|
76
|
+
value_str = match[2].strip
|
|
77
|
+
|
|
78
|
+
# Parse array [a, b, c]
|
|
79
|
+
if value_str.start_with?('[') && value_str.end_with?(']')
|
|
80
|
+
array_content = value_str[1..-2]
|
|
81
|
+
value = array_content.split(',').map { |v| v.strip.gsub(/^["']|["']$/, '') }
|
|
82
|
+
# Parse quoted string
|
|
83
|
+
elsif (value_str.start_with?('"') && value_str.end_with?('"')) ||
|
|
84
|
+
(value_str.start_with?("'") && value_str.end_with?("'"))
|
|
85
|
+
value = value_str[1..-2]
|
|
86
|
+
# Parse date (YYYY-MM-DD) or other values as-is
|
|
87
|
+
else
|
|
88
|
+
value = value_str
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
[key, value]
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def signal_matches?(frontmatter)
|
|
95
|
+
return true if @options.omi_signals.empty?
|
|
96
|
+
|
|
97
|
+
signal = frontmatter['signal']
|
|
98
|
+
return false unless signal
|
|
99
|
+
|
|
100
|
+
@options.omi_signals.include?(signal)
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def routing_matches?(frontmatter)
|
|
104
|
+
return true if @options.omi_routings.empty?
|
|
105
|
+
|
|
106
|
+
routing = frontmatter['routing']
|
|
107
|
+
return false unless routing
|
|
108
|
+
|
|
109
|
+
# routing can be pipe-delimited
|
|
110
|
+
routings = routing.split('|').map(&:strip)
|
|
111
|
+
routings.any? { |r| @options.omi_routings.include?(r) }
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
def activity_matches?(frontmatter)
|
|
115
|
+
return true if @options.omi_activities.empty?
|
|
116
|
+
|
|
117
|
+
activity = frontmatter['activity']
|
|
118
|
+
return false unless activity
|
|
119
|
+
|
|
120
|
+
# activity can be pipe-delimited
|
|
121
|
+
activities = activity.split('|').map(&:strip)
|
|
122
|
+
activities.any? { |a| @options.omi_activities.include?(a) }
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
def date_matches?(frontmatter)
|
|
126
|
+
extracted_at = frontmatter['extracted_at']
|
|
127
|
+
return true if extracted_at.nil? # No date field = include
|
|
128
|
+
|
|
129
|
+
begin
|
|
130
|
+
date = Date.parse(extracted_at)
|
|
131
|
+
rescue StandardError
|
|
132
|
+
return true # Can't parse = include
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
from_ok = @options.date_from.nil? || date >= Date.parse(@options.date_from)
|
|
136
|
+
to_ok = @options.date_to.nil? || date <= Date.parse(@options.date_to)
|
|
137
|
+
|
|
138
|
+
from_ok && to_ok
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
def brain_matches?(frontmatter)
|
|
142
|
+
return true if @options.brain_names.empty?
|
|
143
|
+
|
|
144
|
+
matched_brains = frontmatter['matched_brains']
|
|
145
|
+
return false unless matched_brains
|
|
146
|
+
|
|
147
|
+
# matched_brains is an array
|
|
148
|
+
matched_brains_list = matched_brains.is_a?(Array) ? matched_brains : [matched_brains]
|
|
149
|
+
matched_brains_list.any? { |brain| @options.brain_names.include?(brain) }
|
|
150
|
+
end
|
|
151
|
+
end
|
|
152
|
+
end
|
|
153
|
+
end
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Appydave
|
|
4
|
+
module Tools
|
|
5
|
+
# Options struct for brain/OMI query tools
|
|
6
|
+
class BrainContextOptions
|
|
7
|
+
attr_accessor :brain_names, :tags, :categories, :activity_levels, :status,
|
|
8
|
+
:omi, :omi_signals, :omi_routings, :omi_activities,
|
|
9
|
+
:date_from, :date_to, :enriched_only,
|
|
10
|
+
:include_index, :output_targets, :formats, :line_limit,
|
|
11
|
+
:debug_level, :dry_run, :tokens, :base_dir, :omi_dir
|
|
12
|
+
|
|
13
|
+
def initialize
|
|
14
|
+
@brain_names = []
|
|
15
|
+
@tags = []
|
|
16
|
+
@categories = []
|
|
17
|
+
@activity_levels = []
|
|
18
|
+
@status = 'active' # default: exclude deprecated
|
|
19
|
+
|
|
20
|
+
@omi = false
|
|
21
|
+
@omi_signals = []
|
|
22
|
+
@omi_routings = []
|
|
23
|
+
@omi_activities = []
|
|
24
|
+
@date_from = nil
|
|
25
|
+
@date_to = nil
|
|
26
|
+
@enriched_only = false
|
|
27
|
+
|
|
28
|
+
@include_index = true
|
|
29
|
+
@output_targets = ['clipboard'] # default to clipboard
|
|
30
|
+
@formats = ['content']
|
|
31
|
+
@line_limit = nil
|
|
32
|
+
@debug_level = 'none'
|
|
33
|
+
@dry_run = false
|
|
34
|
+
@tokens = false
|
|
35
|
+
@base_dir = Dir.pwd
|
|
36
|
+
|
|
37
|
+
@omi_dir = File.expand_path('~/dev/raw-intake/omi')
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def brains_root
|
|
41
|
+
@brains_root ||= File.expand_path('~/dev/ad/brains')
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def brains_index_path
|
|
45
|
+
File.join(brains_root, 'audit', 'brains-index.json')
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def brain_query?
|
|
49
|
+
brain_names.any? || tags.any? || categories.any? || activity_levels.any?
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def omi_query?
|
|
53
|
+
omi
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
data/lib/appydave/tools.rb
CHANGED
|
@@ -37,6 +37,10 @@ require 'appydave/tools/llm_context/options'
|
|
|
37
37
|
require 'appydave/tools/llm_context/file_collector'
|
|
38
38
|
require 'appydave/tools/llm_context/output_handler'
|
|
39
39
|
|
|
40
|
+
require 'appydave/tools/brain_context/options'
|
|
41
|
+
require 'appydave/tools/brain_context/brain_finder'
|
|
42
|
+
require 'appydave/tools/brain_context/omi_finder'
|
|
43
|
+
|
|
40
44
|
require 'appydave/tools/configuration/openai'
|
|
41
45
|
require 'appydave/tools/configuration/configurable'
|
|
42
46
|
require 'appydave/tools/configuration/config'
|
data/package.json
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: appydave-tools
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.80.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- David Cruwys
|
|
@@ -190,6 +190,8 @@ executables:
|
|
|
190
190
|
- jump
|
|
191
191
|
- llm_context
|
|
192
192
|
- prompt_tools
|
|
193
|
+
- query_brain
|
|
194
|
+
- query_omi
|
|
193
195
|
- subtitle_processor
|
|
194
196
|
- youtube_automation
|
|
195
197
|
- youtube_manager
|
|
@@ -229,6 +231,8 @@ files:
|
|
|
229
231
|
- bin/llm_context.rb
|
|
230
232
|
- bin/move_images.rb
|
|
231
233
|
- bin/prompt_tools.rb
|
|
234
|
+
- bin/query_brain.rb
|
|
235
|
+
- bin/query_omi.rb
|
|
232
236
|
- bin/setup
|
|
233
237
|
- bin/subtitle_manager-old.rb
|
|
234
238
|
- bin/subtitle_manager.rb
|
|
@@ -338,12 +342,17 @@ files:
|
|
|
338
342
|
- exe/jump
|
|
339
343
|
- exe/llm_context
|
|
340
344
|
- exe/prompt_tools
|
|
345
|
+
- exe/query_brain
|
|
346
|
+
- exe/query_omi
|
|
341
347
|
- exe/subtitle_processor
|
|
342
348
|
- exe/youtube_automation
|
|
343
349
|
- exe/youtube_manager
|
|
344
350
|
- exe/zsh_history
|
|
345
351
|
- images.log
|
|
346
352
|
- lib/appydave/tools.rb
|
|
353
|
+
- lib/appydave/tools/brain_context/brain_finder.rb
|
|
354
|
+
- lib/appydave/tools/brain_context/omi_finder.rb
|
|
355
|
+
- lib/appydave/tools/brain_context/options.rb
|
|
347
356
|
- lib/appydave/tools/cli_actions/_doc.md
|
|
348
357
|
- lib/appydave/tools/cli_actions/base_action.rb
|
|
349
358
|
- lib/appydave/tools/cli_actions/get_video_action.rb
|