Skip to content

Add OpenCode Go usage sample#49

Open
4xvgal wants to merge 3 commits into
runcat-dev:mainfrom
4xvgal:feat/opencode-go-sample
Open

Add OpenCode Go usage sample#49
4xvgal wants to merge 3 commits into
runcat-dev:mainfrom
4xvgal:feat/opencode-go-sample

Conversation

@4xvgal

@4xvgal 4xvgal commented Jul 17, 2026

Copy link
Copy Markdown

Context of Contribution

  • Others

Summary of the Proposal

Add an OpenCode Go usage sample under docs/samples/opencode-go/ that
tracks rolling, weekly, and monthly OpenCode Go subscription usage in
RunCat Neo's Custom Metrics card and Metrics Bar.

Reason for the new feature

OpenCode Go subscribers ($10/month) cannot see their usage limits from
the terminal — they must visit the web dashboard. This sample follows
the same launchd + JSON snapshot pattern as the existing Bitcoin sample,
so users can monitor their Go usage directly in their macOS menu bar
alongside system metrics.

Checklist

  • I have read the CONTRIBUTING.md and agree to follow it.
  • This PR does not contain commits of multiple contexts.
  • Code follows proper indentation and naming conventions.
  • Implemented using only APIs that can be submitted to the App Store.

Signed-off-by: 4xvgal <4xvgal@protonmail.com>
@Kyome22

Kyome22 commented Jul 17, 2026

Copy link
Copy Markdown
Collaborator

@4xvgal
Could you please attach a screenshot showing how it actually looks on your screen?

@4xvgal

4xvgal commented Jul 18, 2026

Copy link
Copy Markdown
Author
Screenshot 2026-07-18 at 6 51 30 PM
It looks like this! design came from claude example

Comment thread docs/samples/opencode-go/README.md Outdated
@Kyome22

Kyome22 commented Jul 20, 2026

Copy link
Copy Markdown
Collaborator

Thanks for the contribution! Before getting into the code, I want to raise a concern about the overall direction, because I think that needs to be resolved before this can be considered for merging regardless of code quality.

The existing samples under docs/samples/ all rely on either a documented public API (Bitcoin → CoinGecko) or an official lifecycle hook exposed by the host tool (Claude Code statusLine, Codex Stop hook). This sample departs from that pattern in a way I'm not comfortable shipping as an "official" example:

  • Session cookie extraction. Instructing users to open DevTools, copy opencode.ai's auth cookie, and drop it into a dotfile is a security posture I don't want to normalise in this repo. That cookie is bearer-equivalent — if it leaks, it's effectively account takeover on opencode.ai. chmod 600 doesn't change that.
  • Scraping a private dashboard. opencode.ai/workspace/:id/go isn't a documented API. It will break the moment the page markup changes, and it sits in a grey area with respect to OpenCode's ToS. I'd rather RunCat Neo not nudge users down that path in its own docs.
  • Third-party CLI as a hard dependency. The sample requires cloning + go build-ing a small single-file scraper from a personal sourcehut repo (default branch is batman, not main), which additionally has a hardcoded fallback workspace ID baked into the binary. That is a lot of fragility to layer a sample on top of.

OpenCode is open source and, similar to Codex, keeps a local session store on disk. The far more natural sample here would mirror docs/samples/codex/ — a lifecycle hook (or a launchd-scheduled script) that reads OpenCode's local session data, with no cookie, no scraper, and no third-party binary. That would slot in cleanly next to the three existing samples.

Would you be open to redirecting the PR along those lines? As it stands I don't think the scrape-based approach is one we can adopt as an official sample. Happy to discuss if you see it differently.

@Kyome22

Kyome22 commented Jul 20, 2026

Copy link
Copy Markdown
Collaborator

Separately from the direction question above, I also went through the current code and found a few quality issues worth flagging, in case the sample lands somewhere similar.

Bugs

  • plist Label / bootout command mismatch. The plist's <Label> is dev.runcat.opencode-go-sample, but README step 6 copies the file to ~/Library/LaunchAgents/dev.runcat.opencode-go.plist (renaming it) and the Stopping section runs launchctl bootout gui/\$(id -u)/dev.runcat.opencode-go. bootout takes the Label, not the filename, so the stop command as written will not find the agent. The Bitcoin sample keeps file / Label / bootout all consistent as dev.runcat.bitcoin-sample; the same needs to hold here.
  • Missing OPENCODE_WORKSPACE silently pulls someone else's data. If the env var is unset the script just omits -workspace, and the upstream CLI falls back to a workspace ID hardcoded into its binary (wrk_01KT241XYZ…, per the README's own Troubleshooting section). The script should fail fast when \$workspace is empty rather than render a stranger's usage in the user's menu bar.
  • null values from jq degrade silently. jq -r '.rolling.percent' on a missing field emits the literal string null, awk coerces it to 0, and the card cheerfully shows 0% with normalizedValue: 0.0000 as if it were real data. Consider jq -e (or an explicit null check) so the script errors out rather than lying.
  • lastUpdatedDate isn't validated. It's copied straight from the upstream .fetched_at — if the upstream ever emits a non-ISO-8601 string, RunCat can't parse it. A date -u +%Y-%m-%dT%H:%M:%SZ fallback keeps the card honest.

Unused code

  • plan=\$(echo \"\$usage\" | jq -r '.plan') on line 39 is assigned and never referenced. This repo's convention (see CLAUDE.md) is to remove variables/functions that end up unused.

Nits

  • The five separate echo \"\$usage\" | jq -r … invocations can be consolidated into a single jq call that emits all fields at once — cheaper and easier to read.
  • args=\"\$args -workspace \$workspace\" and unquoted \$args expansion depend on word-splitting; positional parameters (set -- ... -workspace \"\$workspace\") would be safer against paths with spaces. Not an actual hazard with the current defaults, just idiomatically cleaner.
  • Given how fragile the data source is, the README would benefit from a warning similar to the one at the top of docs/samples/codex/README.md ("format may change; adjust the parser if it breaks").

None of these are large to fix, but flagging so they don't carry over if the sample is redirected to a local-session-based approach.

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.

2 participants