@saptools/cf-inspector 0.7.0 โ†’ 0.8.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
@@ -16,6 +16,15 @@ Built so an AI agent (or a CI job) can drive a debugger from a single shell comm
16
16
 
17
17
  ---
18
18
 
19
+ > **Debug-session safety:** only one local `cf-inspector` process may actively
20
+ > debug a given target at a time. Concurrent CDP debugger clients can receive
21
+ > the same pause and race `Debugger.resume`, disrupting the target and real
22
+ > application traffic. A second local invocation now fails before connecting
23
+ > with `TARGET_ALREADY_DEBUGGED`; wait for the named owner process to finish.
24
+ > Locks left by dead processes are reclaimed automatically. Debuggers running
25
+ > on another machine or outside `cf-inspector` cannot be detected by this local
26
+ > guard and must still be coordinated operationally.
27
+
19
28
  ## โœจ Features
20
29
 
21
30
  - ๐ŸŽฏ **One-shot snapshot** โ€” `cf-inspector snapshot --bp src/handler.ts:42` sets the breakpoint, waits for it to hit, captures requested expressions, auto-resumes, prints JSON, exits
@@ -28,6 +37,8 @@ Built so an AI agent (or a CI job) can drive a debugger from a single shell comm
28
37
  - ๐Ÿ“ก **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
38
  - ๐Ÿ›ก๏ธ **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
39
  - ๐Ÿงต **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
40
+ - ๐Ÿšฆ **Machine-readable readiness** โ€” opt into a versioned `breakpoint-armed` stderr event before triggering external traffic; no prose matching or guessed delay required
41
+ - ๐Ÿ“œ **Isolate-aware script listing** โ€” `list-scripts` aggregates the main isolate and every current worker, tagging every script with its isolate
31
42
  - ๐Ÿง  **Agent-friendly** โ€” JSON-by-default I/O, deterministic shapes, and explicit `truncated`/`originalLength`/`omittedCount` metadata for bounded values
32
43
  - ๐Ÿงญ **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
44
  - ๐Ÿ” **Composes with `cf-debugger`** โ€” pass `--app/--region/--org/--space` and the tunnel is opened automatically; pass `--port` to attach to anything CDP-speaking
@@ -88,6 +99,42 @@ Use `--worker-id <id>` to pin a stable live worker ID from `list-targets`,
88
99
  pin a raw inspector target, or `--main-only` to deliberately ignore workers.
89
100
  Explicit selectors preserve single-isolate behavior.
90
101
 
102
+ ### Automation readiness contract
103
+
104
+ Commands that arm debugger behavior before waiting (`snapshot`, `watch`,
105
+ `exception`, and `log`) accept `--ready-event`. The flag writes exactly one
106
+ compact JSON object to `stderr` after every session present during initial
107
+ arming has completed its CDP setup and immediately before the command waits or
108
+ streams:
109
+
110
+ ```json
111
+ {"event":"breakpoint-armed","schemaVersion":1,"command":"snapshot","sessions":3,"resolvedLocations":2,"timeoutMs":30000}
112
+ ```
113
+
114
+ This is the supported synchronization contract for callers that must start the
115
+ CLI before firing an HTTP request, queue job, or other external trigger. Parse
116
+ the JSON line and require `event === "breakpoint-armed"` plus
117
+ `schemaVersion === 1`, then confirm `command` matches the invocation; do not
118
+ poll prose such as `Waiting up to`.
119
+
120
+ | Field | Contract |
121
+ | --- | --- |
122
+ | `event` | Always `"breakpoint-armed"` |
123
+ | `schemaVersion` | Event schema version; currently `1` |
124
+ | `command` | `snapshot`, `watch`, `exception`, or `log` |
125
+ | `sessions` | Number of main/worker sessions whose initial arming completed before emission |
126
+ | `resolvedLocations` | Total locations V8 had already resolved, or `null` for `exception`; `0` can still represent an accepted URL breakpoint that may resolve when a script loads |
127
+ | `timeoutMs` | Snapshot/exception wait or watch per-hit timeout; `null` for log |
128
+
129
+ Workers attaching after this one-time event are still armed dynamically, but
130
+ are not included in its `sessions` or `resolvedLocations` totals. If initial
131
+ arming fails or the command is cancelled first, no readiness event is emitted.
132
+ With `log --ready-event`, matching events received while the remaining initial
133
+ sessions are still arming are neither emitted nor counted, so the log stream
134
+ cannot precede its readiness marker.
135
+ Without `--ready-event`, stderr/stdout behavior is unchanged. An explicitly
136
+ requested event is still emitted with `snapshot --quiet`.
137
+
91
138
  ---
92
139
 
93
140
  ## ๐Ÿงฐ CLI
@@ -134,6 +181,7 @@ cf-inspector snapshot --port 9229 \
134
181
  | `--include-scopes` | Include expanded paused-frame scopes under `topFrame.scopes`. Omitted by default to keep targeted captures concise |
135
182
  | `--no-json` | Print a human-readable summary instead of JSON |
136
183
  | `--quiet` | Suppress snapshot progress messages on stderr |
184
+ | `--ready-event` | Emit the versioned `breakpoint-armed` JSON event on stderr after every current isolate is armed |
137
185
  | `--keep-paused` | Skip `Debugger.resume` after capture |
138
186
  | `--fail-on-unmatched-pause` | Fail immediately if the target pauses somewhere else instead of waiting cooperatively |
139
187
 
@@ -260,6 +308,7 @@ When the user expression throws, the event is emitted with `error` instead of `v
260
308
  | `--max-value-length <chars>` | Maximum characters per log value (streaming default: `4096`). Truncated events include `truncated` and `originalLength` |
261
309
  | `--remote-root <value>` | Optional path-mapping anchor (same DSL as `snapshot`) |
262
310
  | `--no-json` | Print human-readable lines instead of JSON Lines |
311
+ | `--ready-event` | Emit the versioned `breakpoint-armed` JSON event on stderr after every current isolate is armed |
263
312
 
264
313
  Native logpoint expressions and conditions have no V8 side-effect gate. The
265
314
  CLI warns when its best-effort syntax scan recognizes assignments or common
@@ -310,6 +359,7 @@ Each event is a `WatchEvent`:
310
359
  | `--allow-mutation` | Disable the capture side-effect guard and explicitly allow mutation-shaped native conditions |
311
360
  | `--include-scopes` | Include expanded paused-frame scopes per hit |
312
361
  | `--no-json` | Print human-readable lines instead of JSON Lines |
362
+ | `--ready-event` | Emit the versioned `breakpoint-armed` JSON event on stderr after every current isolate is armed |
313
363
 
314
364
  ### ๐Ÿ’ฅ `cf-inspector exception`
315
365
 
@@ -356,6 +406,7 @@ Result is a `SnapshotResult` with an extra `exception` field:
356
406
  | `--max-value-length <chars>` | Maximum characters per captured value (one-shot default: `131072`) |
357
407
  | `--keep-paused` | Skip `Debugger.resume` after capture |
358
408
  | `--no-json` | Print a human-readable summary instead of JSON |
409
+ | `--ready-event` | Emit the versioned `breakpoint-armed` JSON event on stderr after pause-on-exception is active in every current isolate |
359
410
 
360
411
  ### ๐Ÿงฎ `cf-inspector eval`
361
412
 
@@ -373,12 +424,23 @@ cf-inspector eval --port 9229 --expr 'process.uptime()'
373
424
 
374
425
  ### ๐Ÿ“œ `cf-inspector list-scripts`
375
426
 
376
- Print every script the V8 instance knows about (useful for debugging path-mapping issues). Add `--filter <pattern>` to narrow noisy script lists with a literal/wildcard pattern; `|` separates alternatives and `.*` / `.+` match variable text.
427
+ Print every script known by the main isolate and each currently attached
428
+ NodeWorker (useful for debugging path-mapping issues). Each JSON entry carries
429
+ `isolate: {"kind":"main"}` or
430
+ `isolate: {"kind":"worker","workerId":"โ€ฆ"}`, so duplicate per-isolate
431
+ `scriptId` values remain unambiguous. Add `--filter <pattern>` to narrow noisy
432
+ script lists with a literal/wildcard pattern; `|` separates alternatives and
433
+ `.*` / `.+` match variable text.
377
434
 
378
435
  ```bash
379
436
  cf-inspector list-scripts --port 9229 --filter 'dist/.+\.js'
380
437
  ```
381
438
 
439
+ With `--no-json`, rows are
440
+ `scriptId<TAB>url<TAB>isolate`, where isolate is `main` or
441
+ `worker:<workerId>`. `--main-only`, `--worker-id`, `--worker`, and `--target`
442
+ retain their normal narrowing behavior.
443
+
382
444
  ### ๐ŸŽฏ `cf-inspector list-targets`
383
445
 
384
446
  Print raw `/json/list` inspector targets with stable `index` values, likely