Reference material for shipping v0.0.1.alpha1. Not part of the gem
(excluded from gemspec.files), but lives at repo root so the human
launching it has the steps in one place.
Sections:
1. Publish to Rubygems (gem signin + push + verify; Gemfile swap)
2. Three screenshots (terminal quickstart, rubygems.org page,
Gemfile.lock excerpt) — Tobi's 'don't ship until the screenshots
are beautiful' bar
3. Announcement drafts (r/ruby, dev.to, Twitter/Bluesky/Mastodon)
4. Friendly note to Eric Guo (opencode_client maintainer) — D1
etiquette
5. Demand-signal tracking (60-day window per D18) — thresholds for
deciding whether to extract opencode-rails next
6. Note to OpenCode maintainers about repo donation if traction hits
(D2)
assets/screenshots/ created as an empty directory (with this commit)
so screenshot files can land alongside LAUNCH.md in a single PR
after the human takes them.
7.2 KiB
Launch playbook — opencode-ruby v0.0.1-alpha1
Reference materials for shipping. Not part of the gem; lives at the repo root for the human launching it.
1. Publish to Rubygems
~/.gem/credentials is not set up on the dev machine. To push:
gem signin # one-time, follow prompts to log in
gem push opencode-ruby-0.0.1.alpha1.gem # builds in pkg/ via rake build, or use the local .gem file
sleep 30 # rubygems indexing
curl -s "https://rubygems.org/api/v1/gems/opencode-ruby.json" | jq '.name, .version'
Expected: "opencode-ruby", "0.0.1.alpha1".
After successful push, update ajaynomics/ajent-rails Gemfile (PR #844 land swap):
gem "opencode-ruby", "~> 0.0.1.alpha1"
# (drop the git+tag pin)
2. Take three screenshots
Three is the bar Tobi set. Crisp, real, on a real terminal.
Screenshot 1 — terminal running the quickstart
# Start a local opencode server (in another terminal):
opencode serve --port 4096
# Then in a clean terminal:
ruby -ropencode-ruby -e '
client = Opencode::Client.new(base_url: "http://localhost:4096")
session = client.create_session(title: "Demo")
reply = client.stream(session[:id], "Explain monads in two sentences.") do |part|
print part["content"] if part["type"] == "text"
end
puts
puts
puts "(#{reply.tool_parts.size} tool calls, #{reply.parts_json.size} parts total)"
'
Capture a screenshot showing the streaming text + final tool/part count line.
Recommended terminal: Ghostty with a clean theme, large font (16-18pt). Resize to ~120x30.
Save as assets/screenshots/01-quickstart.png.
Screenshot 2 — rubygems.org page
After gem push + indexing, screenshot the rubygems.org page for the gem. Crop to the title + summary + install command. ~1200×500 px.
Save as assets/screenshots/02-rubygems.png.
Screenshot 3 — gem listed in Gemfile.lock of a host app
After PR #844 lands, take a screenshot of the relevant 5-line Gemfile.lock excerpt showing the gem at v0.0.1.alpha1.
Save as assets/screenshots/03-gemfile-lock.png.
Embed in README
Add to top of README, right after the title:

3. Announcement drafts
Three channels, all under 280 chars unless noted. Don't post until at least one of the screenshots is in the README.
r/ruby (Reddit)
Title: opencode-ruby v0.0.1-alpha — idiomatic Ruby client for OpenCode
Body:
Shipping an early alpha of
opencode-ruby— a hand-rolled Ruby SDK for the OpenCode agent platform (https://opencode.ai).Single headline API:
reply = client.stream(session_id, "Explain monads") do |part| print part["content"] if part["type"] == "text" end reply.full_textBlock-form streaming, typed value-object responses, automatic SSE reconnection, zero Rails coupling at the client level. Complementary to Eric Guo's
opencode_clientwhich auto-generates from OpenAPI — pick whichever fits your taste.Repo: https://gitea.krishnan.ca/ajaynomics/opencode-ruby Rubygems: https://rubygems.org/gems/opencode-ruby
Looking for feedback, especially from Rails developers building chat experiences on OpenCode. A separate
opencode-rails(withacts_as_opencode_session) is in the design doc but deferred until external demand surfaces — see the issue tracker if that's you.
dev.to
Title: Shipping a Ruby SDK for OpenCode — block-form streaming, value-object returns, zero ceremony
(Longer post — ~600-800 words. Skeleton:)
- The problem. OpenCode is the self-hostable agent platform. Ruby developers landing on it from Hacker News need a way to integrate from Ruby. Eric Guo's auto-generated
opencode_clientcovers every endpoint exhaustively; this gem covers the small idiomatic surface. - The postcard. Three lines of setup, four lines of work, full streaming. (Use the screenshot.)
- Design choices that mattered.
- Block-form streaming is the headline;
stream_eventsis the lower seam. - Reply::Result is a Struct, not a Hash — typed shape, both
.full_textand[:full_text]access. - Instrumentation is a pluggable adapter, not Rails-bound (works with AS::Notifications, OpenTelemetry, stdout).
- Error model is exceptions, not return values (
throwOnError: trueequivalent of the TS SDK).
- Block-form streaming is the headline;
- What's not in the gem.
acts_as_opencode_session, generators, ActiveRecord persistence. Theexamples/conversation_recipe.rbblueprint demonstrates the Rails pattern in ~140 lines of plain ActiveRecord. - Demand signal. If you want
opencode-rails, file an issue. We're calibrating against real Rails-shop demand, not stars/installs. - Where to find it. Rubygems, Gitea repo, opencode.ai docs (TBD link).
Twitter / Bluesky / Mastodon (short)
opencode-ruby v0.0.1-alpha is live: an idiomatic Ruby client for @opencode_ai.
reply = client.stream(session_id, "...") { |part| print part["content"] } reply.full_textBlock streaming, Reply::Result Struct, no Rails coupling. https://rubygems.org/gems/opencode-ruby
4. Friendly note to Eric Guo
opencode_client (Eric's gem) is the auto-generated counterpart. Cross-linking + a head's-up is just good manners.
Send via GitHub message or email (his gem page lists his contact). Draft:
Subject: Heads-up: opencode-ruby (complementary alternative)
Hi Eric,
I just shipped
opencode-ruby— a hand-rolled idiomatic Ruby client for OpenCode, intentionally complementary to youropencode_client. My gem covers a small block-form-streaming surface aimed at Rails developers; yours covers every endpoint with generated types.README links your gem near the bottom:
"Want every OpenCode endpoint auto-generated from the OpenAPI spec? Use
opencode_client. This gem is the hand-rolled idiomatic alternative."Happy to coordinate if you'd like — link from your README, joint blog post, whatever fits. Either way, just wanted to give you a friendly heads-up that there's a sibling gem with non-overlapping shape.
Best, Ajay https://gitea.krishnan.ca/ajaynomics/opencode-ruby
5. Demand-signal tracking (60-day window)
Per design D18, the question whether to invest in opencode-rails rides on visible Rails-shop demand. Track:
| Signal | Where | Threshold |
|---|---|---|
| GitHub/Gitea stars | repo page | ≥ 10 |
| Rubygems install count | https://rubygems.org/gems/opencode-ruby | ≥ 50 |
| Substantive issues | repo issue tracker | ≥ 3 (asking for features, not bugs) |
Issues asking specifically for acts_as_opencode_session |
repo | ≥ 1 |
External Rails apps using examples/conversation_recipe.rb |
grep, social mentions | ≥ 1 |
At day 60, decide:
- All thresholds hit AND ≥ 1 acts_as_* request → start opencode-rails design doc.
- Some thresholds hit but no acts_as_* signal → stay the course; keep the recipe file as canonical.
- No thresholds hit → repo is dormant; revisit when something changes upstream.
6. Friendly note to OpenCode maintainers
If adoption picks up, propose donating the repo to anomalyco (OpenCode's org) per design D2. Draft TBD — only do it after the 60-day window confirms a healthy user base.