Class: Ace::Support::Nav::Organisms::NavigationEngine

Inherits:
Object
  • Object
show all
Defined in:
lib/ace/support/nav/organisms/navigation_engine.rb

Overview

Orchestrates navigation operations

Instance Method Summary collapse

Constructor Details

#initialize(handbook_scanner: nil, protocol_scanner: nil, resource_resolver: nil, path_normalizer: nil) ⇒ NavigationEngine

Returns a new instance of NavigationEngine.



13
14
15
16
17
18
# File 'lib/ace/support/nav/organisms/navigation_engine.rb', line 13

def initialize(handbook_scanner: nil, protocol_scanner: nil, resource_resolver: nil, path_normalizer: nil)
  # Support legacy handbook_scanner parameter
  @protocol_scanner = protocol_scanner || handbook_scanner || Molecules::ProtocolScanner.new
  @resource_resolver = resource_resolver || Molecules::ResourceResolver.new(protocol_scanner: @protocol_scanner)
  @path_normalizer = path_normalizer || Atoms::PathNormalizer.new
end

Instance Method Details

#cmd_protocol?(protocol_name) ⇒ Boolean

Check if a protocol is cmd-type (command delegation)

Parameters:

  • protocol_name (String)

    The protocol name to check

Returns:

  • (Boolean)

    true if protocol delegates to external command



89
90
91
# File 'lib/ace/support/nav/organisms/navigation_engine.rb', line 89

def cmd_protocol?(protocol_name)
  config_loader.protocol_type(protocol_name) == "cmd"
end

#create(uri_string, target_path = nil) ⇒ Object

Create a new resource from a template



48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
# File 'lib/ace/support/nav/organisms/navigation_engine.rb', line 48

def create(uri_string, target_path = nil)
  # Resolve the template
  template = @resource_resolver.resolve(uri_string)
  return {error: "Template not found: #{uri_string}"} unless template

  # Determine target path
  target = determine_target_path(template, target_path)
  return {error: "Could not determine target path"} unless target

  # Create directory if needed
  target_dir = File.dirname(target)
  FileUtils.mkdir_p(target_dir) unless Dir.exist?(target_dir)

  # Copy template content
  if template.content
    File.write(target, template.content)
    {created: target, from: template.path}
  else
    {error: "Template has no content: #{template.path}"}
  end
end

#discovered_protocolsObject

Get all discovered protocols



82
83
84
# File 'lib/ace/support/nav/organisms/navigation_engine.rb', line 82

def discovered_protocols
  config_loader.discovered_protocols
end

#list(uri_pattern, options = {}) ⇒ Object

List resources matching a pattern



35
36
37
38
39
40
41
42
43
44
45
# File 'lib/ace/support/nav/organisms/navigation_engine.rb', line 35

def list(uri_pattern, options = {})
  resources = @resource_resolver.resolve_pattern(uri_pattern)

  if options[:tree]
    format_as_tree(resources)
  elsif options[:verbose]
    resources.map(&:to_h)
  else
    format_as_list(resources)
  end
end

#resolve(uri_string, options = {}) ⇒ Object

Resolve a single resource URI to a path



21
22
23
24
25
26
27
28
29
30
31
32
# File 'lib/ace/support/nav/organisms/navigation_engine.rb', line 21

def resolve(uri_string, options = {})
  resource = @resource_resolver.resolve(uri_string)
  return nil unless resource

  if options[:content]
    resource.content
  elsif options[:verbose]
    resource.to_h
  else
    resource.path
  end
end

#resolve_cmd_to_path(uri_string) ⇒ String?

Resolve a cmd-type protocol URI by running its command and capturing stdout Used by tools that need to programmatically obtain the resolved path

Parameters:

  • uri_string (String)

    e.g., “task://8c0.t.05p”

Returns:

  • (String, nil)

    captured stdout (path), or nil on failure



97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
# File 'lib/ace/support/nav/organisms/navigation_engine.rb', line 97

def resolve_cmd_to_path(uri_string)
  protocol, reference = uri_string.split("://", 2)
  return nil unless cmd_protocol?(protocol)

  protocol_config = config_loader.load_protocol_config(protocol)
  command_template = protocol_config["command_template"]
  return nil unless command_template

  require "open3"
  require "shellwords"
  require "timeout"
  args = Shellwords.split(command_template.gsub("%{ref}", Shellwords.escape(reference)))
  stdout, status = Timeout.timeout(10) { Open3.capture2(*args) }
  return nil unless status.success?

  result = stdout.strip
  result.empty? ? nil : result
rescue Timeout::Error
  warn "Warning: cmd protocol timed out for '#{uri_string}'"
  nil
end

#sources(options = {}) ⇒ Object

Show available sources



71
72
73
74
75
76
77
78
79
# File 'lib/ace/support/nav/organisms/navigation_engine.rb', line 71

def sources(options = {})
  all_sources = @protocol_scanner.scan_all_sources

  if options[:verbose]
    all_sources.map(&:to_h)
  else
    all_sources.map { |s| "#{s.alias_name} (#{s.type}): #{s.path}" }
  end
end