rubik 0.3.3 → 0.3.5

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.
Files changed (48) hide show
  1. checksums.yaml +4 -4
  2. data/ATTRIBUTION.md +1 -1
  3. data/CHANGELOG.md +102 -0
  4. data/lib/rubik/adapter/process.rb +11 -8
  5. data/lib/rubik/ast/go_extractor.rb +9 -2
  6. data/lib/rubik/ast/rust_extractor.rb +9 -2
  7. data/lib/rubik/ast/typescript_extractor.rb +13 -7
  8. data/lib/rubik/buffer/manager.rb +99 -69
  9. data/lib/rubik/config/defaults.rb +17 -20
  10. data/lib/rubik/config.rb +0 -6
  11. data/lib/rubik/context/git_lister.rb +3 -1
  12. data/lib/rubik/llm/anthropic.rb +5 -2
  13. data/lib/rubik/llm/client.rb +102 -72
  14. data/lib/rubik/llm/openai_compatible.rb +83 -68
  15. data/lib/rubik/lsp/client.rb +320 -96
  16. data/lib/rubik/lsp/manager.rb +83 -12
  17. data/lib/rubik/lsp/server_command.rb +102 -0
  18. data/lib/rubik/orchestrator/goal_ledger/patch.rb +48 -30
  19. data/lib/rubik/orchestrator/lsp_feedback.rb +20 -4
  20. data/lib/rubik/orchestrator/subagent/reuse.rb +2 -2
  21. data/lib/rubik/orchestrator/subagent/spawn_transaction.rb +60 -31
  22. data/lib/rubik/platform/process.rb +6 -6
  23. data/lib/rubik/platform/sanitize.rb +37 -16
  24. data/lib/rubik/prompt/doctrine.rb +4 -0
  25. data/lib/rubik/repl/commands/agent_context.rb +126 -104
  26. data/lib/rubik/repl/commands/agent_execution.rb +183 -155
  27. data/lib/rubik/repl/commands/agent_models.rb +112 -87
  28. data/lib/rubik/repl/commands/agent_providers.rb +190 -156
  29. data/lib/rubik/repl/commands/buffer.rb +122 -88
  30. data/lib/rubik/repl/commands/lsp.rb +212 -179
  31. data/lib/rubik/repl/commands/mcp.rb +120 -92
  32. data/lib/rubik/repl/commands/session.rb +90 -59
  33. data/lib/rubik/repl/commands/workspace.rb +266 -246
  34. data/lib/rubik/repl/shell.rb +10 -1
  35. data/lib/rubik/runtime/discovery.rb +12 -6
  36. data/lib/rubik/runtime/overlay_storage.rb +59 -2
  37. data/lib/rubik/sandbox/driver/docker.rb +2 -2
  38. data/lib/rubik/session/replayer.rb +1 -2
  39. data/lib/rubik/storage/store.rb +3 -2
  40. data/lib/rubik/storage/vakanuvis/distill_gate.rb +6 -2
  41. data/lib/rubik/storage/vakanuvis/gate.rb +37 -16
  42. data/lib/rubik/storage/vakanuvis/harness.rb +36 -21
  43. data/lib/rubik/storage/vakanuvis/memory_steward.rb +12 -6
  44. data/lib/rubik/tools/builtins/lifecycle.rb +34 -7
  45. data/lib/rubik/tools/builtins/lsp.rb +36 -8
  46. data/lib/rubik/tools/fuzzy_matcher.rb +27 -11
  47. data/lib/rubik/version.rb +1 -1
  48. metadata +2 -1
@@ -153,8 +153,13 @@ module Rubik
153
153
  pref = Array.new(f_lines.size + 1, 0)
154
154
  f_lines.each_with_index { |l, idx| pref[idx + 1] = pref[idx] + (target_set.include?(l) ? 1 : 0) }
155
155
 
156
- (0...(f_lines.size)).each do |i|
157
- window_len = [k, f_lines.size - i].min
156
+ # PERF: while loop with direct index increments avoids Enumerator/Range allocations per call (~17-20% faster, ~12% fewer allocations).
157
+ i = 0
158
+ f_lines_size = f_lines.size
159
+ has_diff_lcs = defined?(Diff::LCS) && Diff::LCS.respond_to?(:LCS)
160
+ while i < f_lines_size
161
+ rem = f_lines_size - i
162
+ window_len = [k, rem].min
158
163
  total = [k, window_len].max
159
164
 
160
165
  overlap_count = pref[i + window_len] - pref[i]
@@ -168,27 +173,38 @@ module Rubik
168
173
  end
169
174
  else
170
175
  # PERF: Upper-bound check — if maximum possible overlap cannot beat best_score, skip LCS
171
- next if (overlap_count.to_f / total) <= best_score
176
+ if (overlap_count.to_f / total) <= best_score
177
+ i += 1
178
+ next
179
+ end
172
180
 
173
181
  # PERF: Array#[start, len] slice avoids Range object allocation inside hot loop
174
182
  window = f_lines[i, window_len]
175
183
 
176
184
  matches =
177
- if defined?(Diff::LCS) && Diff::LCS.respond_to?(:LCS)
185
+ if has_diff_lcs
178
186
  Diff::LCS.LCS(t_lines, window).size
179
187
  else
180
188
  # Fallback line matching
181
- (0...[t_lines.size, window.size].min).count { |idx| t_lines[idx] == window[idx] }
189
+ m = 0
190
+ idx = 0
191
+ limit = [t_lines.size, window.size].min
192
+ while idx < limit
193
+ m += 1 if t_lines[idx] == window[idx]
194
+ idx += 1
195
+ end
196
+ m
182
197
  end
183
198
  score = total.positive? ? (matches.to_f / total) : 0.0
184
199
  end
185
200
 
186
- next unless score > best_score
187
-
188
- best_score = score
189
- best_range = (i + 1)..(i + window_len)
190
- best_i = i
191
- best_window_len = window_len
201
+ if score > best_score
202
+ best_score = score
203
+ best_range = (i + 1)..(i + window_len)
204
+ best_i = i
205
+ best_window_len = window_len
206
+ end
207
+ i += 1
192
208
  end
193
209
 
194
210
  return nil if best_score < 0.25 || best_i.nil?
data/lib/rubik/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Rubik
4
- VERSION = "0.3.3"
4
+ VERSION = "0.3.5"
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rubik
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.3
4
+ version: 0.3.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Özgür Ulukır
@@ -322,6 +322,7 @@ files:
322
322
  - lib/rubik/lsp.rb
323
323
  - lib/rubik/lsp/client.rb
324
324
  - lib/rubik/lsp/manager.rb
325
+ - lib/rubik/lsp/server_command.rb
325
326
  - lib/rubik/mcp.rb
326
327
  - lib/rubik/mcp/boot_lifecycle.rb
327
328
  - lib/rubik/mcp/client.rb