Commit 85d6c9b

mo khan <mo@mokhan.ca>
2026-09-07 17:35:44
feat: add Elelem::Tools.exec, depend on elelem-builtins
Toolbox#exec was removed from core (it hardcoded a dependency on a tool named "execute" that core no longer defines). git/glob/grep/list now call Elelem::Tools.exec(toolbox, ...), which lives here since this gem is the one that actually needs "run a shell command and get a Result back." Claude-Session: https://claude.ai/code/session_01DUuj4amvRrPxDnHPHBkvz5
1 parent a24fa4d
lib/elelem/tools/exec.rb
@@ -0,0 +1,10 @@
+# frozen_string_literal: true
+
+module Elelem
+  module Tools
+    def self.exec(toolbox, *args)
+      command = args.flatten.map { |a| Shellwords.escape(a.to_s) }.join(" ")
+      toolbox.run("execute", { "command" => command })
+    end
+  end
+end
lib/elelem/tools/git.rb
@@ -7,7 +7,7 @@ Elelem.configure do |config|
       params: { command: { type: "string" }, args: { type: "array", items: { type: "string" } } },
       required: ["command"]
     ) do |args|
-      agent.toolbox.exec("git", args["command"], *(args["args"] || []))
+      Elelem::Tools.exec(agent.toolbox, "git", args["command"], *(args["args"] || []))
     end
 
     agent.toolbox.after("git") do |_, result|
lib/elelem/tools/glob.rb
@@ -8,8 +8,8 @@ Elelem.configure do |config|
       required: ["pattern"]
     ) do |args|
       path = args["path"].to_s.empty? ? "." : args["path"]
-      result = agent.toolbox.exec("fd", "--glob", args["pattern"], path)
-      result[:ok] ? result : agent.toolbox.exec("find", path, "-name", args["pattern"])
+      result = Elelem::Tools.exec(agent.toolbox, "fd", "--glob", args["pattern"], path)
+      result[:ok] ? result : Elelem::Tools.exec(agent.toolbox, "find", path, "-name", args["pattern"])
     end
   end
 end
lib/elelem/tools/grep.rb
@@ -12,13 +12,13 @@ Elelem.configure do |config|
 
       rg_args = ["rg", "-n", args["pattern"], path]
       rg_args += ["-g", glob] if glob
-      result = agent.toolbox.exec(*rg_args)
+      result = Elelem::Tools.exec(agent.toolbox, *rg_args)
       next result if result[:ok]
 
       grep_args = ["grep", "-rn"]
       grep_args += ["--include", glob] if glob
       grep_args += [args["pattern"], path]
-      agent.toolbox.exec(*grep_args)
+      Elelem::Tools.exec(agent.toolbox, *grep_args)
     end
   end
 end
lib/elelem/tools/list.rb
@@ -10,7 +10,7 @@ Elelem.configure do |config|
     ) do |args|
       path = args["path"] && !args["path"].empty? ? args["path"] : "."
       flags = args["recursive"] ? "-laR" : "-la"
-      agent.toolbox.exec("ls", flags, path)
+      Elelem::Tools.exec(agent.toolbox, "ls", flags, path)
     end
   end
 end
lib/elelem/tools/version.rb
@@ -2,6 +2,6 @@
 
 module Elelem
   module Tools
-    VERSION = "0.1.1"
+    VERSION = "0.1.2"
   end
 end
lib/elelem/tools.rb
@@ -2,6 +2,7 @@
 
 require "elelem"
 require "pathname"
+require "shellwords"
 require "tempfile"
 
 require_relative "tools/version"
@@ -9,6 +10,7 @@ require_relative "tools/compact"
 require_relative "tools/confirm"
 require_relative "tools/edit"
 require_relative "tools/eval"
+require_relative "tools/exec"
 require_relative "tools/fork"
 require_relative "tools/git"
 require_relative "tools/glob"
elelem-tools.gemspec
@@ -25,7 +25,8 @@ Gem::Specification.new do |spec|
   end
   spec.require_paths = ["lib"]
 
-  spec.add_dependency "elelem", "~> 0.11"
+  spec.add_dependency "elelem", "~> 0.12"
+  spec.add_dependency "elelem-builtins", "~> 0.1"
   spec.add_dependency "pathname", "~> 0.5"
   spec.add_dependency "tempfile", "~> 0.3"
 end
Gemfile.lock
@@ -1,8 +1,9 @@
 PATH
   remote: .
   specs:
-    elelem-tools (0.1.1)
-      elelem (~> 0.11)
+    elelem-tools (0.1.2)
+      elelem (~> 0.12)
+      elelem-builtins (~> 0.1)
       pathname (~> 0.5)
       tempfile (~> 0.3)
 
@@ -11,7 +12,7 @@ GEM
   specs:
     bigdecimal (4.1.2)
     diff-lcs (1.6.2)
-    elelem (0.11.0)
+    elelem (0.12.0)
       erb (~> 6.0)
       fileutils (~> 1.8)
       io-console (~> 0.9)
@@ -23,9 +24,14 @@ GEM
       pathname (~> 0.5)
       reline (~> 0.7)
       shellwords (~> 0.2)
-      stringio (~> 3.2)
-      tempfile (~> 0.3)
       uri (~> 1.0)
+    elelem-builtins (0.1.0)
+      elelem (~> 0.12)
+      fileutils (~> 1.8)
+      json (~> 2.21)
+      open3 (~> 0.2)
+      stringio (~> 3.1)
+      tempfile (~> 0.3)
     erb (6.0.7)
     fileutils (1.8.0)
     hana (1.3.7)
@@ -96,8 +102,9 @@ CHECKSUMS
   bigdecimal (4.1.2) sha256=53d217666027eab4280346fba98e7d5b66baaae1b9c3c1c0ffe89d48188a3fbd
   bundler (4.0.20) sha256=7978a8ac648767f5e635bc522445b79e80a52b907a39a36c2d8085ed6bc762ae
   diff-lcs (1.6.2) sha256=9ae0d2cba7d4df3075fe8cd8602a8604993efc0dfa934cff568969efb1909962
-  elelem (0.11.0)
-  elelem-tools (0.1.1)
+  elelem (0.12.0)
+  elelem-builtins (0.1.0)
+  elelem-tools (0.1.2)
   erb (6.0.7) sha256=c5ca6dc25b0ef974a44dc8f59fe847577122483b1968a38dec305c60bf91ee92
   fileutils (1.8.0) sha256=8c6b1df54e2540bdb2f39258f08af78853aa70bad52b4d394bbc6424593c6e02
   hana (1.3.7) sha256=5425db42d651fea08859811c29d20446f16af196308162894db208cac5ce9b0d