Repository navigation
Releases: woniu9524/open-web-bridge
Releases · woniu9524/open-web-bridge
Release list
v1.2.1
Follow-up to 1.2.0: an independent review reproduced three real defects in that
release's task_end work, and writing the regression test for them surfaced a
fourth, older one. If you are on 1.2.0, upgrade.
Fixed
task_endused the task title to prove ownership, and titles are not
unique — runningtask beginwith the same title deliberately reuses the
group, so two concurrently-running same-named tasks each passed the other's
ownership check. The guard permitted exactly what it was written to prevent:
one task would clear the other's context, stop its recorder, and file its HAR
under its own directory, reporting a clean success. Ownership is now proven
with the task id, whichtask_beginhands to the extension.task_iditself was not unique. It is a second-resolution timestamp plus
a title slug, so two same-titledtask_begincalls in the same second
produced the same id — colliding metadata files, and two tasks sharing one
identity. Ids now get a-2,-3, … suffix on collision.- A task begun with no title could never be ended.
task_beginstored a
timestamp fallback whiletask_endcompared against the empty title, so the
task was always misjudged as someone else's: archived asended_stale, its
extension context never cleared, its recorder never stopped. - Task tab ownership no longer depends on tab groups. Groups are only
created for--new-tabnavigations, so any task that reused an existing tab
looked like it owned no tabs at all, and 1.2.0 silently skipped stopping and
archiving its recording. Each task now tracks the tabs it navigates. A
recorder genuinely outside the task is reported inrecorders_not_archived
rather than passed over in silence. net detailon a WebSocket could dump ~400 KB into the caller's context.
The CLI's output clipper only shrinks top-level strings, so an array of frame
objects slipped past it, and--max-bodydid not apply. It now returns the
last 50 frames by default (--max-frames <n>to raise), and reports
framesReturned/framesKept/framesSeenseparately.frameCountmeant "total seen" innet listbut "currently kept" in
net detail; both now reportframesSeen, so the numbers agree.- Four WebSocket event handlers wrote to the capture buffer without checking
that the connection was known, minting typeless records that never finish —
one of which could stopwait --network-idlefrom ever settling again on
that tab. All four now ignore frames for connections they never saw open. owb cookie set --http-onlyand--same-sitereached validation, but the
unknown-flag error message never mentioned the universal flags (--tab,
--timeout, …), implying they were rejected too.
v1.2.0
Breaking
- A flag a command doesn't take is now a usage error (exit 2) instead of
being silently dropped.owb page --url <url>used to exit 0 having done
nothing — it re-snapshotted whatever the tab was already showing, and the
stale result was indistinguishable from a successful navigation. The error
names the offending flag and lists the valid ones.owb call <tool>is
exempt (its argument surface can't be enumerated) and the contents of
--argsare never checked, so both escape hatches still pass anything.
Added
netsees WebSocket traffic. Connections show up innet listwith
isWebSocket: true,status: 101and a liveframeCount;net detail
returns the frames (dir/opcode/len/data) instead of a response body.
Only the HAR path could see WebSockets before, sonetalone would report a
push-driven page as having no traffic. Two caps keep a chatty socket bounded:
the most recent 200 frames per connection (framesSeenis the true total,
framesDropped/framesNoteappear once frames are lost) and 2000 chars per
payload — record withhar start/har savefor a complete session.
Fixed
task_endno longer reaches outside its own task when cleaning up. It
confirms with the extension that the task is still the live one before
clearing anything, and stops only the recorders on its own tabs rather
than every recorder in the browser — previously, ending one task could stop
and absorb a concurrently-running task's recording into its own HAR, and
clear that task's tab group. The trade-off: a recording on a tab that never
joined the task's group is no longer auto-archived bytask_end(the data is
still there —har saveit yourself).cookie set --http-onlyand--same-sitewere documented but dead: the CLI
turns them intohttp_only/same_siteand the implementation read only the
camelCase spelling, so both were silently discarded. Both spellings now work.task_end's result reportstabs_closed: falsealongsidegroup.cleared,
which only ever meant "the task pointer was cleared" — never that any tab was
closed.
v1.1.1
Fixed
task_endtakes an explicit--task-id(mirroringflow save) instead of
always trusting the daemon's single shared "current task" pointer. With
several agents driving one browser, whichevertask_beginran last owned
that pointer, so an earlier task's plaintask_endeither raisedNO_TASK
or — worse — returnedokwhile archiving someone else's task. Ending a
task that is no longer current now archives it asended_stalewithout
touching the live recorder, tab group, or pointer, and the pointer is
re-checked immediately before it is cleared so atask_beginlanding during
task_end's own awaits can't have its task closed out from under it.framesno longer accumulates execution contexts from pages the tab has
already navigated away from. The registry is cleared on
Runtime.executionContextsClearedrather thanPage.frameNavigated: the
latter is a different CDP domain with no ordering guarantee against the new
page'sexecutionContextCreated, so the stale entries survived and could
shadow the real context —eval --frame-patterncould silently resolve
against a context that no longer existed instead of erroring.cdpexplains itself when its params arrive empty. It is the one command
that does not fold flat--foo-barflags into CDP params, and reaching for
them produced Chrome's opaqueBINDINGS: mandatory field missing at position Nunder anINTERNALcode that invited retries; it is now
BAD_ARGSnaming the nested--args '{"method":…,"params":{…}}'form.
v1.1.0
Breaking
- Command table trimmed to 80 commands in 16 groups. Removed and renamed
names now fail with a usage error that names the replacement, rather than
being kept as silent aliases:Old New owb click-mouse <target>owb click <target> --mouse trueowb har stopowb har discard(andhar saveis the only stop-and-keep)owb debug framesowb debug stack(top-levelowb framesstill lists iframes)owb state export/state importowb call export_state/import_state - The raw event log is off by default. Set
OWB_EVENTS_LOG=1to restore it.
Nothing read the file back —eventsbackfill andhook_logsboth serve from
the in-memory ring buffer — and it grew without bound (18 GiB measured). - Audit results are truncated and redacted.
work/sessions/*.jsonlkeeps
tool-call arguments verbatim (workflow replay depends on them) but caps result
payloads at 2 KB and strips credential fields. Anything parsing those files
for result bodies needs to adjust.
Added
owb seq "<step>" "<step>" …— run several commands over one process and one
connection, removing the ~100–200 ms per-command spawn cost that dominates
long mechanical sequences.--file,--delay-ms,--keep-going; JSONL out.- Log rotation and retention for everything under
work/: per-day files, a
per-file size cap (OWB_LOG_MAX_FILE_MB, default 64) and a retention window
(OWB_LOG_KEEP_DAYS, default 14;0disables). npm run test:browser/test:replay/test:relayfor the suites that need
a real browser, the curl-impersonate binary, or just the relay.
Fixed
eval --await-promiseand--return-by-valuenever took effect — the CLI
snake-cases flags while the tool read only camelCase, so awaiting a Promise
silently returned{}.- An expression serializing to
{}now explains itself (un-awaited Promise,
Map/Set, class instance, DOM node) instead of looking like an empty success. read_pagetriages a near-empty body: still loading, bot-check interstitial,
empty SPA shell, or interaction/iframe-gated content.- Five silent-success paths:
harAssertwithouturl_pattern(matched every
request),verify_signeron a sample withoutexpected(pass_rate1.0),
replaywith a badmax_body(empty body reported as success),
emulate_reset's retry (reported success while overrides remained), and
task_begin's ASCII slug (Chinese titles collapsed, colliding task ids). - A
while(true)insigner_codeno longer hangs the daemon: the vm timeout
now covers the call, not just evaluating the source. - The deadman that detaches debuggers when the daemon disappears now survives
service-worker recycling, and enumerates real attached targets. daemon.*calls respect the caller's timeout;workflow_runstops at its
deadline instead of driving the browser after the caller gave up.workflow_savestreams the audit log within the task's date window instead of
synchronously reading every session file (130 MB measured) into memory.- Relay: tokens are validated before a Durable Object is created (an unbounded
room-creation quota drain), frames are forwarded to the peer role rather than
broadcast, re-pairing no longer deadlocks the daemon, anddaemon.status
reports real pairing state instead of inferring it from environment variables. - The extension popup accepted
ws://for the relay while its own message said
wss://— the token and cookies would have crossed the internet in the clear. - Files under
work/are created0600and directories0700. hooks/fetch.jscaptures the nativeJSON.stringifylike its three siblings,
so the crypto preset no longer records a fabricated call per fetch report.
Changed
npm testruns every headless suite (20, up from 6) plus anode --check
gate over the extension sources, and no longer stops at the first failure.npm versionsyncs the extension manifest, andprepublishOnlyruns the
tests.package.json,manifest.jsonandpackage-lock.jsonhad drifted to
three different versions.- Update checks are silent unless an update exists.