Add LAUNCH.md with Rubygems push + screenshot + announcement playbook
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.
This commit is contained in:
171
LAUNCH.md
Normal file
171
LAUNCH.md
Normal file
@@ -0,0 +1,171 @@
|
||||
# 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:
|
||||
|
||||
```sh
|
||||
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):
|
||||
|
||||
```ruby
|
||||
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
|
||||
|
||||
```sh
|
||||
# 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:
|
||||
|
||||
```markdown
|
||||

|
||||
```
|
||||
|
||||
## 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:
|
||||
>
|
||||
> ```ruby
|
||||
> reply = client.stream(session_id, "Explain monads") do |part|
|
||||
> print part["content"] if part["type"] == "text"
|
||||
> end
|
||||
> reply.full_text
|
||||
> ```
|
||||
>
|
||||
> Block-form streaming, typed value-object responses, automatic SSE reconnection, zero Rails coupling at the client level. Complementary to Eric Guo's [`opencode_client`](https://rubygems.org/gems/opencode_client) which 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` (with `acts_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:)
|
||||
|
||||
1. **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_client` covers every endpoint exhaustively; this gem covers the small idiomatic surface.
|
||||
2. **The postcard.** Three lines of setup, four lines of work, full streaming. (Use the screenshot.)
|
||||
3. **Design choices that mattered.**
|
||||
- Block-form streaming is the headline; `stream_events` is the lower seam.
|
||||
- Reply::Result is a Struct, not a Hash — typed shape, both `.full_text` and `[: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: true` equivalent of the TS SDK).
|
||||
4. **What's not in the gem.** `acts_as_opencode_session`, generators, ActiveRecord persistence. The `examples/conversation_recipe.rb` blueprint demonstrates the Rails pattern in ~140 lines of plain ActiveRecord.
|
||||
5. **Demand signal.** If you want `opencode-rails`, file an issue. We're calibrating against real Rails-shop demand, not stars/installs.
|
||||
6. **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_text
|
||||
> ```
|
||||
>
|
||||
> Block 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 your `opencode_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.
|
||||
Reference in New Issue
Block a user