Project

jules-ruby

0.0
No release in over 3 years
A Ruby gem for interacting with the Jules API to programmatically create and manage asynchronous coding tasks.
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
 Dependencies

Development

~> 3.0
~> 1.0
~> 0.22
~> 3.0

Runtime

~> 0.75
~> 3.0
~> 0.8
~> 1.3
~> 0.23
 Project Readme

Gem Version CI

jules-ruby

jules-ruby

A Ruby gem for interacting with the jules API to programmatically create and manage asynchronous coding tasks.

🚀 New! Use jules-ruby directly from Gemini CLI with our extension: jules-ruby-gemini-cli-extension

Installation

Add this line to your application's Gemfile:

gem 'jules-ruby'

Then execute:

bundle install

Or install it yourself:

gem install jules-ruby

Configuration

Using environment variables (recommended)

Create a .env file in your project root:

JULES_API_KEY=your_api_key_here

The gem automatically loads from .env using dotenv.

Using Ruby configuration

require 'jules-ruby'

JulesRuby.configure do |config|
  config.api_key = 'your_api_key_here'
  config.timeout = 60 # optional, default is 30 seconds
end

Per-client configuration

client = JulesRuby::Client.new(api_key: 'different_api_key')

Command-Line Interface

The gem includes a CLI for interacting with the jules API from your terminal.

Installation

After installing the gem, the jules-ruby command becomes available:

jules-ruby help

Commands

Sources

# List all connected repositories
jules-ruby sources list
jules-ruby sources list --format=json

# Show source details
jules-ruby sources show sources/github/owner/repo

Sessions

# List all sessions
jules-ruby sessions list
jules-ruby sessions list --format=json

# Show session details
jules-ruby sessions show <session_id>

# Create a new session
jules-ruby sessions create \
  --source=sources/github/owner/repo \
  --branch=main \
  --prompt="Fix the login bug" \
  --title="Fix Login" \
  --auto-pr

# Approve a plan
jules-ruby sessions approve <session_id>

# Send a message
jules-ruby sessions message <session_id> --prompt="Also add unit tests"

# Delete a session
jules-ruby sessions delete <session_id>

Activities

# List activities for a session
jules-ruby activities list <session_id>
jules-ruby activities list <session_id> --format=json

# Show activity details
jules-ruby activities show sessions/<session_id>/activities/<activity_id>

Interactive Mode

Start the interactive TUI for guided workflows:

jules-ruby interactive
# or
jules-ruby -i

Interactive mode provides:

  • Main menu - Navigate between actions
  • Session wizard - Step-by-step session creation with source selection
  • Session viewer - View details, approve plans, send messages, delete
  • Activities viewer - See session progress and history

Output Formats

All list commands support --format=table (default) or --format=json.

Gemini CLI Extension

Use jules-ruby directly from Gemini CLI with our extension:

👉 jules-ruby-gemini-cli-extension

Usage

Initialize the client

require 'jules-ruby'

client = JulesRuby::Client.new

Sources

List your connected repositories:

# List sources with pagination
result = client.sources.list(page_size: 10)
result[:sources].each do |source|
  puts "#{source.name}: #{source.github_repo.full_name}"
end

# Get all sources
sources = client.sources.all

Sessions

Create and manage coding sessions:

# Create a new session
session = client.sessions.create(
  prompt: "Fix the login bug in the authentication module",
  source_context: {
    "source" => "sources/github/myorg/myrepo",
    "githubRepoContext" => { "startingBranch" => "main" }
  },
  title: "Fix Login Bug",
  automation_mode: "AUTO_CREATE_PR"  # optional: auto-create PR when done
)

puts "Session created: #{session.url}"
puts "State: #{session.state}"

# List sessions
result = client.sessions.list(page_size: 10)
result[:sessions].each { |s| puts "#{s.title}: #{s.state}" }

# Get a specific session
session = client.sessions.find("12345678")
# or
session = client.sessions.find("sessions/12345678")

# Check session state
if session.awaiting_plan_approval?
  client.sessions.approve_plan(session.name)
end

# Send a message to the agent
client.sessions.send_message(session.name, prompt: "Can you also add unit tests?")

# Delete a session
client.sessions.destroy(session.name)

Activities

Monitor session progress:

# List activities for a session
result = client.activities.list(session.name, page_size: 30)

result[:activities].each do |activity|
  case activity.type
  when :plan_generated
    puts "Plan: #{activity.plan.steps.map(&:title).join(', ')}"
  when :progress_updated
    puts "Progress: #{activity.progress_title}"
  when :session_completed
    puts "Session completed!"
  when :session_failed
    puts "Failed: #{activity.failure_reason}"
  end
end

# Get all activities
activities = client.activities.all(session.name)

Working with models

Session states

session.queued?                 # Waiting to start
session.planning?               # Creating a plan
session.awaiting_plan_approval? # Needs plan approval
session.awaiting_user_feedback? # Waiting for user input
session.in_progress?            # Working on the task
session.completed?              # Finished successfully
session.failed?                 # Failed
session.active?                 # Any non-terminal state

Activity types

activity.agent_message?    # Agent posted a message
activity.user_message?     # User posted a message
activity.plan_generated?   # A plan was created
activity.plan_approved?    # A plan was approved
activity.progress_update?  # Progress update
activity.session_completed? # Session completed
activity.session_failed?   # Session failed

# Get content based on type
activity.message           # For agent/user messages
activity.plan              # For plan_generated (returns Plan object)
activity.progress_title    # For progress updates
activity.failure_reason    # For session_failed

Artifacts

activity.artifacts.each do |artifact|
  case artifact.type
  when :change_set
    puts "Changes to: #{artifact.source}"
    puts "Commit message: #{artifact.suggested_commit_message}"
  when :bash_output
    puts "Command: #{artifact.bash_command}"
    puts "Output: #{artifact.bash_output_text}"
    puts "Exit code: #{artifact.bash_exit_code}"
  when :media
    puts "Media type: #{artifact.media_mime_type}"
  end
end

Error Handling

begin
  client.sessions.find("nonexistent")
rescue JulesRuby::AuthenticationError => e
  puts "Invalid API key"
rescue JulesRuby::NotFoundError => e
  puts "Session not found"
rescue JulesRuby::RateLimitError => e
  puts "Rate limit exceeded, try again later"
rescue JulesRuby::ServerError => e
  puts "Server error: #{e.message}"
rescue JulesRuby::Error => e
  puts "API error: #{e.message} (status: #{e.status_code})"
end

Requirements

  • Ruby 3.0+
  • async-http gem

Development

# Install dependencies
bundle install

# Run tests
bundle exec rspec

# Run linter
bundle exec rubocop

License

The gem is available as open source under the terms of the MIT License.