Commit Graph
140 Commits
Author SHA1 Message Date
dependabot[bot]andGitHub b7c57e6e0b chore(deps): bump impers from 0.1.0 to 0.1.1
Bumps [impers](https://github.com/lexiforest/impers) from 0.1.0 to 0.1.1.
- [Commits](https://github.com/lexiforest/impers/compare/v0.1.0...v0.1.1)

---
updated-dependencies:
- dependency-name: impers
  dependency-version: 0.1.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-09-01 04:49:26 +00:00
Mark CliandGitHub 65322bc5b6 Merge pull request #39 from only-cli/docs/readme-highlights
docs: lead Benchmarks with headline numbers, group auth and proxies under Features
2026-08-26 09:36:39 -04:00
only-cli ba49303527 docs: lead the Benchmarks section with headline numbers, group auth and proxies under Features 2026-08-26 09:32:03 -04:00
Mark CliandGitHub 7f1f109b8e Merge pull request #38 from only-cli/docs/sync-benchmarks
docs: sync the Benchmarks section with the benchmarks README
2026-08-25 10:53:39 -04:00
only-cli 2a5f97204e docs: sync the Benchmarks section with the benchmarks README
Add the language docs suite and the Playwright MCP row, fold the wiki
and docs results into one table, and note where the Codex runs split.
2026-08-25 10:52:12 -04:00
only-cli ccc0cf4476 docs: explain the search shapes a site definition can use, cover every DuckDuckGo search verb
CONTRIBUTING described a command as a URL template only, so a contributor
adding a docs site had no way to learn that a search verb can also name a
static index (sphinx, rdoc, nodedoc), a JSON endpoint (api), or fall back
to DuckDuckGo with a site: filter, or how to pick between them. It also
still counted six files in src/.

The rust, java, ts, and php search verbs had no test; only cpp's did. #25
asked for both verbs per language to be covered offline.
2026-08-25 09:46:23 -04:00
Mark CliandGitHub c12ecf060d Merge pull request #37 from only-cli/chore/codeql-action-v4
ci: bump github/codeql-action to v4.37.8, group its Dependabot updates
2026-08-25 07:55:28 -04:00
only-cliandClaude Fable 5 59964c5dca ci: bump github/codeql-action to v4.37.8, group its Dependabot updates
Dependabot opened separate PRs for init (#35) and analyze (#34). Each
failed because the two steps must run the same version of the action.
Bump init, analyze and upload-sarif together and add a Dependabot group
so future codeql-action bumps arrive as one PR.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-25 07:54:03 -04:00
Mark CliandGitHub 2c8b8f20c4 Merge pull request #36 from only-cli/dependabot/github_actions/actions/dependency-review-action-5.0.0
chore(deps): bump actions/dependency-review-action from 4.9.0 to 5.0.0
2026-08-25 07:53:24 -04:00
Mark CliandGitHub c3952be485 Merge pull request #33 from only-cli/dependabot/github_actions/ossf/scorecard-action-2d1146689b8cda280b9bc96326124645441f03bc
chore(deps): bump ossf/scorecard-action from 55891bbd73f2425e97637d96e306fc9d491d0b21 to 2d1146689b8cda280b9bc96326124645441f03bc
2026-08-25 07:49:10 -04:00
Mark CliandGitHub 0cf453d02c Merge pull request #32 from only-cli/dependabot/github_actions/actions/upload-artifact-7.0.1
chore(deps): bump actions/upload-artifact from 4.6.2 to 7.0.1
2026-08-25 07:48:28 -04:00
dependabot[bot]andGitHub 8d4c4ca4eb chore(deps): bump actions/dependency-review-action from 4.9.0 to 5.0.0
Bumps [actions/dependency-review-action](https://github.com/actions/dependency-review-action) from 4.9.0 to 5.0.0.
- [Release notes](https://github.com/actions/dependency-review-action/releases)
- [Commits](https://github.com/actions/dependency-review-action/compare/2031cfc080254a8a887f58cffee85186f0e49e48...a1d282b36b6f3519aa1f3fc636f609c47dddb294)

---
updated-dependencies:
- dependency-name: actions/dependency-review-action
  dependency-version: 5.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-08-25 04:45:55 +00:00
dependabot[bot]andGitHub 625048a7d1 chore(deps): bump ossf/scorecard-action
Bumps [ossf/scorecard-action](https://github.com/ossf/scorecard-action) from 55891bbd73f2425e97637d96e306fc9d491d0b21 to 2d1146689b8cda280b9bc96326124645441f03bc.
- [Release notes](https://github.com/ossf/scorecard-action/releases)
- [Changelog](https://github.com/ossf/scorecard-action/blob/main/RELEASE.md)
- [Commits](https://github.com/ossf/scorecard-action/compare/55891bbd73f2425e97637d96e306fc9d491d0b21...2d1146689b8cda280b9bc96326124645441f03bc)

---
updated-dependencies:
- dependency-name: ossf/scorecard-action
  dependency-version: 2d1146689b8cda280b9bc96326124645441f03bc
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-08-25 04:44:13 +00:00
dependabot[bot]andGitHub a274761a7b chore(deps): bump actions/upload-artifact from 4.6.2 to 7.0.1
Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 4.6.2 to 7.0.1.
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](https://github.com/actions/upload-artifact/compare/ea165f8d65b6e75b540449e92b4886f43607fa02...043fb46d1a93c77aae656e7c1c64a875d1fc6a0a)

---
updated-dependencies:
- dependency-name: actions/upload-artifact
  dependency-version: 7.0.1
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-08-25 04:44:10 +00:00
only-cli cad6fb4596 docs: sync benchmark numbers to the 0.5.0 run, fix the skill's site list 2026-08-24 21:50:31 -04:00
only-cli 537ddf7d3b docs: copy edits v0.5.0 2026-08-24 21:33:14 -04:00
Mark CliandGitHub e34304a305 Merge pull request #31 from only-cli/release/0.5.0
release: 0.5.0
2026-08-24 21:32:28 -04:00
only-cli 4b6b81f8a0 release: 0.5.0 2026-08-24 21:30:31 -04:00
Mark CliandGitHub 4b3abf218b Merge pull request #26 from only-cli/feat/language-docs
Add language documentation shortcuts (#25): Python, MDN, Node.js, Ruby, Go, Rust, Java, PHP, TypeScript, C/C++, and .NET
2026-08-24 21:27:21 -04:00
only-cli 870ff2cf73 merge main: authenticated sessions via per-session cookie jars 2026-08-24 21:25:44 -04:00
Mark CliandGitHub 06a46abc39 Merge pull request #30 from RonCodes88/feat/authenticated-sessions
feat: authenticated sessions via per-session cookie jars
2026-08-24 21:07:59 -04:00
RonCodes88 e6218a5a5a test: assert the IPv6 tunnel host directly so node's SAN change stops breaking CI 2026-08-25 09:54:35 +09:00
RonCodes88 7aed46ed56 docs: recommend piping the cookie header and explain what logout removes 2026-08-25 09:38:34 +09:00
RonCodes88 218afd7f83 test: cover http downgrades, bare TLDs, control characters, and jar caps 2026-08-25 09:38:34 +09:00
RonCodes88 fd3e3f7681 feat: read the cookie header from stdin and make logout forget the saved page too 2026-08-25 09:38:34 +09:00
RonCodes88 448ac8b7d8 fix: keep seeded cookies https-only and reject unsafe domains, cookie values, and oversized jars 2026-08-25 09:38:34 +09:00
only-cli b0d99cdc14 docs: list the new language references in llms.txt and the changelog 2026-08-24 16:07:11 -04:00
only-cli 86ac90c35f skill: say the docs-search note in a third of the tokens
The skill is paid for on every load, so the note naming which search
verbs run locally now says it in one clause instead of four.
2026-08-24 16:00:49 -04:00
RonCodes88 f9fde64318 Merge upstream/main into feat/authenticated-sessions 2026-08-25 04:18:27 +09:00
RonCodes88 a21db1fc96 Merge upstream/main into feat/authenticated-sessions 2026-08-25 04:15:41 +09:00
RonCodes88 db1e5bb7ef chore: keep saved sessions and cookie files out of git 2026-08-25 04:09:51 +09:00
RonCodes88 c84496a95e docs: document authenticated sessions and the login/logout commands 2026-08-25 04:09:51 +09:00
RonCodes88 f8d813a3f3 test: cover cookie sessions, login detection, and proxy edge cases 2026-08-25 04:09:51 +09:00
RonCodes88 d761f5604d feat: add authenticated browsing with per-session cookie jars 2026-08-25 04:09:51 +09:00
only-cli c880918f3b merge main: scorecard hardening and the fetch/render bounding fixes 2026-08-24 14:00:06 -04:00
only-cli b18e9e5179 fix: cap page-written scalars at the render boundary
The title and every heading are the page's to write, and both skipped
truncate(), so one hostile scalar could print unbounded output whatever
the budget said. The compact view now cuts titles, headings, and input
names at the same cap and marker every other block gets, and read cuts
even a first block bigger than its whole budget, since 'up to N tokens'
is a promise the page must not be able to break. The distilled page
keeps the full values: --json stays the machine-stable view, bounded by
the fetch cap, and machines cut for themselves.

Fixes #28
2026-08-24 13:59:27 -04:00
only-cli 886ce58e27 fix: judge an unreadable page by evidence, not by length alone
contentFailure called every render under 25 tokens a failure, which
made exit 2 claim a terse page was JavaScript-only, gated, or
challenged when it had simply arrived terse. The verdict now needs
evidence: nothing extracted is empty whatever the page weighed, and a
short render is only a failure 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, and
raw applies the same rule before refusing. The --json empty field
follows the same policy, so callers keep a machine-stable distinction
between empty and merely short.

Fixes #29
2026-08-24 13:59:27 -04:00
only-cli 8e645bc4ea fix: bound response bodies before buffering them
Both transports buffered a text response whole before the distiller saw
it, so a hostile URL was an unbounded allocation. Every transport now
enforces one cap, 25MB decoded, three times the largest body oc fetches
on purpose. Content-Length is checked first to fail before the bytes
arrive, and because that header is optional and untrusted, the stream
is counted as it lands too: native fetch and the proxy transport abort
the transfer at the cap, and impers, which buffers inside its own
binding, is checked before its body travels any further. Decoded bytes
are what get counted, which is what stops a decompression bomb.

Fixes #27
2026-08-24 13:59:11 -04:00
only-cli 793e108a5c chore: drop the npm self-upgrade from the publish workflow
Node 24 has bundled an npm new enough for trusted publishing since
24.4, so upgrading npm at publish time only added an unpinned install
to the release path. If a runner ever serves an older 24.x, npm publish
fails loudly rather than shipping anything.
2026-08-24 12:49:50 -04:00
only-cli bbe894bb96 chore: resolve the Scorecard alerts a repo change can fix
Every GitHub action is now pinned to a full commit SHA with its version
in a trailing comment, verified against each upstream repo's tags, so a
retagged release cannot swap code under CI. The publish workflow pins
npm to an exact version instead of @latest, the experiment Dockerfile
pins its base image by digest, and codeql.yml gets a top-level read-all
permissions block so the default token grants nothing the analyze job
does not ask for.

SECURITY.md points reports at GitHub private vulnerability reporting,
which is now enabled, and scopes out experiments/. Branch protection on
main now blocks force pushes and deletions.
2026-08-24 12:47:19 -04:00
only-cli 378d566765 feat: add Go, Rust, Java, PHP, TypeScript, and C/C++ docs shortcuts
The rest of the languages from #25, each probed for the cheapest shape
that works:

- go: pkg.go.dev renders search on the server, so 'search' is a plain
  URL and 'pkg <path>' opens a package page.
- php: manual-lookup.php sends an exact function name straight to its
  manual page, so 'fn array_map' lands on the function doc; fuzzy
  search goes through DuckDuckGo since the suggestions render behind
  the manual's own TOC.
- cpp: cppreference's new static site has clean /cpp/ and /c/ paths;
  its native search page is bare links oc refuses as unreadable, so
  'search' goes through DuckDuckGo.
- rust: std and doc page opens; rustdoc's search-index.js format is
  version-fragile, so 'search' goes through DuckDuckGo.
- java: Javadoc opens pinned to javase/26, the current GA (27
  redirects there); the typeSearchIndex file lacks the module names a
  URL needs, so 'search' goes through DuckDuckGo.
- ts: handbook page opens; the site searches via Algolia client-side,
  so DuckDuckGo again.
- learn gets a 'dotnet <api>' verb, since .NET API docs already live
  there.

README table and prose and the skill notes cover the new sites.
2026-08-24 12:27:17 -04:00
only-cli fa41abbb2e feat: rank Ruby docs search locally via the RDoc index
RDoc publishes a site's whole search index as one static JS file, the
same way Sphinx and the Node.js docs do, so 'oc ruby search' fetches
docs.ruby-lang.org's index (en/3.4, where the file exists), caches it
under the shared day cache, and ranks it with the same scorer the Node
backend uses. Class methods print as Class.name(params), instance
methods as Class#name(params), and every entry links straight to its
method anchor. 'oc ruby class Array' opens a class page directly.

cli.js now dispatches the local search backends through one map, and
the site-resolution guard keys on the query field, which only a search
shape ever carries.
2026-08-24 12:27:05 -04:00
only-cli 6a399cf448 feat: rank Node.js docs search locally from the docs' own reference
nodejs.org has no search results page: the site's search box is a
JavaScript modal asking a third-party service, so the search verb went
through DuckDuckGo. But the API docs publish their entire reference as
one static JSON file, all.json, much the way a Sphinx site publishes
its search index, so a new nodedoc backend ranks that file locally:
every module, class, method, property, and event heading becomes a
result linking to its own anchor, and oc node search prints them as a
normal numbered page.

The file is ~8MB (~1MB over the wire) and static, so the day cache the
Sphinx backend used moves to a shared cache module both backends call:
one directory per backend, one file per host, parsed before written so
a block page never poisons it.

A typical result list costs under 100 tokens and answers from disk in
under 100ms once cached.
2026-08-24 10:49:46 -04:00
only-cli 5706aab2a1 let MDN search ask MDN
MDN renders its search results client-side, so 'oc mdn search' has gone
through DuckDuckGo with a site: filter. But the page it renders gets its
results from a public JSON endpoint, /api/v1/search, which returns the
site's own ranking with a summary per result in one ~11KB response. A new
'api' shortcut shape names such an endpoint and which response fields
hold the list, title, URL, and snippet; the response becomes the same
synthetic results page a Sphinx search produces and rides the normal
render path, so 'do <n>' follows a result. First view is ~520 tokens and
works for any site whose search answers as JSON.
2026-08-24 10:29:28 -04:00
only-cli e9d5ad4660 walk the title instead of regexing it
CodeQL cannot see that the optional '>' already keeps every bracket out
of the flattened title, and it re-flags each shape of the regex. The
character walk does the same thing in a form whose completeness is plain
to read: nothing between or including brackets survives, closed or not.
2026-08-24 10:20:21 -04:00
only-cli d56ddb30a0 fix: never let a '<' survive title flattening
CodeQL flagged the tag strip in plainTitle: requiring a closing '>' means
a title whose markup never closes keeps its '<script' fragment. The '>'
is optional now, so every '<' starts a strip and none reaches the results
page, and the output is trimmed. Both call sites already HTML-escape the
result; this hardens the flattening itself. Covered by a new test.
2026-08-24 10:18:05 -04:00
only-cli e834309363 prototype a Sphinx search backend for the Python docs
docs.python.org has no search server: its search page downloads the
whole Sphinx index (searchindex.js, ~900KB gzipped) and ranks matches
in the browser. oc now does the same ranking itself, so 'oc py search'
answers from the site's own index instead of DuckDuckGo.

The index is cached on disk for a day and never printed; what renders
is a numbered result list that rides the normal open path, so 'do <n>'
follows a result. A query that names a symbol exactly (json.dumps)
links straight to its anchor. A site definition opts in with a
'sphinx' field naming the docs root, so any Sphinx site can use the
backend later.
2026-08-24 09:59:34 -04:00
only-cli 4ae8cffdd2 readme: benchmark table covers the three new documentation pages 2026-08-24 09:44:56 -04:00
only-cli f3f5a93466 add Python, MDN, and Node.js documentation shortcuts
First three languages from #25. Each is one definition in clis/:

- oc py library json, oc py doc reference/datamodel (the .html is
  appended, matching how the aws shortcuts spell pages)
- oc mdn js Array/map, oc mdn css grid-template-columns, and a generic
  oc mdn doc <path> for everything else under /en-US/docs
- oc node api fs

Python renders search client-side (Sphinx), MDN serves its search page
as a client-rendered shell with only the nav in the HTML, and nodejs.org
has no search, so all three get the DuckDuckGo site: filter fallback the
aws and gcp shortcuts already use. Short names py, mdn, and node join
the alias table; python, mozilla, nodejs, and the full domains resolve
as before through the generic rules.
2026-08-24 09:26:41 -04:00
only-cli c5bf068b9e give cli.js the exec bit
package.json points bin.oc at src/cli.js, so an npm link resolves the
global oc to this file directly and running it needs the bit. Without
it every oc invocation dies with Permission denied while node src/cli.js
keeps working, which is easy to miss.
2026-08-24 09:24:16 -04:00