feat(browser): rewrite network for agent-native discovery#1100
feat(browser): rewrite network for agent-native discovery#1100
Conversation
Replace the index-based list + pretty-printed --detail flow with a
structured JSON interface built around stable keys, body-shape previews,
and a persistent capture cache. Agents can now reference captured
requests by operationName (GraphQL) or `METHOD host+pathname` (REST)
instead of array indexes that shift on every rerun.
- `browser network` now emits JSON: `{workspace, captured_at, count,
filtered_out, entries: [{key, method, status, url, ct, size, shape}],
detail_hint}` — no body payloads by default
- Shape inference (src/browser/shape.ts) walks response JSON into a
flat path -> descriptor map with depth cap 6 and a 2KB budget per
entry, so agents see structure without paying body tokens
- Stable key generator (src/browser/network-key.ts) derives
`operationName` from graphql URLs and `METHOD host+pathname`
elsewhere, disambiguating collisions with `#N` suffixes
- Persistent cache (src/browser/network-cache.ts) snapshots every
capture to `~/.opencli/cache/browser-network/<workspace>.json` with
a 24h TTL, so `--detail <key>` survives later commands
- `--detail <key>` returns `{key, url, method, status, ct, size, shape,
body}` with structured error codes (cache_missing / cache_expired /
cache_corrupt / key_not_found, the latter including available_keys)
- Add `--raw` for agents that want every full body inline, `--ttl` for
cache lookups
- Update opencli-adapter-author + opencli-autofix skill docs to
reference `--detail <key>` and the shape-first discovery flow
Supersedes the cache prototype in #1051.
Co-authored-by: freemandealer <freeman.zhang1992@gmail.com>
Self-review findings on the network refactor: - captureNetworkItems throwing (browser crashed / CDP dropped) now emits `error.code: capture_failed` on stdout rather than leaking a bare stderr line from browserAction's generic handler — agents get a parseable JSON blob on every failure path, matching the design goal. - saveNetworkCache throwing (disk full, read-only path) is a soft failure: the captured data is already in hand, so surface a `cache_warning` field in the envelope and keep going instead of aborting. `--detail` lookups on that run will miss the cache but the listing still reaches the agent. - shape.ts: guard the sub-walk on `add()`'s return value so the "budget hits on the array/object descriptor itself" path can never emit a stray child without its parent marker. - network-key.ts: document that `#N` suffixes start at `#2` — the first occurrence stays bare, there is no `#1`. Matches test + code. Added regression tests: `capture_failed` on readNetworkCapture throw, `cache_warning` on persistence failure, shape budget hit on array descriptor. Co-authored-by: freemandealer <freeman.zhang1992@gmail.com>
|
自 review 跑了一轮(code-reviewer subagent),改了三处: [blocker] [blocker 的软化版] [medium] [high 的 doc-only 修正] 新加 3 个回归测试: |
…1100) * feat(browser): rewrite network command for agent-native discovery Replace the index-based list + pretty-printed --detail flow with a structured JSON interface built around stable keys, body-shape previews, and a persistent capture cache. Agents can now reference captured requests by operationName (GraphQL) or `METHOD host+pathname` (REST) instead of array indexes that shift on every rerun. - `browser network` now emits JSON: `{workspace, captured_at, count, filtered_out, entries: [{key, method, status, url, ct, size, shape}], detail_hint}` — no body payloads by default - Shape inference (src/browser/shape.ts) walks response JSON into a flat path -> descriptor map with depth cap 6 and a 2KB budget per entry, so agents see structure without paying body tokens - Stable key generator (src/browser/network-key.ts) derives `operationName` from graphql URLs and `METHOD host+pathname` elsewhere, disambiguating collisions with `#N` suffixes - Persistent cache (src/browser/network-cache.ts) snapshots every capture to `~/.opencli/cache/browser-network/<workspace>.json` with a 24h TTL, so `--detail <key>` survives later commands - `--detail <key>` returns `{key, url, method, status, ct, size, shape, body}` with structured error codes (cache_missing / cache_expired / cache_corrupt / key_not_found, the latter including available_keys) - Add `--raw` for agents that want every full body inline, `--ttl` for cache lookups - Update opencli-adapter-author + opencli-autofix skill docs to reference `--detail <key>` and the shape-first discovery flow Supersedes the cache prototype in jackwener#1051. Co-authored-by: freemandealer <freeman.zhang1992@gmail.com> * fix(browser): structured errors for capture/save, shape budget guard Self-review findings on the network refactor: - captureNetworkItems throwing (browser crashed / CDP dropped) now emits `error.code: capture_failed` on stdout rather than leaking a bare stderr line from browserAction's generic handler — agents get a parseable JSON blob on every failure path, matching the design goal. - saveNetworkCache throwing (disk full, read-only path) is a soft failure: the captured data is already in hand, so surface a `cache_warning` field in the envelope and keep going instead of aborting. `--detail` lookups on that run will miss the cache but the listing still reaches the agent. - shape.ts: guard the sub-walk on `add()`'s return value so the "budget hits on the array/object descriptor itself" path can never emit a stray child without its parent marker. - network-key.ts: document that `#N` suffixes start at `#2` — the first occurrence stays bare, there is no `#1`. Matches test + code. Added regression tests: `capture_failed` on readNetworkCapture throw, `cache_warning` on persistence failure, shape budget hit on array descriptor. Co-authored-by: freemandealer <freeman.zhang1992@gmail.com> --------- Co-authored-by: freemandealer <freeman.zhang1992@gmail.com> (cherry picked from commit 7fd8bd6)
Summary
Replaces the index-based
browser networklisting + pretty-printed--detailwith a structured JSON interface built around:operationName, REST usesMETHOD host+pathname, collisions get#N. Agents no longer reference entries by array index that shifts on every capture.path → typemap (depth cap 6, 2KB/entry budget) instead of the full body. Agents see response structure without paying body tokens.browser networkrun snapshots to~/.opencli/cache/browser-network/<workspace>.json(24h TTL), so--detail <key>still works after later commands clear the live buffer.Structured error codes replace human-readable stderr messages so agents can branch on
error.codewithout regex:cache_missing,cache_expired,cache_corrupt,key_not_found(the last returnsavailable_keysinline).Example
$ opencli browser network { "workspace": "browser:default", "captured_at": "2026-04-21T01:10:00.000Z", "count": 2, "filtered_out": 14, "entries": [ { "key": "UserTweets", "method": "GET", "status": 200, "url": "https://x.com/i/api/graphql/qid/UserTweets?...", "ct": "application/json", "size": 84721, "shape": { "$": "object", "$.data": "object", "$.data.user": "object", "$.data.user.result": "object", "$.data.user.result.timeline_v2": "object" } }, { "key": "UserByScreenName", "...": "..." } ], "detail_hint": "Run \"browser network --detail <key>\" for full body." } $ opencli browser network --detail UserTweets { "key": "UserTweets", "body": { "data": { ... } }, "shape": { ... } }Flags
--detail <key>— full body for the given key (from cache)--raw— emit every full body inline (skip shape preview)--all— include static resources / telemetry that the default filter drops--ttl <ms>— override 24h cache TTL for--detaillookupsBreaking changes
Default output format changed from human-readable text to JSON, and
--detailnow takes a key instead of a numeric index. No backward-compat shim — per the design goal "把 agent 的不确定性变成确定的 CLI 返回值".Supersedes #1051 (@freemandealer's cache prototype, credited as co-author).
Test plan
src/browser/shape.test.ts— primitives, nested objects, arrays, depth cap, long strings, byte budget, Twitter UserTweets envelope (9 tests)src/browser/network-key.test.ts— graphql operationName extraction, REST fallback, collision#Nsuffixes (6 tests)src/browser/network-cache.test.ts— round-trip save/load, missing/expired/corrupt states, filename sanitization (7 tests)src/cli.test.ts— default JSON output,--all,--raw,--detail <key>happy path,key_not_foundwithavailable_keys,cache_missing(6 new tests)npm test— 220 files, 1646 tests, 2 skipped, all greennpm run build— clean TypeScript build + manifest regeneration