yatfa 1.0.79 → 1.0.81

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.
@@ -101,16 +101,20 @@ YATFA_VERSION=${YATFA_VERSION:-main}
101
101
  cat << 'EOF' > /usr/local/bin/setup-agent
102
102
  #!/bin/bash
103
103
  YATFA_VERSION=${YATFA_VERSION:-main}
104
- # Use local setup-agent.rb if mounted (dev mode), otherwise download from remote
105
- if [ -f "/tmp/setup-agent.rb" ]; then
106
- echo "🔧 Using local setup-agent.rb (dev mode)"
107
- ruby /tmp/setup-agent.rb
104
+ BASE_URL="https://objectstore.fra1.civo.com/yatfa/${YATFA_VERSION}"
105
+ # Use local setup/ dir if mounted (dev mode), otherwise download all from remote
106
+ if [ -f "/tmp/setup/setup-agent.rb" ]; then
107
+ echo "🔧 Using local setup/ (dev mode)"
108
+ ruby /tmp/setup/setup-agent.rb
108
109
  else
109
- echo "Downloading latest setup-agent.rb (version: ${YATFA_VERSION})..."
110
- curl -fsSL https://objectstore.fra1.civo.com/yatfa/${YATFA_VERSION}/setup-agent.rb -o /tmp/setup-agent.rb
111
- # Download claw setup (non-fatal only needed when AGENT_TYPE=claw)
112
- curl -fsSL https://objectstore.fra1.civo.com/yatfa/${YATFA_VERSION}/setup-claw-agent.rb -o /tmp/setup-claw-agent.rb 2>/dev/null || true
113
- ruby /tmp/setup-agent.rb
110
+ mkdir -p /tmp/setup
111
+ echo "Downloading setup scripts (version: ${YATFA_VERSION})..."
112
+ # Download manifest listing all setup files
113
+ MANIFEST=$(curl -fsSL "${BASE_URL}/setup/MANIFEST" 2>/dev/null || echo "setup-agent.rb")
114
+ for file in ${MANIFEST}; do
115
+ curl -fsSL "${BASE_URL}/setup/${file}" -o "/tmp/setup/${file}" 2>/dev/null || true
116
+ done
117
+ ruby /tmp/setup/setup-agent.rb
114
118
  fi
115
119
  EOF
116
120
  chmod +x /usr/local/bin/setup-agent
@@ -14,6 +14,19 @@ module YatfaAgent
14
14
  !result.empty?
15
15
  end
16
16
 
17
+ # Get container creation time
18
+ def self.container_creation_time(container_name)
19
+ result = IO.popen(["docker", "inspect", "--format", "{{.Created}}", container_name], err: File::NULL, &:read).strip
20
+ return nil if result.empty?
21
+ Time.parse(result)
22
+ rescue ArgumentError
23
+ nil
24
+ end
25
+
26
+ def self.format_time(t)
27
+ t.strftime("%H:%M")
28
+ end
29
+
17
30
  # Prompt user for input with a default value
18
31
  def self.prompt(message, default: nil, options: nil)
19
32
  loop do
@@ -47,6 +60,28 @@ module YatfaAgent
47
60
  # Handle running container: prompt user for action
48
61
  def self.handle_running_container(agent_type, container_name, config, agent_configs)
49
62
  puts "⚠️ #{agent_type} agent is already running (#{container_name})"
63
+
64
+ # Check if container was created before last deploy
65
+ deploy_manifest = File.join(File.dirname(__FILE__), '..', '..', 'deploy', '.deploy-manifest.json')
66
+ version_file = File.join(File.dirname(__FILE__), '..', '..', 'VERSION')
67
+ stale = false
68
+
69
+ if File.exist?(version_file)
70
+ current_version = File.read(version_file).strip
71
+ container_version = IO.popen(["docker", "exec", container_name, "printenv", "YATFA_VERSION_NUM"], err: File::NULL, &:read).strip
72
+ if !container_version.empty? && container_version != current_version
73
+ puts " 🆕 New version deployed (container: #{container_version}, current: #{current_version})"
74
+ stale = true
75
+ end
76
+ elsif File.exist?(deploy_manifest)
77
+ deploy_time = File.mtime(deploy_manifest)
78
+ container_created = container_creation_time(container_name)
79
+ if container_created && container_created < deploy_time
80
+ puts " 🆕 New deploy detected (container from #{format_time(container_created)}, deploy at #{format_time(deploy_time)})"
81
+ stale = true
82
+ end
83
+ end
84
+
50
85
  puts ""
51
86
 
52
87
  if non_interactive?
@@ -55,7 +90,8 @@ module YatfaAgent
55
90
  exit 0
56
91
  end
57
92
 
58
- choice = prompt(" [A]ttach / [R]estart / [C]ancel? [A/r/c]: ", default: "A", options: %w[A R C])
93
+ default_choice = stale ? "R" : "A"
94
+ choice = prompt(" [A]ttach / [R]estart / [C]ancel? [#{default_choice == 'R' ? 'a/R/c' : 'A/r/c'}]: ", default: default_choice, options: %w[A R C])
59
95
 
60
96
  case choice
61
97
  when "A"
@@ -258,6 +294,13 @@ module YatfaAgent
258
294
  "--tmpfs", "/rails/log"
259
295
  ]
260
296
 
297
+ # Inject current version for staleness detection
298
+ version_file = File.join(File.dirname(__FILE__), '..', '..', 'VERSION')
299
+ if File.exist?(version_file)
300
+ version = File.read(version_file).strip
301
+ docker_cmd += ["-e", "YATFA_VERSION_NUM=#{version}"] unless version.empty?
302
+ end
303
+
261
304
  # Inject custom environment variables from config
262
305
  # Merge global env with agent-specific env (agent-specific takes precedence)
263
306
  merged_env = {}
@@ -320,10 +363,10 @@ module YatfaAgent
320
363
  add_development_mounts!(docker_cmd)
321
364
  end
322
365
 
323
- local_setup_script = File.join(File.dirname(__FILE__), "..", "..", "setup-agent.rb")
366
+ local_setup_dir = File.join(File.dirname(__FILE__), "..", "..", "setup")
324
367
 
325
- if File.exist?(local_setup_script)
326
- docker_cmd += [Config.image_name(config), "ruby", "/tmp/setup-agent.rb"]
368
+ if File.directory?(local_setup_dir)
369
+ docker_cmd += [Config.image_name(config), "ruby", "/tmp/setup/setup-agent.rb"]
327
370
  else
328
371
  docker_cmd += [Config.image_name(config)]
329
372
  end
@@ -389,33 +432,12 @@ module YatfaAgent
389
432
  end
390
433
 
391
434
  def self.add_development_mounts!(docker_cmd)
392
- # Check for local setup-agent.rb (for development)
393
- # Try multiple paths: relative to gem, relative to cwd
394
- setup_script_paths = [
395
- File.join(File.dirname(__FILE__), "..", "..", "setup-agent.rb"), # Relative to gem
396
- File.join(Dir.pwd, "tinker-public", "setup-agent.rb"), # Running from metafolder
397
- File.join(Dir.pwd, "setup-agent.rb"), # Running from yatfa-public
398
- ]
435
+ # Check for local setup/ directory (for development)
436
+ setup_dir = File.join(File.dirname(__FILE__), "..", "..", "setup")
399
437
 
400
- local_setup_script = nil
401
- setup_script_paths.each do |path|
402
- if File.exist?(path)
403
- local_setup_script = path
404
- break
405
- end
406
- end
407
-
408
- # Mount local setup-agent.rb for development if present
409
- # Binaries are always fetched from bucket by setup-agent.rb
410
- if local_setup_script
411
- puts "🔧 Using local setup-agent.rb for development"
412
- docker_cmd.concat(["-v", "#{File.expand_path(local_setup_script)}:/tmp/setup-agent.rb:ro"])
413
-
414
- # Mount companion scripts that setup-agent.rb loads via require_relative
415
- Dir.glob(File.join(File.dirname(local_setup_script), "setup-*.rb")).each do |companion|
416
- basename = File.basename(companion)
417
- docker_cmd.concat(["-v", "#{File.expand_path(companion)}:/tmp/#{basename}:ro"])
418
- end
438
+ if File.directory?(setup_dir)
439
+ puts "🔧 Using local setup/ for development"
440
+ docker_cmd.concat(["-v", "#{File.expand_path(setup_dir)}:/tmp/setup:ro"])
419
441
  end
420
442
  end
421
443
 
package/package.json CHANGED
@@ -1,12 +1,13 @@
1
1
  {
2
2
  "name": "yatfa",
3
- "version": "1.0.79",
3
+ "version": "1.0.81",
4
4
  "description": "YATFA - Yet Another Tool For Agents",
5
5
  "bin": "./bin/run-yatfa-agent.rb",
6
6
  "files": [
7
7
  "bin/run-yatfa-agent.rb",
8
8
  "agents.rb",
9
9
  "lib/",
10
+ "setup/",
10
11
  "bin/agent-bridge-tmux",
11
12
  "bin/install-agent.sh"
12
13
  ],