mirror of
https://github.com/only-cli/oc.git
synced 2026-09-15 10:40:56 +02:00
A JS-only page, a consent wall, and a bot challenge all answer HTTP 200 with markup that carries no text, and oc reported those renders as successes: a title, an actions line, and "100% saved" in verbose mode, which is true of a render that saved every token by extracting none. From the output alone an agent could not tell that from a page that is genuinely empty, so it never fell back to anything heavier and the empty result travelled on as evidence. oc now prints one line on stderr and exits 2 in that case, and --json carries the same verdict as an always-present 'empty' field, so a caller can branch on "nothing on this page" vs "oc could not read this page" without parsing prose. Exit 2 is distinct from the exit 1 every other failure uses. It sets process.exitCode rather than calling process.exit so whatever did render still finishes printing. The thresholds in render.js are measured, not guessed. contentTokens counts text the page wrote (prose, headings, and link or button labels over 25 chars, which is what separates a headline from nav chrome), so a link-list page like Hacker News or a search result still reads as content. Against live pages the failures land at 47 and 51 tokens (reddit.com/r/*, instagram.com) while the thinnest page the README claims support for carries 463 (an X profile), so the floor at 25 and the thin-vs-HTML-weight rule at 100 tokens against 2500 of markup both sit in a wide gap. Verified with no false positives on feeds, the Stack Exchange API, Microsoft Learn RSS, a YouTube watch page, AWS and GCP docs, a one-line HN item, and example.com. 'oc raw' fails only on genuinely blank output, since raw is the fallback the compact view's failure line names and must not refuse the same pages. Closes #14