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:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 54cd3ed2f4a1f275235ee421c6b7a1a398e9b67ee20a5b1aad42ccc7c2bee825
|
|
4
|
+
data.tar.gz: 39c5c13b3fa4fc1ce31808778dc1d89430d45d6878c742108062e266d65a9f17
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
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('✅')}
|
|
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
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
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
|
data/lib/hokipoki/version.rb
CHANGED
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.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
|