← back to darwin__supex

Function bodies 257 total

All specs Real LLM only Function bodies
SupexRuntime::Export.export_scene method · ruby · L17-L34 (18 LOC)
runtime/src/supex_runtime/export.rb
    def self.export_scene(params)
      format = params['format'] || 'skp'

      raise "Unsupported export format: #{format}" unless SUPPORTED_FORMATS.include?(format.downcase)

      model = Sketchup.active_model
      export_path = generate_export_path(format)

      case format.downcase
      when 'skp'
        export_skp(model, export_path)
      when 'obj'
        export_obj(model, export_path)
      when 'stl'
        export_stl(model, export_path)
      when 'png', 'jpg', 'jpeg'
        export_image(model, export_path, format, params)
      end
SupexRuntime.generate_export_path method · ruby · L46-L55 (10 LOC)
runtime/src/supex_runtime/export.rb
    def self.generate_export_path(format)
      temp_dir = File.join(ENV['TEMP'] || ENV['TMP'] || Dir.tmpdir, 'supex_runtime_exports')
      FileUtils.mkdir_p(temp_dir)

      timestamp = Time.now.strftime('%Y%m%d_%H%M%S')
      filename = "supex_runtime_export_#{timestamp}"
      extension = format.downcase == 'jpg' ? 'jpeg' : format.downcase

      File.join(temp_dir, "#{filename}.#{extension}")
    end
SupexRuntime.export_obj method · ruby · L67-L75 (9 LOC)
runtime/src/supex_runtime/export.rb
    def self.export_obj(model, path)
      options = {
        triangulated_faces: true,
        double_sided_faces: true,
        edges: false,
        texture_maps: true
      }
      model.export(path, options)
    end
SupexRuntime.export_image method · ruby · L90-L102 (13 LOC)
runtime/src/supex_runtime/export.rb
    def self.export_image(model, path, format, params)
      view = model.active_view

      options = {
        filename: path,
        width: params['width'] || 1920,
        height: params['height'] || 1080,
        antialias: true,
        transparent: format.downcase == 'png'
      }

      view.write_image(options)
    end
SupexRuntime.start method · ruby · L22-L35 (14 LOC)
runtime/src/supex_runtime/main.rb
    def self.start(repl: nil)
      load_stdlib
      Utils.console_write("Supex: Version #{VERSION}")
      Utils.console_write("Supex: SketchUp #{Sketchup.version} compatibility")

      start_bridge_server

      # Start REPL server unless explicitly disabled
      repl_enabled = repl.nil? ? ENV['SUPEX_REPL_DISABLED'] != '1' : repl
      start_repl_server if repl_enabled

      add_menu_items
      true
    end
stop_repl_server function · ruby · L85-L94 (10 LOC)
runtime/src/supex_runtime/main.rb
    def self.stop_repl_server
      if @repl_server&.running?
        @repl_server.stop
        @repl_server = nil
        Utils.console_write('Supex: REPL server stopped')
        true
      else
        Utils.console_write('Supex: REPL server is not running')
        false
      end
stop function · ruby · L98-L107 (10 LOC)
runtime/src/supex_runtime/main.rb
    def self.stop
      stopped = false

      # Stop REPL server first
      if @repl_server&.running?
        @repl_server.stop
        @repl_server = nil
        Utils.console_write('Supex: REPL server stopped')
        stopped = true
      end
Repobility (the analyzer behind this table) · https://repobility.com
server_status function · ruby · L130-L147 (18 LOC)
runtime/src/supex_runtime/main.rb
    def self.server_status
      status = {
        version: VERSION,
        bridge: {
          running: @bridge_server&.running? || false,
          port: @bridge_server&.running? ? BridgeServer::DEFAULT_PORT : nil
        },
        repl: {
          running: @repl_server&.running? || false,
          port: @repl_server&.running? ? @repl_server.port : nil
        }
      }

      if @bridge_server&.running?
        status[:sketchup_version] = Sketchup.version
        status[:mcp_version] = MCP_VERSION
        status[:required_sketchup] = REQUIRED_SKETCHUP_VERSION
      end
reload_extension function · ruby · L171-L191 (21 LOC)
runtime/src/supex_runtime/main.rb
    def self.reload_extension
      Utils.console_write('Supex: Reloading extension...')

      begin
        was_running = @bridge_server&.running?
        stop if was_running

        remove_extension_constants
        unload_extension_files

        GC.start
        reload_main_extension_file

        Utils.console_write('Supex: Extension reloaded successfully')
        restart_if_was_running(was_running)
        true
      rescue StandardError => e
        Utils.console_write("Supex: Failed to reload extension: #{e.message}")
        Utils.console_write("Supex: #{e.backtrace.join("\n")}")
        false
      end
remove_extension_constants function · ruby · L195-L206 (12 LOC)
runtime/src/supex_runtime/main.rb
    def self.remove_extension_constants
      return unless defined?(SupexRuntime::VERSION)

      constants_to_remove = %i[
        VERSION REQUIRED_SKETCHUP_VERSION MCP_VERSION
        EXTENSION_NAME EXTENSION_DESCRIPTION EXTENSION_CREATOR EXTENSION_COPYRIGHT
      ]
      constants_to_remove.each do |const|
        SupexRuntime.send(:remove_const, const)
      rescue StandardError
        nil
      end
unload_extension_files function · ruby · L210-L222 (13 LOC)
runtime/src/supex_runtime/main.rb
    def self.unload_extension_files
      files_to_reload = %w[
        version.rb utils.rb geometry.rb materials.rb
        export.rb joinery.rb batch_screenshot.rb tools.rb
        bridge_server.rb repl_server.rb main.rb
      ]
      extension_dir = __dir__

      files_to_reload.each do |file|
        full_path = File.join(extension_dir, file)
        loaded_files = $LOADED_FEATURES.select do |f|
          f == full_path || f.end_with?("/supex_runtime/#{file}")
        end
restart_if_was_running function · ruby · L240-L245 (6 LOC)
runtime/src/supex_runtime/main.rb
    def self.restart_if_was_running(was_running)
      return unless was_running

      sleep(1)
      start
    end
load_stdlib function · ruby · L249-L260 (12 LOC)
runtime/src/supex_runtime/main.rb
    def self.load_stdlib
      stdlib_path = ENV['SUPEX_STDLIB_PATH'] ||
                    File.expand_path('../../../stdlib/src/supex_stdlib.rb', __dir__)

      if File.exist?(stdlib_path)
        require stdlib_path
        Utils.console_write("Supex: Stdlib v#{SupexStdlib::VERSION} loaded")
        true
      else
        Utils.console_write('Supex: Stdlib not found (optional)')
        false
      end
add_menu_items function · ruby · L267-L275 (9 LOC)
runtime/src/supex_runtime/main.rb
    def self.add_menu_items
      # Skip if menu already exists (simple check - menu creation will fail if exists)
      begin
        extensions_menu = UI.menu('Extensions')
        supex_runtime_menu = extensions_menu.add_submenu('Supex')
      rescue ArgumentError
        # Menu already exists, skip creation
        return
      end
show_server_status function · ruby · L297-L311 (15 LOC)
runtime/src/supex_runtime/main.rb
    def self.show_server_status
      status = server_status

      bridge_status = status[:bridge][:running] ? "RUNNING (port #{status[:bridge][:port]})" : 'STOPPED'
      repl_status = status[:repl][:running] ? "RUNNING (port #{status[:repl][:port]})" : 'STOPPED'

      message = "Supex Server Status\n\n" \
                "Version: #{status[:version]}\n\n" \
                "Bridge Server: #{bridge_status}\n" \
                "REPL Server: #{repl_status}"

      if status[:bridge][:running]
        message += "\n\nSketchUp: #{status[:sketchup_version]}\n" \
                   "MCP Version: #{status[:mcp_version]}"
      end
If a scraper extracted this row, it came from Repobility (https://repobility.com)
show_about_dialog function · ruby · L317-L326 (10 LOC)
runtime/src/supex_runtime/main.rb
    def self.show_about_dialog
      message = "Supex v#{VERSION}\n\n" \
                "A SketchUp Model Context Protocol server.\n" \
                "Provides AI-accessible tools for SketchUp automation.\n\n" \
                "Supported SketchUp: #{REQUIRED_SKETCHUP_VERSION}+\n" \
                "Current SketchUp: #{Sketchup.version}\n" \
                "MCP Version: #{MCP_VERSION}"

      UI.messagebox(message, MB_OK)
    end
SupexRuntime::PathPolicy::PathAccessDenied#validate! method · ruby · L22-L30 (9 LOC)
runtime/src/supex_runtime/path_policy.rb
      def validate!(path, operation: 'access')
        return if allow_all?
        return unless path

        resolved = resolve_path(path)
        return if allowed?(resolved)

        raise PathAccessDenied, "Path access denied for #{operation}: #{path}"
      end
SupexRuntime::PathPolicy::PathAccessDenied#allowed_roots method · ruby · L41-L46 (6 LOC)
runtime/src/supex_runtime/path_policy.rb
      def allowed_roots
        roots = ALLOWED_ROOTS.dup
        roots << PROJECT_ROOT if PROJECT_ROOT && !PROJECT_ROOT.empty?
        roots << DEFAULT_TMP
        roots.map { |r| File.expand_path(r) }.uniq
      end
SupexRuntime#initialize method · ruby · L41-L49 (9 LOC)
runtime/src/supex_runtime/repl_server.rb
    def initialize(port: DEFAULT_REPL_PORT, host: DEFAULT_REPL_HOST)
      @port = Integer(ENV.fetch('SUPEX_REPL_PORT', port))
      @host = host
      @server = nil
      @running = false
      @timer_id = nil
      @verbose = ENV['SUPEX_VERBOSE'] == '1'
      @clients = [] # Active client connections
    end
SupexRuntime#start method · ruby · L52-L60 (9 LOC)
runtime/src/supex_runtime/repl_server.rb
    def start
      return true if @running

      # Check if binding to non-loopback without explicit opt-in
      unless loopback_address?(@host)
        unless ALLOW_REMOTE
          log "ERROR: Binding to non-loopback address '#{@host}' requires SUPEX_ALLOW_REMOTE=1"
          return false
        end
stop function · ruby · L85-L94 (10 LOC)
runtime/src/supex_runtime/repl_server.rb
    def stop
      log 'Stopping REPL server...'
      @running = false

      stop_timer
      close_all_clients
      close_server

      log 'REPL server stopped'
    end
start_request_handler function · ruby · L111-L116 (6 LOC)
runtime/src/supex_runtime/repl_server.rb
    def start_request_handler
      @timer_id = UI.start_timer(REQUEST_CHECK_INTERVAL, true) do
        handle_tick if @running
      rescue StandardError => e
        log "Timer handler error: #{e.message}"
      end
stop_timer function · ruby · L120-L125 (6 LOC)
runtime/src/supex_runtime/repl_server.rb
    def stop_timer
      return unless @timer_id

      UI.stop_timer(@timer_id)
      @timer_id = nil
    end
Want this analysis on your repo? https://repobility.com/scan/
close_all_clients function · ruby · L128-L135 (8 LOC)
runtime/src/supex_runtime/repl_server.rb
    def close_all_clients
      @clients.each do |client|
        log_client_closed(client)
        begin
          client.socket.close
        rescue
          nil
        end
close_server function · ruby · L141-L146 (6 LOC)
runtime/src/supex_runtime/repl_server.rb
    def close_server
      return unless @server

      @server.close
      @server = nil
    end
handle_tick function · ruby · L149-L154 (6 LOC)
runtime/src/supex_runtime/repl_server.rb
    def handle_tick
      return unless @server && @running

      accept_new_connections
      process_client_data
    end
accept_new_connections function · ruby · L157-L173 (17 LOC)
runtime/src/supex_runtime/repl_server.rb
    def accept_new_connections
      loop do
        socket = @server.accept_nonblock
        client = ClientConnection.new(
          socket: socket,
          client_info: nil,
          session_dir: nil,
          snippet_counter: 0
        )
        @clients << client
        log_verbose 'New client connected'
      rescue Errno::EWOULDBLOCK, Errno::EAGAIN
        break # No more pending connections
      rescue StandardError => e
        log "Error accepting connection: #{e.message}"
        break
      end
process_client function · ruby · L186-L201 (16 LOC)
runtime/src/supex_runtime/repl_server.rb
    def process_client(client)
      # Check if data is available (non-blocking)
      # rubocop:disable Lint/IncompatibleIoSelectWithFiberScheduler
      ready = IO.select([client.socket], nil, nil, 0)
      # rubocop:enable Lint/IncompatibleIoSelectWithFiberScheduler
      return nil unless ready

      # Try to read a line
      line = client.socket.gets
      unless line
        log_client_closed(client)
        begin
          client.socket.close
        rescue
          nil
        end
process_request function · ruby · L230-L239 (10 LOC)
runtime/src/supex_runtime/repl_server.rb
    def process_request(client, data)
      request = JSON.parse(data)
      log_verbose "REPL request: #{request['method']}"

      response = handle_jsonrpc_request(request, client)
      client.socket.write("#{response.to_json}\n")
      client.socket.flush
    rescue JSON::ParserError => e
      send_error_response(client.socket, "Parse error: #{e.message}", -32_700, nil)
    end
handle_jsonrpc_request function · ruby · L245-L255 (11 LOC)
runtime/src/supex_runtime/repl_server.rb
    def handle_jsonrpc_request(request, client)
      case request['method']
      when 'hello'
        handle_hello(request, client)
      when 'eval'
        return require_hello_error(request) unless client.identified?

        handle_eval(request, client)
      else
        error_response(request, "Method not found: #{request['method']}", -32_601)
      end
handle_hello function · ruby · L262-L271 (10 LOC)
runtime/src/supex_runtime/repl_server.rb
    def handle_hello(request, client)
      params = request['params'] || {}

      # Token validation (if token is configured)
      if AUTH_TOKEN && !AUTH_TOKEN.empty?
        token = params['token']
        unless token == AUTH_TOKEN
          log 'Authentication failed: invalid or missing token'
          return error_response(request, 'Authentication failed: invalid or missing token', -32_001)
        end
Repobility's GitHub App fixes findings like these · https://github.com/apps/repobility-bot
handle_eval function · ruby · L298-L310 (13 LOC)
runtime/src/supex_runtime/repl_server.rb
    def handle_eval(request, client)
      code = request.dig('params', 'code')
      return error_response(request, 'Missing code parameter', -32_602) unless code

      client.snippet_counter += 1
      snippet_path = File.join(client.session_dir, format('%04d.rb', client.snippet_counter))
      File.write(snippet_path, code)

      log_verbose "Evaluating snippet #{client.snippet_counter}"

      output = eval_code_with_capture(code, snippet_path)
      success_response(request, { output: output, success: true })
    end
eval_code_with_capture function · ruby · L323-L335 (13 LOC)
runtime/src/supex_runtime/repl_server.rb
    def eval_code_with_capture(code, snippet_path)
      output = StringIO.new

      with_captured_output(output) do
        # rubocop:disable Security/Eval
        result = eval(code, TOPLEVEL_BINDING, snippet_path, 1)
        # rubocop:enable Security/Eval
        output.puts "=> #{result.inspect}"
      rescue Exception => e # rubocop:disable Lint/RescueException
        output.puts "#<#{e.class}: #{e.message}>"
        filtered = filter_backtrace(e.backtrace)
        output.puts filtered.first(5).join("\n") if filtered.any?
      end
filter_backtrace function · ruby · L344-L351 (8 LOC)
runtime/src/supex_runtime/repl_server.rb
    def filter_backtrace(backtrace)
      return [] unless backtrace

      backtrace.reject do |line|
        line.include?('repl_server.rb') ||
          line.include?("in `eval'") ||
          line.include?('supex_runtime/')
      end
with_captured_output function · ruby · L356-L365 (10 LOC)
runtime/src/supex_runtime/repl_server.rb
    def with_captured_output(output)
      prev_stdout = $stdout
      prev_stderr = $stderr
      $stdout = output
      $stderr = output
      yield
    ensure
      $stdout = prev_stdout
      $stderr = prev_stderr
    end
log_client_closed function · ruby · L397-L403 (7 LOC)
runtime/src/supex_runtime/repl_server.rb
    def log_client_closed(client)
      if client.identified?
        info = client.client_info
        log "Client closed: #{info['name']} [PID:#{info['pid']}]"
      else
        log_verbose 'Client closed (unidentified)'
      end
SupexRuntime::Tools#model_info method · ruby · L14-L22 (9 LOC)
runtime/src/supex_runtime/tools.rb
    def model_info
      model = Sketchup.active_model
      return { success: false, error: 'No active model' } unless model

      build_model_info_response(model)
    rescue StandardError => e
      log "Error getting model info: #{e.message}"
      raise "Failed to get model info: #{e.message}"
    end
SupexRuntime::Tools#list_entities method · ruby · L27-L40 (14 LOC)
runtime/src/supex_runtime/tools.rb
    def list_entities(params)
      model = Sketchup.active_model
      entity_type = params['entity_type'] || 'all'
      return { success: false, error: 'No active model' } unless model

      entities = filter_entities_by_type(model, entity_type)
      entities_data = entities.map { |entity| build_entity_data(entity) }

      { success: true, entity_type: entity_type, count: entities_data.length,
        entities: entities_data }
    rescue StandardError => e
      log "Error listing entities: #{e.message}"
      raise "Failed to list entities: #{e.message}"
    end
SupexRuntime::Tools#selection_info method · ruby · L44-L53 (10 LOC)
runtime/src/supex_runtime/tools.rb
    def selection_info
      model = Sketchup.active_model
      return { success: false, error: 'No active model' } unless model

      entities_data = model.selection.map { |entity| build_selection_entity_data(entity) }
      { success: true, count: model.selection.count, entities: entities_data }
    rescue StandardError => e
      log "Error getting selection: #{e.message}"
      raise "Failed to get selection: #{e.message}"
    end
Repobility (the analyzer behind this table) · https://repobility.com
SupexRuntime::Tools#layers_info method · ruby · L57-L63 (7 LOC)
runtime/src/supex_runtime/tools.rb
    def layers_info
      model = Sketchup.active_model
      return { success: false, error: 'No active model' } unless model

      layers_data = model.layers.map do |layer|
        { name: layer.name, visible: layer.visible?, page_behavior: layer.page_behavior }
      end
SupexRuntime#materials_info method · ruby · L72-L81 (10 LOC)
runtime/src/supex_runtime/tools.rb
    def materials_info
      model = Sketchup.active_model
      return { success: false, error: 'No active model' } unless model

      materials_data = model.materials.map { |material| build_material_data(material) }
      { success: true, count: materials_data.length, materials: materials_data }
    rescue StandardError => e
      log "Error getting materials: #{e.message}"
      raise "Failed to get materials: #{e.message}"
    end
SupexRuntime#camera_info method · ruby · L85-L93 (9 LOC)
runtime/src/supex_runtime/tools.rb
    def camera_info
      model = Sketchup.active_model
      return { success: false, error: 'No active model' } unless model

      build_camera_info_response(model)
    rescue StandardError => e
      log "Error getting camera info: #{e.message}"
      raise "Failed to get camera info: #{e.message}"
    end
SupexRuntime#take_screenshot method · ruby · L98-L111 (14 LOC)
runtime/src/supex_runtime/tools.rb
    def take_screenshot(params)
      model = Sketchup.active_model
      return { success: false, error: 'No active model' } unless model

      # Validate output_path if provided
      PathPolicy.validate!(params['output_path'], operation: 'take_screenshot') if params['output_path']

      screenshot_path = determine_screenshot_path(params['output_path'])
      write_screenshot(model, screenshot_path, params)
    rescue StandardError => e
      log "Error taking screenshot: #{e.message}"
      log e.backtrace.join("\n")
      raise "Failed to take screenshot: #{e.message}"
    end
SupexRuntime#batch_screenshot method · ruby · L117-L123 (7 LOC)
runtime/src/supex_runtime/tools.rb
    def batch_screenshot(params)
      BatchScreenshot.execute(params)
    rescue StandardError => e
      log "Error taking batch screenshots: #{e.message}"
      log e.backtrace.join("\n")
      raise "Failed to take batch screenshots: #{e.message}"
    end
SupexRuntime#open_model method · ruby · L128-L142 (15 LOC)
runtime/src/supex_runtime/tools.rb
    def open_model(params)
      file_path = params['path']
      return { success: false, error: 'No file path provided' } unless file_path

      PathPolicy.validate!(file_path, operation: 'open_model')
      return { success: false, error: "File not found: #{file_path}" } unless File.exist?(file_path)

      Sketchup.open_file(file_path)
      model = Sketchup.active_model
      { success: true, file_path: file_path, file_name: File.basename(file_path),
        title: model.title }
    rescue StandardError => e
      log "Error opening model: #{e.message}"
      raise "Failed to open model: #{e.message}"
    end
SupexRuntime#save_model method · ruby · L147-L160 (14 LOC)
runtime/src/supex_runtime/tools.rb
    def save_model(params)
      model = Sketchup.active_model
      return { success: false, error: 'No active model' } unless model

      # Validate path if provided
      PathPolicy.validate!(params['path'], operation: 'save_model') if params['path']

      saved_path = perform_save(model, params['path'])
      { success: true, file_path: saved_path, file_name: File.basename(saved_path),
        title: model.title }
    rescue StandardError => e
      log "Error saving model: #{e.message}"
      raise "Failed to save model: #{e.message}"
    end
SupexRuntime#build_model_info_response method · ruby · L164-L180 (17 LOC)
runtime/src/supex_runtime/tools.rb
    def build_model_info_response(model)
      units_options = model.options['UnitsOptions']
      length_unit = units_options['LengthUnit']
      units_map = { 0 => 'inches', 1 => 'feet', 2 => 'millimeters', 3 => 'centimeters',
                    4 => 'meters' }

      {
        success: true,
        title: model.title.empty? ? 'Untitled' : model.title,
        units: units_map[length_unit] || 'unknown',
        num_faces: model.entities.grep(Sketchup::Face).count,
        num_edges: model.entities.grep(Sketchup::Edge).count,
        num_groups: model.entities.grep(Sketchup::Group).count,
        num_components: model.entities.grep(Sketchup::ComponentInstance).count,
        modified: model.modified?
      }
    end
If a scraper extracted this row, it came from Repobility (https://repobility.com)
SupexRuntime#filter_entities_by_type method · ruby · L182-L189 (8 LOC)
runtime/src/supex_runtime/tools.rb
    def filter_entities_by_type(model, entity_type)
      case entity_type
      when 'faces' then model.entities.grep(Sketchup::Face)
      when 'edges' then model.entities.grep(Sketchup::Edge)
      when 'groups' then model.entities.grep(Sketchup::Group)
      when 'components' then model.entities.grep(Sketchup::ComponentInstance)
      else model.entities.to_a
      end
build_entity_data function · ruby · L192-L208 (17 LOC)
runtime/src/supex_runtime/tools.rb
    def build_entity_data(entity)
      data = { type: entity.typename, entity_id: entity.entityID }

      case entity
      when Sketchup::Group
        data[:name] = entity.name.empty? ? '(unnamed)' : entity.name
        data[:layer] = entity.layer.name
      when Sketchup::ComponentInstance
        data[:name] = entity.definition.name
        data[:layer] = entity.layer.name
      when Sketchup::Face
        data[:area] = entity.area
        data[:layer] = entity.layer.name
      when Sketchup::Edge
        data[:length] = entity.length
        data[:layer] = entity.layer.name
      end
build_selection_entity_data function · ruby · L213-L227 (15 LOC)
runtime/src/supex_runtime/tools.rb
    def build_selection_entity_data(entity)
      data = { type: entity.typename, entity_id: entity.entityID }

      case entity
      when Sketchup::Face
        data[:area] = entity.area
        normal = entity.normal
        data[:normal] = [normal.x, normal.y, normal.z]
      when Sketchup::Edge
        data[:length] = entity.length
      when Sketchup::Group
        data[:name] = entity.name.empty? ? '(unnamed)' : entity.name
      when Sketchup::ComponentInstance
        data[:name] = entity.definition.name
      end
‹ prevpage 4 / 6next ›