v0.19.0-alpha - Structured failures, a creator dimension, and a self-reloading bridge
Three of this release's four changes came from agents hitting the same wall
in different places: a command that fails in a way the caller cannot read is
indistinguishable from one that succeeded and found nothing.
Fixed
- Every failure path now carries
errors.omnireach media download <url> --jsonreportedok: falsewith an emptyerrorslist and no yt-dlp
invocation. The root cause was not in the media layer:cli.py::_entrypoint
rendered everyClickExceptionas anerrorobject with noerrorskey at
all, so an agent doingenvelope.get("errors", [])saw an empty list. The
legacyerrorobject is still emitted for pre-0.19 callers. (#45, #47) - Crash diagnostics no longer corrupt stdout. A traceback used to be
printed to stdout, where an agent is parsing JSON. It now goes to stderr,
with a real envelope on stdout carrying the traceback inside it. (#47) - MCP exception fallbacks return real envelopes. Every tool's crash path
answered{"error": "..."}, which none of the declaredoutputSchemas
accept. Each now returns a validSearchEnvelope,FetchEnvelope,
MediaEnvelopeorAuthorEnvelope. (#47) - Douyin fresh-cookie flake is retried, not backed off. Measured: 1/10
failures on a cold start, 4/10 once rate-limited, and a 1s gap failed as
often as a 5s gap. More attempts help; waiting between them does not. Four
attempts now share one timeout budget. (#47)
Added
-
omnireach authorand theomnireach_authorMCP tool. Keyword search
matches captions, so ranking a creator query by likes returns strangers —
omnireach search --on douyin "彭十六"returned three videos, none of them
hers. The catalog dimension resolves the account and walks it:omnireach author "彭十六" --order likes --limit 8 --timeout 300 # → 彭十六elf, 28,195,000 followers, scanned 355 works, complete=true, 43.6s
AuthorEnvelopereusesSearchResultforresults, so anything that reads
a search envelope reads a catalog. Data comes from Douyin's own
aweme/v1/web/aweme/post/, called from the logged-in page context where it
needs noa_bogus/X-Bogussigning, solikes/comments/shares/
collectsare exact rather than the zero-fills a card scrape produces.
viewsis reported unknown becausestatistics.play_countis always 0 on
this endpoint. (#46, #48) -
omnireach bridge reload. Every change under
omnireach/chrome_extension/used to require a human to click Reload at
chrome://extensions:bridge installonly copies files, a running Chrome
ignores them, and an idle MV3 service-worker restart does not pick them up
either. Chrome 136+ stopped exposing extension targets to CDP, so there was
nothing to attach to. The extension now reloads itself via
chrome.runtime.reload()in 1.8 seconds, and the service worker and
offscreen document both come back on their own. (#51)
Documentation
CLAUDE.mdforbadedownload/parse/fetch-contentsubcommands that
v0.17 and v0.18 had already shipped, and its version history stopped at
v0.11. Both now describe what exists.docs/releases/was missing v0.15.0,
v0.16.0 and v0.16.1; they are backfilled from the published releases. (#50)
Real upstream verification
- Creator catalog:
docs/verification/douyin-author.md
— including the 19 consecutive empty pages mid-catalog that make any
empty-page tolerance truncate silently, and the fact that a handle which
does not exist returns Douyin's recommended accounts, so a name-resolving
parser can quietly answer with a stranger's works. - Bridge self-reload:
docs/verification/bridge-self-reload.md
— a round trip between two installed extension versions, with a real
omnireach authorcall afterwards to prove the bridge was functional rather
than merely answeringsystem.ping.
Compatibility
The bundled Chrome extension is 0.4.0. NATIVE_EXTENSION_MIN_VERSION is
deliberately not raised: a user who has not reloaded the extension keeps
every other command working, and omnireach bridge status --json reports
reload_required.
485 tests.