2026-08-23 23:22:46 -04:00
|
|
|
# Changelog
|
|
|
|
|
|
|
|
|
|
Notable changes per release. Releases before 0.4.0 are listed at
|
|
|
|
|
[github.com/only-cli/oc/releases](https://github.com/only-cli/oc/releases).
|
|
|
|
|
|
2026-08-24 21:30:31 -04:00
|
|
|
## 0.5.0
|
2026-08-24 16:07:11 -04:00
|
|
|
|
|
|
|
|
### Added
|
|
|
|
|
|
|
|
|
|
- Language documentation shortcuts: `py`, `mdn`, `node`, `ruby`, `go`, `rust`,
|
|
|
|
|
`java`, `php`, `cpp`, and `ts`, plus a `dotnet` verb on `learn` for the .NET
|
|
|
|
|
API browser. `search` on `py`, `node`, and `ruby` ranks the docs' own search
|
|
|
|
|
index locally and on `mdn` asks the site's API; the sites that only render
|
|
|
|
|
docs search client-side go through DuckDuckGo with a baked-in `site:` filter
|
|
|
|
|
instead. (#25)
|
2026-08-24 21:30:31 -04:00
|
|
|
- Authenticated sessions: `oc login` seeds cookies for a session and every
|
|
|
|
|
fetch in that session sends them; `oc logout` forgets a session early,
|
|
|
|
|
cookies and saved page both. Cookies live in a per-session jar under
|
|
|
|
|
`OC_HOME`, separate from page state, pinned to the exact host they were
|
|
|
|
|
seeded for, and marked secure by default so they travel over https only
|
|
|
|
|
(`--allow-http` at login opts a plain-http site in). A session lasts an hour
|
|
|
|
|
unless `--expires` says otherwise. `--cookie -` reads the header from stdin,
|
|
|
|
|
the form to prefer since an argv secret is visible in `ps` and kept in shell
|
|
|
|
|
history. (#4)
|
|
|
|
|
|
|
|
|
|
### Fixed
|
|
|
|
|
|
|
|
|
|
- Response bodies are bounded at every transport, 25MB decoded, checked
|
|
|
|
|
against `Content-Length` before the bytes arrive and counted as they land,
|
|
|
|
|
so a hostile URL is no longer an unbounded allocation and a decompression
|
|
|
|
|
bomb stops at the cap. (#27)
|
|
|
|
|
- Titles, headings, and input names are cut at the render boundary like every
|
|
|
|
|
other block, so one hostile page-written scalar can no longer print
|
|
|
|
|
unbounded output whatever the budget said. The distilled page keeps the
|
|
|
|
|
full values and `--json` stays the machine-stable view. (#28)
|
|
|
|
|
- A short page is judged unreadable by evidence, not by length alone: nothing
|
|
|
|
|
extracted is empty whatever the page weighed, and a short render only fails
|
|
|
|
|
when the markup behind it was far too big to have carried only that. A
|
|
|
|
|
status endpoint or a one-line answer now exits 0; script-only shells and
|
|
|
|
|
consent walls still exit 2. (#29)
|
2026-08-24 16:07:11 -04:00
|
|
|
|
2026-08-23 23:22:46 -04:00
|
|
|
## 0.4.0
|
|
|
|
|
|
|
|
|
|
### Added
|
|
|
|
|
|
|
|
|
|
- Site shortcuts are dispatched, not just documented. `oc <site> <verb> [args]`
|
|
|
|
|
resolves to a URL and then takes the same path `oc open` does, so it costs the
|
|
|
|
|
same and reads the same. A site is named by short name, bare name, or domain
|
|
|
|
|
(`oc hn`, `oc ycombinator`, `oc news.ycombinator.com`), the last argument
|
|
|
|
|
absorbs every word after it so a query needs no quoting, and `oc sites` lists
|
|
|
|
|
every site with its verbs. Shortcuts come from `clis/*.json`, so adding a site
|
|
|
|
|
is a JSON file and no code. (#19)
|
|
|
|
|
- Wikipedia shortcuts: `oc wiki article <title>`, `oc wiki search <query>`, and
|
|
|
|
|
`oc wiki lang <code> <title>` for the other language editions. Articles are
|
|
|
|
|
read through `action=render`, which serves the article body without the site
|
|
|
|
|
chrome, navigation, and edit controls that surround `/wiki/<Title>`. (#22)
|
|
|
|
|
- Outbound fetches honor `HTTP_PROXY`, `HTTPS_PROXY`, and `NO_PROXY`, including
|
|
|
|
|
the lowercase forms, so oc works in a sandbox whose only route out is a proxy.
|
|
|
|
|
HTTP and HTTPS proxies are supported and proxy credentials in the URL are
|
|
|
|
|
sent as `Proxy-Authorization`. (#17)
|
|
|
|
|
- The MIT `LICENSE` file that the badge and `package.json` were already
|
|
|
|
|
claiming. (#18)
|
|
|
|
|
|
|
|
|
|
### Changed
|
|
|
|
|
|
|
|
|
|
- A page that distills to no readable text now fails loud instead of printing an
|
|
|
|
|
empty render and exiting 0. It writes one line to stderr and exits 2, which is
|
|
|
|
|
distinct from the exit 1 every other failure uses, so a caller can tell "this
|
|
|
|
|
page is empty" from "oc could not read this page" and fall back to a browser
|
|
|
|
|
only when that is worth doing. `--json` carries the same verdict as an `empty`
|
|
|
|
|
field. (#20)
|
|
|
|
|
- The SSRF guard runs before a proxy is chosen, so a proxied request cannot be
|
|
|
|
|
used to reach an address the direct path would have refused. (#17)
|
|
|
|
|
|
|
|
|
|
### Fixed
|
|
|
|
|
|
|
|
|
|
- GitHub and Reddit shortcut URL templates corrected so their verbs reach the
|
|
|
|
|
pages they name. (#19)
|