Commit Graph

5 Commits

Author SHA1 Message Date
b289335f45 Add GitHub Actions CI workflow
Some checks failed
Test / test (3.4) (push) Failing after 9m56s
Test / test (3.3) (push) Failing after 9m56s
Test / test (3.2) (push) Failing after 9m57s
Tobi T4 consensus: alpha gems shouldn't ship without proof that
'bundle exec rake test' passes on push. Workflow runs the test
suite + gem build + post-install smoke load on Ruby 3.2, 3.3,
and 3.4.

Workflow will activate when the repo moves to GitHub. Local
'bundle exec rake test' continues to be the dev feedback loop.
2026-05-20 06:45:53 -07:00
abe69f1515 Add Opencode::Instrumentation.notify; bump to 0.0.1.alpha2
Code review consensus from Tobi+Sandi: the empty-block call
'Opencode::Instrumentation.instrument(name, payload) { }' at fire-
and-forget call sites in opencode-rails is API smell. Tobi: 'two
named verbs are clearer than one verb with a vestigial block.'
Sandi: 'a method with a block parameter that's optional but expected
empty in some call sites is doing two things.'

Two emission shapes now:

  .instrument(name, payload) { ... }   # block; duration measured
  .notify(name, payload)                # fire-and-forget; no block

Both flow through the same adapter. The adapter still always
receives a block argument (some adapters key on it, e.g. AS::
Notifications.instrument requires a block) — .notify passes an
empty {}. Adapter return value is ignored for .notify (it returns
nil); .instrument continues to pass through the block's return.

Three new tests in smoke_test.rb:
  - no-op when no adapter set
  - forwards to adapter + verifies block presence + verifies that
    .notify returns nil (not the adapter's return)
  - works without a block at the call site

Also: switched gemspec metadata URLs from Gitea to GitHub. The gem
will eventually publish from github.com/ajaynomics/opencode-ruby —
the metadata now reflects that. (No actual GitHub remote push yet;
that's the user's manual step.)

15 tests pass, 32 assertions, 0 failures.
2026-05-20 06:42:51 -07:00
ac0fe87940 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.
2026-05-19 20:20:46 -07:00
e3e7b69c7f Initial opencode-ruby v0.0.1.alpha1 — hand-rolled HTTP+SSE client for OpenCode
Headline API:

  reply = client.stream(session_id, "Explain monads") do |part|
    print part["content"] if part["type"] == "text"
  end
  reply.full_text   # final accumulated text

Sources ported from ajaynomics/ajent-rails lib/opencode/client/ after
the Phase-1+2 tier carve + Phase-2.5 boundary cleanup (see ajent-rails
PRs #840 and #843). Rails-runtime coupling stripped:

  - Defaults read from ENV[OPENCODE_BASE_URL/SERVER_PASSWORD/TIMEOUT]
    instead of Rails.application.config.x.opencode_blackline.*
  - EventTraceable.timed_event(...) calls swapped for
    Opencode::Instrumentation.instrument(...) — pluggable adapter
    (default no-op) that callers wire to ActiveSupport::Notifications,
    OpenTelemetry, stdout, etc.

Runtime dependency: activesupport (>= 6.1, < 9.0) for the small
core_ext surface (blank?/present?/presence/truncate/duplicable?/
megabytes). ActiveSupport is NOT Rails — it's a standalone helpers
gem that most Ruby apps already have transitively.

What's in the gem:

  Opencode::Client          HTTP + SSE client; #stream block-form API
  Opencode::Reply           SSE-event accumulator with observer protocol
  Opencode::Reply::Result   typed Struct value object
  Opencode::ReplyObserver   observer protocol module (no-op defaults)
  Opencode::Prompts         per-Reply pending question/permission registry
  Opencode::Tracer          callable that prefixes event names
  Opencode::Instrumentation pluggable adapter
  Opencode::ResponseParser  wire-format extractors
  Opencode::ToolPart        canonical tool-part hash shape
  Opencode::PartSource      wire-vs-stream-only discriminator
  Opencode::Todo            todo status canonicalization
  Opencode::Error (+ 7 subclasses)

What's out (per design D18 — wait for demand signal):

  - acts_as_opencode_session concern
  - ActiveRecord-backed session lifecycle
  - rails generators
  - opencode-rails as a separate gem

Instead, examples/conversation_recipe.rb ships as a ~140-line
plain-ActiveRecord blueprint demonstrating session lifecycle,
with_lock, update_columns mid-stream pattern, and CAS-safe finalize.

Tests: 12 runs, 25 assertions, 0 failures (smoke test against
WebMock-stubbed OpenCode endpoints — covers the postcard, error
model, Instrumentation, and Reply::Result shape).

Authored against ajent-rails commit 02954eeb (opencode-gem/phase-3-prep).
2026-05-19 20:06:40 -07:00
a04330b78d Initial commit 2026-05-20 02:58:22 +00:00