rubylens 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 59011e25213524d532e90ea20c237e82e8e3d615c37767bdf1d46038c64921be
4
- data.tar.gz: feddff17e812a22b342c9e6c8ff65f06a58b45531e41b900e60dd984a31f3efc
3
+ metadata.gz: d79e23df4b2738a967167958385f2ef8b6c8dd6bd333f70a96690ed3c6f35823
4
+ data.tar.gz: '09f0c64309ee0427d3b3cf326187d9aaf9e6cf3d3b6766fd7951c3ba4fccd5e0'
5
5
  SHA512:
6
- metadata.gz: 17d770ab8bbb1b651c1e7c6680ad27b6db38b4614d438c3ffb0b85c1919cec1e51c7fb2be447d61004c54ca23d4df7292ffc006bdcabd6fc04eaba9efcd2f433
7
- data.tar.gz: f36f788b765f4cc60037b251574f9c22da8e65f4a4b78702a317e0443fcc4e832fd1572863731ab0d9f1593e751b749fd4e07cf9ea0cd37bc04dc18cef615ed1
6
+ metadata.gz: e1edf50d830b80dd72f9d033f6d1f9a74a51a90a559c6cc37329701b3762891145fe2e86a4b9f412224af2092a3c4b5c128473b0d453a19d83a689ff9c0570b0
7
+ data.tar.gz: 22e667b3baec097b8bb30c48ba9aa1c8fcd4817993479c0680b45f1605880ff8351f8ee0355e9ac3e06a3a3cc588471a0fd8953ea1561628e3fa411880d0961b
data/README.md CHANGED
@@ -1,32 +1,46 @@
1
1
  # RubyLens
2
2
 
3
- RubyLens turns a Ruby codebase into an interactive galaxy in one self-contained HTML file. It runs locally, keeps source text out of the generated HTML, and gives you two ways to see a project: explore it yourself or let it play as an autonomous presentation.
3
+ Your Ruby codebase, as a galaxy.
4
4
 
5
- [![Five synthetic RubyLens renders showing elliptical, lenticular, spiral, barred spiral, and irregular galaxy shapes.](docs/images/galaxy-morphology-families.jpg)](docs/images/galaxy-morphology-families.jpg)
5
+ [![Five galaxy families rendered by RubyLens: elliptical, lenticular, spiral, barred spiral, irregular.](docs/images/galaxy-morphology-families.jpg)](docs/images/galaxy-morphology-families.jpg)
6
6
 
7
- *Five galaxy families rendered from the same synthetic codebase data.*
8
-
9
- > [!NOTE]
10
- > RubyLens 0.1 is an early release. It supports Ruby 3.2 through 4.0 and pins [Rubydex 0.2.9](https://rubygems.org/gems/rubydex/versions/0.2.9) because Rubydex's API is still pre-1.0.
11
-
12
- ## Quick start
13
-
14
- RubyLens works from inside an existing Ruby project's bundle. The project must be inside a Git repository.
15
-
16
- Add RubyLens to the project's `Gemfile`:
7
+ RubyLens reads a Ruby project and writes one self-contained HTML file: classes and modules as magenta stars, tests as a cyan halo, gems as orbiting gold clouds. The galaxy's shape is derived from the code: spiral, elliptical, barred, lenticular, or irregular.
17
8
 
18
9
  ```ruby
10
+ # Gemfile
19
11
  gem "rubylens", require: false
20
12
  ```
21
13
 
22
- Install the bundle, then generate an Explorer:
23
-
24
14
  ```sh
25
- bundle install
26
15
  bundle exec rubylens report
27
16
  ```
28
17
 
29
- Open `rubylens-report.html` in a browser with WebGL2. No server is required.
18
+ Open `rubylens-report.html` in your browser. No server needed.
19
+
20
+ Three levels of disclosure:
21
+
22
+ | For | Command | Reveals |
23
+ | --- | --- | --- |
24
+ | Yourself | `rubylens report` | Real class, module, and gem names, sparse reference topology, and full interaction |
25
+ | Your team or a talk | `rubylens clip --details` | Project name, shape, scale, sparse reference topology, stats, and selected names |
26
+ | Anyone | `rubylens clip` | Project name, galaxy shape and scale, and sparse anonymous reference topology |
27
+
28
+ > [!IMPORTANT]
29
+ > Nothing is uploaded and no source code is embedded. Outputs still describe your project: they name it, can name classes and gems, and reveal some relationship topology. See [Privacy and sharing](#privacy-and-sharing).
30
+
31
+ https://github.com/user-attachments/assets/43570623-6d98-46c9-9303-7faa4035b2a7
32
+
33
+ *The Explorer on Rails: search, fly to a class, expand a gem cloud.*
34
+
35
+ https://github.com/user-attachments/assets/bb266de5-bbd7-4ccd-814b-15961b45bd39
36
+
37
+ *A `--details` clip: what your team sees.*
38
+
39
+ ## Setup notes
40
+
41
+ RubyLens runs from inside an existing Ruby project's bundle, and the project must be inside a Git repository.
42
+
43
+ `clip` needs Chrome (or Chromium) and ffmpeg; see [Using Clip](#using-clip). Swap in `rubylens showcase [--details]` for the self-playing HTML page alone.
30
44
 
31
45
  RubyLens uses the current directory when you omit `TARGET`. To visualize a subdirectory while using the current project's bundle and root lockfile, run:
32
46
 
@@ -34,31 +48,20 @@ RubyLens uses the current directory when you omit `TARGET`. To visualize a subdi
34
48
  bundle exec rubylens report components/payments --lockfile Gemfile.lock
35
49
  ```
36
50
 
37
- Run RubyLens from each separate project's own bundle.
38
-
39
51
  For complete gem clouds, generate from a project with a readable `Gemfile.lock` after `bundle install`. Without a lockfile, RubyLens still shows Core and Tests but omits Gems and reports a warning. It never fetches missing dependencies during generation.
40
52
 
41
- ## Choose a view
42
-
43
- | Output | Command | Best for | What it reveals |
44
- | --- | --- | --- | --- |
45
- | **Explorer** | `bundle exec rubylens report` | Privately exploring a codebase | Class, module, and gem names, relationships, and aggregate Ruby statistics |
46
- | **Minimal Showcase** | `bundle exec rubylens showcase` | Sharing a visual with fewer details | Project name plus the galaxy's shape and scale |
47
- | **Details Showcase** | `bundle exec rubylens showcase --details` | A presentation with project-specific labels | Aggregate statistics and a capped selection of class, module, and dependency names |
48
-
49
- Explorer writes `rubylens-report.html`. Both Showcase commands write `rubylens-showcase.html`.
50
-
51
53
  ## Privacy and sharing
52
54
 
53
- RubyLens indexes and renders locally. Generated files contain their scripts, styles, fonts, and data, make no network requests, and open without Node or an HTTP server.
55
+ RubyLens indexes and renders locally. Generated HTML files contain their scripts, styles, fonts, and data, make no network requests, and open without Node or an HTTP server. Clip rendering also stays local: it drives your own Chrome and ffmpeg over loopback and never uploads anything.
54
56
 
55
- But the HTML still describes your project:
57
+ But the outputs still describe your project:
56
58
 
57
59
  - Explorer embeds fully qualified class, module, and gem names. It omits source text, comments, paths, and names for individual dependency stars.
58
- - Minimal Showcase omits code and gem names, but still reveals the project name plus the galaxy's shape and scale.
59
- - Details Showcase adds aggregate statistics and selected code/dependency names.
60
+ - Minimal Showcase omits code and gem names, but still reveals the project name, the galaxy's shape and scale, and a sparse anonymous sample of constant-reference topology.
61
+ - Details Showcase adds aggregate statistics and selected code/dependency names to the same topology.
62
+ - Clip shows on screen exactly what the recorded Showcase shows, in a format anyone can replay.
60
63
 
61
- Galaxy shape is also information: a package's rendered shape can make the rough makeup of that gem easier to see, even though it reveals no source text.
64
+ Galaxy shape is also information: a package's rendered shape can make the rough makeup of that gem easier to see, even though it reveals no source text. Relationship topology is information too: a travel line means that one rendered namespace contains a resolved reference to another rendered declaration.
62
65
 
63
66
  Default outputs are written atomically with owner-only `0600` permissions. RubyLens also adds the exact default output and its temporary-file pattern to the repository's local `.git/info/exclude`, so it does not change the shared `.gitignore`.
64
67
 
@@ -70,6 +73,8 @@ Custom output paths are written exactly where requested, may replace an existing
70
73
 
71
74
  Explorer lets you search and move through Core code, Tests, and Gems while the galaxy continues to drift.
72
75
 
76
+ While drift runs, RubyLens scales traffic with the rendered project population: very small reports show one flight at a time, and larger reports show at most two simultaneous flights. Individual launches follow one seeded stream with varied gaps, and a finished flight frees capacity for another after a short randomized breath. There are no synchronized bursts or two-second pauses. Routes to exact Gem declaration stars are preferred three times out of four while workspace-only routes stay eligible. Admission skips very short or out-of-bounds guides and rejects capacity-conflicting or shared-endpoint routes. Each admitted 2.2-second flight follows one immutable world-space quadratic with a compact tapered wake whose thickest end overlaps one elongated same-hue drop. Admission checks a screen-space guide, then unprojects its control point; the live camera projects the resulting path throughout the flight. A rotating Gem star may move away after departure. Orbit, pan, zoom, and camera flights keep active paths visible; pausing drift or requesting reduced motion clears them.
77
+
73
78
  - Drag to orbit.
74
79
  - Scroll at the cursor to zoom.
75
80
  - Shift-drag, use Pan mode, or use the arrow keys to move across the galaxy.
@@ -79,11 +84,11 @@ Explorer lets you search and move through Core code, Tests, and Gems while the g
79
84
  - Press Space or use the toolbar to pause/resume drift.
80
85
  - Use Reset to restore the default camera without changing your drift choice.
81
86
 
82
- Explorer requires WebGL2 to render the complete galaxy. If WebGL2 is unavailable or its context is lost, RubyLens stops the artwork and shows an explicit warning instead of silently presenting a sampled or incomplete galaxy.
87
+ Explorer requires WebGL2 to render the complete galaxy. If WebGL2 is missing or the browser loses the context, RubyLens shows a warning rather than quietly drawing a partial galaxy.
83
88
 
84
89
  ## Using Showcase
85
90
 
86
- Showcase is autonomous and noninteractive. It opens directly, rotates once per minute, and contains no Explorer controls, search, hover, or navigation.
91
+ Showcase is self-playing and noninteractive. It opens directly, rotates once per minute, and contains no Explorer controls, search, hover, or navigation.
87
92
 
88
93
  Use the default Minimal mode when the visual shape is enough:
89
94
 
@@ -97,7 +102,23 @@ Use `--details` when you want aggregate statistics and one-at-a-time cinematic l
97
102
  bundle exec rubylens showcase --details
98
103
  ```
99
104
 
100
- Showcase also requires WebGL2. A browser with `prefers-reduced-motion` enabled receives one stable frame with no cinematic labels.
105
+ Both Showcase modes include the same bounded, anonymous travel flights. Showcase also requires WebGL2. A browser with `prefers-reduced-motion` enabled receives one stable frame with no travel flights or cinematic labels.
106
+
107
+ ## Using Clip
108
+
109
+ Clip records the Showcase into `rubylens-clip.mp4`: one full camera rotation at 1920×1080 and 30 frames per second, encoded as H.264 for compatibility with Slack, X, LinkedIn, and slide decks. The camera ends where it started, so the loop has no visible cut.
110
+
111
+ ```sh
112
+ bundle exec rubylens clip
113
+ bundle exec rubylens clip --details
114
+ ```
115
+
116
+ Clip needs two locally installed tools and checks for them before doing any work:
117
+
118
+ - **Chrome or Chromium** for headless WebGL2 rendering. Discovery checks `PATH` and common install locations; set `RUBYLENS_CHROME` to point at a specific binary.
119
+ - **ffmpeg** for H.264 encoding (`brew install ffmpeg` or `apt install ffmpeg`); set `RUBYLENS_FFMPEG` to override discovery.
120
+
121
+ Frames render deterministically off-screen, so nothing flashes across your display, and progress is reported as the 1,800 frames encode. Expect a few minutes on machines without GPU acceleration. The showcase HTML is always written next to the video, so a failed render still leaves you a shareable page.
101
122
 
102
123
  ## What the stars mean
103
124
 
@@ -105,7 +126,7 @@ Showcase also requires WebGL2. A browser with `prefers-reduced-motion` enabled r
105
126
  - **Tests** are cyan. They represent test classes and modules. RubyLens also adds class-like stars for RSpec `describe` and `context` calls under `spec/` or `specs/`.
106
127
  - **Gems** are warm gold. Each gem forms a cloud of anonymous stars. Related gems from the same materialized Git source can appear together as one dependency system.
107
128
 
108
- RubyLens uses Rubydex to find classes, modules, methods, constants, inheritance, reopenings, and references. It does not claim that references form a complete call graph, and it never executes the project or its tests.
129
+ RubyLens uses Rubydex to find classes, modules, methods, constants, inheritance, reopenings, and references. Shuttle flights draw from resolved references whose occurrences belong to Core or Test namespaces; their targets may be another workspace namespace or an exact anonymous Gem declaration star. Core-to-Core, Core-to-Test, Test-to-Core, Test-to-Test, and workspace-to-Gem flights are included; top-level, ambiguous, exact-self, and non-workspace origins are omitted. Flights travel from the referenced declaration to the referrer and show a bounded visual sample, not call edges or a complete relationship graph. RubyLens never executes the project or its tests.
109
130
 
110
131
  RubyLens analyzes tracked `.rb`, `.rake`, `.rbs`, and `.ru` files inside the target, plus untracked files of those types that Git does not ignore. It reads dependency versions from `Gemfile.lock` and analyzes gem code already installed locally.
111
132
 
@@ -115,6 +136,8 @@ RubyLens is not a type checker, whole-program call graph, source browser, route
115
136
 
116
137
  RubyLens uses the [Hubble sequence](https://science.nasa.gov/asset/hubble/the-hubble-tuning-fork-classification-of-galaxies/) as a visual vocabulary. It uses broad code counts to choose a repeatable shape for the central Core/Test galaxy and each dependency package independently. A package never inherits the project's, host's, or dependency system's decision.
117
138
 
139
+ Very large dependency packages that would otherwise render as smooth elliptical or lenticular clouds use a deterministic Spiral or Barred Spiral enrichment. This keeps their visual mass structured while smaller packages retain their aggregate-derived family.
140
+
118
141
  The morphology describes the rendered shape. It is not a claim about the project's architecture, purpose, quality, or correctness.
119
142
 
120
143
  [![Paired synthetic RubyLens renders comparing E2 with E6, Sa with Sc, and SBa with SBc.](docs/images/galaxy-morphology-variations.jpg)](docs/images/galaxy-morphology-variations.jpg)
@@ -127,16 +150,17 @@ Read the [accepted morphology design](docs/specs/2026-07-14-galaxy-morphology-de
127
150
 
128
151
  ```text
129
152
  rubylens report [OPTIONS] [TARGET]
153
+ rubylens clip [OPTIONS] [TARGET]
130
154
  rubylens showcase [OPTIONS] [TARGET]
131
155
  ```
132
156
 
133
- Both commands accept:
157
+ All commands accept:
134
158
 
135
159
  - `-o FILE` / `--output FILE` to choose an output path
136
160
  - `--lockfile FILE` to use a specific `Gemfile.lock`
137
161
  - `-h` / `--help` to show command help
138
162
 
139
- `rubylens showcase` also accepts `--details`.
163
+ `rubylens clip` and `rubylens showcase` also accept `--details`. A custom `rubylens clip --output movie.mp4` writes the recorded showcase to `movie.html` next to it.
140
164
 
141
165
  ## Ruby API
142
166
 
@@ -150,6 +174,10 @@ puts report.warnings
150
174
 
151
175
  showcase = RubyLens.generate_showcase(path: ".", details: true)
152
176
  puts showcase.output_path
177
+
178
+ clip = RubyLens.generate_clip(path: ".", progress: ->(done, total) { puts "#{done}/#{total}" })
179
+ puts clip.output_path # the MP4
180
+ puts clip.showcase_path # the showcase HTML it recorded
153
181
  ```
154
182
 
155
183
  Passing `output:` selects a custom path. The caller is responsible for keeping custom outputs private.