tidewave 0.3.0 → 0.3.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: d140360315f54166fc14e330f33fc5dd62e561c49ba3d6cb5044a8e7b5247e41
4
- data.tar.gz: c69a1a0363ce0f50a396599f2b551896a602431929731dd9fbf4fbe283823cf1
3
+ metadata.gz: 0f3737d76d054bed63cb68932692d012571e6dc6592e4acb3d38cfc996e136c9
4
+ data.tar.gz: 826dda40d4b76b7e399f91bf696463a1b8c70554ebc29a96ddea0d3aa43cef4a
5
5
  SHA512:
6
- metadata.gz: 6f3203bbce1c31681fcb2b21575ea62a8714a469f61ec30be8d59ccd22028592b7a33317b4f434e0d7a4051caaf1db1aa82247d395a961d4a09f1a1538cc6cd8
7
- data.tar.gz: 968742eed4690b5c2a1f8c0ecf233e4742a19bc2ac8a700d4f64eca2878bea8f70d1d2228cffc472019462790eb122601b7acfc608fd7950c100974f3c9053d4
6
+ metadata.gz: 7f48e43388215ba5d6db70be3e450d7f3358921f82ae4b6c855801ad3ee48aeea3ff1cdd2b7d00acbf072556cf8b4ab5982541f894b470a502dbf149c63a798f
7
+ data.tar.gz: d4acf2d1625913bbbbae42d74c9816f200dba1ab2e25dff182a83c63aff9f236c21062b8745568beb2dd4378e39cc23073d7c39cde725a31c36a74e0ba2edfd2
data/README.md CHANGED
@@ -57,7 +57,7 @@ The following config is available:
57
57
 
58
58
  * `preferred_orm` - which ORM to use, either `:active_record` (default) or `:sequel`
59
59
 
60
- * `team` - set your team configuration, such as `config.tidewave.team = { id: "my-company }`
60
+ * `team` - set your Tidewave Team configuration, such as `config.tidewave.team = { id: "my-company" }`
61
61
 
62
62
  ## Acknowledgements
63
63
 
@@ -2,13 +2,13 @@
2
2
 
3
3
  module Tidewave
4
4
  class Configuration
5
- attr_accessor :logger, :allow_remote_access, :preferred_orm, :credentials, :client_url, :team
5
+ attr_accessor :logger, :allow_remote_access, :preferred_orm, :dev, :client_url, :team
6
6
 
7
7
  def initialize
8
8
  @logger = nil
9
9
  @allow_remote_access = true
10
10
  @preferred_orm = :active_record
11
- @credentials = {}
11
+ @dev = false
12
12
  @client_url = "https://tidewave.ai"
13
13
  @team = {}
14
14
  end
@@ -26,8 +26,8 @@ module Tidewave
26
26
  raise NotImplementedError, "Subclasses must implement execute_query"
27
27
  end
28
28
 
29
- def get_base_class
30
- raise NotImplementedError, "Subclasses must implement get_base_class"
29
+ def get_models
30
+ raise NotImplementedError, "Subclasses must implement get_models"
31
31
  end
32
32
  end
33
33
  end
@@ -25,8 +25,8 @@ module Tidewave
25
25
  }
26
26
  end
27
27
 
28
- def get_base_class
29
- ::ActiveRecord::Base
28
+ def get_models
29
+ ::ActiveRecord::Base.descendants
30
30
  end
31
31
 
32
32
  private
@@ -29,8 +29,9 @@ module Tidewave
29
29
  }
30
30
  end
31
31
 
32
- def get_base_class
33
- ::Sequel::Model
32
+ def get_models
33
+ # Filter out anonymous Sequel models that can't be resolved as constants
34
+ ::Sequel::Model.descendants.reject { |model| model.name&.start_with?("Sequel::_Model(") }
34
35
  end
35
36
  end
36
37
  end
@@ -11,7 +11,6 @@ require "erb"
11
11
 
12
12
  class Tidewave::Middleware
13
13
  TIDEWAVE_ROUTE = "tidewave".freeze
14
- EMPTY_ROUTE = "empty".freeze
15
14
  SSE_ROUTE = "mcp".freeze
16
15
  MESSAGES_ROUTE = "mcp/message".freeze
17
16
  SHELL_ROUTE = "shell".freeze
@@ -63,8 +62,6 @@ class Tidewave::Middleware
63
62
  case [ request.request_method, path ]
64
63
  when [ "GET", [ TIDEWAVE_ROUTE ] ]
65
64
  return home(request)
66
- when [ "GET", [ TIDEWAVE_ROUTE, EMPTY_ROUTE ] ]
67
- return empty(request)
68
65
  when [ "POST", [ TIDEWAVE_ROUTE, SHELL_ROUTE ] ]
69
66
  return shell(request)
70
67
  end
@@ -98,11 +95,6 @@ class Tidewave::Middleware
98
95
  [ 200, { "Content-Type" => "text/html" }, [ html ] ]
99
96
  end
100
97
 
101
- def empty(request)
102
- html = ""
103
- [ 200, { "Content-Type" => "text/html" }, [ html ] ]
104
- end
105
-
106
98
  def forbidden(message)
107
99
  Rails.logger.warn(message)
108
100
  [ 403, { "Content-Type" => "text/plain" }, [ message ] ]
@@ -17,13 +17,63 @@ class Tidewave::Tools::GetLogs < Tidewave::Tools::Base
17
17
  log_file = Rails.root.join("log", "#{Rails.env}.log")
18
18
  return "Log file not found" unless File.exist?(log_file)
19
19
 
20
- logs = File.readlines(log_file)
20
+ regex = Regexp.new(grep, Regexp::IGNORECASE) if grep
21
+ matching_lines = []
21
22
 
22
- if grep
23
- regex = Regexp.new(grep, Regexp::IGNORECASE)
24
- logs = logs.select { |line| line.match?(regex) }
23
+ tail_lines(log_file) do |line|
24
+ if regex.nil? || line.match?(regex)
25
+ matching_lines.unshift(line)
26
+ break if matching_lines.size >= tail
27
+ end
25
28
  end
26
29
 
27
- logs.last(tail).join
30
+ matching_lines.join
31
+ end
32
+
33
+ private
34
+
35
+ def tail_lines(file_path)
36
+ File.open(file_path, "rb") do |file|
37
+ file.seek(0, IO::SEEK_END)
38
+ file_size = file.pos
39
+ return if file_size == 0
40
+
41
+ buffer_size = [ 4096, file_size ].min
42
+ pos = file_size
43
+ buffer = ""
44
+
45
+ while pos > 0 && buffer.count("\n") < 10000 # Safety limit
46
+ # Move back by buffer_size or to beginning of file
47
+ seek_pos = [ pos - buffer_size, 0 ].max
48
+ file.seek(seek_pos)
49
+
50
+ # Read chunk
51
+ chunk = file.read(pos - seek_pos)
52
+ buffer = chunk + buffer
53
+ pos = seek_pos
54
+
55
+ # Extract complete lines from buffer
56
+ lines = buffer.split("\n")
57
+
58
+ # Keep the first partial line (if any) for next iteration
59
+ if pos > 0 && !buffer.start_with?("\n")
60
+ buffer = lines.shift || ""
61
+ else
62
+ buffer = ""
63
+ end
64
+
65
+ # Yield lines in reverse order (last to first)
66
+ lines.reverse_each do |line|
67
+ yield line + "\n" unless line.empty?
68
+ end
69
+
70
+ break if pos == 0
71
+ end
72
+
73
+ # Handle any remaining buffer content
74
+ unless buffer.empty?
75
+ yield buffer + "\n"
76
+ end
77
+ end
28
78
  end
29
79
  end
@@ -10,8 +10,10 @@ class Tidewave::Tools::GetModels < Tidewave::Tools::Base
10
10
  # Ensure all models are loaded
11
11
  Rails.application.eager_load!
12
12
 
13
- base_class = Tidewave::DatabaseAdapter.current.get_base_class
14
- base_class.descendants.map do |model|
13
+ # Use adapter to get models (encapsulates ORM-specific logic)
14
+ models = Tidewave::DatabaseAdapter.current.get_models
15
+
16
+ models.map do |model|
15
17
  if location = get_relative_source_location(model.name)
16
18
  "* #{model.name} at #{location}"
17
19
  else
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Tidewave
4
- VERSION = "0.3.0"
4
+ VERSION = "0.3.1"
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tidewave
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yorick Jacquin
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2025-09-08 00:00:00.000000000 Z
12
+ date: 2025-09-16 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rails