hokipoki 0.3.4 → 0.5.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/lib/generators/hive_mind/install_generator.rb +18 -2
- data/lib/generators/hive_mind/start_generator.rb +582 -0
- data/lib/generators/hive_mind/templates/hokipoki_claude.rb +45 -0
- data/lib/generators/hokipoki/attach_parasite_generator.rb +355 -0
- data/lib/generators/hokipoki/install_generator.rb +515 -0
- data/lib/generators/hokipoki/scan_project_generator.rb +279 -0
- data/lib/generators/parasite/install_generator.rb +458 -0
- data/lib/hokipoki/atomic_fact_extractor.rb +524 -0
- data/lib/hokipoki/claude/parasite.rb +62 -10
- data/lib/hokipoki/claude/thought_interceptor.rb +385 -0
- data/lib/hokipoki/claude_auto_loader.rb +28 -11
- data/lib/hokipoki/template_store.rb +425 -0
- data/lib/hokipoki/vector_engine.rb +525 -0
- data/lib/hokipoki/version.rb +1 -1
- data/lib/hokipoki.rb +260 -6
- metadata +81 -1
data/lib/hokipoki.rb
CHANGED
|
@@ -16,6 +16,16 @@ require_relative "hokipoki/engine"
|
|
|
16
16
|
require_relative "hokipoki/feedback/display_manager"
|
|
17
17
|
require_relative "hokipoki/claude_auto_loader"
|
|
18
18
|
|
|
19
|
+
# Core intelligence components (loaded on demand)
|
|
20
|
+
begin
|
|
21
|
+
require_relative "hokipoki/vector_engine"
|
|
22
|
+
require_relative "hokipoki/template_store"
|
|
23
|
+
require_relative "hokipoki/atomic_fact_extractor"
|
|
24
|
+
rescue LoadError => e
|
|
25
|
+
# Components will be available after gem installation
|
|
26
|
+
Rails.logger&.debug "🦠 Hokipoki: Advanced components not yet loaded: #{e.message}"
|
|
27
|
+
end
|
|
28
|
+
|
|
19
29
|
module Hokipoki
|
|
20
30
|
# Validate license on gem load (before anything else)
|
|
21
31
|
begin
|
|
@@ -40,16 +50,248 @@ module Hokipoki
|
|
|
40
50
|
configuration || configure
|
|
41
51
|
end
|
|
42
52
|
|
|
43
|
-
#
|
|
53
|
+
# Claude parasite detection and activation (Enhanced)
|
|
44
54
|
def claude_parasite_active?
|
|
45
|
-
ENV['CLAUDE_CODE_SESSION'] == 'true' ||
|
|
55
|
+
ENV['CLAUDE_CODE_SESSION'] == 'true' ||
|
|
56
|
+
File.exist?('/tmp/claude_session_active') ||
|
|
57
|
+
File.exist?('/tmp/hokipoki_parasite_active') ||
|
|
58
|
+
ClaudeAutoLoader.claude_cli_detected?
|
|
46
59
|
end
|
|
47
60
|
|
|
48
|
-
# Main API -
|
|
61
|
+
# Main API - REAL intelligent fact retrieval with vector engine
|
|
49
62
|
def retrieve_facts(query, token_budget: 1500)
|
|
50
|
-
Rails.logger&.info "
|
|
51
|
-
|
|
52
|
-
|
|
63
|
+
Rails.logger&.info "🦠 <PARASITIC INTELLIGENCE RETRIEVAL> Query: #{query[0..50]}..."
|
|
64
|
+
|
|
65
|
+
# If Claude CLI is detected, activate FULL parasite mode
|
|
66
|
+
if claude_parasite_active?
|
|
67
|
+
$stdout.puts "🧠 VECTOR ENGINE: Activating parasitic intelligence..."
|
|
68
|
+
|
|
69
|
+
begin
|
|
70
|
+
# Use REAL vector engine if available
|
|
71
|
+
if defined?(VectorEngine)
|
|
72
|
+
vector_engine = VectorEngine.instance
|
|
73
|
+
facts = vector_engine.retrieve_facts(query, token_budget: token_budget)
|
|
74
|
+
|
|
75
|
+
if facts.any?
|
|
76
|
+
$stdout.puts "✅ PARASITE: Enhanced vector context delivered"
|
|
77
|
+
return facts
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
# Try HiveMind as fallback
|
|
82
|
+
if defined?(SmartRetrievalEngine)
|
|
83
|
+
engine = SmartRetrievalEngine.new
|
|
84
|
+
facts = engine.retrieve_targeted_facts(query, token_budget: token_budget)
|
|
85
|
+
|
|
86
|
+
if facts.any?
|
|
87
|
+
$stdout.puts "✅ PARASITE: HiveMind context retrieved"
|
|
88
|
+
return facts
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
# Enhanced fallback with template-based generation
|
|
93
|
+
enhanced_context = generate_enhanced_context(query, token_budget)
|
|
94
|
+
$stdout.puts "✅ PARASITE: Template-enhanced context generated"
|
|
95
|
+
return [enhanced_context]
|
|
96
|
+
|
|
97
|
+
rescue => e
|
|
98
|
+
Rails.logger&.error "🦠 Parasite retrieval failed: #{e.message}"
|
|
99
|
+
$stdout.puts "❌ PARASITE: Error occurred, using emergency fallback"
|
|
100
|
+
return generate_emergency_context(query, e)
|
|
101
|
+
end
|
|
102
|
+
else
|
|
103
|
+
# Non-Claude mode - minimal retrieval
|
|
104
|
+
Rails.logger&.info "🔍 Standard retrieval mode (Claude not detected)"
|
|
105
|
+
[]
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
# Enhanced context generation with intelligence patterns
|
|
110
|
+
def generate_enhanced_context(query, token_budget)
|
|
111
|
+
# Load template store if available
|
|
112
|
+
template_store = get_template_store
|
|
113
|
+
|
|
114
|
+
# Analyze query for better context
|
|
115
|
+
intent = analyze_query_intent(query)
|
|
116
|
+
keywords = extract_query_keywords(query)
|
|
117
|
+
|
|
118
|
+
# Try template-based generation first
|
|
119
|
+
if template_store
|
|
120
|
+
template_content = template_store.generate_content(
|
|
121
|
+
detect_query_template_type(query),
|
|
122
|
+
keywords: keywords,
|
|
123
|
+
intent: intent,
|
|
124
|
+
params: { token_budget: token_budget }
|
|
125
|
+
)
|
|
126
|
+
|
|
127
|
+
return template_content if template_content
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
# Fallback to pattern-based generation
|
|
131
|
+
generate_pattern_based_context(query, intent, keywords, token_budget)
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
# Pattern-based context generation (improved from before)
|
|
135
|
+
def generate_pattern_based_context(query, intent, keywords, token_budget)
|
|
136
|
+
context_parts = []
|
|
137
|
+
|
|
138
|
+
case intent
|
|
139
|
+
when :implementation
|
|
140
|
+
context_parts << "Implementation context: #{keywords.join(', ')}"
|
|
141
|
+
context_parts << "Best practices: Follow conventions, write tests, consider edge cases"
|
|
142
|
+
context_parts << "Architecture: Use appropriate design patterns, separate concerns"
|
|
143
|
+
|
|
144
|
+
if keywords.any? { |k| k.match?(/rails|ruby/) }
|
|
145
|
+
context_parts << "Rails patterns: RESTful routes, strong parameters, ActiveRecord conventions"
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
when :debugging
|
|
149
|
+
context_parts << "Debugging context: #{keywords.join(', ')}"
|
|
150
|
+
context_parts << "Systematic approach: Reproduce error, check logs, isolate variables"
|
|
151
|
+
context_parts << "Common issues: Environment config, dependencies, permissions, data validation"
|
|
152
|
+
|
|
153
|
+
when :learning
|
|
154
|
+
context_parts << "Learning context: #{keywords.join(', ')}"
|
|
155
|
+
context_parts << "Educational approach: Start with fundamentals, practice with examples"
|
|
156
|
+
context_parts << "Resources: Official documentation, community guides, code examples"
|
|
157
|
+
|
|
158
|
+
when :optimization
|
|
159
|
+
context_parts << "Optimization context: #{keywords.join(', ')}"
|
|
160
|
+
context_parts << "Performance strategy: Profile first, optimize bottlenecks, measure results"
|
|
161
|
+
context_parts << "Rails optimization: Database queries, caching, background processing"
|
|
162
|
+
|
|
163
|
+
else
|
|
164
|
+
context_parts << "Context: #{keywords.join(', ')}"
|
|
165
|
+
context_parts << "General guidance: Follow best practices, maintain code quality"
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
# Add project context if Rails is available
|
|
169
|
+
if defined?(Rails)
|
|
170
|
+
context_parts << "Project: #{Rails.application.class.module_parent_name} (#{Rails.env})"
|
|
171
|
+
|
|
172
|
+
# Add structural context
|
|
173
|
+
if Dir.exist?('app')
|
|
174
|
+
models = Dir['app/models/**/*.rb'].size
|
|
175
|
+
controllers = Dir['app/controllers/**/*.rb'].size
|
|
176
|
+
context_parts << "Structure: #{models} models, #{controllers} controllers"
|
|
177
|
+
end
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
# Ensure token budget compliance
|
|
181
|
+
full_context = context_parts.join(' | ')
|
|
182
|
+
apply_token_budget(full_context, token_budget)
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
# Emergency context for error cases
|
|
186
|
+
def generate_emergency_context(query, error)
|
|
187
|
+
[
|
|
188
|
+
"Emergency context: #{extract_query_keywords(query).first(3).join(', ')}",
|
|
189
|
+
"Status: Vector engine temporarily unavailable (#{error.class.name})",
|
|
190
|
+
"Fallback: Basic guidance available - check documentation and verify configuration"
|
|
191
|
+
]
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
# Helper methods for enhanced intelligence
|
|
195
|
+
|
|
196
|
+
def get_template_store
|
|
197
|
+
return @template_store if defined?(@template_store)
|
|
198
|
+
|
|
199
|
+
begin
|
|
200
|
+
require_relative 'hokipoki/template_store'
|
|
201
|
+
@template_store = TemplateStore.new
|
|
202
|
+
rescue LoadError
|
|
203
|
+
@template_store = nil
|
|
204
|
+
end
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
def analyze_query_intent(query)
|
|
208
|
+
case query.downcase
|
|
209
|
+
when /\b(implement|create|build|make|add|generate|write)\b/
|
|
210
|
+
:implementation
|
|
211
|
+
when /\b(error|bug|fix|debug|troubleshoot|issue|problem)\b/
|
|
212
|
+
:debugging
|
|
213
|
+
when /\b(how|what|why|when|where|explain|understand|learn)\b/
|
|
214
|
+
:learning
|
|
215
|
+
when /\b(optimize|improve|enhance|better|faster|performance)\b/
|
|
216
|
+
:optimization
|
|
217
|
+
when /\b(example|show|demo|sample|tutorial|guide)\b/
|
|
218
|
+
:reference
|
|
219
|
+
when /\b(test|testing|spec|rspec|jest|unit|integration)\b/
|
|
220
|
+
:testing
|
|
221
|
+
else
|
|
222
|
+
:general
|
|
223
|
+
end
|
|
224
|
+
end
|
|
225
|
+
|
|
226
|
+
def extract_query_keywords(query)
|
|
227
|
+
# Remove stop words and extract meaningful terms
|
|
228
|
+
stop_words = %w[
|
|
229
|
+
the a an and or but in on at to for of with by from
|
|
230
|
+
how do i can you please help me show get make create
|
|
231
|
+
what is are was were will would should could might
|
|
232
|
+
this that these those here there where when why
|
|
233
|
+
]
|
|
234
|
+
|
|
235
|
+
words = query.downcase
|
|
236
|
+
.gsub(/[^\w\s]/, ' ')
|
|
237
|
+
.split(/\s+/)
|
|
238
|
+
.reject { |word| stop_words.include?(word) || word.length < 2 }
|
|
239
|
+
.select { |word| word.length > 2 || technical_term?(word) }
|
|
240
|
+
|
|
241
|
+
words.uniq.first(8) # Limit to most relevant keywords
|
|
242
|
+
end
|
|
243
|
+
|
|
244
|
+
def technical_term?(word)
|
|
245
|
+
# Short technical terms that should be preserved
|
|
246
|
+
technical_terms = %w[css js sql api url ui ux db id ai ml]
|
|
247
|
+
technical_terms.include?(word.downcase)
|
|
248
|
+
end
|
|
249
|
+
|
|
250
|
+
def detect_query_template_type(query)
|
|
251
|
+
case query
|
|
252
|
+
when /\b(model|activerecord|database|table|migration)\b/i
|
|
253
|
+
'active_record_model'
|
|
254
|
+
when /\b(controller|action|route|params)\b/i
|
|
255
|
+
'rails_controller'
|
|
256
|
+
when /\b(class|module|method|function)\b/i
|
|
257
|
+
'ruby_class'
|
|
258
|
+
when /\b(javascript|js|function|async|await)\b/i
|
|
259
|
+
'javascript_code'
|
|
260
|
+
when /\b(css|style|stylesheet|class)\b/i
|
|
261
|
+
'css_styles'
|
|
262
|
+
when /\b(erb|template|view|render)\b/i
|
|
263
|
+
'erb_template'
|
|
264
|
+
when /\b(test|spec|rspec|describe|it)\b/i
|
|
265
|
+
'test_spec'
|
|
266
|
+
when /\b(error|exception|rescue|debug)\b/i
|
|
267
|
+
'error_analysis'
|
|
268
|
+
when /\b(config|configuration|environment|settings)\b/i
|
|
269
|
+
'configuration'
|
|
270
|
+
when /\b(documentation|docs|readme|guide)\b/i
|
|
271
|
+
'documentation'
|
|
272
|
+
else
|
|
273
|
+
'implementation_guide'
|
|
274
|
+
end
|
|
275
|
+
end
|
|
276
|
+
|
|
277
|
+
def apply_token_budget(content, budget)
|
|
278
|
+
estimated_tokens = estimate_tokens(content)
|
|
279
|
+
|
|
280
|
+
if estimated_tokens <= budget
|
|
281
|
+
content
|
|
282
|
+
else
|
|
283
|
+
# Truncate content to fit budget
|
|
284
|
+
chars_per_token = content.length.to_f / estimated_tokens
|
|
285
|
+
max_chars = (budget * chars_per_token * 0.9).to_i # 90% safety margin
|
|
286
|
+
|
|
287
|
+
content[0..max_chars].strip + "..."
|
|
288
|
+
end
|
|
289
|
+
end
|
|
290
|
+
|
|
291
|
+
def estimate_tokens(text)
|
|
292
|
+
return 0 if text.nil? || text.empty?
|
|
293
|
+
# Conservative estimation: ~4 characters per token
|
|
294
|
+
(text.length / 4.0).ceil
|
|
53
295
|
end
|
|
54
296
|
|
|
55
297
|
# Get system status
|
|
@@ -77,4 +319,16 @@ end
|
|
|
77
319
|
# Auto-configure if Rails is present
|
|
78
320
|
if defined?(Rails)
|
|
79
321
|
require_relative "hokipoki/railtie"
|
|
322
|
+
|
|
323
|
+
# Force Claude activation on Rails startup if detected
|
|
324
|
+
Rails.application.config.after_initialize do
|
|
325
|
+
# Small delay to ensure everything is loaded
|
|
326
|
+
Thread.new do
|
|
327
|
+
sleep(1) # Give Rails time to initialize
|
|
328
|
+
if Hokipoki.claude_parasite_active?
|
|
329
|
+
$stdout.puts "🦠 FORCE ACTIVATION: Claude CLI detected during Rails startup"
|
|
330
|
+
ClaudeAutoLoader.force_load!
|
|
331
|
+
end
|
|
332
|
+
end
|
|
333
|
+
end
|
|
80
334
|
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: hokipoki
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.5.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Rails Utilities
|
|
@@ -23,6 +23,62 @@ dependencies:
|
|
|
23
23
|
- - ">="
|
|
24
24
|
- !ruby/object:Gem::Version
|
|
25
25
|
version: '7.0'
|
|
26
|
+
- !ruby/object:Gem::Dependency
|
|
27
|
+
name: rotp
|
|
28
|
+
requirement: !ruby/object:Gem::Requirement
|
|
29
|
+
requirements:
|
|
30
|
+
- - "~>"
|
|
31
|
+
- !ruby/object:Gem::Version
|
|
32
|
+
version: '6.0'
|
|
33
|
+
type: :runtime
|
|
34
|
+
prerelease: false
|
|
35
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
36
|
+
requirements:
|
|
37
|
+
- - "~>"
|
|
38
|
+
- !ruby/object:Gem::Version
|
|
39
|
+
version: '6.0'
|
|
40
|
+
- !ruby/object:Gem::Dependency
|
|
41
|
+
name: rqrcode
|
|
42
|
+
requirement: !ruby/object:Gem::Requirement
|
|
43
|
+
requirements:
|
|
44
|
+
- - "~>"
|
|
45
|
+
- !ruby/object:Gem::Version
|
|
46
|
+
version: '2.2'
|
|
47
|
+
type: :runtime
|
|
48
|
+
prerelease: false
|
|
49
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
50
|
+
requirements:
|
|
51
|
+
- - "~>"
|
|
52
|
+
- !ruby/object:Gem::Version
|
|
53
|
+
version: '2.2'
|
|
54
|
+
- !ruby/object:Gem::Dependency
|
|
55
|
+
name: omniauth-github
|
|
56
|
+
requirement: !ruby/object:Gem::Requirement
|
|
57
|
+
requirements:
|
|
58
|
+
- - "~>"
|
|
59
|
+
- !ruby/object:Gem::Version
|
|
60
|
+
version: '2.0'
|
|
61
|
+
type: :runtime
|
|
62
|
+
prerelease: false
|
|
63
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
64
|
+
requirements:
|
|
65
|
+
- - "~>"
|
|
66
|
+
- !ruby/object:Gem::Version
|
|
67
|
+
version: '2.0'
|
|
68
|
+
- !ruby/object:Gem::Dependency
|
|
69
|
+
name: omniauth-rails_csrf_protection
|
|
70
|
+
requirement: !ruby/object:Gem::Requirement
|
|
71
|
+
requirements:
|
|
72
|
+
- - "~>"
|
|
73
|
+
- !ruby/object:Gem::Version
|
|
74
|
+
version: '1.0'
|
|
75
|
+
type: :runtime
|
|
76
|
+
prerelease: false
|
|
77
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
78
|
+
requirements:
|
|
79
|
+
- - "~>"
|
|
80
|
+
- !ruby/object:Gem::Version
|
|
81
|
+
version: '1.0'
|
|
26
82
|
- !ruby/object:Gem::Dependency
|
|
27
83
|
name: pg
|
|
28
84
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -51,6 +107,20 @@ dependencies:
|
|
|
51
107
|
- - ">="
|
|
52
108
|
- !ruby/object:Gem::Version
|
|
53
109
|
version: '0.3'
|
|
110
|
+
- !ruby/object:Gem::Dependency
|
|
111
|
+
name: sqlite3
|
|
112
|
+
requirement: !ruby/object:Gem::Requirement
|
|
113
|
+
requirements:
|
|
114
|
+
- - "~>"
|
|
115
|
+
- !ruby/object:Gem::Version
|
|
116
|
+
version: '1.4'
|
|
117
|
+
type: :runtime
|
|
118
|
+
prerelease: false
|
|
119
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
120
|
+
requirements:
|
|
121
|
+
- - "~>"
|
|
122
|
+
- !ruby/object:Gem::Version
|
|
123
|
+
version: '1.4'
|
|
54
124
|
- !ruby/object:Gem::Dependency
|
|
55
125
|
name: thor
|
|
56
126
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -201,14 +271,22 @@ extra_rdoc_files: []
|
|
|
201
271
|
files:
|
|
202
272
|
- LICENSE
|
|
203
273
|
- lib/generators/hive_mind/install_generator.rb
|
|
274
|
+
- lib/generators/hive_mind/start_generator.rb
|
|
204
275
|
- lib/generators/hive_mind/templates/create_hive_mind_documents.rb
|
|
205
276
|
- lib/generators/hive_mind/templates/embedding_service.rb
|
|
206
277
|
- lib/generators/hive_mind/templates/hive_mind_document.rb
|
|
278
|
+
- lib/generators/hive_mind/templates/hokipoki_claude.rb
|
|
207
279
|
- lib/generators/hive_mind/templates/smart_retrieval_engine.rb
|
|
280
|
+
- lib/generators/hokipoki/attach_parasite_generator.rb
|
|
281
|
+
- lib/generators/hokipoki/install_generator.rb
|
|
282
|
+
- lib/generators/hokipoki/scan_project_generator.rb
|
|
283
|
+
- lib/generators/parasite/install_generator.rb
|
|
208
284
|
- lib/hokipoki.rb
|
|
285
|
+
- lib/hokipoki/atomic_fact_extractor.rb
|
|
209
286
|
- lib/hokipoki/claude/auto_loader.rb
|
|
210
287
|
- lib/hokipoki/claude/connection_manager.rb
|
|
211
288
|
- lib/hokipoki/claude/parasite.rb
|
|
289
|
+
- lib/hokipoki/claude/thought_interceptor.rb
|
|
212
290
|
- lib/hokipoki/claude_auto_loader.rb
|
|
213
291
|
- lib/hokipoki/configuration.rb
|
|
214
292
|
- lib/hokipoki/console.rb
|
|
@@ -222,6 +300,8 @@ files:
|
|
|
222
300
|
- lib/hokipoki/parasites/universal_generator.rb
|
|
223
301
|
- lib/hokipoki/railtie.rb
|
|
224
302
|
- lib/hokipoki/tasks.rb
|
|
303
|
+
- lib/hokipoki/template_store.rb
|
|
304
|
+
- lib/hokipoki/vector_engine.rb
|
|
225
305
|
- lib/hokipoki/version.rb
|
|
226
306
|
homepage: https://github.com/rails-utilities/hokipoki
|
|
227
307
|
licenses:
|