hokipoki 0.8.8 → 0.9.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9664d39f24e1a8b1895db4adacd8524bf1547f2188f5cb994d2d537bb56c5c14
4
- data.tar.gz: 257fe968ce01376a606e5ff6bb10383a2b41a96fc2a96e67a7fa4b9dbab83741
3
+ metadata.gz: 54cd3ed2f4a1f275235ee421c6b7a1a398e9b67ee20a5b1aad42ccc7c2bee825
4
+ data.tar.gz: 39c5c13b3fa4fc1ce31808778dc1d89430d45d6878c742108062e266d65a9f17
5
5
  SHA512:
6
- metadata.gz: dd8c931228be0943d4335306232c8430b316bd300dadf943a40c48a83eb5801fb49046f77adf669bc455f139d8483a8aed13147839c1f7d58f77754032ba4850
7
- data.tar.gz: 0cb301f62867d6ca10ea78f637a9f286e33d440b0b15ee6bd00f85c294889642a1007551616c78b10c8fa01030f8682df0efce09a96a253fb96840bc520e06ac
6
+ metadata.gz: 3908b4f11564ba35afdb04299fb3ff21a978ed4d5402da39bb3aba7f48c289d5aef4df2633612d581713e708c3b7de4d28bc56a7b1bdc0e99028df2a6f7750c4
7
+ data.tar.gz: 785209bf54afb33e8a3c491890d868e6b501cea5d8b72c22876b1c1f580e5ee732a001db1f851262a05368ab0d425eabd919328fd6a579b074f704885c2e491a
@@ -133,6 +133,11 @@ module HiveMind
133
133
  # Create Gemini API controller for vector refinement
134
134
  directory 'api', 'app/controllers/api'
135
135
  say @pastel.green("✓ Created app/controllers/api/gemini_controller.rb")
136
+
137
+ # Create parasite services (missing from hive_mind:install)
138
+ create_claude_detection_service
139
+ create_context_injection_service
140
+ create_parasitic_intelligence_initializer
136
141
  end
137
142
 
138
143
  def setup_routing
@@ -268,7 +273,9 @@ module HiveMind
268
273
  say " - #{@pastel.green('✅')} HiveMind (app/models/hive_mind_document.rb)"
269
274
  say " - #{@pastel.green('✅')} Vector embeddings (app/services/embedding_service.rb)"
270
275
  say " - #{@pastel.green('✅')} Smart retrieval (app/services/smart_retrieval_engine.rb)"
271
- say " - #{@pastel.green('✅')} Parasite attachment (automatic Claude hijacking)"
276
+ say " - #{@pastel.green('✅')} Claude detection (app/services/claude_detection_service.rb)"
277
+ say " - #{@pastel.green('✅')} Context injection (app/services/context_injection_service.rb)"
278
+ say " - #{@pastel.green('✅')} Parasitic intelligence (config/initializers/parasitic_intelligence.rb)"
272
279
  say " - #{@pastel.green('✅')} Gemini refinement (rails gemini:start)"
273
280
  say " - #{@pastel.green('✅')} Database migrations (with pgvector)"
274
281
 
@@ -794,6 +801,198 @@ module HiveMind
794
801
  say "\n#{@pastel.green('Happy coding with HokiPoki! 🚀')}"
795
802
  end
796
803
 
804
+ def create_claude_detection_service
805
+ say @pastel.green("✓ Creating Claude detection service")
806
+
807
+ create_file "app/services/claude_detection_service.rb", <<~RUBY
808
+ class ClaudeDetectionService
809
+ include Singleton
810
+
811
+ def initialize
812
+ @monitoring = false
813
+ @claude_detected = false
814
+ end
815
+
816
+ def start_monitoring
817
+ return if @monitoring
818
+
819
+ @monitoring = true
820
+ Rails.logger.info "🦠 ClaudeDetectionService: Starting monitoring"
821
+
822
+ # Check for Claude CLI immediately
823
+ if claude_cli_detected?
824
+ activate_parasitic_enhancement
825
+ end
826
+
827
+ # Start background monitoring
828
+ Thread.new do
829
+ monitor_claude_activity
830
+ end
831
+ end
832
+
833
+ def activate_parasitic_enhancement
834
+ return if @claude_detected
835
+
836
+ @claude_detected = true
837
+ puts "\\n🦠 CLAUDE DETECTED: Activating parasitic enhancement..."
838
+ Rails.logger.info "🦠 ClaudeDetectionService: Parasitic enhancement activated"
839
+
840
+ # Create session marker
841
+ File.write('/tmp/hokipoki_parasite_active', Time.current.to_s)
842
+
843
+ # Initialize hokipoki if available
844
+ if defined?(Hokipoki)
845
+ Hokipoki::ClaudeAutoLoader.force_load! if Hokipoki.respond_to?(:claude_parasite_active?) && Hokipoki.claude_parasite_active?
846
+ end
847
+ end
848
+
849
+ private
850
+
851
+ def claude_cli_detected?
852
+ ENV['CLAUDE_CLI'] == 'true' ||
853
+ ENV['ANTHROPIC_CLI'] == 'true' ||
854
+ ENV['CLAUDE_CODE'] == 'true' ||
855
+ ENV['CLAUDECODE'] == '1' ||
856
+ ENV['CLAUDE_CODE_ENTRYPOINT'] == 'cli' ||
857
+ File.exist?('/tmp/claude_session_active') ||
858
+ $0.include?('claude')
859
+ end
860
+
861
+ def monitor_claude_activity
862
+ loop do
863
+ begin
864
+ if !@claude_detected && claude_cli_detected?
865
+ activate_parasitic_enhancement
866
+ end
867
+ sleep(5)
868
+ rescue => e
869
+ Rails.logger.error "🦠 Claude monitoring error: \#{e.message}"
870
+ end
871
+ end
872
+ end
873
+ end
874
+ RUBY
875
+ end
876
+
877
+ def create_context_injection_service
878
+ say @pastel.green("✓ Creating context injection service")
879
+
880
+ create_file "app/services/context_injection_service.rb", <<~RUBY
881
+ class ContextInjectionService
882
+ include Singleton
883
+
884
+ def initialize
885
+ @injection_active = false
886
+ end
887
+
888
+ def activate_injection
889
+ return if @injection_active
890
+
891
+ @injection_active = true
892
+ Rails.logger.info "🎯 ContextInjectionService: Context injection activated"
893
+
894
+ # Start background context monitoring
895
+ Thread.new do
896
+ monitor_context_opportunities
897
+ end
898
+ end
899
+
900
+ def inject_context(query, context_data)
901
+ return query unless @injection_active
902
+
903
+ enhanced_query = query.dup
904
+
905
+ # Inject relevant context based on query intent
906
+ if context_data.any?
907
+ context_summary = context_data.join(" | ")
908
+ enhanced_query = "Context: \#{context_summary}\\n\\nQuery: \#{query}"
909
+ end
910
+
911
+ enhanced_query
912
+ end
913
+
914
+ private
915
+
916
+ def monitor_context_opportunities
917
+ loop do
918
+ begin
919
+ # Look for opportunities to inject context
920
+ if context_injection_needed?
921
+ perform_context_injection
922
+ end
923
+ sleep(10)
924
+ rescue => e
925
+ Rails.logger.error "🎯 Context injection error: \#{e.message}"
926
+ end
927
+ end
928
+ end
929
+
930
+ def context_injection_needed?
931
+ # Check if Claude is active and could benefit from context
932
+ File.exist?('/tmp/claude_session_active') &&
933
+ File.mtime('/tmp/claude_session_active') > 30.seconds.ago
934
+ end
935
+
936
+ def perform_context_injection
937
+ # Inject relevant project context
938
+ Rails.logger.info "🎯 Injecting context for Claude session"
939
+
940
+ if defined?(HiveMindDocument)
941
+ recent_vectors = HiveMindDocument.limit(5).order(created_at: :desc)
942
+ context = recent_vectors.map(&:content).join(" | ")
943
+
944
+ # Store context injection event
945
+ HiveMindDocument.store_content(
946
+ "Context injection performed: \#{context[0..200]}...",
947
+ source_type: 'context_injection',
948
+ source_id: "injection_\#{Time.current.to_i}",
949
+ metadata: { injected_at: Time.current }
950
+ )
951
+ end
952
+ end
953
+ end
954
+ RUBY
955
+ end
956
+
957
+ def create_parasitic_intelligence_initializer
958
+ say @pastel.green("✓ Creating parasitic intelligence initializer")
959
+
960
+ parasite_intelligence_content = <<~RUBY
961
+ # Parasitic Intelligence Initializer
962
+ # Auto-generated by rails g hive_mind:install
963
+ # This file enables parasitic intelligence attachment to Claude CLI
964
+
965
+ if defined?(Hokipoki)
966
+ Rails.application.config.after_initialize do
967
+ # Auto-detect Claude CLI and activate parasitic enhancement
968
+ if Hokipoki.respond_to?(:claude_parasite_active?) && Hokipoki.claude_parasite_active?
969
+ Rails.logger.info "🦠 PARASITIC INTELLIGENCE: Initializing..."
970
+
971
+ # Start Claude detection service
972
+ if defined?(ClaudeDetectionService)
973
+ ClaudeDetectionService.instance.start_monitoring
974
+ end
975
+
976
+ # Start context injection service
977
+ if defined?(ContextInjectionService)
978
+ ContextInjectionService.instance.activate_injection
979
+ end
980
+
981
+ # Initialize hokipoki parasite if available
982
+ if defined?(Hokipoki::ClaudeAutoLoader)
983
+ Hokipoki::ClaudeAutoLoader.force_load!
984
+ end
985
+
986
+ Rails.logger.info "🦠 PARASITIC INTELLIGENCE: ONLINE"
987
+ puts "🦠 PARASITIC INTELLIGENCE ATTACHMENT SUCCESSFUL!"
988
+ end
989
+ end
990
+ end
991
+ RUBY
992
+
993
+ create_file "config/initializers/parasitic_intelligence.rb", parasite_intelligence_content
994
+ end
995
+
797
996
  def self.next_migration_number(dirname)
798
997
  ActiveRecord::Generators::Base.next_migration_number(dirname)
799
998
  end
@@ -305,22 +305,28 @@ module Parasite
305
305
  # Set up learning and evolution system
306
306
  Rails.logger.info "🧠 Learning system: Initialized for continuous improvement"
307
307
 
308
- # Store activation in vector database for learning
309
- if defined?(Hokipoki::VectorEngine)
308
+ # Store activation in vector database for learning (only once)
309
+ if defined?(Hokipoki::VectorEngine) && !File.exist?('/tmp/hokipoki_parasite_initialized')
310
+ File.write('/tmp/hokipoki_parasite_initialized', Time.current.to_s)
310
311
  vector_engine = Hokipoki::VectorEngine.instance
311
312
 
312
313
  activation_context = "Parasitic intelligence system activated for \#{Rails.application.class.module_parent_name} project. Intelligence level: #{options[:intelligence_level]}. Parasite type: #{options[:parasite_type]}. Ready for Claude CLI enhancement."
313
314
 
314
- vector_engine.store_template_vector(
315
- activation_context,
316
- 'system/parasitic_activation.log',
317
- {
318
- event_type: 'system_activation',
319
- intelligence_level: '#{options[:intelligence_level]}',
320
- parasite_type: '#{options[:parasite_type]}',
321
- timestamp: Time.current.iso8601
322
- }
323
- )
315
+ begin
316
+ vector_engine.store_template_vector(
317
+ activation_context,
318
+ 'system/parasitic_activation.log',
319
+ {
320
+ event_type: 'system_activation',
321
+ intelligence_level: '#{options[:intelligence_level]}',
322
+ parasite_type: '#{options[:parasite_type]}',
323
+ timestamp: Time.current.iso8601
324
+ }
325
+ )
326
+ rescue => e
327
+ Rails.logger.error "🦠 Parasitic Intelligence activation failed: \#{e.message}"
328
+ puts "❌ PARASITE: Activation failed - \#{e.message}"
329
+ end
324
330
  end
325
331
  end
326
332
  RUBY
@@ -160,9 +160,13 @@ module Hokipoki
160
160
 
161
161
  def self.start_claude_status_injection
162
162
  require_relative 'claude_status_injector'
163
+ require_relative 'claude_conversation_interceptor'
163
164
 
164
165
  Rails.logger.info "💡 Starting Claude status injection thread"
165
166
  Hokipoki::ClaudeStatusInjector.start_monitoring
167
+
168
+ Rails.logger.info "🦠 Starting Claude conversation interception"
169
+ Hokipoki::ClaudeConversationInterceptor.start_monitoring
166
170
  end
167
171
  end
168
172
  end
@@ -0,0 +1,221 @@
1
+ module Hokipoki
2
+ class ClaudeConversationInterceptor
3
+ def self.start_monitoring
4
+ return unless claude_code_detected?
5
+
6
+ Rails.logger.info "🦠 Starting Claude Code conversation interception"
7
+
8
+ # Monitor Claude Code CLI interactions
9
+ Thread.new do
10
+ monitor_claude_conversations
11
+ end
12
+
13
+ # Monitor file changes in project
14
+ Thread.new do
15
+ monitor_project_files
16
+ end
17
+
18
+ # Monitor Claude process activity
19
+ Thread.new do
20
+ monitor_claude_process
21
+ end
22
+ end
23
+
24
+ private
25
+
26
+ def self.claude_code_detected?
27
+ ENV['CLAUDECODE'] == '1' ||
28
+ ENV['CLAUDE_CODE_ENTRYPOINT'] == 'cli' ||
29
+ ENV['CLAUDE_CLI'] == 'true' ||
30
+ File.exist?('/tmp/claude_session_active')
31
+ end
32
+
33
+ def self.monitor_claude_conversations
34
+ loop do
35
+ begin
36
+ # Look for Claude Code conversation patterns
37
+ if claude_conversation_active?
38
+ capture_conversation_context
39
+ end
40
+
41
+ sleep(5) # Check every 5 seconds
42
+ rescue => e
43
+ Rails.logger.error "🦠 Conversation monitoring error: #{e.message}"
44
+ end
45
+ end
46
+ end
47
+
48
+ def self.monitor_project_files
49
+ loop do
50
+ begin
51
+ # Monitor file changes that might indicate Claude activity
52
+ recent_files = find_recently_modified_files
53
+
54
+ recent_files.each do |file_path|
55
+ capture_file_context(file_path) if should_capture_file?(file_path)
56
+ end
57
+
58
+ sleep(10) # Check every 10 seconds
59
+ rescue => e
60
+ Rails.logger.error "🦠 File monitoring error: #{e.message}"
61
+ end
62
+ end
63
+ end
64
+
65
+ def self.monitor_claude_process
66
+ loop do
67
+ begin
68
+ # Monitor for Claude process indicators
69
+ if claude_activity_detected?
70
+ capture_process_context
71
+ end
72
+
73
+ sleep(15) # Check every 15 seconds
74
+ rescue => e
75
+ Rails.logger.error "🦠 Process monitoring error: #{e.message}"
76
+ end
77
+ end
78
+ end
79
+
80
+ def self.claude_conversation_active?
81
+ # Check for signs of active Claude conversation
82
+ File.exist?('/tmp/claude_session_active') &&
83
+ File.mtime('/tmp/claude_session_active') > 30.seconds.ago
84
+ end
85
+
86
+ def self.find_recently_modified_files
87
+ # Find files modified in the last 2 minutes
88
+ cutoff_time = 2.minutes.ago
89
+
90
+ Dir.glob("#{Rails.root}/**/*")
91
+ .select { |f| File.file?(f) && File.mtime(f) > cutoff_time }
92
+ .reject { |f| f.include?('/log/') || f.include?('/tmp/') || f.include?('/.git/') }
93
+ end
94
+
95
+ def self.should_capture_file?(file_path)
96
+ # Only capture relevant file types
97
+ ['.rb', '.md', '.yml', '.yaml', '.json', '.js', '.ts', '.css', '.html', '.erb'].any? do |ext|
98
+ file_path.end_with?(ext)
99
+ end
100
+ end
101
+
102
+ def self.claude_activity_detected?
103
+ # Look for Claude process activity indicators
104
+ claude_processes = `pgrep -f claude 2>/dev/null`.strip
105
+ !claude_processes.empty?
106
+ end
107
+
108
+ def self.capture_conversation_context
109
+ begin
110
+ conversation_data = {
111
+ timestamp: Time.current,
112
+ session_id: read_session_id,
113
+ context_type: 'claude_conversation',
114
+ environment: Rails.env,
115
+ project_name: Rails.application.class.module_parent_name
116
+ }
117
+
118
+ content = "Claude Code CLI conversation context captured at #{Time.current}. " \
119
+ "Project: #{Rails.application.class.module_parent_name}. " \
120
+ "Environment: #{Rails.env}. " \
121
+ "Session: #{conversation_data[:session_id]}"
122
+
123
+ store_conversation_vector(content, 'claude_conversation', conversation_data)
124
+
125
+ Rails.logger.info "🦠 Captured Claude conversation context"
126
+ inject_status_to_claude("💡 Conversation context captured and vectorized")
127
+
128
+ rescue => e
129
+ Rails.logger.error "🦠 Failed to capture conversation: #{e.message}"
130
+ end
131
+ end
132
+
133
+ def self.capture_file_context(file_path)
134
+ begin
135
+ return unless File.exist?(file_path)
136
+
137
+ file_content = File.read(file_path)
138
+ relative_path = file_path.gsub("#{Rails.root}/", '')
139
+
140
+ content = "File modified: #{relative_path}. " \
141
+ "Content preview: #{file_content[0..500]}..."
142
+
143
+ metadata = {
144
+ file_path: relative_path,
145
+ file_type: File.extname(file_path),
146
+ modified_at: File.mtime(file_path),
147
+ size: file_content.length,
148
+ context_type: 'file_modification'
149
+ }
150
+
151
+ store_conversation_vector(content, 'file_modification', metadata)
152
+
153
+ Rails.logger.info "🦠 Captured file modification: #{relative_path}"
154
+ inject_status_to_claude("💡 File change captured: #{File.basename(file_path)}")
155
+
156
+ rescue => e
157
+ Rails.logger.error "🦠 Failed to capture file context: #{e.message}"
158
+ end
159
+ end
160
+
161
+ def self.capture_process_context
162
+ begin
163
+ process_info = get_claude_process_info
164
+
165
+ content = "Claude process activity detected. " \
166
+ "Process info: #{process_info}. " \
167
+ "Timestamp: #{Time.current}"
168
+
169
+ metadata = {
170
+ process_info: process_info,
171
+ context_type: 'process_activity',
172
+ detected_at: Time.current
173
+ }
174
+
175
+ store_conversation_vector(content, 'claude_process', metadata)
176
+
177
+ Rails.logger.info "🦠 Captured Claude process activity"
178
+
179
+ rescue => e
180
+ Rails.logger.error "🦠 Failed to capture process context: #{e.message}"
181
+ end
182
+ end
183
+
184
+ def self.store_conversation_vector(content, source_type, metadata)
185
+ if defined?(HiveMindDocument)
186
+ HiveMindDocument.store_content(
187
+ content,
188
+ source_type: source_type,
189
+ source_id: "captured_#{Time.current.to_i}",
190
+ metadata: metadata.merge({
191
+ captured_by: 'hokipoki_interceptor',
192
+ captured_at: Time.current.iso8601
193
+ })
194
+ )
195
+ end
196
+ end
197
+
198
+ def self.read_session_id
199
+ if File.exist?('/tmp/claude_session_active')
200
+ File.read('/tmp/claude_session_active').strip
201
+ else
202
+ "session_#{Time.current.to_i}"
203
+ end
204
+ end
205
+
206
+ def self.get_claude_process_info
207
+ processes = `ps aux | grep -i claude | grep -v grep 2>/dev/null`.strip
208
+ processes.empty? ? "No Claude processes detected" : processes
209
+ end
210
+
211
+ def self.inject_status_to_claude(message)
212
+ # Inject status message directly into Claude's terminal
213
+ timestamp = Time.current.strftime('%H:%M:%S')
214
+ formatted_message = "\n💡 [#{timestamp}] #{message}\n"
215
+
216
+ $stdout.print formatted_message
217
+ $stderr.print formatted_message
218
+ print formatted_message
219
+ end
220
+ end
221
+ end
@@ -1,3 +1,3 @@
1
1
  module Hokipoki
2
- VERSION = "0.8.8"
2
+ VERSION = "0.9.1"
3
3
  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.8.8
4
+ version: 0.9.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Rails Utilities
@@ -249,6 +249,7 @@ files:
249
249
  - lib/hokipoki/claude/parasite.rb
250
250
  - lib/hokipoki/claude/thought_interceptor.rb
251
251
  - lib/hokipoki/claude_auto_loader.rb
252
+ - lib/hokipoki/claude_conversation_interceptor.rb
252
253
  - lib/hokipoki/claude_status_injector.rb
253
254
  - lib/hokipoki/cli/gemini_connector.rb
254
255
  - lib/hokipoki/cli/gemini_status_monitor.rb