Lumitrace instruments Ruby source code at load time (via RubyVM::InstructionSequence.translate when available), records expression results, and renders text or HTML output that overlays recorded values on your code. It is designed for local “what happened here?” inspection.
docs/ai-help.mddocs/ai-schema.mdrake docs:airequire "lumitrace"at_exit).require "lumitrace" + Lumitrace.enable!(...)require "lumitrace/enable" (calls Lumitrace.enable!)require "lumitrace/enable_git_diff" (diff-scoped Lumitrace.enable!)LUMITRACE_ENABLE=1 + require "lumitrace" (auto-enable!)LUMITRACE_ENABLE="-t -h -j ..." + require "lumitrace" (CLI-style options parsed and passed to enable!)Lumitrace.enable!(max_samples: nil, ranges_by_file: nil, root: nil, text: nil, html: nil, json: nil, verbose: nil, at_exit: true)max_samples: integer, string, or nil.ranges_by_file: hash or nil. { "/path/to/file.rb" => [1..5, 10..12] }.text: boolean or string or nil. When nil, determined from environment variables. When string, uses it as the text output path.html: boolean or string or nil. When nil, determined from environment variables.json: boolean or string or nil. When nil, determined from environment variables.verbose: integer (level) or nil. When nil, determined from LUMITRACE_VERBOSE.at_exit: boolean. When true, registers output at exit.nil.at_exit hook (if at_exit: true).Dir.pwd at call time.root if provided, otherwise ENV["LUMITRACE_ROOT"] if set, otherwise Dir.pwd.Lumitrace.enable!):
LUMITRACE_MAX_SAMPLES: default max samples per expression when max_samples is nil (default 3 if unset).LUMITRACE_COLLECT_MODE: value collection mode (last, types, history; default last).LUMITRACE_ROOT: root directory used to decide which files are instrumented.LUMITRACE_HTML: enable HTML output; 1 uses the default path, otherwise treats the value as the HTML output path. 0/false disables.LUMITRACE_TEXT: control text output. 1 forces text on, 0/false disables. If unset, text is enabled only when both HTML and JSON are disabled. Any other value is treated as the text output path.LUMITRACE_JSON: enable JSON output; 1 uses the default path, otherwise treats the value as the JSON output path. 0/false disables.LUMITRACE_GIT_DIFF_UNTRACKED: include untracked files in git diff ranges (1 default). Set to 0 to exclude.LUMITRACE_VERBOSE: verbosity level (1-3). 1/true enables basic logs, 2 adds instrumented file names, 3 adds instrumented source output.LUMITRACE_ENABLE: when 1/true, require "lumitrace" will call Lumitrace.enable!. When set to a non-boolean string, it is parsed as CLI-style arguments and passed to enable!.LUMITRACE_RANGE: semicolon-separated range specs, e.g. a.rb:1-3,5-6;b.rb.LUMITRACE_RESULTS_DIR: internal use. Shared results directory for fork/exec merge (default: Dir.tmpdir/lumitrace_results/<user>_<parent_pid>).LUMITRACE_RESULTS_PARENT_PID: internal use. Parent PID for fork/exec merge (auto-set).Lumitrace.disable!nil.require "lumitrace/enable"Lumitrace.enable! with default arguments.require "lumitrace/enable_git_diff"ranges_by_file from git diff scoped to the current program file.Lumitrace.enable! when diff is non-empty.LUMITRACE_GIT_DIFF=working|staged|base:REV|range:SPEC selects diff source.LUMITRACE_GIT_DIFF_CONTEXT=N expands hunks by +/-N lines (default 3; negative treated as 0).LUMITRACE_GIT_CMD overrides the git executable (default: git).LUMITRACE_RANGE can be used to pass explicit ranges via env.Lumitrace.enable!.RubyVM::InstructionSequence.translate to rewrite files at load time.Dir.pwd (or ENV["LUMITRACE_ROOT"] if set).record_instrument.rbrecord_require.rbgenerate_resulted_html.rbLumitrace::R(id, (expr)) where id maps to location metadata.ranges_by_file is a hash like { "/path/to/file.rb" => [1..5, 10..12] }.nil or an empty array for ranges, the entire file is instrumented.CallNode (except those with block bodies)YieldNodeLocalVariableReadNodeConstantReadNodeInstanceVariableReadNodeClassVariableReadNodeGlobalVariableReadNodeLumitrace::R at the start of the body.id (an integer assigned at instrumentation time) with a separate id -> location table.collect_mode (last, types, history; default last).history mode, keep only the last N values (max_samples_per_expr, default 3).total count for how many times the expression executed.collect_mode=last, last_value.preview is always the inspect result string.last_value.length is included only when preview is truncated.kind: "arg" and name (argument name).LUMITRACE_RESULTS_DIR and do not write final outputs.Process._fork is available, Lumitrace hooks it to reset child events immediately after fork.exec inherits LUMITRACE_RESULTS_DIR and LUMITRACE_RESULTS_PARENT_PID via the environment. Lumitrace.enable! also appends -rlumitrace to RUBYOPT to ensure the exec’d process loads Lumitrace.lumitrace_recorded.json contains an array of entries.
collect_mode=last (default):
{
"file": "/path/to/file.rb",
"start_line": 10,
"start_col": 4,
"end_line": 10,
"end_col": 20,
"kind": "expr",
"name": null,
"last_value": { "type": "String", "preview": "\"ok\"" },
"types": { "Integer": 10, "NilClass": 2, "String": 111 },
"total": 123
}
collect_mode=types:
{
"file": "/path/to/file.rb",
"start_line": 10,
"start_col": 4,
"end_line": 10,
"end_col": 20,
"kind": "expr",
"name": null,
"types": { "Integer": 10, "NilClass": 2, "String": 111 },
"total": 123
}
collect_mode=history:
{
"file": "/path/to/file.rb",
"start_line": 10,
"start_col": 4,
"end_line": 10,
"end_col": 20,
"kind": "expr",
"name": null,
"sampled_values": [
{ "type": "Integer", "preview": "42" },
{ "type": "NilClass", "preview": "nil" },
{ "type": "String", "preview": "\"ok\"" }
],
"types": { "Integer": 10, "NilClass": 2, "String": 111 },
"total": 123
}
last_value: summary of the last observed value: { type, preview } (+ length only when truncated).types: observed Ruby class counts (class name => count).sampled_values: retained sample (last N values) of summary objects ({ type, preview } + optional length) in history mode.lumitracelumitrace [options] script.rb [ruby_opt]
lumitrace [options] exec CMD [args...]
-t enables text output to stdout. --text=PATH writes to a file.-h enables HTML output (default path). --html=PATH writes to a file.-j enables JSON output (default path). --json=PATH writes to a file.-g enables git diff with working mode. --git-diff=MODE selects staged|base:REV|range:SPEC.--max-samples sets max samples per expression in collect_mode=history.--collect-mode sets value collection mode (last|types|history).--range restricts instrumentation per file (FILE or FILE:1-5,10-12). Can be repeated.--git-diff=MODE restricts instrumentation to diff hunks (staged|base:REV|range:SPEC).--git-diff-context expands hunks by +/-N lines.--git-cmd overrides the git executable.--git-diff-no-untracked excludes untracked files (untracked files are included by default).--verbose[=LEVEL] prints verbose logs to stderr (level 1-3).LUMITRACE_MAX_SAMPLES sets the default max samples per expression.exec target) with RUBYOPT=-rlumitrace and LUMITRACE_* env vars.=== Lumitrace Results (text) ===.### path/to/file.rb.| Each line is prefixed with a line number like ` 12 | `. |
!.....value (Type); if an expression ran multiple times, the last value is annotated with the ordinal run (e.g., #=> 2 (Integer) (3rd run)).collect_mode=history and --text is used with no --max-samples, max_samples defaults to 1.ranges_by_file is provided, only files present in the hash are shown in text output.tty: true), long comments are truncated to the terminal width (using COLUMNS or IO.console.winsize). File output is not truncated.GenerateResultedHtml.render_all renders all files in one page.<noscript> message is shown otherwise).Mode: last (last value)Mode: types (type counts)Mode: history (last N sample[s])history, N uses configured max_samples when available; otherwise it is inferred from the loaded events.Command: ....#file=... (using the rendered file path label) so links can open a specific file view.#file=lib/foo.rb&line=42).(executed_lines / lines_with_expressions) for a quick per-file overview.🔎 for executed, ∅ for not hit).value (Type); additional values are summarized as ... (+N more).... in the line-number column.v1)<script id="lumitrace-payload" type="application/json">...</script>{
"version": 1,
"meta": {
"mode": "last|types|history",
"mode_text": "Mode: ...",
"max_samples": 3
},
"files": [
{
"path": "/abs/path/to/file.rb",
"display_path": "path/to/file.rb",
"source": "file contents...",
"ranges": [[1, 10], [20, 30]],
"trace": [
{
"location": [1, 0, 1, 5],
"kind": "expr|arg",
"name": "x",
"sampled_values": [{"type": "Integer", "preview": "1"}],
"types": {"Integer": 3},
"total": 3
}
]
}
]
}
version:
1.meta.mode:
last, types, history).meta.mode_text:
meta.max_samples:
history; may be null.meta.command:
files[]:
files[].path:
files[].display_path:
#file=..., #file=...&line=...) use this value as the file key.files[].source:
files[].ranges:
[start_line, end_line] pairs, or null when unrestricted.files[].trace[]:
file is intentionally omitted from each event).files[].trace[].location:
[start_line, start_col, end_line, end_col].files[].trace[].kind:
expr or arg).files[].trace[].name:
kind=arg; otherwise null.files[].trace[].sampled_values:
last_value entry when collect mode is last).files[].trace[].types:
{ "TypeName": count }.files[].trace[].total:
RubyVM::InstructionSequence.translate support in the Ruby build.defined?(...) are intentionally not instrumented to preserve defined? semantics.