module CursorAgentRunner
Constants
- CLI_CONFIG_ERROR_PATTERN
- CONFIG_DIR
- CONFIG_PATH
- DEFAULT_CAPTURE_ATTEMPTS
- LANES
- LOCK_PATH
- LOCK_PATHS
- MINIMAL_CONFIG
- RETRY_SLEEP_SEC
Public Instance Methods
Source
# File lib/cursor_agent_runner.rb, line 43 def capture3(*args, lane: :chat, attempts: DEFAULT_CAPTURE_ATTEMPTS) prepare! with_lock(lane: lane) do run_capture3_with_retry(*args, attempts: attempts) end end
Source
# File lib/cursor_agent_runner.rb, line 57 def cli_config_error?(*texts) combined = texts.map(&:to_s).join("\n") combined.match?(CLI_CONFIG_ERROR_PATTERN) && combined.match?(/ENOENT|no such file/i) end
Source
# File lib/cursor_agent_runner.rb, line 71 def failure_message(stdout:, stderr:, fallback: "AI request failed") raw = stderr.to_s.strip raw = stdout.to_s.strip if raw.empty? message = friendly_error(raw) message.empty? ? fallback : message end
Source
# File lib/cursor_agent_runner.rb, line 62 def friendly_error(message) text = message.to_s.strip if cli_config_error?(text) return "AI is temporarily unavailable (Cursor config busy) — try again in a moment." end text end
Source
# File lib/cursor_agent_runner.rb, line 30 def lock_path_for(lane) LOCK_PATHS.fetch(lane.to_sym) end
Source
# File lib/cursor_agent_runner.rb, line 50 def popen3(*args, lane: :build, &block) prepare! with_lock(lane: lane) do Open3.popen3(*args, &block) end end
Source
# File lib/cursor_agent_runner.rb, line 34 def prepare! FileUtils.mkdir_p(CONFIG_DIR) return if File.file?(CONFIG_PATH) File.write(CONFIG_PATH, "#{JSON.generate(MINIMAL_CONFIG)}\n") rescue StandardError nil end
Source
# File lib/cursor_agent_runner.rb, line 78 def run_capture3_with_retry(*args, attempts:) last = nil attempts.times do |index| last = Open3.capture3(*args) stdout, stderr, = last return last unless cli_config_error?(stdout, stderr) prepare! sleep RETRY_SLEEP_SEC if index < attempts - 1 end last end
Source
# File lib/cursor_agent_runner.rb, line 91 def with_lock(lane: :chat) FileUtils.mkdir_p(CONFIG_DIR) File.open(lock_path_for(lane), File::RDWR | File::CREAT, 0o644) do |lock| lock.flock(File::LOCK_EX) yield end end