### Create a new Rails app
Source: https://terminalwire.com/docs/rails/getting-started
Command to create a new Rails application. Assumes Rails is installed.
```bash
rails new my-app
cd my-app
```
--------------------------------
### Install Terminalwire Rails Gem
Source: https://terminalwire.com/docs/rails/getting-started
Command to add the Terminalwire Rails gem to your application's Gemfile and install it.
```bash
bundle add terminalwire-rails
rails g terminalwire:install my-app
```
--------------------------------
### Terminalwire Binary Stub Configuration
Source: https://terminalwire.com/docs/rails/getting-started
Configuration file for the Terminalwire executable stub used in development. Specifies the WebSocket URL for the server connection.
```shell
#!/usr/bin/env terminalwire-exec
url: "ws://localhost:3000"
```
--------------------------------
### Configure Routes for Terminalwire Server
Source: https://terminalwire.com/docs/rails/getting-started
Mounts the Terminalwire::Thor::Server with the MainTerminal class to the '/terminal' endpoint using WebSocket for client connections.
```ruby
# ./config/routes.rb
Rails.application.routes.draw do
match '/terminal',
to: Terminalwire::Thor::Server.new(MainTerminal),
via: [:get, :connect]
end
```
--------------------------------
### Define MainTerminal Commands in Rails
Source: https://terminalwire.com/docs/rails/getting-started
Defines application-specific commands (hello, login, whoami, logout) by inheriting from ApplicationTerminal and utilizing Terminalwire::Thor for session management and authentication.
```ruby
# ./app/terminals/main_terminal.rb
class MainTerminal < ApplicationTerminal
desc "hello NAME", "say hello to NAME"
def hello(name)
puts "Hello #{name}"
end
desc "login", "Login to your account"
def login
print "Email: "
email = gets.chomp
print "Password: "
password = getpass
# Replace this with your own authentication logic; this is an example
# of how you might do this with Devise.
user = User.find_for_authentication(email: email)
if user && user.valid_password?(password)
self.current_user = user
puts "Successfully logged in as #{current_user.email}."
else
puts "Could not find a user with that email and password."
end
end
desc "whoami", "Displays current user information."
def whoami
if self.current_user
puts "Logged in as #{current_user.email}."
else
puts "Not logged in. Run `#{self.class.basename} login` to login."
end
end
desc "logout", "Logout of your account"
def logout
session.reset
puts "Successfully logged out."
end
end
```
--------------------------------
### Test Terminalwire Integration in Rails
Source: https://terminalwire.com/docs/rails/getting-started
Command to test the Terminalwire integration by running a command through the generated binary stub. Assumes Rails server is running.
```bash
./bin/my-app version
```
--------------------------------
### Configure ApplicationTerminal in Rails
Source: https://terminalwire.com/docs/rails/getting-started
Defines the base Thor command-line parser for Terminalwire, enabling IO streaming and user authentication. Requires Thor and Terminalwire::Thor.
```ruby
# ./app/terminals/application_terminal.rb
# Learn how to use Thor at http://whatisthor.com.
class ApplicationTerminal < Thor
# Enables IO Streaming.
include Terminalwire::Thor
# The name of your binary. Thor uses this for its help output.
def self.basename = "<%= binary_name %>"
private
def current_user=(user)
# The Session object is a hash-like object that encrypts and signs a hash that's
# stored on the client's file sytem. Conceptually, it's similar to Rails signed
# and encrypted client-side cookies.
session["user_id"] = user.id
end
def current_user
@current_user ||= User.find(session["user_id"])
end
end
```
--------------------------------
### One-off Installation by URL (terminalwire CLI)
Source: https://terminalwire.com/docs/rails/distribution
Performs a one-off installation of an application directly from a URL. Uses the Terminalwire CLI with the --url and --name flags.
```bash
terminalwire install \
--url https://example.com/terminal \
--name my-app
```
--------------------------------
### Install App (terminalwire CLI)
Source: https://terminalwire.com/docs/rails/distribution
Installs an application via the Terminalwire CLI, typically used with applications listed in the Terminalwire directory.
```bash
terminalwire install my-app
```
--------------------------------
### One-liner Curl Installer (bash)
Source: https://terminalwire.com/docs/rails/distribution
Provides a one-liner curl installer for distributing your application. Replace `my-app` with the actual binary name.
```bash
curl -sSL https://my-app.terminalwire.sh | bash
```
--------------------------------
### Write output to terminal using stdout (Ruby)
Source: https://terminalwire.com/docs/rails/stdio
Demonstrates how to send text to the client terminal using standard output. In Ruby, `puts` and `print` are redirected by Terminalwire to stream over WebSockets. Use for regular informational messages.
```Ruby
# Print "Hello, World!" to the terminal and append a newline
puts "Hello, World!"
# Print "Hi!" to the terminal without a newline
print "Hi!"
```
--------------------------------
### Read user input from terminal using stdin (Ruby)
Source: https://terminalwire.com/docs/rails/stdio
Shows how to capture text entered by the user via standard input. Terminalwire forwards `$stdin.gets` calls to the client, allowing interactive prompts. Trim the newline withchomp` for clean values.
```Ruby
print "What is your name?: "
# Read a line of text from the terminal
name = gets.chomp # chomp removes the newline character
# Print a greeting to the terminal
puts "Hello, #{name}!"
```
--------------------------------
### Launch URL with Rails ApplicationTerminal
Source: https://terminalwire.com/docs/rails/browser
Demonstrates how to use `browser.launch` within a Rails `ApplicationTerminal` to open URLs in the client's default browser. The example shows launching the root URL of a Rails application when a user runs a command.
```ruby
class MainTerminal < ApplicationTerminal
desc "open", "Open in browser."
def open
# Launch's the root URL of a Rails app from the console
browser.launch root_url
end
end
```
--------------------------------
### GET /terminal/sessions/new
Source: https://terminalwire.com/docs/rails/authentication
Displays a form for the user to approve or deny access for a terminal application. This is the initial step in the terminal app authorization flow.
```APIDOC
## GET /terminal/sessions/new
### Description
This endpoint renders the authorization form for a terminal application. It presents the user with a title, subtitle, and buttons to "Approve" or "Deny" the app's access request. The "Approve" button submits a POST request to the `create` action with the authorization token.
### Method
GET
### Endpoint
/terminal/sessions/new
### Parameters
#### Query Parameters
- **token** (string) - Required - A token provided by the terminal app, used to identify the authorization request.
### Request Example
```
GET /terminal/sessions/new?token=some_auth_token
```
### Response
#### Success Response (200 OK)
- **HTML Form**: Renders an HTML form with fields for approval and denial.
#### Response Example
```html
```
```
--------------------------------
### GET /terminal/session
Source: https://terminalwire.com/docs/rails/authentication
Displays a success message after a terminal application has been successfully authorized.
```APIDOC
## GET /terminal/session
### Description
This endpoint displays a success message to the user indicating that the command-line application has been successfully authorized. It informs the user they can now close the window and continue using the CLI.
### Method
GET
### Endpoint
/terminal/session
### Parameters
None
### Request Example
```
GET /terminal/session
```
### Response
#### Success Response (200 OK)
- **HTML Page**: Renders a success message.
#### Response Example
```html
Successfully authorized command line app
You may now close this window and continue using the command-line interface.
```
```
--------------------------------
### Prompt for password securely using getpass (Ruby)
Source: https://terminalwire.com/docs/rails/stdio
Uses the `getpass` helper provided by Thor/Terminalwire to read a password without echoing it to the terminal. This method returns the entered string, suitable authentication checks. No visible feedback is shown to the user while typing.
```Ruby
puts "Login to your account"
# Read a line of text from the terminal
password = getpass # chomp removes the newline
# Check if the password is correct.
if password == "password"
puts "You are logged in"
else
puts "Incorrect password"
end
```
--------------------------------
### Implement email and password login in Terminalwire (Ruby)
Source: https://terminalwire.com/docs/rails/authentication
Provides a Ruby method for logging in via email and password within a Terminalwire terminal. Uses `gets` for email input and `getpass` to securely read the password, then authenticates with Devise's `find_for_authentication` and `valid_password?`. Outputs success or error messages.
```Ruby
# ./app/terminals/main_terminal.rb
desc "login", "Login to your account"
def login
print "Email: "
email = gets.chomp
print "Password: "
password = getpass
# Replace this with your own authentication logic; this is an example
# of how you might do this with Devise.
user = User.find_for_authentication(email: email)
if user && user.valid_password?(password)
self.current_user = user
puts "Successfully logged in as #{current_user.email}."
else
puts "Could not find a user with that email and password."
end
end
```
--------------------------------
### Write error messages to terminal using stderr (Ruby)
Source: https://terminalwire.com/docs/rails/stdio
Illustrates sending error output to the client terminal via standard error. In Ruby, `warn` writes to `$stderr`, which Terminalwire streams to the user's console. Useful for reporting issues without interrupting normal output.
```Ruby
# Write an error message to the users terminal
warn "Oops, An error occurred"
```
--------------------------------
### Implement web browser authentication command in Terminalwire (Ruby)
Source: https://terminalwire.com/docs/rails/authentication
Shows a Ruby class method that initiates a web-browser based authentication flow. Generates a secure nonce, creates a signed token with Rails secret key, constructs a URL, opens the browser, waits for the user to authorize, and retrieves the user ID to set the current user. Requires Rails, SecureRandom, ActiveSupport::MessageVerifier, and ActiveExchange.
```Ruby
# ./app/terminals/main_terminal.rb
class MainTerminal < ApplicationTerminal
desc "login", "Login to application"
def login
# Create a nonce
nonce = SecureRandom.hex
# Encrypt it with Rails secret key
verifier = ActiveSupport::MessageVerifier.new(Rails.application.secret_key_base)
# Generate a token that expires in 10 minutes
token = verifier.generate(nonce, expires_in: 10.minutes)
# Generate a URL that the user can visit to authenticate
url = new_terminal_session_url(token:)
puts "Opening #{url} in your browser..."
# How sign it with Rails and gem it into the URL...
client.browser.launch(new_terminal_session_url(token:))
# Wait for the user to authenticate. This is a blocking call that waits
# fot the user to successfully authenticate in the browser.
authorization = ActiveExchange::Channel.new(name: "auth:#{nonce}")
if user_id = JSON.parse(authorization.read).fetch("user_id")
self.current_user = User.find(user_id)
puts "Welcome #{current_user.email}"
else
puts "Well that didn't work"
end
end
end
```
--------------------------------
### Request Core License (terminalwire CLI)
Source: https://terminalwire.com/docs/rails/distribution
Requests a Core license for a personal application using the terminalwire CLI. Requires the URL of the web application and the --product core flag.
```bash
terminalwire license request https://hobbyist.example.com/terminal \
--product core
```
--------------------------------
### Create Distribution (terminalwire CLI)
Source: https://terminalwire.com/docs/rails/distribution
Creates a distribution for your application using the terminalwire CLI. Requires the app name and the URL where it can be accessed.
```bash
terminalwire distribution create my-app \
--url https://example.com/terminal
```
--------------------------------
### Request Pro License (terminalwire CLI)
Source: https://terminalwire.com/docs/rails/distribution
Requests a Pro license for a commercial web application using the terminalwire CLI. Requires the URL of the web application and the --product pro flag.
```bash
terminalwire license request https://mega-corp.example.com/terminal \
--product pro
```
--------------------------------
### Implement terminal app authorization controller in Ruby on Rails
Source: https://terminalwire.com/docs/rails/authentication
Defines a SessionsController with a before_action to ensure the user is logged in, inline New and Show view classes for rendering the approval form and success message, and a create action that verifies a signed token, broadcasts the user ID over a dynamic channel, and redirects to the terminal session URL. Requires ActiveSupport, ActiveExchange, and Superview gems.
```Ruby
class Terminal::SessionsController < ApplicationController
# If the user is not logged in, this will force them to login before they
# can authorize the terminal app.
before_action :authorize_user
# Enabled inline rendering of the views below.
layout false
include Superview::Actions
View = DeveloperView
# Display a form asking the user to Approve or Deny the terminal app.
class New < View
def title = "Authorize command line app"
def subtitle = "The terminal app is requesting access to your account. Do you approve?"
def view_template
form action: url_for(action: :create), method: :post, class: "flex flex-row gap-4" do
input type: "hidden", value: helpers.params.fetch("token"), name: "token"
input type: "submit", class: "btn btn-primary", value: "Approve"
input type: "cancel", class: "btn btn-error", value: "Deny"
end
end
end
# Display a success message after the user has approved the terminal app.
class Show < View
def title = "Successfully authorized command line app"
def subtitle = "You may now close this window and continue using the command-line interface."
def view_template
end
end
# The New view submits a form to this action. If the user approves the terminal authorization
# it will send a message to the terminal app with the user's ID to the nonce they're listening on.
def create
verifier = ActiveSupport::MessageVerifier.new(Rails.application.secret_key_base)
nonce = verifier.verified(helpers.params[:token])
message = JSON.generate(user_id: current_user.id)
ActiveExchange::Channel.new(name: "auth:#{nonce}").broadcast(message)
redirect_to terminal_session_url
end
end
```
--------------------------------
### POST /terminal/sessions
Source: https://terminalwire.com/docs/rails/authentication
Creates a new terminal session by authorizing a terminal app. This endpoint is typically accessed via a form submission after the user has been prompted to approve or deny access.
```APIDOC
## POST /terminal/sessions
### Description
This endpoint handles the submission of the terminal app authorization form. If the user approves, it verifies the provided token, broadcasts a message containing the user's ID to a specific channel, and redirects the user to the terminal session URL.
### Method
POST
### Endpoint
/terminal/sessions
### Parameters
#### Query Parameters
- **token** (string) - Required - A token used to verify the authorization request.
### Request Body
- **token** (string) - Required - The authorization token provided by the terminal app.
### Request Example
```json
{
"token": "a_verified_token_string"
}
```
### Response
#### Success Response (302 Redirect)
- **Location** (string) - Redirects to the terminal session URL.
#### Response Example
```
HTTP/1.1 302 Found
Location: /terminal/session
```
### Error Handling
- If the token is invalid or expired, an appropriate error response will be returned (e.g., 400 Bad Request or 422 Unprocessable Entity, depending on implementation).
- If the user is not authenticated, they will be redirected to the login page due to the `authorize_user` before_action.
```
--------------------------------
### Reading Environment Variables in Terminalwire Ruby
Source: https://terminalwire.com/docs/rails/environment-variables
Demonstrates two methods to read environment variables from the client's workstation: directly via the ENV hash in context or using the environment_variables device. Requires TERMINALWIRE_HOME to be set; access to other vars needs client permission. Outputs the value of the specified variable; note potential typo in 'environmnent_variables'.
```ruby
# Access the ENV hash
context.ENV["TERMINALWIRE_HOME"]
# Or use the env device
context.environmnent_variables.read("TERMINALWIRE_HOME")
```
--------------------------------
### Write file to client storage path
Source: https://terminalwire.com/docs/rails/file-system
Writes a file to the client's Terminalwire storage directory. The operation is restricted to the ~/.terminalwire/authorities/$AUTHORITY/storage path by default. Requires appropriate context and storage path variables to be defined.
```ruby
# Write a file to the client's file system at
# ~/.terminalwire/authorities/$AUTHORITY/storage/hello.txt
context.file.write storage_path.join("hello.txt"), "Hello, World!"
```
--------------------------------
### List files in client storage directory
Source: https://terminalwire.com/docs/rails/file-system
Lists all files in the client's Terminalwire storage path using directory globbing. This operation is restricted to the ~/.terminalwire/authorities/$AUTHORITY/storage path by default. Requires context and storage path variables to be defined.
```ruby
# List all of the files in the client's file system in their Terminalwire storage path.
context.dir.glob storage_path
```
--------------------------------
### Perform Bulk Session Updates in Terminalwire
Source: https://terminalwire.com/docs/rails/sessions
This Ruby code illustrates how to efficiently update multiple session attributes in a single operation using the `session.edit` method with a block. This approach minimizes client-server communication by making all changes in one round-trip, ensuring data consistency.
```ruby
session.edit |data|
data["uuid"] = SecureRandom.uuid
data["id"] = user.id
data["expires_at"] = 1.month.from_now
end
```
--------------------------------
### Manage User Session in Rails Application
Source: https://terminalwire.com/docs/rails/sessions
This Ruby code demonstrates how to set and retrieve a user's ID within the Terminalwire session, mimicking Rails' approach to session management. It uses a `session` object, which acts like a hash, to store and retrieve the `user_id` after encrypting and signing it.
```ruby
# Learn how to use Thor at http://whatisthor.com.
class ApplicationTerminal < Thor
# .. Code ...
private
def current_user=(user)
# The Session object is a hash-like object that encrypts and signs a hash that's
# stored on the client's file sytem. Conceptually, it's similar to Rails signed
# and encrypted client-side cookies.
session["user_id"] = user.id
end
def current_user
@current_user ||= User.find(session["user_id"])
end
end
```
--------------------------------
### Override Default URL Options in Rails
Source: https://terminalwire.com/docs/rails/browser
Shows how to override the `default_url_options` method in your `ApplicationTerminal` to customize URL settings. This is useful for setting a custom host name.
```ruby
class ApplicationTerminal < Thor
include Terminalwire::Thor
def default_url_options
{ host: 'your-custom-host.com' }
end
end
```
--------------------------------
### Set Session Expiration and UUID Manually
Source: https://terminalwire.com/docs/rails/sessions
This Ruby code shows how to manually set session expiration and a unique identifier (UUID) within the session data using the `session.edit` block. This is necessary because Terminalwire sessions do not have built-in expiration or IDs like Rails sessions.
```ruby
session.edit do |data|
data["expires_at"] = 1.month.from_now
data["uuid"] = SecureRandom.uuid
end
```
=== COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.