lumitrace 0.4.2 → 0.6.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 +4 -4
- data/README.md +2 -1
- data/docs/spec.md +119 -2
- data/docs/supported_syntax.md +7 -0
- data/docs/tutorial.ja.md +67 -31
- data/docs/tutorial.md +67 -0
- data/lib/lumitrace/generate_resulted_html.rb +327 -393
- data/lib/lumitrace/generate_resulted_html_renderer.js +774 -0
- data/lib/lumitrace/record_instrument.rb +127 -27
- data/lib/lumitrace/version.rb +1 -1
- data/lib/lumitrace.rb +36 -7
- data/runv/index.html +1234 -427
- data/runv/sync_inline.rb +13 -1
- data/test/test_lumitrace.rb +295 -0
- metadata +2 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 4511842d6a3c76fbf50be2da922a089e852adfe571d952efe770e536060d2ab2
|
|
4
|
+
data.tar.gz: e24617018967e09c04e8d79079e1182ae32b64f8ff69a2046bb802e1daadd6a9
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: aeb9654b4eb02f0b0d60a1f15567d5abd591b27abb1e3b1acf660b19f3e23ddd74487699e667a15d533d793bdc6f4700f2d8f5ee4a6ee0ec9507ae6053f164be
|
|
7
|
+
data.tar.gz: 98a92961b2dc9cf10e50fe7310cfdd5f4d6c138fc13f41a9485a4cdad0a68007145c7bfb5c5f1cfe4980733f6a287c8ceb7a133b1bd41d6cf19612d9275a61d8
|
data/README.md
CHANGED
data/docs/spec.md
CHANGED
|
@@ -167,7 +167,21 @@ Lumitrace instruments Ruby source code at load time (via `RubyVM::InstructionSeq
|
|
|
167
167
|
|
|
168
168
|
### Output JSON
|
|
169
169
|
|
|
170
|
-
`lumitrace_recorded.json`
|
|
170
|
+
`lumitrace_recorded.json` is a JSON object with the following top-level structure:
|
|
171
|
+
|
|
172
|
+
```json
|
|
173
|
+
{
|
|
174
|
+
"version": 1,
|
|
175
|
+
"events": [ ... ],
|
|
176
|
+
"coverage": [ ... ]
|
|
177
|
+
}
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
- `version`: Schema version (currently `1`).
|
|
181
|
+
- `events`: Array of trace event entries (see below).
|
|
182
|
+
- `coverage`: Array of per-file coverage summaries (see below).
|
|
183
|
+
|
|
184
|
+
#### Event entries
|
|
171
185
|
|
|
172
186
|
`collect_mode=last` (default):
|
|
173
187
|
|
|
@@ -226,6 +240,24 @@ Lumitrace instruments Ruby source code at load time (via `RubyVM::InstructionSeq
|
|
|
226
240
|
- `last_value`: summary of the last observed value: `{ type, preview }` (+ `length` only when truncated).
|
|
227
241
|
- `types`: observed Ruby class counts (class name => count).
|
|
228
242
|
- `sampled_values`: retained sample (last N values) of summary objects (`{ type, preview }` + optional `length`) in `history` mode.
|
|
243
|
+
- `total`: total execution count. When `0`, the expression was instrumented but never executed (uncovered).
|
|
244
|
+
|
|
245
|
+
#### Coverage summary
|
|
246
|
+
|
|
247
|
+
Each entry in the `coverage` array summarizes line-level coverage for one file:
|
|
248
|
+
|
|
249
|
+
```json
|
|
250
|
+
{
|
|
251
|
+
"file": "/path/to/file.rb",
|
|
252
|
+
"total_lines": 18,
|
|
253
|
+
"covered_lines": 12,
|
|
254
|
+
"coverage_percent": 66.7
|
|
255
|
+
}
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
- `total_lines`: number of lines that contain at least one instrumented expression.
|
|
259
|
+
- `covered_lines`: number of those lines where at least one expression has `total > 0`.
|
|
260
|
+
- `coverage_percent`: `covered_lines / total_lines * 100`, rounded to one decimal place.
|
|
229
261
|
|
|
230
262
|
## CLI
|
|
231
263
|
|
|
@@ -267,26 +299,111 @@ lumitrace [options] exec CMD [args...]
|
|
|
267
299
|
## HTML Rendering
|
|
268
300
|
|
|
269
301
|
- `GenerateResultedHtml.render_all` renders all files in one page.
|
|
302
|
+
- Generated HTML is a single self-contained file (no external fetch): it embeds source/trace data as JSON and renders DOM with JavaScript.
|
|
303
|
+
- JavaScript is required to render the code/trace view (a `<noscript>` message is shown otherwise).
|
|
270
304
|
- The page header shows the active collect mode:
|
|
271
305
|
- `Mode: last (last value)`
|
|
272
306
|
- `Mode: types (type counts)`
|
|
273
307
|
- `Mode: history (last N sample[s])`
|
|
274
308
|
- In `history`, `N` uses configured `max_samples` when available; otherwise it is inferred from the loaded events.
|
|
309
|
+
- When available, the page header also shows the executed command as `Command: ...`.
|
|
275
310
|
- Each file is shown in its own section.
|
|
311
|
+
- When multiple files are present, the HTML UI shows a left file tree and a single-file viewer on the right.
|
|
312
|
+
- Directory nodes in the file tree are expanded by default.
|
|
313
|
+
- Selecting a file in the tree switches the visible file without reloading the page.
|
|
314
|
+
- The selected file is reflected in the URL hash as `#file=...` (using the rendered file path label) so links can open a specific file view.
|
|
315
|
+
- Clicking a line number updates the URL hash to include the selected line (for example `#file=lib/foo.rb&line=42`).
|
|
316
|
+
- When the HTML is opened with a file+line hash, the renderer selects that file and scrolls to the target line.
|
|
317
|
+
- File tree items show line coverage as `(executed_lines / lines_with_expressions)` for a quick per-file overview.
|
|
318
|
+
- Files with no instrumentable expressions do not show a coverage count.
|
|
276
319
|
- Expressions are marked with an inline icon (`🔎` for executed, `∅` for not hit).
|
|
277
320
|
- Hovering the icon shows recorded values.
|
|
278
321
|
- Only the last 3 values are shown in the tooltip as `value (Type)`; additional values are summarized as `... (+N more)`.
|
|
279
322
|
- Tooltip is scrollable horizontally for long values.
|
|
323
|
+
- Tooltip is shown above the marker icon (to avoid covering the mouse cursor).
|
|
280
324
|
- When ranges are used, skipped sections are shown as `...` in the line-number column.
|
|
281
325
|
- Lines where all instrumentable expressions are unexecuted are highlighted in a light red. If a line mixes executed and unexecuted expressions, only the unexecuted expressions are highlighted.
|
|
326
|
+
- The page footer includes an attribution link to the Lumitrace site and the Lumitrace version used to generate the report.
|
|
327
|
+
|
|
328
|
+
### HTML Payload Schema (`v1`)
|
|
329
|
+
|
|
330
|
+
- The generated HTML embeds a JSON payload in:
|
|
331
|
+
- `<script id="lumitrace-payload" type="application/json">...</script>`
|
|
332
|
+
- Payload top-level shape:
|
|
333
|
+
|
|
334
|
+
```json
|
|
335
|
+
{
|
|
336
|
+
"version": 1,
|
|
337
|
+
"meta": {
|
|
338
|
+
"mode": "last|types|history",
|
|
339
|
+
"mode_text": "Mode: ...",
|
|
340
|
+
"max_samples": 3
|
|
341
|
+
},
|
|
342
|
+
"files": [
|
|
343
|
+
{
|
|
344
|
+
"path": "/abs/path/to/file.rb",
|
|
345
|
+
"display_path": "path/to/file.rb",
|
|
346
|
+
"source": "file contents...",
|
|
347
|
+
"ranges": [[1, 10], [20, 30]],
|
|
348
|
+
"trace": [
|
|
349
|
+
{
|
|
350
|
+
"location": [1, 0, 1, 5],
|
|
351
|
+
"kind": "expr|arg",
|
|
352
|
+
"name": "x",
|
|
353
|
+
"sampled_values": [{"type": "Integer", "preview": "1"}],
|
|
354
|
+
"types": {"Integer": 3},
|
|
355
|
+
"total": 3
|
|
356
|
+
}
|
|
357
|
+
]
|
|
358
|
+
}
|
|
359
|
+
]
|
|
360
|
+
}
|
|
361
|
+
```
|
|
362
|
+
|
|
363
|
+
- `version`:
|
|
364
|
+
- Payload schema version for the embedded HTML renderer. Current version is `1`.
|
|
365
|
+
- `meta.mode`:
|
|
366
|
+
- Effective collect mode used for display (`last`, `types`, `history`).
|
|
367
|
+
- `meta.mode_text`:
|
|
368
|
+
- Human-readable label shown in the HTML header.
|
|
369
|
+
- `meta.max_samples`:
|
|
370
|
+
- Effective/inferred max samples for `history`; may be `null`.
|
|
371
|
+
- `meta.command`:
|
|
372
|
+
- Optional command line shown in the HTML header (for CLI-generated reports).
|
|
373
|
+
- `files[]`:
|
|
374
|
+
- One entry per rendered source file.
|
|
375
|
+
- `files[].path`:
|
|
376
|
+
- Absolute path used internally to associate trace events with source.
|
|
377
|
+
- `files[].display_path`:
|
|
378
|
+
- Path label shown in the HTML report (typically root-relative).
|
|
379
|
+
- Multi-file HTML navigation and URL hash (`#file=...`, `#file=...&line=...`) use this value as the file key.
|
|
380
|
+
- `files[].source`:
|
|
381
|
+
- Full Ruby source text for that file.
|
|
382
|
+
- `files[].ranges`:
|
|
383
|
+
- Normalized line ranges as inclusive `[start_line, end_line]` pairs, or `null` when unrestricted.
|
|
384
|
+
- `files[].trace[]`:
|
|
385
|
+
- Trace events for that file only (`file` is intentionally omitted from each event).
|
|
386
|
+
- `files[].trace[].location`:
|
|
387
|
+
- Location tuple `[start_line, start_col, end_line, end_col]`.
|
|
388
|
+
- `files[].trace[].kind`:
|
|
389
|
+
- Event kind (`expr` or `arg`).
|
|
390
|
+
- `files[].trace[].name`:
|
|
391
|
+
- Argument name when `kind=arg`; otherwise `null`.
|
|
392
|
+
- `files[].trace[].sampled_values`:
|
|
393
|
+
- Normalized sampled values (or synthesized `last_value` entry when collect mode is `last`).
|
|
394
|
+
- `files[].trace[].types`:
|
|
395
|
+
- Type counts map, normalized as `{ "TypeName": count }`.
|
|
396
|
+
- `files[].trace[].total`:
|
|
397
|
+
- Total execution count for the location.
|
|
282
398
|
|
|
283
399
|
### Copy/Paste Behavior
|
|
284
400
|
|
|
285
401
|
- Inline icon uses a separate marker span to reduce copy/paste artifacts.
|
|
286
|
-
- Lines are rendered as
|
|
402
|
+
- Lines are rendered as per-line block spans to keep copy/paste artifacts small while preserving line alignment.
|
|
287
403
|
|
|
288
404
|
## Known Limitations
|
|
289
405
|
|
|
290
406
|
- Requires `RubyVM::InstructionSequence.translate` support in the Ruby build.
|
|
291
407
|
- Instrumentation is for debugging; semantics may change for unusual edge cases.
|
|
408
|
+
- Expressions inside `defined?(...)` are intentionally not instrumented to preserve `defined?` semantics.
|
|
292
409
|
- Tool does not attempt to preserve file encoding comments.
|
data/docs/supported_syntax.md
CHANGED
|
@@ -112,6 +112,13 @@ These are intentionally skipped to keep output valid Ruby:
|
|
|
112
112
|
```
|
|
113
113
|
- The implicit `token` read is **not** instrumented.
|
|
114
114
|
|
|
115
|
+
- Expressions inside `defined?(...)`:
|
|
116
|
+
- Example:
|
|
117
|
+
```ruby
|
|
118
|
+
defined?(foo + bar)
|
|
119
|
+
```
|
|
120
|
+
- The operand expression (`foo + bar`) is **not** instrumented, to preserve `defined?` semantics.
|
|
121
|
+
|
|
115
122
|
## Rationale
|
|
116
123
|
|
|
117
124
|
All skips above correspond to syntactic positions where wrapping the token with
|
data/docs/tutorial.ja.md
CHANGED
|
@@ -130,6 +130,73 @@ HTML について:
|
|
|
130
130
|
- 引数の値は HTML では `🧷` で表示されます。
|
|
131
131
|
- 記録対象の式がすべて未実行の行は薄い赤で表示され、混在行では未実行の式のみ薄赤になります。
|
|
132
132
|
- 範囲指定時の省略は行番号欄に `...` が入ります。
|
|
133
|
+
- 複数ファイルが含まれる場合は、左側のファイルツリーで表示ファイルを切り替えられます。
|
|
134
|
+
- ファイルツリーのディレクトリはデフォルトで展開されています。
|
|
135
|
+
- ファイルツリーには、ファイルごとの行カバレッジが `(実行行数/式のある行数)` で表示されます。
|
|
136
|
+
- 選択中ファイルは URL ハッシュ(`#file=...`)に反映されるため、URL を共有するとそのファイル表示を開けます。
|
|
137
|
+
- 行番号をクリックすると、その行を含む URL ハッシュ(`#file=...&line=...`)に更新され、同じファイル・行を開けます。
|
|
138
|
+
- 移動時に URL ハッシュは自動更新されるため、専用の permalink ボタンはありません。
|
|
139
|
+
- CLI から生成した HTML では、ヘッダに `Command: ...` が表示されます。
|
|
140
|
+
- フッターには、HTML を生成した Lumitrace のバージョンが表示されます。
|
|
141
|
+
|
|
142
|
+
### AI と使う
|
|
143
|
+
|
|
144
|
+
テストが落ちたとき、Lumitrace で実行時の値を取得し、その結果を AI に渡すと効率的にデバッグできます。
|
|
145
|
+
|
|
146
|
+
**典型的なシナリオ:**
|
|
147
|
+
|
|
148
|
+
1. テストが失敗する
|
|
149
|
+
2. Lumitrace でテスト実行時の値を記録する
|
|
150
|
+
3. 結果を AI に渡して原因を分析してもらう
|
|
151
|
+
|
|
152
|
+
```bash
|
|
153
|
+
# テストを lumitrace 付きで実行し、JSON を取得
|
|
154
|
+
lumitrace --collect-mode last -j exec rake test
|
|
155
|
+
|
|
156
|
+
# 結果の JSON を AI に渡す
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
**CLAUDE.md / AGENTS.md に貼れるスニペット例:**
|
|
160
|
+
|
|
161
|
+
プロジェクトの `CLAUDE.md` や `AGENTS.md` に以下を追加すると、AI エージェントが Lumitrace を活用しやすくなります:
|
|
162
|
+
|
|
163
|
+
````markdown
|
|
164
|
+
## デバッグ(Lumitrace)
|
|
165
|
+
lumitrace は Ruby の各式の実行時の値を記録するツール。
|
|
166
|
+
テスト失敗時は `lumitrace help` を読んでから使うこと。
|
|
167
|
+
基本: `lumitrace -t exec rake test`
|
|
168
|
+
````
|
|
169
|
+
|
|
170
|
+
**段階的アプローチ(トークン節約):**
|
|
171
|
+
|
|
172
|
+
AI に読ませる前提なら、次の順番にすると効率が良いです。
|
|
173
|
+
|
|
174
|
+
1. まず型分布だけ取る(安く全体像を見る)
|
|
175
|
+
|
|
176
|
+
```bash
|
|
177
|
+
lumitrace --collect-mode types -j path/to/entry.rb
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
2. 次に最終値を見る(値の当たりを付ける)
|
|
181
|
+
|
|
182
|
+
```bash
|
|
183
|
+
lumitrace --collect-mode last -j path/to/entry.rb
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
3. 変化が必要な箇所だけ履歴を見る
|
|
187
|
+
|
|
188
|
+
```bash
|
|
189
|
+
lumitrace --collect-mode history --max-samples 5 -j path/to/entry.rb
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
4. 対象を絞る(トークン節約)
|
|
193
|
+
|
|
194
|
+
```bash
|
|
195
|
+
lumitrace --collect-mode last -j --range path/to/entry.rb:120-180 path/to/entry.rb
|
|
196
|
+
lumitrace --collect-mode last -j -g path/to/entry.rb
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
補助情報は `lumitrace help --format json` と `lumitrace schema --format json` で機械可読に取得できます。
|
|
133
200
|
|
|
134
201
|
### 範囲指定の例
|
|
135
202
|
|
|
@@ -294,37 +361,6 @@ GitHub Actions への追加手順(`LUMITRACE_GIT_DIFF` や Pages へのアッ
|
|
|
294
361
|
|
|
295
362
|
fork/exec の結果はデフォルトでマージされます。親プロセスが最終出力を行い、子プロセスは `LUMITRACE_RESULTS_DIR` に断片 JSON を保存します。
|
|
296
363
|
|
|
297
|
-
### AI と使う
|
|
298
|
-
|
|
299
|
-
AI に読ませる前提なら、次の順番にすると効率が良いです。
|
|
300
|
-
|
|
301
|
-
1. まず型分布だけ取る(安く全体像を見る)
|
|
302
|
-
|
|
303
|
-
```bash
|
|
304
|
-
lumitrace --collect-mode types -j path/to/entry.rb
|
|
305
|
-
```
|
|
306
|
-
|
|
307
|
-
2. 次に最終値を見る(値の当たりを付ける)
|
|
308
|
-
|
|
309
|
-
```bash
|
|
310
|
-
lumitrace --collect-mode last -j path/to/entry.rb
|
|
311
|
-
```
|
|
312
|
-
|
|
313
|
-
3. 変化が必要な箇所だけ履歴を見る
|
|
314
|
-
|
|
315
|
-
```bash
|
|
316
|
-
lumitrace --collect-mode history --max-samples 5 -j path/to/entry.rb
|
|
317
|
-
```
|
|
318
|
-
|
|
319
|
-
4. 対象を絞る(トークン節約)
|
|
320
|
-
|
|
321
|
-
```bash
|
|
322
|
-
lumitrace --collect-mode last -j --range path/to/entry.rb:120-180 path/to/entry.rb
|
|
323
|
-
lumitrace --collect-mode last -j -g path/to/entry.rb
|
|
324
|
-
```
|
|
325
|
-
|
|
326
|
-
補助情報は `lumitrace help --format json` と `lumitrace schema --format json` で機械可読に取得できます。
|
|
327
|
-
|
|
328
364
|
## 2. ライブラリとして使う
|
|
329
365
|
|
|
330
366
|
CLI を使わずアプリに組み込みたい場合はここから始めます。
|
data/docs/tutorial.md
CHANGED
|
@@ -130,6 +130,73 @@ HTML notes:
|
|
|
130
130
|
- Argument values show `🧷` in HTML.
|
|
131
131
|
- Lines where all instrumentable expressions are unexecuted are shaded light red; mixed lines only shade the unexecuted expressions.
|
|
132
132
|
- When ranges are used, skipped sections are shown as `...` in the line-number column.
|
|
133
|
+
- When multiple files are included, use the left file tree to switch files.
|
|
134
|
+
- Directory nodes in the file tree are expanded by default.
|
|
135
|
+
- The file tree shows per-file line coverage as `(executed/expression-lines)`.
|
|
136
|
+
- The selected file is stored in the URL hash (`#file=...`), so copying the URL shares a direct link to that file view.
|
|
137
|
+
- Click a line number to update the URL with that line (`#file=...&line=...`) and open the same file+line later.
|
|
138
|
+
- The URL hash is updated automatically while navigating (there is no separate permalink button).
|
|
139
|
+
- The header also shows `Command: ...` for CLI-generated reports.
|
|
140
|
+
- The footer shows the Lumitrace version that generated the report.
|
|
141
|
+
|
|
142
|
+
### Using with AI agents
|
|
143
|
+
|
|
144
|
+
When a test fails, you can use Lumitrace to capture runtime values and pass the results to an AI for efficient debugging.
|
|
145
|
+
|
|
146
|
+
**Typical scenario:**
|
|
147
|
+
|
|
148
|
+
1. A test fails
|
|
149
|
+
2. Run the test with Lumitrace to record runtime values
|
|
150
|
+
3. Pass the results to an AI to analyze the root cause
|
|
151
|
+
|
|
152
|
+
```bash
|
|
153
|
+
# Run tests with lumitrace and get JSON output
|
|
154
|
+
lumitrace --collect-mode last -j exec rake test
|
|
155
|
+
|
|
156
|
+
# Pass the resulting JSON to your AI
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
**Snippet for CLAUDE.md / AGENTS.md:**
|
|
160
|
+
|
|
161
|
+
Add the following to your project's `CLAUDE.md` or `AGENTS.md` so AI agents can leverage Lumitrace:
|
|
162
|
+
|
|
163
|
+
````markdown
|
|
164
|
+
## Debugging (Lumitrace)
|
|
165
|
+
lumitrace is a tool that records runtime values of each Ruby expression.
|
|
166
|
+
When a test fails, read `lumitrace help` first, then use it.
|
|
167
|
+
Basic: `lumitrace -t exec rake test`
|
|
168
|
+
````
|
|
169
|
+
|
|
170
|
+
**Gradual approach (save tokens):**
|
|
171
|
+
|
|
172
|
+
When feeding results to an AI, this order is efficient:
|
|
173
|
+
|
|
174
|
+
1. Start with type distributions (cheap overview)
|
|
175
|
+
|
|
176
|
+
```bash
|
|
177
|
+
lumitrace --collect-mode types -j path/to/entry.rb
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
2. Then check last values (get a feel for the data)
|
|
181
|
+
|
|
182
|
+
```bash
|
|
183
|
+
lumitrace --collect-mode last -j path/to/entry.rb
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
3. Look at history only where changes are needed
|
|
187
|
+
|
|
188
|
+
```bash
|
|
189
|
+
lumitrace --collect-mode history --max-samples 5 -j path/to/entry.rb
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
4. Narrow the scope (save tokens)
|
|
193
|
+
|
|
194
|
+
```bash
|
|
195
|
+
lumitrace --collect-mode last -j --range path/to/entry.rb:120-180 path/to/entry.rb
|
|
196
|
+
lumitrace --collect-mode last -j -g path/to/entry.rb
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
Machine-readable help is available via `lumitrace help --format json` and `lumitrace schema --format json`.
|
|
133
200
|
|
|
134
201
|
### Range example
|
|
135
202
|
|