hokipoki 0.8.8 ā 0.9.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
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: fa1b62d607dfb2520ace80c1f6c3900eaa2ae8343988d393027fea0666b1c57a
|
|
4
|
+
data.tar.gz: f284a626fa0d9eb9d805a94982869ee8b3b056209105707a8289a2b5d9c4162e
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 9a3a46c449c391a4bc07a161a51f1ae994d855bac9633dfcde9419dcc81ab16b976cf6be51270e1a3989fe87ef8de3a76bc601e116662827ef2c702710b7ce97
|
|
7
|
+
data.tar.gz: 5b791d24546050f74a825c3bae350a19d66be47a2d90c46295df0b4f263829fded112c5f0a249dba96c61086d9b1fb09f9d944a57933eca7accc6dd6dcf4c09d
|
|
@@ -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.0
|
|
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
|