tina4ruby 3.10.55 → 3.10.60
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 +4 -4
- data/README.md +2 -1
- data/lib/tina4/metrics.rb +7 -5
- data/lib/tina4/rack_app.rb +2 -1
- data/lib/tina4/version.rb +1 -1
- data/lib/tina4/webserver.rb +65 -4
- data/lib/tina4.rb +2 -1
- metadata +5 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: ddb9c534659e0d305415603e274260d767bc4970a35522a810953265096d3749
|
|
4
|
+
data.tar.gz: 81fcaba8b3541777f3211b4e9972004b08718e97821debdb534fad71f06a1796
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 80aae860b1a396277acbd1c6157f3d463f8345e803c8a70d1e89a3a0915ab609bda1eb6825fc73e107681105ada1a226b77f85e2e782af5940c6ba634a4e1582
|
|
7
|
+
data.tar.gz: 46f3e5b59f8d98e1c7574093e3ecb2e5dbc0160bc3565b04cbd086beaf2a43ea74005c530de5a70bd3f0108965d3ada5e902328a58fcb75c5d6a12d067d57c66
|
data/README.md
CHANGED
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
<img src="https://tina4.com/logo.svg" alt="Tina4" width="200">
|
|
3
3
|
</p>
|
|
4
4
|
<h1 align="center">Tina4 Ruby</h1>
|
|
5
|
-
<h3 align="center">
|
|
5
|
+
<h3 align="center">TINA4 — The Intelligent Native Application 4ramework</h3>
|
|
6
|
+
<p align="center"><em>Simple. Fast. Human. | Built for AI. Built for you.</em></p>
|
|
6
7
|
<p align="center">54 built-in features. Zero runtime dependencies. One require, everything works.</p>
|
|
7
8
|
<p align="center">
|
|
8
9
|
<a href="https://rubygems.org/gems/tina4ruby"><img src="https://img.shields.io/gem/v/tina4ruby?color=7b1fa2&label=RubyGems" alt="RubyGems"></a>
|
data/lib/tina4/metrics.rb
CHANGED
|
@@ -406,11 +406,13 @@ module Tina4
|
|
|
406
406
|
|
|
407
407
|
def self._has_matching_test(rel_path)
|
|
408
408
|
name = File.basename(rel_path, '.rb')
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
409
|
+
File.exist?("spec/#{name}_spec.rb") ||
|
|
410
|
+
File.exist?("spec/#{name}s_spec.rb") ||
|
|
411
|
+
File.exist?("spec/tina4/#{name}_spec.rb") ||
|
|
412
|
+
File.exist?("test/#{name}_test.rb") ||
|
|
413
|
+
File.exist?("spec/#{name}_test.rb") ||
|
|
414
|
+
File.exist?("test/test_#{name}.rb") ||
|
|
415
|
+
File.exist?("test/#{name}_spec.rb")
|
|
414
416
|
end
|
|
415
417
|
|
|
416
418
|
def self._files_hash(root)
|
data/lib/tina4/rack_app.rb
CHANGED
|
@@ -460,7 +460,8 @@ module Tina4
|
|
|
460
460
|
<div class="hero">
|
|
461
461
|
<img src="/images/tina4-logo-icon.webp" class="logo" alt="Tina4">
|
|
462
462
|
<h1>Tina4Ruby</h1>
|
|
463
|
-
<p class="tagline">
|
|
463
|
+
<p class="tagline">The Intelligent Native Application 4ramework</p>
|
|
464
|
+
<p class="tagline" style="font-size:0.95rem;margin-top:-1rem">Simple. Fast. Human. | Built for AI. Built for you.</p>
|
|
464
465
|
<div class="actions">
|
|
465
466
|
<a href="https://tina4.com/ruby" class="btn" target="_blank">Website</a>
|
|
466
467
|
<a href="/__dev" class="btn">Dev Admin</a>
|
data/lib/tina4/version.rb
CHANGED
data/lib/tina4/webserver.rb
CHANGED
|
@@ -8,10 +8,71 @@ module Tina4
|
|
|
8
8
|
@port = port
|
|
9
9
|
end
|
|
10
10
|
|
|
11
|
+
# Kill whatever process is listening on *port*.
|
|
12
|
+
# Uses lsof on macOS/Linux and netstat + taskkill on Windows.
|
|
13
|
+
# Raises RuntimeError if the port cannot be freed.
|
|
14
|
+
def free_port(port)
|
|
15
|
+
puts " Port #{port} in use — killing existing process..."
|
|
16
|
+
|
|
17
|
+
if RUBY_PLATFORM =~ /mswin|mingw|cygwin/
|
|
18
|
+
output = `netstat -ano 2>&1`
|
|
19
|
+
pid = nil
|
|
20
|
+
output.each_line do |line|
|
|
21
|
+
if line.include?(":#{port}") && (line.include?("LISTENING") || line.include?("ESTABLISHED"))
|
|
22
|
+
parts = line.strip.split(/\s+/)
|
|
23
|
+
candidate = parts.last
|
|
24
|
+
if candidate =~ /^\d+$/
|
|
25
|
+
pid = candidate
|
|
26
|
+
break
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
if pid
|
|
31
|
+
system("taskkill /PID #{pid} /F")
|
|
32
|
+
else
|
|
33
|
+
raise "Could not free port #{port}: no PID found"
|
|
34
|
+
end
|
|
35
|
+
else
|
|
36
|
+
pids = `lsof -ti :#{port} 2>/dev/null`.strip.split("\n")
|
|
37
|
+
if pids.empty?
|
|
38
|
+
return # Nothing found — port may have freed itself
|
|
39
|
+
end
|
|
40
|
+
pids.each do |pid|
|
|
41
|
+
pid = pid.strip
|
|
42
|
+
next unless pid =~ /^\d+$/
|
|
43
|
+
begin
|
|
44
|
+
Process.kill("TERM", pid.to_i)
|
|
45
|
+
rescue Errno::ESRCH
|
|
46
|
+
# Process already gone
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# Give the OS a moment to reclaim the port
|
|
52
|
+
sleep(0.5)
|
|
53
|
+
puts " Port #{port} freed"
|
|
54
|
+
end
|
|
55
|
+
|
|
11
56
|
def start
|
|
12
57
|
require "webrick"
|
|
13
58
|
require "stringio"
|
|
14
59
|
require "socket"
|
|
60
|
+
|
|
61
|
+
# Ensure the main port is available — kill whatever is on it if needed
|
|
62
|
+
begin
|
|
63
|
+
test = TCPServer.new("0.0.0.0", @port)
|
|
64
|
+
test.close
|
|
65
|
+
rescue Errno::EADDRINUSE
|
|
66
|
+
free_port(@port)
|
|
67
|
+
# Verify the port is now free; raise if still occupied
|
|
68
|
+
begin
|
|
69
|
+
test = TCPServer.new("0.0.0.0", @port)
|
|
70
|
+
test.close
|
|
71
|
+
rescue Errno::EADDRINUSE
|
|
72
|
+
raise "Could not free port #{@port}"
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
15
76
|
Tina4.print_banner(host: @host, port: @port)
|
|
16
77
|
Tina4::Log.info("Starting Tina4 WEBrick server on http://#{@host}:#{@port}")
|
|
17
78
|
@server = WEBrick::HTTPServer.new(
|
|
@@ -103,14 +164,14 @@ module Tina4
|
|
|
103
164
|
|
|
104
165
|
@server.mount("/", servlet, rack_app)
|
|
105
166
|
|
|
106
|
-
#
|
|
167
|
+
# Test port (port + 1000) — stable, no-browser
|
|
107
168
|
@ai_server = nil
|
|
108
169
|
@ai_thread = nil
|
|
109
170
|
no_ai_port = %w[true 1 yes].include?(ENV.fetch("TINA4_NO_AI_PORT", "").downcase)
|
|
110
171
|
is_debug = %w[true 1 yes].include?(ENV.fetch("TINA4_DEBUG", "").downcase)
|
|
111
172
|
|
|
112
173
|
if is_debug && !no_ai_port
|
|
113
|
-
ai_port = @port +
|
|
174
|
+
ai_port = @port + 1000
|
|
114
175
|
begin
|
|
115
176
|
test = TCPServer.new("0.0.0.0", ai_port)
|
|
116
177
|
test.close
|
|
@@ -201,9 +262,9 @@ module Tina4
|
|
|
201
262
|
|
|
202
263
|
@ai_server.mount("/", ai_servlet, ai_rack_app)
|
|
203
264
|
@ai_thread = Thread.new { @ai_server.start }
|
|
204
|
-
puts "
|
|
265
|
+
puts " Test Port: http://localhost:#{ai_port} (stable — no hot-reload)"
|
|
205
266
|
rescue Errno::EADDRINUSE
|
|
206
|
-
puts "
|
|
267
|
+
puts " Test Port: SKIPPED (port #{ai_port} in use)"
|
|
207
268
|
end
|
|
208
269
|
end
|
|
209
270
|
|
data/lib/tina4.rb
CHANGED
|
@@ -138,7 +138,8 @@ module Tina4
|
|
|
138
138
|
end
|
|
139
139
|
|
|
140
140
|
puts "#{color}#{BANNER}#{reset}"
|
|
141
|
-
puts "
|
|
141
|
+
puts " TINA4 — The Intelligent Native Application 4ramework"
|
|
142
|
+
puts " Simple. Fast. Human. | Built for AI. Built for you."
|
|
142
143
|
puts ""
|
|
143
144
|
puts " Server: http://#{display}:#{port} (#{server_name})"
|
|
144
145
|
puts " Swagger: http://localhost:#{port}/swagger"
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: tina4ruby
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 3.10.
|
|
4
|
+
version: 3.10.60
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Tina4 Team
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-04-
|
|
11
|
+
date: 2026-04-03 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: rack
|
|
@@ -262,8 +262,9 @@ dependencies:
|
|
|
262
262
|
- - "~>"
|
|
263
263
|
- !ruby/object:Gem::Version
|
|
264
264
|
version: '1.50'
|
|
265
|
-
description:
|
|
266
|
-
|
|
265
|
+
description: 'TINA4: The Intelligent Native Application 4ramework for Ruby — Simple.
|
|
266
|
+
Fast. Human. Built for AI. Built for you. 54 built-in features, zero dependencies.
|
|
267
|
+
Full parity with Python, PHP, and Node.js.'
|
|
267
268
|
email:
|
|
268
269
|
- info@tina4.com
|
|
269
270
|
executables:
|