@saptools/cf-inspector 0.6.2 โ†’ 0.7.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.
package/README.md CHANGED
@@ -27,7 +27,7 @@ Built so an AI agent (or a CI job) can drive a debugger from a single shell comm
27
27
  - ๐Ÿ’ฅ **Exception breakpoints** โ€” `cf-inspector exception --type uncaught --capture err.message` pauses on the next thrown error and materializes the exception value
28
28
  - ๐Ÿ“ก **Non-pausing logpoints** โ€” `cf-inspector log --at file:line --expr 'JSON.stringify({โ€ฆ})'` streams JSON Lines as the line executes without pausing the inspectee, with optional `--condition`, `--hit-count`, and `--max-events`
29
29
  - ๐Ÿ›ก๏ธ **Read-only capture guard** โ€” snapshot, watch, and exception captures use V8's side-effect analysis by default; `--allow-mutation` is an explicit escape hatch
30
- - ๐Ÿงต **Worker-aware sessions** โ€” `list-targets` discovers raw inspector targets and nested NodeWorker sessions; use `--target` or `--worker` to select an isolate
30
+ - ๐Ÿงต **Automatic worker fan-out** โ€” snapshot, watch, exception, and log attach to the main isolate plus every current or newly-spawned NodeWorker; explicit selectors remain available for pinning
31
31
  - ๐Ÿง  **Agent-friendly** โ€” JSON-by-default I/O, deterministic shapes, and explicit `truncated`/`originalLength`/`omittedCount` metadata for bounded values
32
32
  - ๐Ÿงญ **Path mapping** โ€” local `src/handler.ts:42` is matched against the remote URL via a `urlRegex`, with optional `--remote-root` literal or regex (same DSL as `cds-debug`)
33
33
  - ๐Ÿ” **Composes with `cf-debugger`** โ€” pass `--app/--region/--org/--space` and the tunnel is opened automatically; pass `--port` to attach to anything CDP-speaking
@@ -73,6 +73,21 @@ Cloud Foundry targeting is deliberately deterministic: `--app` requires
73
73
  from ambient `cf target` state. Use `--api-endpoint` only when the selected
74
74
  region needs an explicit endpoint override.
75
75
 
76
+ ### Worker behavior
77
+
78
+ When no isolate selector is passed, `snapshot`, `watch`, `exception`, `log`, and
79
+ `check-breakpoint` attach to the main isolate and every NodeWorker under the
80
+ selected raw target. Breakpoints are mirrored to workers that attach later, the
81
+ first matching pause wins, and JSON/human output identifies the winning
82
+ `isolate` as either `{"kind":"main"}` or
83
+ `{"kind":"worker","workerId":"โ€ฆ"}`. Losing isolates that also paused are
84
+ resumed before the command continues or exits.
85
+
86
+ Use `--worker-id <id>` to pin a stable live worker ID from `list-targets`,
87
+ `--worker <index>` for the legacy positional selector, `--target <index>` to
88
+ pin a raw inspector target, or `--main-only` to deliberately ignore workers.
89
+ Explicit selectors preserve single-isolate behavior.
90
+
76
91
  ---
77
92
 
78
93
  ## ๐Ÿงฐ CLI
@@ -103,6 +118,8 @@ cf-inspector snapshot --port 9229 \
103
118
  | `--api-endpoint <url>` | Override the API endpoint resolved from `--region` |
104
119
  | `--target <index>` | Raw `/json/list` target index (default: `0`) |
105
120
  | `--worker <index>` | Nested NodeWorker index reported under the selected raw target by `list-targets` |
121
+ | `--worker-id <id>` | Stable live NodeWorker ID reported by `list-targets` |
122
+ | `--main-only` | Attach only to the main isolate and ignore NodeWorkers |
106
123
  | `--bp <file:line>` | **Required.** Source location to break at. Pass multiple times to race several locations โ€” the first one to hit wins |
107
124
  | `--condition <expr>` | Native breakpoint condition. It is compile-checked before arming; mutation-shaped conditions require `--allow-mutation` because CDP provides no side-effect guard for native conditions |
108
125
  | `--hit-count <n>` | Skip the first N โˆ’ 1 hits and only pause on the Nth (combines with `--condition` via logical AND) |
@@ -232,7 +249,8 @@ When the user expression throws, the event is emitted with `error` instead of `v
232
249
  | Flag | Description |
233
250
  | --- | --- |
234
251
  | `--port <number>` | Local port the inspector or tunnel listens on. **Required** unless `--app/--region/--org/--space` are all set |
235
- | `--target <index>` / `--worker <index>` | Select a raw inspector target or nested NodeWorker session from `list-targets` |
252
+ | `--target <index>` / `--worker <index>` / `--worker-id <id>` | Pin one raw target or worker instead of automatic fan-out |
253
+ | `--main-only` | Ignore workers and attach only to the main isolate |
236
254
  | `--at <file:line>` | **Required.** Source location to log at |
237
255
  | `--expr <expression>` | **Required.** JavaScript expression evaluated at each hit, wrapped in try/catch on the inspectee side. It is mutation-capable; recognizable risks produce a warning |
238
256
  | `--duration <seconds>` | Stop streaming after N seconds (default: run until SIGINT) |
@@ -275,7 +293,8 @@ Each event is a `WatchEvent`:
275
293
  | Flag | Description |
276
294
  | --- | --- |
277
295
  | `--port <number>` | Local port the inspector or tunnel listens on. Otherwise pass all explicit Cloud Foundry selectors |
278
- | `--target <index>` / `--worker <index>` | Select a raw inspector target or nested NodeWorker session from `list-targets` |
296
+ | `--target <index>` / `--worker <index>` / `--worker-id <id>` | Pin one raw target or worker instead of automatic fan-out |
297
+ | `--main-only` | Ignore workers and attach only to the main isolate |
279
298
  | `--bp <file:line>` | **Required.** Source location to capture on (repeatable) |
280
299
  | `--capture <expr,โ€ฆ>` | Top-level comma-separated expressions evaluated per hit under V8's side-effect guard |
281
300
  | `--setup-eval <expr>` | Repeatable mutation-capable global expression evaluated before breakpoint setup; recognizable risks produce a warning |
@@ -324,7 +343,8 @@ Result is a `SnapshotResult` with an extra `exception` field:
324
343
  | Flag | Description |
325
344
  | --- | --- |
326
345
  | `--port` or explicit `--region/--org/--space/--app` | Select the local inspector or deterministic Cloud Foundry target |
327
- | `--target <index>` / `--worker <index>` | Select a raw inspector target or nested NodeWorker session from `list-targets` |
346
+ | `--target <index>` / `--worker <index>` / `--worker-id <id>` | Pin one raw target or worker instead of automatic fan-out |
347
+ | `--main-only` | Ignore workers and attach only to the main isolate |
328
348
  | `--type <state>` | Pause on which exceptions: `uncaught` (default), `caught`, or `all` |
329
349
  | `--capture <expr,โ€ฆ>` | Top-level expressions evaluated in the paused frame under V8's side-effect guard |
330
350
  | `--stack-depth <n>` | Walk this many call frames (default: `1`) |
@@ -368,7 +388,8 @@ nested workers with their own indexes.
368
388
 
369
389
  ```bash
370
390
  cf-inspector list-targets --port 9229
371
- cf-inspector snapshot --port 9229 --worker 0 --bp dist/worker.js:42
391
+ cf-inspector snapshot --port 9229 --bp dist/worker.js:42
392
+ cf-inspector snapshot --port 9229 --worker-id 1 --bp dist/worker.js:42
372
393
  # If a runtime publishes a worker as another raw /json/list target instead:
373
394
  cf-inspector snapshot --port 9229 --target 1 --bp dist/worker.js:42
374
395
  ```
@@ -394,23 +415,38 @@ JSON output nests workers beneath their raw target:
394
415
  ]
395
416
  ```
396
417
 
397
- `--target` selects a complete raw inspector endpoint. `--worker` selects a
398
- nested NodeWorker session under the chosen raw target (raw target `0` unless
399
- `--target` is also passed). Modern Node.js 20โ€“25 verification found workers on
418
+ `--target` selects a complete raw inspector endpoint. `--worker-id` selects a
419
+ live nested worker by its stable ID, while `--worker` retains positional-index
420
+ selection for compatibility. Modern Node.js 20โ€“25 verification found workers on
400
421
  the `NodeWorker` path, including workers already alive before post-hoc
401
422
  `SIGUSR1` inspector activation; the raw-target selector remains supported for
402
423
  runtimes that publish that shape.
403
424
 
404
- When multiple raw targets or nested workers exist and no selector is passed,
405
- commands attach to raw target `0` and print a selection notice. A bound
406
- breakpoint that sees no hit prints a worker-isolate hint. If only one raw target
425
+ When no selector is passed, breakpoint-oriented commands attach to raw target
426
+ `0` and automatically fan out across its main isolate and nested workers. If only one raw target
407
427
  and no workers are visible, `list-targets` explains that the worker may have
408
428
  exited, the runtime may not expose NodeWorker discovery, or a separate worker
409
429
  port may be unreachable through the single Cloud Foundry tunnel. Rerun the
410
- command while the worker is alive before selecting an index.
430
+ command while the worker is alive before pinning its `workerId`.
411
431
 
412
432
  If `list-targets`, `attach`, or another command reports `ECONNREFUSED`, the local inspector or tunnel on that port is usually stale/closed. Restart the local Node inspector or tunnel and retry; for Cloud Foundry targets, pass the complete `--region/--org/--space/--app` selector so `cf-inspector` can open a fresh tunnel.
413
433
 
434
+ ### โœ… `cf-inspector check-breakpoint`
435
+
436
+ Check whether a `file:line` can accept a breakpoint before arming one. The
437
+ command uses the same path mapping as `--bp` and checks every currently attached
438
+ isolate by default.
439
+
440
+ ```bash
441
+ cf-inspector check-breakpoint --port 9229 --bp dist/handler.js:42
442
+ ```
443
+
444
+ `status: "script-not-loaded"` means no loaded script matched the file/path
445
+ mapping; use `list-scripts`, adjust `--remote-root`, or trigger lazy loading.
446
+ `status: "unbreakable"` means the script is loaded but that exact line has no
447
+ V8 break location; choose a neighboring executable line. `status: "breakable"`
448
+ includes the concrete script IDs, isolate identities, lines, and columns.
449
+
414
450
  ### ๐Ÿ”— `cf-inspector attach`
415
451
 
416
452
  Connect, fetch the runtime version, print it, disconnect. Useful as a smoke-test that the tunnel is healthy.
@@ -480,7 +516,7 @@ pre-existing session.
480
516
  ```
481
517
  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” 1. GET http://127.0.0.1:<port>/json/list
482
518
  โ”‚ cf-inspector โ”‚ 2. Open the selected raw WebSocket target
483
- โ”‚ snapshot --bp X:Y โ”‚ โ”€โ–บ3. Optionally attach to a selected NodeWorker sub-session
519
+ โ”‚ snapshot --bp X:Y โ”‚ โ”€โ–บ3. Auto-attach to current and future NodeWorker sub-sessions
484
520
  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ 4. Debugger.enable + Runtime.enable
485
521
  โ”‚ 5. Debugger.setBreakpointByUrl({ urlRegex, lineNumber: Y - 1 })
486
522
  โ–ผ 6. Wait for `Debugger.paused`
@@ -510,7 +546,8 @@ CLI does not read ambient `cf target` state. It calls `startDebugger(...)` from
510
546
  on exit. You get the same one-shot UX whether the target is local or in CF.
511
547
 
512
548
  The tunnel forwards one inspector port. Nested NodeWorker sessions carried by
513
- that inspector connection are selectable with `--worker`; a worker exposing
549
+ that inspector connection are auto-attached by breakpoint-oriented commands and
550
+ can be pinned with `--worker-id`; a worker exposing
514
551
  only an unrelated separate port is outside that tunnel's reach.
515
552
 
516
553
  ```bash