Class: Chiridion::Engine

Inherits:
Object
  • Object
show all
Defined in:
lib/chiridion/engine.rb,
lib/chiridion/engine/writer.rb,
lib/chiridion/engine/renderer.rb,
lib/chiridion/engine/extractor.rb,
lib/chiridion/engine/rbs_loader.rb,
lib/chiridion/engine/file_writer.rb,
lib/chiridion/engine/type_merger.rb,
lib/chiridion/engine/class_linker.rb,
lib/chiridion/engine/drift_checker.rb,
lib/chiridion/engine/file_renderer.rb,
lib/chiridion/engine/github_linker.rb,
lib/chiridion/engine/document_model.rb,
lib/chiridion/engine/post_processor.rb,
lib/chiridion/engine/inline_rbs_loader.rb,
lib/chiridion/engine/semantic_renderer.rb,
lib/chiridion/engine/template_renderer.rb,
lib/chiridion/engine/semantic_extractor.rb,
lib/chiridion/engine/frontmatter_builder.rb,
lib/chiridion/engine/spec_example_loader.rb,
lib/chiridion/engine/generated_rbs_loader.rb,
lib/chiridion/engine/rbs_type_alias_loader.rb

Overview

Documentation engine for generating agent-oriented docs from Ruby source.

Coordinates several specialized components:

  • Extractor - Walks YARD registry, extracts class/method/constant metadata

  • RbsLoader - Loads RBS type signatures from sig/ directory

  • SpecExampleLoader - Extracts usage examples from RSpec files

  • TypeMerger - Merges RBS types with YARD documentation

  • Renderer - Generates markdown with Obsidian-compatible wikilinks

  • Writer - Handles file I/O with content-based change detection

  • DriftChecker - Detects when docs are out of sync with source

## YARD Registry Persistence

For performance, the engine persists YARD’s parsed registry to .yardoc/. This enables efficient partial refreshes: when a single file changes, we load the existing registry, re-parse only that file, and regenerate only the affected documentation.

Examples:

Generate docs via Engine

engine = Chiridion::Engine.new(
  paths: ['lib/myproject'],
  output: 'docs/sys',
  namespace_filter: 'MyProject::'
)
engine.refresh

Partial refresh (single file)

engine = Chiridion::Engine.new(
  paths: ['lib/myproject/config.rb'],
  output: 'docs/sys',
  namespace_filter: 'MyProject::'
)
engine.refresh

Defined Under Namespace

Modules: DocumentModel Classes: ClassLinker, DriftChecker, Extractor, FileRenderer, FileWriter, FrontmatterBuilder, GeneratedRbsLoader, GithubLinker, InlineRbsLoader, PostProcessor, RbsLoader, RbsTypeAliasLoader, Renderer, SemanticExtractor, SemanticRenderer, SpecExampleLoader, TemplateRenderer, TypeMerger, Writer

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(paths:, output:, namespace_filter: nil, namespace_strip: nil, include_specs: false, verbose: false, logger: nil, root: Dir.pwd, rbs_path: "sig", spec_path: "test", github_repo: nil, github_branch: "main", project_title: "API Documentation", index_description: nil, inline_source_threshold: 10, output_mode: :per_class) ⇒ Engine

Create a new documentation engine.

Parameters:

  • paths (Array<String>)

    Source files or directories to document. Can be specific files for partial refresh or directories for full refresh.

  • output (String)

    Output directory for generated markdown docs.

  • namespace_filter (String, nil) (defaults to: nil)

    Only document classes starting with this prefix.

  • namespace_strip (String, nil) (defaults to: nil)

    Strip this prefix from output paths (defaults to namespace_filter).

  • include_specs (Boolean) (defaults to: false)

    Whether to extract usage examples from spec files.

  • verbose (Boolean) (defaults to: false)

    Whether to show detailed progress and warnings.

  • logger (#info, #warn, nil) (defaults to: nil)

    Logger for output messages.

  • root (String) (defaults to: Dir.pwd)

    Project root directory for resolving relative paths.

  • rbs_path (String) (defaults to: "sig")

    Path to RBS signatures directory.

  • spec_path (String) (defaults to: "test")

    Path to spec directory.

  • github_repo (String, nil) (defaults to: nil)

    GitHub repository for source links.

  • github_branch (String) (defaults to: "main")

    Git branch for source links.

  • project_title (String) (defaults to: "API Documentation")

    Title for the documentation index.

  • index_description (String, nil) (defaults to: nil)

    Custom description for the index page.

  • inline_source_threshold (Integer, nil) (defaults to: 10)

    Max body lines for inline source display.

  • output_mode (:per_class, :per_file) (defaults to: :per_class)

    Output organization strategy.



67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
# File 'lib/chiridion/engine.rb', line 67

def initialize(
  paths:,
  output:,
  namespace_filter: nil,
  namespace_strip: nil,
  include_specs: false,
  verbose: false,
  logger: nil,
  root: Dir.pwd,
  rbs_path: "sig",
  spec_path: "test",
  github_repo: nil,
  github_branch: "main",
  project_title: "API Documentation",
  index_description: nil,
  inline_source_threshold: 10,
  output_mode: :per_class
)
  @paths                   = Array(paths)
  @output                  = output
  @namespace_filter        = namespace_filter
  @namespace_strip         = namespace_strip || namespace_filter
  @include_specs           = include_specs
  @verbose                 = verbose
  @logger                  = logger || DefaultLogger.new
  @root                    = root
  @rbs_path                = rbs_path
  @spec_path               = spec_path
  @github_repo             = github_repo
  @github_branch           = github_branch
  @project_title           = project_title
  @index_description       = index_description
  @inline_source_threshold = inline_source_threshold
  @output_mode             = output_mode
end

Instance Attribute Details

#outputString (readonly)

Returns Output directory for generated docs.

Returns:

  • (String)

    Output directory for generated docs



46
47
48
# File 'lib/chiridion/engine.rb', line 46

def output
  @output
end

#pathsArray<String> (readonly)

Returns Source paths being documented.

Returns:

  • (Array<String>)

    Source paths being documented



43
44
45
# File 'lib/chiridion/engine.rb', line 43

def paths
  @paths
end

Instance Method Details

#checkvoid

This method returns an undefined value.

Check for documentation drift without writing files.

Compares what would be generated against existing docs. Useful in CI to ensure docs are kept in sync with source code changes.

Raises:

  • (SystemExit)

    Exits with code 1 if drift is detected



179
180
181
182
183
184
185
186
187
188
# File 'lib/chiridion/engine.rb', line 179

def check
  require "yard"
  register_rbs_tag

  @logger.info "Checking documentation drift for #{paths_description}..."

  load_sources
  doc_structure = extract_documentation(YARD::Registry)
  check_for_drift(doc_structure)
end

#refreshvoid

This method returns an undefined value.

Generate documentation from source and write to output directory.

This is the main entry point for documentation generation. It:

  1. Parses Ruby source files with YARD

  2. Loads RBS type signatures

  3. Extracts spec examples (if enabled)

  4. Merges types with YARD docs

  5. Renders to markdown with wikilinks

  6. Writes files with content-based change detection



114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
# File 'lib/chiridion/engine.rb', line 114

def refresh
  require "yard"
  register_rbs_tag

  @logger.info "Parsing Ruby files in #{paths_description}..."

  load_sources

  if @output_mode == :per_file
    refresh_per_file
  else
    doc_structure = extract_documentation(YARD::Registry)
    write_documentation(doc_structure)
  end

  @logger.info "Documentation written to #{@output}/"
end

#refresh_per_filevoid

This method returns an undefined value.

Generate per-file documentation using the semantic extraction pipeline.

Produces one markdown file per source file, containing all namespaces (classes/modules) defined in that file.



138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
# File 'lib/chiridion/engine.rb', line 138

def refresh_per_file
  extractor = SemanticExtractor.new(
    rbs_types:        @rbs_types,
    rbs_attr_types:   @rbs_attr_types,
    type_aliases:     @type_aliases,
    spec_examples:    @spec_examples,
    namespace_filter: @namespace_filter,
    logger:           @logger
  )

  project = extractor.extract(
    YARD::Registry,
    title:       @project_title,
    description: @index_description,
    root:        @root
  )

  writer = FileWriter.new(
    output:                  @output,
    namespace_strip:         @namespace_strip,
    include_specs:           @include_specs,
    verbose:                 @verbose,
    logger:                  @logger,
    root:                    @root,
    github_repo:             @github_repo,
    github_branch:           @github_branch,
    project_title:           @project_title,
    index_description:       @index_description,
    inline_source_threshold: @inline_source_threshold
  )

  writer.write(project)
end