Skip to content

feat: ship pixelbrowse as an opencode plugin - #129

Draft
tauanbinato wants to merge 5 commits into
StarTrail-org:mainfrom
tauanbinato:feat/opencode-plugin
Draft

feat: ship pixelbrowse as an opencode plugin#129
tauanbinato wants to merge 5 commits into
StarTrail-org:mainfrom
tauanbinato:feat/opencode-plugin

Conversation

@tauanbinato

Copy link
Copy Markdown

Summary

Closes #117.

Adds plugin/opencode/ — an npm package (opencode-pixelbrowse) so opencode users can load pixelbrowse under "plugin" in opencode.json:

{
  "$schema": "https://opencode.ai/config.json",
  "plugin": ["opencode-pixelbrowse"]
}

The plugin registers a screenshot custom tool (via @opencode-ai/plugin) that:

  • runs pixelshot <target> --output /tmp/pixelbrowse --tile-height 1568 (plus --wait-network-idle for URLs) — the same visual-readability defaults the Claude Code skill mandates
  • supports URLs, local HTML files, PDFs, and images, with optional output and viewportWidth args
  • returns the sorted tile image paths so the agent reads them directly with its Read tool
  • embeds the skill's key guidance in the tool description (when to use, tile ordering, Pillow crop-and-zoom for small text)
  • returns a friendly install hint (uv tool install pixelrag / pipx / pip) when pixelshot is not on PATH

Also adds an opencode note in plugin/README.md and the main README's "Give Claude eyes" section.

Notes for maintainers

  • Publishing: the package is not published yet — npm publish --access public from plugin/opencode/ (documented in its README). Happy to adjust the package name if you'd prefer a scoped one (e.g. @startrail/pixelbrowse).
  • Validation done: node --check, npm pack --dry-run, and an import smoke test (PixelbrowsePlugin loads and registers the screenshot tool). Not yet exercised end-to-end inside a live opencode session.

Test plan

  • Maintainer: npm publish --access public from plugin/opencode/
  • With pixelshot on PATH, add "plugin": ["opencode-pixelbrowse"] to opencode.json and run e.g. opencode run "screenshot https://news.ycombinator.com and summarize the top stories"

Adds plugin/opencode/, an npm package (opencode-pixelbrowse) that registers
a screenshot custom tool via @opencode-ai/plugin. The tool runs pixelshot
with the same visual-readability defaults as the Claude skill
(--tile-height 1568, --wait-network-idle for URLs) and returns the tile
paths for the agent to read.

Closes StarTrail-org#117
@vercel

vercel Bot commented Jul 29, 2026

Copy link
Copy Markdown

@tauanbinato is attempting to deploy a commit to the andylizf's projects Team on Vercel.

A member of the Team first needs to authorize it.

@tauanbinato
tauanbinato marked this pull request as draft July 29, 2026 04:52
StarTrail-org#141 made tiles.json the manifest a consumer is meant to read — it carries
the ordered tile list and a `complete` flag that is false when pixelshot
could not confirm it measured the whole page. The Claude Code skill was
updated to read it; this tool was still globbing tile_NNNN.jpg, so it would
have presented a truncated capture as the whole page.

Reads the manifest, falls back to the directory scan when it is missing, and
passes the incompleteness warning through to the agent.
@yichuan-w

Copy link
Copy Markdown
Contributor

Nice work — merging. Clean, idiomatic, and it handles the two things these wrappers usually get wrong: a missing pixelshot gets an actionable install hint instead of a stack trace, and --wait-network-idle is added for http(s) targets, which is what the Claude Code skill tells people to do too.

Verified locally: claude plugin validate . and claude plugin validate ./plugin both pass with this branch merged onto main, so the Plugin validate CI job is happy. (CI never actually ran here — fork PRs sit at action_required until a maintainer approves the workflow, so only the Vercel check reported.)

I pushed one commit before merging. #141 landed while this was open and made tiles.json the thing a consumer reads: it carries the ordered tile list plus a complete flag that is false when pixelshot could not confirm it measured the whole page. The Claude Code skill was updated to read it, but this tool was still doing:

readdirSync(tilesDir).filter((name) => /^tile_\d+\.jpg$/.test(name)).sort()

which works, but means a truncated capture gets handed to the agent as if it were the whole page — exactly the failure #141 exists to prevent. It now reads the manifest, falls back to the directory scan when it's absent (older pixelshot, or a failed write), and appends the incompleteness warning when complete === false. Also widened the fallback regex to .png, since local images are copied through as-is.

Checked the three paths by hand: manifest present → uses its list; complete: false → warning fires; no manifest → falls back to the scan and stays quiet.

Two things left for you or whoever picks this up, neither blocking:

  • latestTilesDir picks the newest *.tiles directory by mtime. Fine for one target at a time, but it can pick the wrong one if a previous run left directories behind and the clock is coarse. Deriving the expected directory name from target would be exact.
  • npm publish --access public for opencode-pixelbrowse is a maintainer step and hasn't happened yet, so the opencode.json snippet in the README won't resolve until it does. Worth a note in the release checklist.

Thanks for the first contribution — this closes #117.

@yichuan-w

Copy link
Copy Markdown
Contributor

Correction to my last comment: I said "merging" and then didn't — this is still a draft, and on re-reading your notes that's deliberate rather than an oversight, so I'm leaving it that way. The code review above stands and the commit I pushed is on the branch.

Two things are genuinely blocked on the maintainer, and both are in your test plan already:

  • Package name. opencode-pixelbrowse (unscoped) vs @startrail/pixelbrowse. That's a call for @yichuan520030910320 — it decides what goes in the README snippet and what gets published.
  • npm publish. Needs org credentials, so it can't happen from here. Until it does, the "plugin": ["opencode-pixelbrowse"] line in the README won't resolve for anyone.

The remaining unchecked item — end-to-end in a live opencode session — is the one piece of verification neither of us has done. Everything I checked was static: plugin manifests validate, node --check passes, and I exercised the manifest-reading logic directly (manifest present, complete: false, and no-manifest fallback). That's not the same as the tool actually being called by an opencode agent.

So: ready from a code standpoint, waiting on a name decision and a publish. Mark it ready for review once those land and it can go in.

Maintainer picked the scoped name. Renamed the package and every reference
to it (root README, plugin/README.md, plugin/opencode/README.md), and added
publishConfig.access=public — npm defaults scoped packages to restricted, so
without it `npm publish` would fail or publish privately.
@yichuan-w

Copy link
Copy Markdown
Contributor

@andylizf can you help launch the NPM

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[feat] Ship pixelbrowse as an opencode plugin

3 participants