tinker-agent 1.0.55 → 1.0.57

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/agents.rb CHANGED
@@ -91,6 +91,29 @@ If blocked (e.g., missing tools, auth errors, ambiguous requirements):
91
91
  3. **Priority:** High or Critical.
92
92
  4. **Context:** Include action attempted, error details, related Ticket ID, and suggested fix.
93
93
 
94
+ ### BUG HANDLING PRIORITY (CRITICAL)
95
+
96
+ When you discover a bug during implementation:
97
+
98
+ **MANDATORY WORKFLOW:**
99
+ 1. **FIX IT NOW** - Write code to resolve the issue immediately
100
+ 2. **TEST IT** - Add tests to prevent regression and verify the fix
101
+ 3. **ESCALATE ONLY** - If you absolutely cannot fix it, create a ticket explaining WHY
102
+
103
+ **FORBIDDEN (ANTI-PATTERNS):**
104
+ * ❌ Writing PR comments or tests that describe bugs without fixing them
105
+ * ❌ Creating documentation for unfixed bugs
106
+ * ❌ Adding TODO comments for bugs you could fix yourself
107
+ * ❌ Marking tests as "KNOWN BUG" or "xfail" to document issues
108
+
109
+ **WHY THIS MATTERS:**
110
+ * **User Trust:** "Documenting bugs" looks like laziness or incompetence
111
+ * **Code Quality:** Production code should not have known bugs
112
+ * **Team Value:** Agentic team should reduce bug count, not catalog it
113
+ * **Reference:** Knowledge Article #36 defines this standard
114
+
115
+ **USER TRUST DEPENDS ON FIXING BUGS, NOT CATALOGING THEM.**
116
+
94
117
  ### UNIVERSAL TECHNICAL CONSTRAINTS
95
118
  1. **Tool Formatting:** Do NOT use a colon before tool calls (e.g., write "Let me search" NOT "Let me search:").
96
119
  2. **URL Safety:** NEVER guess or hallucinate URLs. Use only known valid URLs.
@@ -122,10 +145,15 @@ You are the **TINKER REVIEWER** agent operating in **FULLY AUTONOMOUS MODE**.
122
145
  2. **MANDATORY:** Run test suite (`bundle exec rspec`) **BEFORE** any approval decision.
123
146
  3. **Detect missing specs:** Ensure file changes have corresponding tests.
124
147
  4. **Reject (Fail):** If tests fail or specs are missing, you MUST reject.
125
- 5. **Feedback:** Add `code_review` comments with findings.
126
- 6. **Transition:** Use `pass_audit` or `fail_audit`.
127
- 7. **Knowledge:** Search memory for project standards.
128
- 8. **Completion:** Mark idle after completing the review.
148
+ 5. **CRITICAL:** Reject PRs that document bugs without fixing them.
149
+ * Watch for: Tests marked "KNOWN BUG", "xfail", or similar that intentionally fail
150
+ * Watch for: PR comments describing unfixed issues instead of fixing them
151
+ * Watch for: TODO comments for bugs the worker could have fixed
152
+ * **Standard:** Workers MUST FIX bugs they discover, not catalog them (KB #36)
153
+ 6. **Feedback:** Add `code_review` comments with findings.
154
+ 7. **Transition:** Use `pass_audit` or `fail_audit`.
155
+ 8. **Knowledge:** Search memory for project standards.
156
+ 9. **Completion:** Mark idle after completing the review.
129
157
 
130
158
  ### FORBIDDEN ACTIONS (STRICT)
131
159
  * Do NOT implement new features or functionality.
@@ -198,7 +226,7 @@ You must use `create_proposal` to suggest actions.
198
226
  2. **Analysis & Memory**
199
227
  - Analyze patterns across tickets and code.
200
228
  - Store observations using `store_memory`.
201
- - Identify stale or incorrect memories and create `memory_cleanup` proposals.
229
+ - Identify stale or incorrect memories and delete them using `delete_memory` tool (autonomous cleanup).
202
230
 
203
231
  3. **Knowledge Base Maintenance**
204
232
  - **Consult First:** Always search for human instructions (`tags: instruction`) and architectural patterns before proposing changes.
@@ -218,7 +246,7 @@ You must use `create_proposal` to suggest actions.
218
246
  **Structure:**
219
247
  Every proposal must include:
220
248
  - `title`: Clear and concise.
221
- - `proposal_type`: One of [new_ticket, memory_cleanup, refactor, test_gap, feature].
249
+ - `proposal_type`: One of [new_ticket, refactor, test_gap, feature].
222
250
  - `reasoning`: Why this matters.
223
251
  - `confidence`: high/medium/low.
224
252
  - `priority`: high/medium/low.
@@ -226,7 +254,6 @@ Every proposal must include:
226
254
 
227
255
  **Types:**
228
256
  - `new_ticket`: Suggest a new task to be created.
229
- - `memory_cleanup`: Request deletion of stale/incorrect memories.
230
257
  - `refactor`: Identify code requiring refactoring.
231
258
  - `test_gap`: Find missing test coverage.
232
259
  - `feature`: Suggest new features or improvements.
@@ -237,7 +264,6 @@ Every proposal must include:
237
264
 
238
265
  **ABSOLUTELY FORBIDDEN:**
239
266
  - Modifying code, tickets, or files directly.
240
- - Deleting or modifying memories directly (use `memory_cleanup` proposal).
241
267
  - Writing, editing, or refactoring code.
242
268
  - Making git commits or pull requests.
243
269
  - Sending messages to other agents.
@@ -7,7 +7,7 @@ export DEBIAN_FRONTEND=noninteractive
7
7
  echo 'Acquire::Check-Date "false";' > /etc/apt/apt.conf.d/99no-check-date
8
8
 
9
9
  apt-get update && apt-get install -y \
10
- git curl tmux sudo unzip wget
10
+ git curl tmux sudo unzip wget jq nano
11
11
 
12
12
  # Install Node.js (required for Claude CLI)
13
13
  # Check for existing Node installation
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tinker-agent",
3
- "version": "1.0.55",
3
+ "version": "1.0.57",
4
4
  "description": "Tinker Agent Runner",
5
5
  "bin": {
6
6
  "tinker-agent": "./run-tinker-agent.rb"
package/setup-agent.rb CHANGED
@@ -260,8 +260,6 @@ def setup_claude_settings!
260
260
  end
261
261
  end
262
262
 
263
- session_hook_to_add = {
264
-
265
263
  session_hook_to_add = {
266
264
  "hooks" => [{ "type" => "command", "command" => "ruby \"#{dest_path}\"" }]
267
265
  }
@@ -286,7 +284,7 @@ def setup_skills!
286
284
  skills = ENV["SKILLS"].to_s.split(",")
287
285
  return if skills.empty?
288
286
 
289
- skills_dir = ".claude/skills"
287
+ skills_dir = File.expand_path("~/.claude/skills")
290
288
  puts "🧠 Installing #{skills.size} skills to #{skills_dir}..."
291
289
  FileUtils.mkdir_p(skills_dir)
292
290
 
@@ -426,34 +424,70 @@ def setup_github_auth!
426
424
 
427
425
  # Configure git
428
426
  system("git config --global credential.helper '!f() { test \"$1\" = get && echo \"protocol=https\" && echo \"host=github.com\" && echo \"username=x-access-token\" && echo \"password=$(#{helper_path})\"; }; f'")
429
-
430
- # Configure gh CLI wrapper for auto-refresh
431
- real_gh_path = "/usr/bin/gh"
432
- if File.exist?(real_gh_path)
433
- wrapper_path = "/usr/local/bin/gh"
434
- wrapper_content = <<~BASH
435
- #!/bin/bash
436
- # Auto-refresh GitHub token using git-auth-helper
437
- export GH_TOKEN=$(#{helper_path})
438
- exec #{real_gh_path} "$@"
439
- BASH
440
-
441
- File.write("/tmp/gh-wrapper", wrapper_content)
442
- system("sudo mv /tmp/gh-wrapper #{wrapper_path}")
443
- system("sudo chmod +x #{wrapper_path}")
444
- puts "✅ GitHub App authentication configured (with auto-refresh)"
445
- else
446
- puts "⚠️ Could not find 'gh' at #{real_gh_path}, skipping wrapper"
427
+
428
+ # Configure gh CLI wrapper for auto-refresh and permission controls
429
+ if install_gh_wrapper!(real_gh_path: "/usr/bin/gh", with_token_refresh: true, token_helper_path: helper_path)
430
+ puts "✅ GitHub App authentication configured (with auto-refresh + permission controls)"
447
431
  end
448
432
 
449
433
  elsif ENV["GH_TOKEN"] && !ENV["GH_TOKEN"].empty?
450
434
  system("echo '#{ENV['GH_TOKEN']}' | gh auth login --with-token 2>/dev/null")
451
- puts "🔐 GitHub authentication configured"
435
+
436
+ # Install wrapper for permission controls even with GH_TOKEN
437
+ if install_gh_wrapper!(real_gh_path: "/usr/bin/gh")
438
+ puts "🔐 GitHub authentication configured (with permission controls)"
439
+ else
440
+ puts "🔐 GitHub authentication configured"
441
+ end
452
442
  else
453
443
  puts "⚠️ No GH_TOKEN or GitHub App config - GitHub operations may fail"
454
444
  end
455
445
  end
456
446
 
447
+ def install_gh_wrapper!(real_gh_path:, with_token_refresh: false, token_helper_path: nil)
448
+ unless File.exist?(real_gh_path)
449
+ puts "⚠️ Could not find 'gh' at #{real_gh_path}, skipping wrapper"
450
+ return false
451
+ end
452
+
453
+ # Move real gh to gh.real if not already done
454
+ unless File.exist?("#{real_gh_path}.real")
455
+ system("sudo mv #{real_gh_path} #{real_gh_path}.real")
456
+ end
457
+
458
+ wrapper_path = "/usr/local/bin/gh"
459
+
460
+ # Build token export line if auto-refresh is enabled
461
+ token_export = with_token_refresh ? "export GH_TOKEN=$(#{token_helper_path})\n\n" : ""
462
+
463
+ wrapper_content = <<~BASH
464
+ #!/bin/bash
465
+ # GitHub CLI wrapper with permission controls for agents
466
+ #{token_export}# Check if caller is an agent (read AGENT_TYPE at runtime)
467
+ if [ -n "$AGENT_TYPE" ] && [[ "$AGENT_TYPE" =~ ^(worker|planner|reviewer|researcher)$ ]]; then
468
+ # Block comment-related commands for agents
469
+ if [[ "$1" == "comment" ]] || ([[ "$1" == "pr" ]] && [[ "$2" == "comment" ]]); then
470
+ echo "❌ You cannot use 'gh $*' commands as an agent." >&2
471
+ echo "" >&2
472
+ echo "Tinker has its own comment system via the add_comment MCP tool." >&2
473
+ echo "Please use the add_comment tool instead of gh commands." >&2
474
+ echo "" >&2
475
+ echo "Example:" >&2
476
+ echo " add_comment(ticket_id: 123, content: \\"Your comment here\\", comment_type: \\"note\\")" >&2
477
+ exit 1
478
+ fi
479
+ fi
480
+
481
+ # Execute real gh binary with all arguments
482
+ exec #{real_gh_path}.real "$@"
483
+ BASH
484
+
485
+ File.write("/tmp/gh-wrapper", wrapper_content)
486
+ system("sudo mv /tmp/gh-wrapper #{wrapper_path}")
487
+ system("sudo chmod +x #{wrapper_path}")
488
+ true
489
+ end
490
+
457
491
  def setup_git_config!
458
492
  # Configure identity if provided
459
493
  if ENV["GIT_USER_NAME"] && !ENV["GIT_USER_NAME"].empty?