codebase_index 0.2.1 → 0.3.1
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 +60 -0
- data/README.md +95 -300
- data/exe/codebase-index-mcp +3 -31
- data/exe/codebase-index-mcp-http +3 -31
- data/lib/codebase_index/ast/method_extractor.rb +3 -8
- data/lib/codebase_index/ast/node.rb +28 -0
- data/lib/codebase_index/ast/parser.rb +53 -92
- data/lib/codebase_index/builder.rb +67 -4
- data/lib/codebase_index/cache/cache_middleware.rb +199 -0
- data/lib/codebase_index/cache/cache_store.rb +264 -0
- data/lib/codebase_index/cache/redis_cache_store.rb +116 -0
- data/lib/codebase_index/cache/solid_cache_store.rb +111 -0
- data/lib/codebase_index/chunking/semantic_chunker.rb +29 -24
- data/lib/codebase_index/console/adapters/good_job_adapter.rb +7 -40
- data/lib/codebase_index/console/adapters/job_adapter.rb +68 -0
- data/lib/codebase_index/console/adapters/sidekiq_adapter.rb +7 -40
- data/lib/codebase_index/console/adapters/solid_queue_adapter.rb +7 -40
- data/lib/codebase_index/console/bridge.rb +7 -0
- data/lib/codebase_index/console/console_response_renderer.rb +3 -7
- data/lib/codebase_index/console/embedded_executor.rb +2 -1
- data/lib/codebase_index/console/server.rb +1 -4
- data/lib/codebase_index/dependency_graph.rb +28 -19
- data/lib/codebase_index/embedding/indexer.rb +18 -8
- data/lib/codebase_index/embedding/openai.rb +27 -6
- data/lib/codebase_index/embedding/provider.rb +29 -2
- data/lib/codebase_index/evaluation/evaluator.rb +5 -12
- data/lib/codebase_index/extractor.rb +40 -44
- data/lib/codebase_index/extractors/action_cable_extractor.rb +9 -36
- data/lib/codebase_index/extractors/callback_analyzer.rb +22 -8
- data/lib/codebase_index/extractors/controller_extractor.rb +3 -93
- data/lib/codebase_index/extractors/decorator_extractor.rb +7 -14
- data/lib/codebase_index/extractors/engine_extractor.rb +20 -1
- data/lib/codebase_index/extractors/graphql_extractor.rb +4 -29
- data/lib/codebase_index/extractors/job_extractor.rb +11 -6
- data/lib/codebase_index/extractors/lib_extractor.rb +0 -31
- data/lib/codebase_index/extractors/mailer_extractor.rb +15 -85
- data/lib/codebase_index/extractors/manager_extractor.rb +1 -15
- data/lib/codebase_index/extractors/model_extractor.rb +20 -53
- data/lib/codebase_index/extractors/phlex_extractor.rb +8 -8
- data/lib/codebase_index/extractors/policy_extractor.rb +1 -24
- data/lib/codebase_index/extractors/poro_extractor.rb +0 -17
- data/lib/codebase_index/extractors/serializer_extractor.rb +12 -7
- data/lib/codebase_index/extractors/service_extractor.rb +1 -38
- data/lib/codebase_index/extractors/shared_utility_methods.rb +183 -1
- data/lib/codebase_index/extractors/validator_extractor.rb +3 -17
- data/lib/codebase_index/extractors/view_component_extractor.rb +10 -9
- data/lib/codebase_index/filename_utils.rb +32 -0
- data/lib/codebase_index/flow_analysis/operation_extractor.rb +1 -4
- data/lib/codebase_index/formatting/base.rb +0 -10
- data/lib/codebase_index/graph_analyzer.rb +1 -1
- data/lib/codebase_index/mcp/bootstrapper.rb +58 -0
- data/lib/codebase_index/mcp/renderers/markdown_renderer.rb +35 -34
- data/lib/codebase_index/mcp/renderers/plain_renderer.rb +29 -29
- data/lib/codebase_index/mcp/server.rb +59 -68
- data/lib/codebase_index/mcp/tool_response_renderer.rb +23 -0
- data/lib/codebase_index/notion/client.rb +2 -2
- data/lib/codebase_index/notion/mapper.rb +1 -0
- data/lib/codebase_index/notion/mappers/column_mapper.rb +3 -11
- data/lib/codebase_index/notion/mappers/model_mapper.rb +20 -23
- data/lib/codebase_index/notion/mappers/shared.rb +22 -0
- data/lib/codebase_index/observability/health_check.rb +0 -2
- data/lib/codebase_index/observability/structured_logger.rb +12 -30
- data/lib/codebase_index/operator/pipeline_guard.rb +0 -7
- data/lib/codebase_index/resilience/index_validator.rb +3 -21
- data/lib/codebase_index/retrieval/context_assembler.rb +19 -7
- data/lib/codebase_index/retrieval/query_classifier.rb +14 -12
- data/lib/codebase_index/retrieval/ranker.rb +6 -2
- data/lib/codebase_index/retrieval/search_executor.rb +8 -19
- data/lib/codebase_index/retriever.rb +1 -9
- data/lib/codebase_index/ruby_analyzer/class_analyzer.rb +5 -25
- data/lib/codebase_index/ruby_analyzer/dataflow_analyzer.rb +6 -7
- data/lib/codebase_index/ruby_analyzer/mermaid_renderer.rb +58 -53
- data/lib/codebase_index/ruby_analyzer/trace_enricher.rb +11 -7
- data/lib/codebase_index/session_tracer/file_store.rb +1 -8
- data/lib/codebase_index/session_tracer/redis_store.rb +1 -7
- data/lib/codebase_index/session_tracer/session_flow_assembler.rb +4 -13
- data/lib/codebase_index/session_tracer/solid_cache_store.rb +1 -7
- data/lib/codebase_index/session_tracer/store.rb +14 -0
- data/lib/codebase_index/storage/metadata_store.rb +37 -10
- data/lib/codebase_index/storage/pgvector.rb +37 -5
- data/lib/codebase_index/storage/qdrant.rb +39 -6
- data/lib/codebase_index/storage/vector_store.rb +11 -0
- data/lib/codebase_index/temporal/snapshot_store.rb +14 -10
- data/lib/codebase_index/token_utils.rb +19 -0
- data/lib/codebase_index/version.rb +1 -1
- data/lib/codebase_index.rb +25 -6
- data/lib/tasks/codebase_index.rake +2 -2
- metadata +11 -2
|
@@ -35,6 +35,20 @@ module CodebaseIndex
|
|
|
35
35
|
raise NotImplementedError
|
|
36
36
|
end
|
|
37
37
|
|
|
38
|
+
# Find multiple units by IDs in a single query.
|
|
39
|
+
#
|
|
40
|
+
# Default implementation falls back to individual find calls.
|
|
41
|
+
# Adapters should override for batch-optimized behavior.
|
|
42
|
+
#
|
|
43
|
+
# @param ids [Array<String>] The identifiers to look up
|
|
44
|
+
# @return [Hash<String, Hash>] Map of id => metadata for found units
|
|
45
|
+
def find_batch(ids)
|
|
46
|
+
ids.each_with_object({}) do |id, result|
|
|
47
|
+
data = find(id)
|
|
48
|
+
result[id] = data if data
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
38
52
|
# Find all units of a given type.
|
|
39
53
|
#
|
|
40
54
|
# @param type [String] The unit type to filter by
|
|
@@ -112,14 +126,21 @@ module CodebaseIndex
|
|
|
112
126
|
JSON.parse(row['data'])
|
|
113
127
|
end
|
|
114
128
|
|
|
129
|
+
# @see Interface#find_batch
|
|
130
|
+
def find_batch(ids)
|
|
131
|
+
return {} if ids.empty?
|
|
132
|
+
|
|
133
|
+
placeholders = Array.new(ids.size, '?').join(', ')
|
|
134
|
+
rows = @db.execute("SELECT id, data FROM units WHERE id IN (#{placeholders})", ids)
|
|
135
|
+
rows.to_h do |row|
|
|
136
|
+
[row['id'], JSON.parse(row['data'])]
|
|
137
|
+
end
|
|
138
|
+
end
|
|
139
|
+
|
|
115
140
|
# @see Interface#find_by_type
|
|
116
141
|
def find_by_type(type)
|
|
117
142
|
rows = @db.execute('SELECT id, data FROM units WHERE type = ?', [type.to_s])
|
|
118
|
-
rows.map
|
|
119
|
-
parsed = JSON.parse(row['data'])
|
|
120
|
-
parsed['id'] = row['id']
|
|
121
|
-
parsed
|
|
122
|
-
end
|
|
143
|
+
rows.map { |row| parse_row(row) }
|
|
123
144
|
end
|
|
124
145
|
|
|
125
146
|
# @see Interface#search
|
|
@@ -132,11 +153,7 @@ module CodebaseIndex
|
|
|
132
153
|
rows = @db.execute('SELECT id, data FROM units WHERE data LIKE ?', ["%#{query}%"])
|
|
133
154
|
end
|
|
134
155
|
|
|
135
|
-
rows.map
|
|
136
|
-
parsed = JSON.parse(row['data'])
|
|
137
|
-
parsed['id'] = row['id']
|
|
138
|
-
parsed
|
|
139
|
-
end
|
|
156
|
+
rows.map { |row| parse_row(row) }
|
|
140
157
|
end
|
|
141
158
|
|
|
142
159
|
# @see Interface#delete
|
|
@@ -151,6 +168,16 @@ module CodebaseIndex
|
|
|
151
168
|
|
|
152
169
|
private
|
|
153
170
|
|
|
171
|
+
# Parse a database row into a metadata hash with the id field injected.
|
|
172
|
+
#
|
|
173
|
+
# @param row [Hash] Database row with 'id' and 'data' keys
|
|
174
|
+
# @return [Hash] Parsed metadata with 'id' key set
|
|
175
|
+
def parse_row(row)
|
|
176
|
+
parsed = JSON.parse(row['data'])
|
|
177
|
+
parsed['id'] = row['id']
|
|
178
|
+
parsed
|
|
179
|
+
end
|
|
180
|
+
|
|
154
181
|
# Create the units table if it doesn't exist.
|
|
155
182
|
def create_table
|
|
156
183
|
@db.execute(<<~SQL)
|
|
@@ -17,7 +17,7 @@ module CodebaseIndex
|
|
|
17
17
|
# store.store("User", [0.1, 0.2, ...], { type: "model" })
|
|
18
18
|
# results = store.search([0.1, 0.2, ...], limit: 5, filters: { type: "model" })
|
|
19
19
|
#
|
|
20
|
-
class Pgvector
|
|
20
|
+
class Pgvector # rubocop:disable Metrics/ClassLength
|
|
21
21
|
include Interface
|
|
22
22
|
|
|
23
23
|
TABLE = 'codebase_index_vectors'
|
|
@@ -56,13 +56,32 @@ module CodebaseIndex
|
|
|
56
56
|
# @see Interface#store
|
|
57
57
|
def store(id, vector, metadata = {})
|
|
58
58
|
validate_vector!(vector)
|
|
59
|
-
|
|
60
|
-
quoted_metadata = @connection.quote(JSON.generate(metadata))
|
|
61
|
-
vector_literal = "[#{vector.join(',')}]"
|
|
59
|
+
entry = format_entry(id, vector, metadata)
|
|
62
60
|
|
|
63
61
|
@connection.execute(<<~SQL)
|
|
64
62
|
INSERT INTO #{TABLE} (id, embedding, metadata, created_at)
|
|
65
|
-
VALUES
|
|
63
|
+
VALUES #{entry}
|
|
64
|
+
ON CONFLICT (id) DO UPDATE SET
|
|
65
|
+
embedding = EXCLUDED.embedding,
|
|
66
|
+
metadata = EXCLUDED.metadata,
|
|
67
|
+
created_at = CURRENT_TIMESTAMP
|
|
68
|
+
SQL
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
# Store multiple vectors in a single multi-row INSERT.
|
|
72
|
+
#
|
|
73
|
+
# @param entries [Array<Hash>] Each entry has :id, :vector, :metadata keys
|
|
74
|
+
def store_batch(entries)
|
|
75
|
+
return if entries.empty?
|
|
76
|
+
|
|
77
|
+
values = entries.map do |entry|
|
|
78
|
+
validate_vector!(entry[:vector])
|
|
79
|
+
format_entry(entry[:id], entry[:vector], entry[:metadata] || {})
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
@connection.execute(<<~SQL)
|
|
83
|
+
INSERT INTO #{TABLE} (id, embedding, metadata, created_at)
|
|
84
|
+
VALUES #{values.join(",\n")}
|
|
66
85
|
ON CONFLICT (id) DO UPDATE SET
|
|
67
86
|
embedding = EXCLUDED.embedding,
|
|
68
87
|
metadata = EXCLUDED.metadata,
|
|
@@ -114,6 +133,19 @@ module CodebaseIndex
|
|
|
114
133
|
|
|
115
134
|
private
|
|
116
135
|
|
|
136
|
+
# Format a single entry as a SQL VALUES tuple.
|
|
137
|
+
#
|
|
138
|
+
# @param id [String] Unique identifier
|
|
139
|
+
# @param vector [Array<Float>] Embedding vector
|
|
140
|
+
# @param metadata [Hash] Entry metadata
|
|
141
|
+
# @return [String] SQL values row literal
|
|
142
|
+
def format_entry(id, vector, metadata)
|
|
143
|
+
quoted_id = @connection.quote(id)
|
|
144
|
+
quoted_metadata = @connection.quote(JSON.generate(metadata))
|
|
145
|
+
vector_literal = "[#{vector.join(',')}]"
|
|
146
|
+
"(#{quoted_id}, '#{vector_literal}', #{quoted_metadata}::jsonb, CURRENT_TIMESTAMP)"
|
|
147
|
+
end
|
|
148
|
+
|
|
117
149
|
# Convert a database row to a SearchResult.
|
|
118
150
|
#
|
|
119
151
|
# @param row [Hash] Database row with id, distance, metadata
|
|
@@ -19,7 +19,7 @@ module CodebaseIndex
|
|
|
19
19
|
# store.store("User", [0.1, 0.2, ...], { type: "model" })
|
|
20
20
|
# results = store.search([0.1, 0.2, ...], limit: 5)
|
|
21
21
|
#
|
|
22
|
-
class Qdrant
|
|
22
|
+
class Qdrant # rubocop:disable Metrics/ClassLength
|
|
23
23
|
include Interface
|
|
24
24
|
|
|
25
25
|
# @param url [String] Qdrant server URL
|
|
@@ -64,6 +64,25 @@ module CodebaseIndex
|
|
|
64
64
|
request(:put, "/collections/#{@collection}/points", body)
|
|
65
65
|
end
|
|
66
66
|
|
|
67
|
+
# Store multiple vectors in a single batch upsert request.
|
|
68
|
+
#
|
|
69
|
+
# Sends the entire entries array in one HTTP call. Callers are responsible
|
|
70
|
+
# for chunking into reasonable batch sizes (e.g., 100–500 points) before
|
|
71
|
+
# calling this method; the embedding Indexer's +batch_size+ config controls
|
|
72
|
+
# the upstream chunk size.
|
|
73
|
+
#
|
|
74
|
+
# @param entries [Array<Hash>] Each entry has :id, :vector, :metadata keys
|
|
75
|
+
def store_batch(entries)
|
|
76
|
+
return if entries.empty?
|
|
77
|
+
|
|
78
|
+
body = {
|
|
79
|
+
points: entries.map do |entry|
|
|
80
|
+
{ id: entry[:id], vector: entry[:vector], payload: entry[:metadata] || {} }
|
|
81
|
+
end
|
|
82
|
+
}
|
|
83
|
+
request(:put, "/collections/#{@collection}/points", body)
|
|
84
|
+
end
|
|
85
|
+
|
|
67
86
|
# Search for similar vectors.
|
|
68
87
|
#
|
|
69
88
|
# @param query_vector [Array<Float>] The query embedding
|
|
@@ -130,26 +149,40 @@ module CodebaseIndex
|
|
|
130
149
|
# @return [Hash] Parsed JSON response
|
|
131
150
|
# @raise [CodebaseIndex::Error] if the API returns a non-success status
|
|
132
151
|
def request(method, path, body = nil)
|
|
133
|
-
http = build_http
|
|
134
152
|
req = build_request(method, path, body)
|
|
135
|
-
response =
|
|
153
|
+
response = http_client.request(req)
|
|
136
154
|
|
|
137
155
|
unless response.is_a?(Net::HTTPSuccess)
|
|
138
156
|
raise CodebaseIndex::Error, "Qdrant API error: #{response.code} #{response.body}"
|
|
139
157
|
end
|
|
140
158
|
|
|
159
|
+
JSON.parse(response.body)
|
|
160
|
+
rescue Errno::ECONNRESET, Net::OpenTimeout, IOError
|
|
161
|
+
# Connection dropped — reset and retry once
|
|
162
|
+
@http_client = nil
|
|
163
|
+
response = http_client.request(req)
|
|
164
|
+
unless response.is_a?(Net::HTTPSuccess)
|
|
165
|
+
raise CodebaseIndex::Error, "Qdrant API error: #{response.code} #{response.body}"
|
|
166
|
+
end
|
|
167
|
+
|
|
141
168
|
JSON.parse(response.body)
|
|
142
169
|
end
|
|
143
170
|
|
|
144
|
-
#
|
|
171
|
+
# Return a reusable, started HTTP client for the Qdrant server.
|
|
172
|
+
# Calling http.start opens a persistent TCP connection so
|
|
173
|
+
# keep_alive_timeout actually takes effect across requests.
|
|
145
174
|
#
|
|
146
175
|
# @return [Net::HTTP]
|
|
147
|
-
def
|
|
176
|
+
def http_client
|
|
177
|
+
return @http_client if @http_client&.started?
|
|
178
|
+
|
|
148
179
|
http = Net::HTTP.new(@uri.host, @uri.port)
|
|
149
180
|
http.use_ssl = @uri.scheme == 'https'
|
|
150
181
|
http.open_timeout = 10
|
|
151
182
|
http.read_timeout = 30
|
|
152
|
-
http
|
|
183
|
+
http.keep_alive_timeout = 30
|
|
184
|
+
http.start
|
|
185
|
+
@http_client = http
|
|
153
186
|
end
|
|
154
187
|
|
|
155
188
|
# Build an HTTP request with headers and body.
|
|
@@ -25,6 +25,17 @@ module CodebaseIndex
|
|
|
25
25
|
raise NotImplementedError
|
|
26
26
|
end
|
|
27
27
|
|
|
28
|
+
# Store multiple vectors in a single batch operation.
|
|
29
|
+
#
|
|
30
|
+
# Default implementation falls back to individual store calls.
|
|
31
|
+
# Adapters should override for bulk-optimized behavior (e.g.,
|
|
32
|
+
# multi-row INSERT for pgvector, batch upsert for Qdrant).
|
|
33
|
+
#
|
|
34
|
+
# @param entries [Array<Hash>] Each entry has :id, :vector, :metadata keys
|
|
35
|
+
def store_batch(entries)
|
|
36
|
+
entries.each { |e| store(e[:id], e[:vector], e[:metadata] || {}) }
|
|
37
|
+
end
|
|
38
|
+
|
|
28
39
|
# Search for similar vectors using cosine similarity.
|
|
29
40
|
#
|
|
30
41
|
# @param query_vector [Array<Float>] The query embedding vector
|
|
@@ -230,16 +230,20 @@ module CodebaseIndex
|
|
|
230
230
|
VALUES (?, ?, ?, ?, ?, ?)
|
|
231
231
|
SQL
|
|
232
232
|
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
233
|
+
# Wrap in a transaction to batch all inserts into a single commit,
|
|
234
|
+
# reducing per-row fsync overhead from O(n) to O(1).
|
|
235
|
+
@db.transaction do
|
|
236
|
+
unit_hashes.each do |uh|
|
|
237
|
+
params = [
|
|
238
|
+
snapshot_id,
|
|
239
|
+
mget(uh, 'identifier'),
|
|
240
|
+
mget(uh, 'type').to_s,
|
|
241
|
+
mget(uh, 'source_hash'),
|
|
242
|
+
mget(uh, 'metadata_hash'),
|
|
243
|
+
mget(uh, 'dependencies_hash')
|
|
244
|
+
]
|
|
245
|
+
@db.execute(sql, params)
|
|
246
|
+
end
|
|
243
247
|
end
|
|
244
248
|
end
|
|
245
249
|
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module CodebaseIndex
|
|
4
|
+
# Shared token estimation utility.
|
|
5
|
+
#
|
|
6
|
+
# Uses project convention: (string.length / 4.0).ceil
|
|
7
|
+
# See docs/TOKEN_BENCHMARK.md — conservative floor (~10.6% overestimate).
|
|
8
|
+
module TokenUtils
|
|
9
|
+
module_function
|
|
10
|
+
|
|
11
|
+
# Estimate token count for a string.
|
|
12
|
+
#
|
|
13
|
+
# @param text [String] Text to estimate
|
|
14
|
+
# @return [Integer] Estimated token count
|
|
15
|
+
def estimate_tokens(text)
|
|
16
|
+
(text.length / 4.0).ceil
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
data/lib/codebase_index.rb
CHANGED
|
@@ -42,8 +42,10 @@ module CodebaseIndex
|
|
|
42
42
|
:concurrent_extraction, :precompute_flows, :enable_snapshots,
|
|
43
43
|
:session_tracer_enabled, :session_store, :session_id_proc, :session_exclude_paths,
|
|
44
44
|
:console_mcp_enabled, :console_mcp_path, :console_redacted_columns,
|
|
45
|
-
:notion_api_token, :notion_database_ids
|
|
46
|
-
|
|
45
|
+
:notion_api_token, :notion_database_ids,
|
|
46
|
+
:cache_store, :cache_options
|
|
47
|
+
attr_reader :max_context_tokens, :similarity_threshold, :extractors, :pretty_json, :context_format,
|
|
48
|
+
:cache_enabled
|
|
47
49
|
|
|
48
50
|
def initialize # rubocop:disable Metrics/MethodLength
|
|
49
51
|
@output_dir = nil # Resolved lazily; Rails.root is nil at require time
|
|
@@ -68,6 +70,9 @@ module CodebaseIndex
|
|
|
68
70
|
@console_redacted_columns = []
|
|
69
71
|
@notion_api_token = nil
|
|
70
72
|
@notion_database_ids = {}
|
|
73
|
+
@cache_enabled = false
|
|
74
|
+
@cache_store = nil # :redis, :solid_cache, :memory, or a CacheStore instance
|
|
75
|
+
@cache_options = {} # { redis: client, cache: store, ttl: { embeddings: 86400, ... } }
|
|
71
76
|
end
|
|
72
77
|
|
|
73
78
|
# @return [Pathname, String] Output directory, defaulting to Rails.root/tmp/codebase_index
|
|
@@ -119,10 +124,7 @@ module CodebaseIndex
|
|
|
119
124
|
# @param value [Boolean] Must be true or false
|
|
120
125
|
# @raise [ConfigurationError] if value is not a boolean
|
|
121
126
|
def pretty_json=(value)
|
|
122
|
-
|
|
123
|
-
raise ConfigurationError, "pretty_json must be true or false, got #{value.inspect}"
|
|
124
|
-
end
|
|
125
|
-
|
|
127
|
+
validate_boolean!(:pretty_json, value)
|
|
126
128
|
@pretty_json = value
|
|
127
129
|
end
|
|
128
130
|
|
|
@@ -137,6 +139,13 @@ module CodebaseIndex
|
|
|
137
139
|
@context_format = value
|
|
138
140
|
end
|
|
139
141
|
|
|
142
|
+
# @param value [Boolean] Enable or disable the cache layer
|
|
143
|
+
# @raise [ConfigurationError] if value is not a boolean
|
|
144
|
+
def cache_enabled=(value)
|
|
145
|
+
validate_boolean!(:cache_enabled, value)
|
|
146
|
+
@cache_enabled = value
|
|
147
|
+
end
|
|
148
|
+
|
|
140
149
|
# Add a gem to be indexed
|
|
141
150
|
#
|
|
142
151
|
# @param gem_name [String] Name of the gem
|
|
@@ -145,6 +154,14 @@ module CodebaseIndex
|
|
|
145
154
|
def add_gem(gem_name, paths:, priority: :medium)
|
|
146
155
|
@gem_configs[gem_name] = { paths: paths, priority: priority }
|
|
147
156
|
end
|
|
157
|
+
|
|
158
|
+
private
|
|
159
|
+
|
|
160
|
+
def validate_boolean!(name, value)
|
|
161
|
+
return if value.is_a?(TrueClass) || value.is_a?(FalseClass)
|
|
162
|
+
|
|
163
|
+
raise ConfigurationError, "#{name} must be true or false, got #{value.inspect}"
|
|
164
|
+
end
|
|
148
165
|
end
|
|
149
166
|
|
|
150
167
|
# ════════════════════════════════════════════════════════════════════════
|
|
@@ -224,4 +241,6 @@ end
|
|
|
224
241
|
|
|
225
242
|
require_relative 'codebase_index/builder'
|
|
226
243
|
require_relative 'codebase_index/cost_model'
|
|
244
|
+
require_relative 'codebase_index/cache/cache_store'
|
|
245
|
+
require_relative 'codebase_index/cache/cache_middleware'
|
|
227
246
|
require_relative 'codebase_index/railtie' if defined?(Rails::Railtie)
|
|
@@ -304,7 +304,7 @@ namespace :codebase_index do
|
|
|
304
304
|
end
|
|
305
305
|
end
|
|
306
306
|
|
|
307
|
-
|
|
307
|
+
# Internal debugging tool — hidden from `rails -T`
|
|
308
308
|
task :retrieve, [:query] => :environment do |_t, args|
|
|
309
309
|
query = args[:query] || raise('Usage: rake codebase_index:retrieve[query]')
|
|
310
310
|
|
|
@@ -400,7 +400,7 @@ namespace :codebase_index do
|
|
|
400
400
|
puts " Errors: #{stats[:errors]}"
|
|
401
401
|
end
|
|
402
402
|
|
|
403
|
-
|
|
403
|
+
# Internal debugging tool — hidden from `rails -T`
|
|
404
404
|
task :self_analyze do
|
|
405
405
|
require 'digest'
|
|
406
406
|
require 'json'
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: codebase_index
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.3.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Leah Armstrong
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-
|
|
11
|
+
date: 2026-03-04 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: mcp
|
|
@@ -72,10 +72,15 @@ files:
|
|
|
72
72
|
- lib/codebase_index/ast/node.rb
|
|
73
73
|
- lib/codebase_index/ast/parser.rb
|
|
74
74
|
- lib/codebase_index/builder.rb
|
|
75
|
+
- lib/codebase_index/cache/cache_middleware.rb
|
|
76
|
+
- lib/codebase_index/cache/cache_store.rb
|
|
77
|
+
- lib/codebase_index/cache/redis_cache_store.rb
|
|
78
|
+
- lib/codebase_index/cache/solid_cache_store.rb
|
|
75
79
|
- lib/codebase_index/chunking/chunk.rb
|
|
76
80
|
- lib/codebase_index/chunking/semantic_chunker.rb
|
|
77
81
|
- lib/codebase_index/console/adapters/cache_adapter.rb
|
|
78
82
|
- lib/codebase_index/console/adapters/good_job_adapter.rb
|
|
83
|
+
- lib/codebase_index/console/adapters/job_adapter.rb
|
|
79
84
|
- lib/codebase_index/console/adapters/sidekiq_adapter.rb
|
|
80
85
|
- lib/codebase_index/console/adapters/solid_queue_adapter.rb
|
|
81
86
|
- lib/codebase_index/console/audit_logger.rb
|
|
@@ -159,6 +164,7 @@ files:
|
|
|
159
164
|
- lib/codebase_index/extractors/view_template_extractor.rb
|
|
160
165
|
- lib/codebase_index/feedback/gap_detector.rb
|
|
161
166
|
- lib/codebase_index/feedback/store.rb
|
|
167
|
+
- lib/codebase_index/filename_utils.rb
|
|
162
168
|
- lib/codebase_index/flow_analysis/operation_extractor.rb
|
|
163
169
|
- lib/codebase_index/flow_analysis/response_code_mapper.rb
|
|
164
170
|
- lib/codebase_index/flow_assembler.rb
|
|
@@ -170,6 +176,7 @@ files:
|
|
|
170
176
|
- lib/codebase_index/formatting/gpt_adapter.rb
|
|
171
177
|
- lib/codebase_index/formatting/human_adapter.rb
|
|
172
178
|
- lib/codebase_index/graph_analyzer.rb
|
|
179
|
+
- lib/codebase_index/mcp/bootstrapper.rb
|
|
173
180
|
- lib/codebase_index/mcp/index_reader.rb
|
|
174
181
|
- lib/codebase_index/mcp/renderers/claude_renderer.rb
|
|
175
182
|
- lib/codebase_index/mcp/renderers/json_renderer.rb
|
|
@@ -184,6 +191,7 @@ files:
|
|
|
184
191
|
- lib/codebase_index/notion/mappers/column_mapper.rb
|
|
185
192
|
- lib/codebase_index/notion/mappers/migration_mapper.rb
|
|
186
193
|
- lib/codebase_index/notion/mappers/model_mapper.rb
|
|
194
|
+
- lib/codebase_index/notion/mappers/shared.rb
|
|
187
195
|
- lib/codebase_index/notion/rate_limiter.rb
|
|
188
196
|
- lib/codebase_index/observability/health_check.rb
|
|
189
197
|
- lib/codebase_index/observability/instrumentation.rb
|
|
@@ -220,6 +228,7 @@ files:
|
|
|
220
228
|
- lib/codebase_index/storage/qdrant.rb
|
|
221
229
|
- lib/codebase_index/storage/vector_store.rb
|
|
222
230
|
- lib/codebase_index/temporal/snapshot_store.rb
|
|
231
|
+
- lib/codebase_index/token_utils.rb
|
|
223
232
|
- lib/codebase_index/version.rb
|
|
224
233
|
- lib/generators/codebase_index/install_generator.rb
|
|
225
234
|
- lib/generators/codebase_index/pgvector_generator.rb
|