tinker-agent 1.0.24 → 1.0.27

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 CHANGED
@@ -16,10 +16,55 @@ ENTRYPOINT ["/entrypoint.sh"]
16
16
  CMD ["bash", "-c", "curl -fsSL https://raw.githubusercontent.com/RoM4iK/tinker-public/${TINKER_VERSION:-main}/setup-agent.rb | ruby"]
17
17
  ```
18
18
 
19
- ## Usage
20
-
21
- ```bash
22
- npx tinker-agent worker
19
+ ## Configuration (tinker.env.rb)
20
+
21
+ Agents are configured via a `tinker.env.rb` file in your project root. This Ruby file allows you to define configuration and secrets (using heredocs).
22
+
23
+ **Do not commit `tinker.env.rb` to git!** Add it to your `.gitignore`.
24
+
25
+ Example `tinker.env.rb`:
26
+
27
+ ```ruby
28
+ {
29
+ project_id: 2,
30
+ rails_ws_url: "wss://tinkerai.win/cable",
31
+ rails_api_url: "https://tinker.tinkerai.win/api/v1",
32
+
33
+ # Git Identity
34
+ git: {
35
+ user_name: "Tinker Agent",
36
+ user_email: "agent@example.com"
37
+ },
38
+
39
+ # GitHub Auth (App or Token)
40
+ github: {
41
+ method: "app",
42
+ app_client_id: "Iv23liFDGt4FWGJSHAS",
43
+ app_installation_id: "102387777",
44
+ app_private_key_path: "/absolute/path/to/key.pem"
45
+ },
46
+
47
+ # Agent Specific Config
48
+ agents: {
49
+ worker: {
50
+ mcp_api_key: "...",
51
+ container_name: "tinker-worker"
52
+ },
53
+ planner: {
54
+ mcp_api_key: "...",
55
+ container_name: "tinker-planner"
56
+ }
57
+ },
58
+
59
+ # Environment Variables Injection
60
+ # Simple strings or Heredocs supported
61
+ dot_env: <<~ENV
62
+ PORT=3200
63
+ DB_HOST=localhost
64
+ SECRET_KEY_BASE=very_secret
65
+ OPENAI_API_KEY=sk-...
66
+ ENV
67
+ }
23
68
  ```
24
69
 
25
70
  ## Environment Variables
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tinker-agent",
3
- "version": "1.0.24",
3
+ "version": "1.0.27",
4
4
  "description": "Tinker Agent Runner",
5
5
  "bin": {
6
6
  "tinker-agent": "./run-tinker-agent.rb"
@@ -9,7 +9,7 @@
9
9
  # - Docker
10
10
  # - Ruby
11
11
  # - Dockerfile.sandbox in project root
12
- # - tinker.env.json in project root (gitignored)
12
+ # - tinker.env.rb in project root (gitignored)
13
13
 
14
14
  require "json"
15
15
 
@@ -21,19 +21,55 @@ IMAGE_NAME = "tinker-sandbox"
21
21
  AGENT_TYPES = AGENT_CONFIGS.keys.freeze
22
22
 
23
23
  def load_config
24
- config_file = File.join(Dir.pwd, "tinker.env.json")
25
-
26
- unless File.exist?(config_file)
27
- puts "❌ Error: tinker.env.json not found in current directory"
24
+ # Support Ruby config for heredocs and comments (tinker.env.rb)
25
+ rb_config_file = File.join(Dir.pwd, "tinker.env.rb")
26
+
27
+ unless File.exist?(rb_config_file)
28
+ puts "❌ Error: tinker.env.rb not found in current directory"
28
29
  puts ""
29
- puts "Create it:"
30
- puts " curl -fsSL https://raw.githubusercontent.com/RoM4iK/tinker-public/main/tinker.env.example.json -o tinker.env.json"
31
- puts " # Edit with your project config"
32
- puts " echo 'tinker.env.json' >> .gitignore"
30
+ puts "Create tinker.env.rb:"
31
+ puts " {"
32
+ puts " project_id: 1,"
33
+ puts " rails_ws_url: '...',"
34
+ puts " # ..."
35
+ puts " # Paste your stripped .env content here:"
36
+ puts " dot_env: <<~ENV"
37
+ puts " STRIPE_KEY=sk_test_..."
38
+ puts " OPENAI_KEY=sk-..."
39
+ puts " ENV"
40
+ puts " }"
41
+ puts " echo 'tinker.env.rb' >> .gitignore"
33
42
  exit 1
34
43
  end
35
44
 
36
- JSON.parse(File.read(config_file))
45
+ puts "⚙️ Loading configuration from tinker.env.rb"
46
+ config = eval(File.read(rb_config_file), binding, rb_config_file)
47
+
48
+ # Convert symbols to strings for easier handling before JSON normalization
49
+ config = config.transform_keys(&:to_s)
50
+
51
+ # Parse dot_env heredoc if present
52
+ if (dotenv = config["dot_env"])
53
+ config["env"] ||= {}
54
+ # Ensure env is string-keyed
55
+ config["env"] = config["env"].transform_keys(&:to_s)
56
+
57
+ dotenv.each_line do |line|
58
+ line = line.strip
59
+ next if line.empty? || line.start_with?('#')
60
+ k, v = line.split('=', 2)
61
+ next unless k && v
62
+ # Remove surrounding quotes and trailing comments (simple)
63
+ v = v.strip.gsub(/^['"]|['"]$/, '')
64
+ config["env"][k.strip] = v
65
+ end
66
+
67
+ config.delete("dot_env")
68
+ puts "🌿 Parsed dot_env into #{config['env'].size} environment variables"
69
+ end
70
+
71
+ # Normalize symbols to strings for consistency via JSON round-trip
72
+ JSON.parse(JSON.generate(config))
37
73
  end
38
74
 
39
75
  def check_dockerfile!
@@ -97,6 +133,17 @@ def run_agent(agent_type, config)
97
133
  "docker", "run", "-d",
98
134
  "--name", container_name,
99
135
  "--network=host",
136
+ ]
137
+
138
+ # Inject custom environment variables from config
139
+ if (custom_env = config["env"])
140
+ custom_env.each do |k, v|
141
+ docker_cmd += ["-e", "#{k}=#{v}"]
142
+ end
143
+ puts "🌿 Injected #{custom_env.size} custom env vars from config"
144
+ end
145
+
146
+ docker_cmd += [
100
147
  # Mount Claude config
101
148
  "-v", "#{ENV['HOME']}/.claude.json:/tmp/cfg/claude.json:ro",
102
149
  "-v", "#{ENV['HOME']}/.claude:/tmp/cfg/claude_dir:ro",
@@ -117,7 +164,7 @@ def run_agent(agent_type, config)
117
164
 
118
165
  unless File.exist?(key_path) && !File.directory?(key_path)
119
166
  puts "❌ Error: GitHub App private key not found at: #{key_path}"
120
- puts " Please check 'app_private_key_path' in tinker.env.json"
167
+ puts " Please check 'app_private_key_path' in tinker.env.rb"
121
168
  exit 1
122
169
  end
123
170
 
@@ -133,7 +180,7 @@ def run_agent(agent_type, config)
133
180
  puts "🔑 Using GitHub token authentication"
134
181
  else
135
182
  puts "❌ Error: No GitHub authentication configured"
136
- puts " Please configure 'github' in tinker.env.json"
183
+ puts " Please configure 'github' in tinker.env.rb"
137
184
  exit 1
138
185
  end
139
186
 
@@ -193,15 +240,17 @@ def attach_to_agent(agent_type, config)
193
240
  exit 1
194
241
  end
195
242
 
243
+ agent_def = AGENT_CONFIGS[agent_type]
196
244
  agent_config = config.dig("agents", agent_type) || {}
197
- container_name = agent_config["container_name"] || "tinker-#{agent_type}"
245
+ container_name = agent_config["container_name"] || agent_def[:name]
198
246
 
199
247
  running = `docker ps --filter name=^#{container_name}$ --format '{{.Names}}'`.strip
200
248
 
201
249
  if running.empty?
202
- puts "#{agent_type} agent is not running"
203
- puts " Start with: npx tinker-agent #{agent_type}"
204
- exit 1
250
+ puts "⚠️ #{agent_type} agent is not running. Auto-starting..."
251
+ build_docker_image
252
+ run_agent(agent_type, config)
253
+ sleep 3
205
254
  end
206
255
 
207
256
  puts "📎 Attaching to #{agent_type} agent..."
@@ -224,6 +273,14 @@ def attach_to_agent(agent_type, config)
224
273
 
225
274
  puts " User: #{user}"
226
275
 
276
+ # Wait for tmux session to be ready
277
+ 10.times do
278
+ if system("docker", "exec", "-u", user, container_name, "tmux", "has-session", "-t", "agent", err: File::NULL, out: File::NULL)
279
+ break
280
+ end
281
+ sleep 1
282
+ end
283
+
227
284
  # Attach to agent session which has the status bar
228
285
  # Must run as agent user since tmux server runs under that user
229
286
  exec("docker", "exec", "-it", "-u", user, container_name, "tmux", "attach", "-t", "agent")
@@ -237,10 +294,9 @@ def show_usage
237
294
  puts ""
238
295
  puts "Setup:"
239
296
  puts " 1. Create Dockerfile.sandbox (see https://github.com/RoM4iK/tinker-public/blob/main/README.md)"
240
- puts " 2. curl -fsSL https://raw.githubusercontent.com/RoM4iK/tinker-public/main/tinker.env.example.json -o tinker.env.json"
241
- puts " 3. Edit tinker.env.json with your config"
242
- puts " 4. echo 'tinker.env.json' >> .gitignore"
243
- puts " 5. npx tinker-agent worker"
297
+ puts " 2. Create tinker.env.rb (see https://github.com/RoM4iK/tinker-public/blob/main/README.md)"
298
+ puts " 3. echo 'tinker.env.rb' >> .gitignore"
299
+ puts " 4. npx tinker-agent worker"
244
300
  exit 1
245
301
  end
246
302