yatfa 1.0.65 → 1.0.67
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.
- package/README.md +29 -14
- package/bin/run-yatfa-agent.rb +16 -10
- package/lib/yatfa_agent/agent.rb +121 -44
- package/lib/yatfa_agent/config.rb +5 -8
- package/lib/yatfa_agent/setup.rb +5 -5
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -7,7 +7,7 @@ Run YATFA agents in any Docker container with Ruby.
|
|
|
7
7
|
The easiest way to get started is with the interactive setup wizard:
|
|
8
8
|
|
|
9
9
|
```bash
|
|
10
|
-
npx yatfa
|
|
10
|
+
npx yatfa setup
|
|
11
11
|
```
|
|
12
12
|
|
|
13
13
|
The wizard will guide you through:
|
|
@@ -30,7 +30,7 @@ Agents are configured via a `yatfa.env.rb` file in your project root. This Ruby
|
|
|
30
30
|
|
|
31
31
|
**Do not commit `yatfa.env.rb` to git!** Add it to your `.gitignore`.
|
|
32
32
|
|
|
33
|
-
**Pro tip:** Use `npx yatfa
|
|
33
|
+
**Pro tip:** Use `npx yatfa setup` to generate this file interactively with validation.
|
|
34
34
|
|
|
35
35
|
Example `yatfa.env.rb`:
|
|
36
36
|
|
|
@@ -97,39 +97,52 @@ Example `yatfa.env.rb`:
|
|
|
97
97
|
### Setup
|
|
98
98
|
|
|
99
99
|
```bash
|
|
100
|
-
npx yatfa
|
|
100
|
+
npx yatfa setup
|
|
101
101
|
```
|
|
102
102
|
|
|
103
103
|
Launches interactive setup wizard to configure `yatfa.env.rb`.
|
|
104
104
|
|
|
105
105
|
### Run Agents
|
|
106
106
|
|
|
107
|
+
When you run an agent, the CLI automatically:
|
|
108
|
+
1. **Checks if the agent is already running** - prompts to Attach, Restart, or Cancel
|
|
109
|
+
2. **Starts the agent** - creates the Docker container
|
|
110
|
+
3. **Prompts to attach** - after starting, asks if you want to attach to the session
|
|
111
|
+
|
|
107
112
|
```bash
|
|
108
|
-
|
|
109
|
-
npx yatfa
|
|
110
|
-
npx yatfa
|
|
111
|
-
npx yatfa
|
|
112
|
-
npx yatfa-agent researcher
|
|
113
|
+
npx yatfa worker
|
|
114
|
+
npx yatfa planner
|
|
115
|
+
npx yatfa reviewer
|
|
116
|
+
npx yatfa researcher
|
|
113
117
|
```
|
|
114
118
|
|
|
115
|
-
|
|
119
|
+
#### Non-interactive Mode (for CI/scripts)
|
|
116
120
|
|
|
117
121
|
```bash
|
|
118
|
-
|
|
122
|
+
# Run without prompts
|
|
123
|
+
npx yatfa worker --no-prompt
|
|
124
|
+
# or
|
|
125
|
+
YATFA_NO_PROMPT=1 npx yatfa worker
|
|
119
126
|
```
|
|
120
127
|
|
|
121
|
-
|
|
128
|
+
### Attach to Running Agents (deprecated)
|
|
129
|
+
|
|
130
|
+
The `attach` command still works but is deprecated. Running `npx yatfa <agent-type>` now prompts to attach automatically.
|
|
131
|
+
|
|
132
|
+
```bash
|
|
133
|
+
npx yatfa attach worker # Deprecated - use 'npx yatfa worker' instead
|
|
134
|
+
```
|
|
122
135
|
|
|
123
136
|
### List Running Agents
|
|
124
137
|
|
|
125
138
|
```bash
|
|
126
|
-
npx yatfa
|
|
139
|
+
npx yatfa list
|
|
127
140
|
```
|
|
128
141
|
|
|
129
142
|
### Stop All Agents
|
|
130
143
|
|
|
131
144
|
```bash
|
|
132
|
-
npx yatfa
|
|
145
|
+
npx yatfa stop-all
|
|
133
146
|
```
|
|
134
147
|
|
|
135
148
|
## What the Script Does
|
|
@@ -241,8 +254,10 @@ See hook files for implementation details and customization options.
|
|
|
241
254
|
|
|
242
255
|
## Attaching to Running Agent
|
|
243
256
|
|
|
257
|
+
After starting an agent, the CLI will prompt you to attach. You can also attach directly:
|
|
258
|
+
|
|
244
259
|
```bash
|
|
245
|
-
docker exec -it <container> tmux attach -t agent
|
|
260
|
+
docker exec -it <container> tmux attach -t agent
|
|
246
261
|
```
|
|
247
262
|
|
|
248
263
|
Press `Ctrl+B` then `D` to detach.
|
package/bin/run-yatfa-agent.rb
CHANGED
|
@@ -2,9 +2,8 @@
|
|
|
2
2
|
# frozen_string_literal: true
|
|
3
3
|
|
|
4
4
|
# YATFA Agent Runner (Yet Another Tool For Agents)
|
|
5
|
-
# Usage: npx yatfa
|
|
6
|
-
# npx yatfa
|
|
7
|
-
# npx yatfa-agent setup
|
|
5
|
+
# Usage: npx yatfa [worker|planner|reviewer|researcher]
|
|
6
|
+
# npx yatfa setup
|
|
8
7
|
#
|
|
9
8
|
# Requirements:
|
|
10
9
|
# - Docker
|
|
@@ -22,18 +21,21 @@ def show_usage
|
|
|
22
21
|
puts "YATFA Agent Runner (Yet Another Tool For Agents)"
|
|
23
22
|
puts ""
|
|
24
23
|
puts "Usage:"
|
|
25
|
-
puts " npx yatfa
|
|
26
|
-
puts " npx yatfa
|
|
27
|
-
puts "
|
|
24
|
+
puts " npx yatfa setup # Interactive setup wizard"
|
|
25
|
+
puts " npx yatfa [worker|planner|reviewer|researcher] # Run agent (prompts to attach)"
|
|
26
|
+
puts ""
|
|
27
|
+
puts "Options:"
|
|
28
|
+
puts " --no-prompt, -d Run without prompts (for CI/scripts)"
|
|
29
|
+
puts " YATFA_NO_PROMPT=1 Environment variable alternative"
|
|
28
30
|
puts ""
|
|
29
31
|
puts "Setup:"
|
|
30
|
-
puts " Run 'npx yatfa
|
|
32
|
+
puts " Run 'npx yatfa setup' for interactive configuration"
|
|
31
33
|
puts ""
|
|
32
34
|
puts "Manual setup:"
|
|
33
35
|
puts " 1. Create Dockerfile.sandbox (see https://github.com/RoM4iK/yatfa-public/blob/main/README.md)"
|
|
34
36
|
puts " 2. Create yatfa.env.rb (see https://github.com/RoM4iK/yatfa-public/blob/main/README.md)"
|
|
35
37
|
puts " 3. echo 'yatfa.env.rb' >> .gitignore"
|
|
36
|
-
puts " 4. npx yatfa
|
|
38
|
+
puts " 4. npx yatfa worker"
|
|
37
39
|
exit 1
|
|
38
40
|
end
|
|
39
41
|
|
|
@@ -49,10 +51,14 @@ if command == "setup"
|
|
|
49
51
|
exit 0
|
|
50
52
|
end
|
|
51
53
|
|
|
52
|
-
# Handle attach command
|
|
54
|
+
# Handle attach command (deprecated - will still work)
|
|
53
55
|
if command == "attach"
|
|
56
|
+
puts ""
|
|
57
|
+
puts "⚠️ Deprecation: The 'attach' command is deprecated"
|
|
58
|
+
puts " Running `npx yatfa <agent-type>` now prompts to attach automatically."
|
|
59
|
+
puts ""
|
|
54
60
|
agent_type = ARGV[1]&.downcase
|
|
55
|
-
abort "Usage: npx yatfa
|
|
61
|
+
abort "Usage: npx yatfa attach [agent-type]" unless agent_type
|
|
56
62
|
config = YatfaAgent::Config.load
|
|
57
63
|
YatfaAgent::Config.fetch_repositories!(config)
|
|
58
64
|
YatfaAgent::Agent.attach(agent_type, config, AGENT_CONFIGS)
|
package/lib/yatfa_agent/agent.rb
CHANGED
|
@@ -3,6 +3,72 @@ require 'fileutils'
|
|
|
3
3
|
|
|
4
4
|
module YatfaAgent
|
|
5
5
|
module Agent
|
|
6
|
+
# Check if container is currently running
|
|
7
|
+
def self.container_running?(container_name)
|
|
8
|
+
# Use IO.popen with array arguments to avoid shell injection
|
|
9
|
+
result = IO.popen(["docker", "ps", "--filter", "name=^#{container_name}$", "--format", "{{.Names}}"], err: File::NULL, &:read).strip
|
|
10
|
+
!result.empty?
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
# Prompt user for input with a default value
|
|
14
|
+
def self.prompt(message, default: nil, options: nil)
|
|
15
|
+
loop do
|
|
16
|
+
print message
|
|
17
|
+
input = $stdin.gets&.strip&.downcase || ""
|
|
18
|
+
|
|
19
|
+
# Handle default on empty input
|
|
20
|
+
if input.empty? && default
|
|
21
|
+
return default
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# If options specified, validate input
|
|
25
|
+
if options
|
|
26
|
+
valid = options.any? { |opt| opt.downcase == input || opt.downcase.start_with?(input) }
|
|
27
|
+
if valid
|
|
28
|
+
# Return the full option that matches
|
|
29
|
+
return options.find { |opt| opt.downcase.start_with?(input) }
|
|
30
|
+
end
|
|
31
|
+
puts " Invalid option. Please choose: #{options.join('/')}"
|
|
32
|
+
else
|
|
33
|
+
return input
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# Check if running in non-interactive mode
|
|
39
|
+
def self.non_interactive?
|
|
40
|
+
!$stdin.tty? || ENV['YATFA_NO_PROMPT'] == '1' || ARGV.include?('--no-prompt') || ARGV.include?('-d')
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# Handle running container: prompt user for action
|
|
44
|
+
def self.handle_running_container(agent_type, container_name, config, agent_configs)
|
|
45
|
+
puts "⚠️ #{agent_type} agent is already running (#{container_name})"
|
|
46
|
+
puts ""
|
|
47
|
+
|
|
48
|
+
if non_interactive?
|
|
49
|
+
puts " Running in non-interactive mode. Run 'npx yatfa #{agent_type}' to attach, or stop the container first."
|
|
50
|
+
puts " docker stop #{container_name}"
|
|
51
|
+
exit 0
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
choice = prompt(" [A]ttach / [R]estart / [C]ancel? [A/r/c]: ", default: "A", options: %w[A R C])
|
|
55
|
+
|
|
56
|
+
case choice
|
|
57
|
+
when "A"
|
|
58
|
+
puts ""
|
|
59
|
+
attach(agent_type, config, agent_configs)
|
|
60
|
+
when "R"
|
|
61
|
+
puts ""
|
|
62
|
+
puts "🔄 Stopping existing container..."
|
|
63
|
+
system("docker", "stop", container_name, err: File::NULL, out: File::NULL)
|
|
64
|
+
system("docker", "rm", "-f", container_name, err: File::NULL, out: File::NULL)
|
|
65
|
+
return true # Continue with start
|
|
66
|
+
when "C"
|
|
67
|
+
puts " Cancelled."
|
|
68
|
+
exit 0
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
|
|
6
72
|
def self.run(agent_type, config, agent_configs)
|
|
7
73
|
unless agent_configs.keys.include?(agent_type)
|
|
8
74
|
puts "❌ Unknown agent type: #{agent_type}"
|
|
@@ -14,13 +80,18 @@ module YatfaAgent
|
|
|
14
80
|
agent_config = config.dig("agents", agent_type) || {}
|
|
15
81
|
container_name = agent_config["container_name"] || agent_def[:name]
|
|
16
82
|
|
|
17
|
-
|
|
83
|
+
# Check if container is already running and handle interactively
|
|
84
|
+
if container_running?(container_name)
|
|
85
|
+
should_continue = handle_running_container(agent_type, container_name, config, agent_configs)
|
|
86
|
+
# If user chose Attach or Cancel, the method calls exec/exit, so we never reach here
|
|
87
|
+
# If user chose Restart, should_continue is true and we proceed to start a new container
|
|
88
|
+
return unless should_continue
|
|
89
|
+
end
|
|
18
90
|
|
|
19
|
-
|
|
20
|
-
system("docker", "rm", "-f", container_name, err: File::NULL, out: File::NULL)
|
|
91
|
+
puts "🚀 Starting #{agent_type} agent..."
|
|
21
92
|
|
|
22
93
|
# Write banner to a persistent temp file (not auto-deleted)
|
|
23
|
-
banner_path = "/tmp/yatfa-
|
|
94
|
+
banner_path = "/tmp/yatfa-banner-#{agent_type}.txt"
|
|
24
95
|
FileUtils.rm_rf(banner_path)
|
|
25
96
|
|
|
26
97
|
# Append repository context to banner
|
|
@@ -47,15 +118,46 @@ module YatfaAgent
|
|
|
47
118
|
if success
|
|
48
119
|
puts "✅ Agent started in background"
|
|
49
120
|
puts ""
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
121
|
+
|
|
122
|
+
# Prompt to attach (interactive mode only)
|
|
123
|
+
prompt_to_attach(agent_type, container_name, config, agent_configs)
|
|
53
124
|
else
|
|
54
125
|
puts "❌ Failed to start agent"
|
|
55
126
|
exit 1
|
|
56
127
|
end
|
|
57
128
|
end
|
|
58
129
|
|
|
130
|
+
# Prompt user to attach after starting a new agent
|
|
131
|
+
def self.prompt_to_attach(agent_type, container_name, config, agent_configs)
|
|
132
|
+
if non_interactive?
|
|
133
|
+
# Non-interactive: just print helpful info
|
|
134
|
+
puts " Logs: docker logs -f #{container_name}"
|
|
135
|
+
puts " Stop: docker stop #{container_name}"
|
|
136
|
+
puts " Attach: docker exec -it #{container_name} tmux attach -t agent"
|
|
137
|
+
return
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
choice = prompt(" Agent started. Attach to session? [Y/n]: ", default: "Y", options: %w[Y N])
|
|
141
|
+
|
|
142
|
+
if choice == "Y"
|
|
143
|
+
puts ""
|
|
144
|
+
# Wait briefly for container to initialize
|
|
145
|
+
print " Waiting for agent to initialize"
|
|
146
|
+
5.times do
|
|
147
|
+
print "."
|
|
148
|
+
sleep 1
|
|
149
|
+
end
|
|
150
|
+
puts ""
|
|
151
|
+
attach(agent_type, config, agent_configs)
|
|
152
|
+
else
|
|
153
|
+
puts ""
|
|
154
|
+
puts " Agent is running in background."
|
|
155
|
+
puts " Logs: docker logs -f #{container_name}"
|
|
156
|
+
puts " Stop: docker stop #{container_name}"
|
|
157
|
+
puts " Attach: docker exec -it #{container_name} tmux attach -t agent"
|
|
158
|
+
end
|
|
159
|
+
end
|
|
160
|
+
|
|
59
161
|
def self.attach(agent_type, config, agent_configs)
|
|
60
162
|
unless agent_configs.keys.include?(agent_type)
|
|
61
163
|
puts "❌ Unknown agent type: #{agent_type}"
|
|
@@ -66,7 +168,7 @@ module YatfaAgent
|
|
|
66
168
|
agent_config = config.dig("agents", agent_type) || {}
|
|
67
169
|
container_name = agent_config["container_name"] || agent_def[:name]
|
|
68
170
|
|
|
69
|
-
running =
|
|
171
|
+
running = IO.popen(["docker", "ps", "--filter", "name=^#{container_name}$", "--format", "{{.Names}}"], err: File::NULL, &:read).strip
|
|
70
172
|
|
|
71
173
|
if running.empty?
|
|
72
174
|
puts "⚠️ #{agent_type} agent is not running. Auto-starting..."
|
|
@@ -208,52 +310,27 @@ module YatfaAgent
|
|
|
208
310
|
|
|
209
311
|
def self.add_development_mounts!(docker_cmd)
|
|
210
312
|
# Check for local setup-agent.rb (for development)
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
# Try multiple possible paths for the binary (built Go binaries in dist/)
|
|
218
|
-
possible_paths = [
|
|
219
|
-
File.join(Dir.pwd, "overrides", "agent-bridge-linux-#{linux_arch}"), # YATFA_SANDBOX/overrides
|
|
220
|
-
File.join(Dir.pwd, "yatfa-public", "dist", "agent-bridge-linux-#{linux_arch}"), # Running from metafolder
|
|
221
|
-
File.join(Dir.pwd, "dist", "agent-bridge-linux-#{linux_arch}"), # Running from yatfa-public
|
|
313
|
+
# Try multiple paths: relative to gem, relative to cwd
|
|
314
|
+
setup_script_paths = [
|
|
315
|
+
File.join(File.dirname(__FILE__), "..", "..", "setup-agent.rb"), # Relative to gem
|
|
316
|
+
File.join(Dir.pwd, "tinker-public", "setup-agent.rb"), # Running from metafolder
|
|
317
|
+
File.join(Dir.pwd, "setup-agent.rb"), # Running from yatfa-public
|
|
222
318
|
]
|
|
223
319
|
|
|
224
|
-
|
|
225
|
-
|
|
320
|
+
local_setup_script = nil
|
|
321
|
+
setup_script_paths.each do |path|
|
|
226
322
|
if File.exist?(path)
|
|
227
|
-
|
|
323
|
+
local_setup_script = path
|
|
228
324
|
break
|
|
229
325
|
end
|
|
230
326
|
end
|
|
231
327
|
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
if File.exist?(local_setup_script)
|
|
328
|
+
# Mount local setup-agent.rb for development if present
|
|
329
|
+
# Binaries are always fetched from bucket by setup-agent.rb
|
|
330
|
+
if local_setup_script
|
|
236
331
|
puts "🔧 Using local setup-agent.rb for development"
|
|
237
332
|
docker_cmd.concat(["-v", "#{File.expand_path(local_setup_script)}:/tmp/setup-agent.rb:ro"])
|
|
238
333
|
end
|
|
239
|
-
|
|
240
|
-
if linux_bridge && File.exist?(linux_bridge)
|
|
241
|
-
puts "🔧 Using local linux binary: #{linux_bridge}"
|
|
242
|
-
docker_cmd.concat(["-v", "#{File.expand_path(linux_bridge)}:/tmp/agent-bridge:ro"])
|
|
243
|
-
elsif File.exist?(local_bridge_default)
|
|
244
|
-
# Check if it's a binary or script
|
|
245
|
-
is_script = File.read(local_bridge_default, 4) == "#!/b"
|
|
246
|
-
if is_script
|
|
247
|
-
puts "⚠️ bin/agent-bridge is a host wrapper script. Please run 'bin/build-bridge' to generate linux binaries."
|
|
248
|
-
else
|
|
249
|
-
puts "🔧 Using local agent-bridge binary"
|
|
250
|
-
docker_cmd.concat(["-v", "#{local_bridge_default}:/tmp/agent-bridge:ro"])
|
|
251
|
-
end
|
|
252
|
-
end
|
|
253
|
-
|
|
254
|
-
if File.exist?(local_tmux)
|
|
255
|
-
docker_cmd.concat(["-v", "#{File.expand_path(local_tmux)}:/tmp/agent-bridge-tmux:ro"])
|
|
256
|
-
end
|
|
257
334
|
end
|
|
258
335
|
|
|
259
336
|
def self.detect_agent_user(container_name)
|
|
@@ -5,16 +5,14 @@ require "json"
|
|
|
5
5
|
module YatfaAgent
|
|
6
6
|
module Config
|
|
7
7
|
def self.load
|
|
8
|
-
|
|
8
|
+
config_file = File.join(Dir.pwd, "yatfa.env.rb")
|
|
9
9
|
|
|
10
|
-
unless File.exist?(
|
|
10
|
+
unless File.exist?(config_file)
|
|
11
11
|
puts "❌ Error: yatfa.env.rb not found in current directory"
|
|
12
12
|
puts ""
|
|
13
13
|
puts "Create yatfa.env.rb:"
|
|
14
14
|
puts " {"
|
|
15
15
|
puts " yatfa_url: 'https://yatfa.example.com', # Required"
|
|
16
|
-
puts " # OR legacy name:"
|
|
17
|
-
puts " rails_api_url: 'https://yatfa.example.com/api/v1',"
|
|
18
16
|
puts " # ..."
|
|
19
17
|
puts " # Paste your stripped .env content here:"
|
|
20
18
|
puts " dot_env: <<~ENV"
|
|
@@ -23,11 +21,11 @@ module YatfaAgent
|
|
|
23
21
|
puts " ENV"
|
|
24
22
|
puts " }"
|
|
25
23
|
puts " echo 'yatfa.env.rb' >> .gitignore"
|
|
26
|
-
|
|
24
|
+
exit 1
|
|
27
25
|
end
|
|
28
26
|
|
|
29
27
|
puts "⚙️ Loading configuration from yatfa.env.rb"
|
|
30
|
-
config = eval(File.read(
|
|
28
|
+
config = eval(File.read(config_file), binding, config_file)
|
|
31
29
|
|
|
32
30
|
# Convert symbols to strings for easier handling before JSON normalization
|
|
33
31
|
config = config.transform_keys(&:to_s)
|
|
@@ -69,8 +67,7 @@ module YatfaAgent
|
|
|
69
67
|
end
|
|
70
68
|
|
|
71
69
|
def self.yatfa_url(config)
|
|
72
|
-
|
|
73
|
-
config["yatfa_url"] || config["yafta_url"] || config["rails_api_url"]
|
|
70
|
+
config["yatfa_url"] || config["rails_api_url"]
|
|
74
71
|
end
|
|
75
72
|
|
|
76
73
|
def self.api_url(config)
|
package/lib/yatfa_agent/setup.rb
CHANGED
|
@@ -58,7 +58,7 @@ module YatfaAgent
|
|
|
58
58
|
puts "║ YATFA Agent Setup Wizard ║"
|
|
59
59
|
puts "║ (Yet Another Tool For Agents) ║"
|
|
60
60
|
puts "║ ║"
|
|
61
|
-
puts "║ This wizard will guide you through configuring yatfa
|
|
61
|
+
puts "║ This wizard will guide you through configuring yatfa ║"
|
|
62
62
|
puts "║ ║"
|
|
63
63
|
puts "╚═══════════════════════════════════════════════════════════════╝"
|
|
64
64
|
puts ""
|
|
@@ -157,7 +157,7 @@ module YatfaAgent
|
|
|
157
157
|
|
|
158
158
|
# Set defaults from parent directory if available
|
|
159
159
|
default_name = "YATFA Agent"
|
|
160
|
-
default_email = "yatfa
|
|
160
|
+
default_email = "yatfa@yatfa.ai"
|
|
161
161
|
|
|
162
162
|
parent_config = File.join(Dir.pwd, "..", "yatfa.env.rb")
|
|
163
163
|
if File.exist?(parent_config)
|
|
@@ -512,12 +512,12 @@ module YatfaAgent
|
|
|
512
512
|
puts ""
|
|
513
513
|
puts " 3. Start an agent:"
|
|
514
514
|
if @config[:agents].key?(:worker)
|
|
515
|
-
puts " npx yatfa
|
|
515
|
+
puts " npx yatfa worker"
|
|
516
516
|
elsif @config[:agents].key?(:planner)
|
|
517
|
-
puts " npx yatfa
|
|
517
|
+
puts " npx yatfa planner"
|
|
518
518
|
else
|
|
519
519
|
agent = @config[:agents].keys.first
|
|
520
|
-
puts " npx yatfa
|
|
520
|
+
puts " npx yatfa #{agent}"
|
|
521
521
|
end
|
|
522
522
|
puts ""
|
|
523
523
|
puts "For more information, see: https://github.com/RoM4iK/yatfa-public"
|