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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d58e330a4db4410a5ab30043d6f222d3a1281e06b1b9bf9b499b663d85e9e502
4
- data.tar.gz: 7d12352c93ec9cba4dba03df61bc6dd618632902e7930867262cdb428393876c
3
+ metadata.gz: 4511842d6a3c76fbf50be2da922a089e852adfe571d952efe770e536060d2ab2
4
+ data.tar.gz: e24617018967e09c04e8d79079e1182ae32b64f8ff69a2046bb802e1daadd6a9
5
5
  SHA512:
6
- metadata.gz: 336673fd02c877740c3970354dfde67b7c149ecd812cb897159c097dda9e90346f0f35f0dd1bbd149a8805d75043518f82d8e687929be1c63d85bd33cb614b4c
7
- data.tar.gz: ac97e8d31ef4fbc053b306f1f4d95b0467e7e2ce58e95e443ad81a0aa4258ff4007851ff81aff42a56350b509a741ce4dba5d01697107907a38bb59127cd731f
6
+ metadata.gz: aeb9654b4eb02f0b0d60a1f15567d5abd591b27abb1e3b1acf660b19f3e23ddd74487699e667a15d533d793bdc6f4700f2d8f5ee4a6ee0ec9507ae6053f164be
7
+ data.tar.gz: 98a92961b2dc9cf10e50fe7310cfdd5f4d6c138fc13f41a9485a4cdad0a68007145c7bfb5c5f1cfe4980733f6a287c8ceb7a133b1bd41d6cf19612d9275a61d8
data/README.md CHANGED
@@ -67,7 +67,8 @@ lumitrace help --format json
67
67
  lumitrace schema --format json
68
68
  ```
69
69
 
70
- AI-oriented usage guide (Japanese):
70
+ AI-oriented usage guide:
71
+ - `docs/tutorial.md` section "Using with AI agents"
71
72
  - `docs/tutorial.ja.md` section "AI と使う"
72
73
 
73
74
  ### Library
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` contains an array of entries.
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 inline spans with explicit `\n` inserted.
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.
@@ -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