From 8bd3980bf892bab77ebe1ea622fdaf299434bf1f Mon Sep 17 00:00:00 2001 From: Brad Gessler Date: Tue, 23 Jun 2026 13:39:01 -0700 Subject: [PATCH] v2/rails: Terminalwire::V2::Rails::Thor mixin + browser/file/directory/env helpers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Make the v2 Thor CLI a drop-in for v1's Rails terminal: - Terminalwire::V2::Rails::Thor — include it to get v2 I/O + the client session + Rails route URL helpers (root_url, *_url) in no_commands. The v2 equivalent of v1's Terminalwire::Thor. The per-connection host is already set by the handler. - Expose the client resources on the CLI instance via the v2 Thor Helpers: browser, file, directory, env, client (alias for context) — so unchanged Thor commands like `browser.launch(terminal_authorization_url)` work over v2. Verified: v2-only ogplus login now reaches 'Waiting for authorization' (URL helper + browser resolve); whoami stays graceful. Full suite 96/0. --- v2/ruby/lib/terminalwire/v2/rails.rb | 19 +++++++++++++++++++ v2/ruby/lib/terminalwire/v2/server/thor.rb | 7 +++++++ 2 files changed, 26 insertions(+) diff --git a/v2/ruby/lib/terminalwire/v2/rails.rb b/v2/ruby/lib/terminalwire/v2/rails.rb index 6f488dc..63abe16 100644 --- a/v2/ruby/lib/terminalwire/v2/rails.rb +++ b/v2/ruby/lib/terminalwire/v2/rails.rb @@ -131,6 +131,25 @@ def file_exist? end end + # Drop-in Rails terminal mixin — the v2 equivalent of v1's `Terminalwire::Thor`. + # `include Terminalwire::V2::Rails::Thor` in your Thor CLI and it: + # * streams I/O over the v2 wire (Terminalwire::V2::Server::Thor), + # * exposes the client `session` (the shell delegator), and + # * mixes in Rails route URL helpers (root_url, *_url, *_path) so commands like + # login/browser-open can build links. The per-connection host is set by the + # handler, so the *_url helpers resolve to the host the client connected on. + # The url_helpers go in `no_commands` so Thor doesn't register them as commands. + module Thor + def self.included(base) + base.include Terminalwire::V2::Server::Thor + base.class_eval do + no_commands do + include ::Rails.application.routes.url_helpers + end + end + end + end + # Returns a Rack endpoint that serves `cli` over both protocols. Pass `v1:`/`v2:` # to override the handlers (tests, custom adapters); by default it builds the # stock v1 `Terminalwire::Rails::Thor` and v2 `Terminalwire::V2::Server::Rack`. diff --git a/v2/ruby/lib/terminalwire/v2/server/thor.rb b/v2/ruby/lib/terminalwire/v2/server/thor.rb index 11bcffc..713a69d 100644 --- a/v2/ruby/lib/terminalwire/v2/server/thor.rb +++ b/v2/ruby/lib/terminalwire/v2/server/thor.rb @@ -23,6 +23,13 @@ def warn(*args) = args.each { |arg| shell.context.warn(arg.to_s) } def gets = shell.context.gets def getpass = shell.context.getpass def context = shell.context + # The client-side resources, exposed on the CLI instance like v1 (so a Thor + # command can call `browser.launch(url)`, `file.read(path)`, `env("HOME")`). + def browser = shell.context.browser + def file = shell.context.file + def directory = shell.context.directory + def env(name) = shell.context.env(name) + def client = shell.context end class Shell < ::Thor::Shell::Basic