jules-ruby 0.0.67

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. checksums.yaml +7 -0
  2. data/.jules/bolt.md +4 -0
  3. data/.rubocop.yml +51 -0
  4. data/AGENTS.md +250 -0
  5. data/CHANGELOG.md +20 -0
  6. data/CONTRIBUTING.md +82 -0
  7. data/LICENSE +21 -0
  8. data/README.md +330 -0
  9. data/Rakefile +70 -0
  10. data/SECURITY.md +41 -0
  11. data/assets/banner.png +0 -0
  12. data/bin/jules-ruby +7 -0
  13. data/jules-ruby.gemspec +43 -0
  14. data/lib/jules-ruby/cli/activities.rb +142 -0
  15. data/lib/jules-ruby/cli/banner.rb +113 -0
  16. data/lib/jules-ruby/cli/base.rb +38 -0
  17. data/lib/jules-ruby/cli/interactive/activity_renderer.rb +81 -0
  18. data/lib/jules-ruby/cli/interactive/session_creator.rb +112 -0
  19. data/lib/jules-ruby/cli/interactive/session_manager.rb +285 -0
  20. data/lib/jules-ruby/cli/interactive/source_manager.rb +65 -0
  21. data/lib/jules-ruby/cli/interactive.rb +48 -0
  22. data/lib/jules-ruby/cli/prompts.rb +184 -0
  23. data/lib/jules-ruby/cli/sessions.rb +185 -0
  24. data/lib/jules-ruby/cli/sources.rb +72 -0
  25. data/lib/jules-ruby/cli.rb +127 -0
  26. data/lib/jules-ruby/client.rb +130 -0
  27. data/lib/jules-ruby/configuration.rb +20 -0
  28. data/lib/jules-ruby/errors.rb +35 -0
  29. data/lib/jules-ruby/models/activity.rb +137 -0
  30. data/lib/jules-ruby/models/artifact.rb +78 -0
  31. data/lib/jules-ruby/models/github_branch.rb +17 -0
  32. data/lib/jules-ruby/models/github_repo.rb +31 -0
  33. data/lib/jules-ruby/models/plan.rb +23 -0
  34. data/lib/jules-ruby/models/plan_step.rb +25 -0
  35. data/lib/jules-ruby/models/pull_request.rb +23 -0
  36. data/lib/jules-ruby/models/session.rb +111 -0
  37. data/lib/jules-ruby/models/source.rb +23 -0
  38. data/lib/jules-ruby/models/source_context.rb +35 -0
  39. data/lib/jules-ruby/resources/activities.rb +76 -0
  40. data/lib/jules-ruby/resources/base.rb +27 -0
  41. data/lib/jules-ruby/resources/sessions.rb +125 -0
  42. data/lib/jules-ruby/resources/sources.rb +61 -0
  43. data/lib/jules-ruby/version.rb +5 -0
  44. data/lib/jules-ruby.rb +43 -0
  45. data/mise.toml +2 -0
  46. metadata +232 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 0b8c57f38a3d3f7419ad7bd5a6a1f2690ba72b0106ccbe01ce4cdf28b115af7d
4
+ data.tar.gz: 04cd808849c6993f215fd99a697e7b02553c3616ce308782881365c21f6f2026
5
+ SHA512:
6
+ metadata.gz: bd7a74a418c3fbaaf2b5118433ec6268dd4da3bd1485dfd066193c380953f742a9e1ef00067f6d29acdc0146ab43ce12d7495ca3676222d027ccd5cdbc667bb8
7
+ data.tar.gz: 31d50df4687c9fbfef15cab8299f3997cab960f5a5286f7bacd5db0e6094f7a42833747e14f23f1c4a70716e9c3821e114a1528842108889c4323666f78acca8
data/.jules/bolt.md ADDED
@@ -0,0 +1,4 @@
1
+ ## 2025-10-18 - Async::HTTP::Internet Usage
2
+
3
+ **Learning:** `Async::HTTP::Internet.new` is instantiated for every request in `JulesRuby::Client#request`, which likely prevents connection keep-alive/pooling.
4
+ **Action:** A significant future optimization would be to reuse the `Async::HTTP::Internet` instance, but this requires careful management of the `Async` reactor lifecycle since the current implementation wraps each request in its own `Async { ... }.wait` block.
data/.rubocop.yml ADDED
@@ -0,0 +1,51 @@
1
+ AllCops:
2
+ NewCops: enable
3
+ TargetRubyVersion: 3.0
4
+ Exclude:
5
+ - 'bin/**/*'
6
+ - 'vendor/**/*'
7
+ - 'Gemfile'
8
+ - 'Rakefile'
9
+ - '*.gemspec'
10
+ - 'test-jules-ruby.rb'
11
+ - 'lib/jules-ruby/cli/banner.rb'
12
+
13
+ Style/Documentation:
14
+ Enabled: false
15
+
16
+ Metrics/MethodLength:
17
+ Max: 20
18
+
19
+ Metrics/ClassLength:
20
+ Max: 150
21
+ Exclude:
22
+ - 'lib/jules-ruby/cli/sessions.rb'
23
+ - 'lib/jules-ruby/cli/interactive/session_manager.rb'
24
+
25
+ Layout/LineLength:
26
+ Max: 120
27
+
28
+ Metrics/BlockLength:
29
+ Exclude:
30
+ - 'spec/**/*'
31
+
32
+ Metrics/AbcSize:
33
+ Max: 25
34
+
35
+ Metrics/CyclomaticComplexity:
36
+ Max: 10
37
+
38
+ Metrics/PerceivedComplexity:
39
+ Max: 10
40
+
41
+ Naming/FileName:
42
+ Exclude:
43
+ - 'lib/jules-ruby.rb'
44
+
45
+ Style/OptionalBooleanParameter:
46
+ Exclude:
47
+ - 'lib/jules-ruby/cli.rb'
48
+
49
+ Metrics/ModuleLength:
50
+ Exclude:
51
+ - 'lib/jules-ruby/cli/prompts.rb'
data/AGENTS.md ADDED
@@ -0,0 +1,250 @@
1
+ # AI Agent Guide for jules-ruby
2
+
3
+ This document helps AI coding agents understand the codebase structure, conventions, and common commands.
4
+
5
+ ## Project Overview
6
+
7
+ **jules-ruby** is a Ruby gem providing a client for the [Jules API](https://developers.google.com/jules/api) to programmatically create and manage asynchronous coding tasks. It includes both a Ruby library and a CLI with interactive TUI mode.
8
+
9
+ ## Project Structure
10
+
11
+ ```
12
+ jules-ruby/
13
+ ├── lib/
14
+ │ ├── jules-ruby.rb # Main entry point, requires all modules
15
+ │ └── jules-ruby/
16
+ │ ├── client.rb # HTTP client with async-http
17
+ │ ├── configuration.rb # Global config (api_key, timeout)
18
+ │ ├── errors.rb # Custom error classes
19
+ │ ├── version.rb # Gem version
20
+ │ ├── cli.rb # Thor-based CLI commands
21
+ │ ├── cli/
22
+ │ │ ├── banner.rb # CLI banner/logo display
23
+ │ │ ├── interactive.rb # Interactive TUI mode (TTY::Prompt)
24
+ │ │ └── prompts.rb # Shared prompt helpers
25
+ │ ├── models/ # Data objects returned from API
26
+ │ │ ├── activity.rb
27
+ │ │ ├── artifact.rb
28
+ │ │ ├── github_repo.rb
29
+ │ │ ├── github_branch.rb
30
+ │ │ ├── plan.rb
31
+ │ │ ├── plan_step.rb
32
+ │ │ ├── pull_request.rb
33
+ │ │ ├── session.rb
34
+ │ │ ├── source.rb
35
+ │ │ └── source_context.rb
36
+ │ └── resources/ # API resource classes
37
+ │ ├── base.rb # Base resource with HTTP methods
38
+ │ ├── activities.rb
39
+ │ ├── sessions.rb
40
+ │ └── sources.rb
41
+ ├── bin/
42
+ │ └── jules-ruby # CLI executable
43
+ ├── spec/ # RSpec tests
44
+ └── .env # API key configuration (JULES_API_KEY)
45
+ ```
46
+
47
+ ## Common Commands
48
+
49
+ ```bash
50
+ # Install dependencies
51
+ bundle install
52
+
53
+ # Run tests
54
+ bundle exec rspec
55
+
56
+ # Run linter
57
+ bundle exec rubocop
58
+
59
+ # Fix lint issues automatically
60
+ bundle exec rubocop -a
61
+
62
+ # Build the gem
63
+ gem build jules-ruby.gemspec
64
+
65
+ # Install locally
66
+ gem install ./jules-ruby-*.gem
67
+ ```
68
+
69
+ ## Environment Setup (Already setup on Jules)
70
+
71
+ These commands were already run on Jules to prepare the environment:
72
+
73
+ ```bash
74
+ #!/bin/bash
75
+ set -e # Exit immediately if a command exits with a non-zero status
76
+
77
+ # 1. System Packages: Check individually before apt update/install
78
+ # We gather missing packages first to avoid running apt update unnecessarily
79
+ REQUIRED_PKGS="curl libssl-dev libyaml-dev zlib1g-dev libreadline-dev libgdbm-dev"
80
+ MISSING_PKGS=""
81
+
82
+ for pkg in $REQUIRED_PKGS; do
83
+ if ! dpkg -s "$pkg" >/dev/null 2>&1; then
84
+ MISSING_PKGS="$MISSING_PKGS $pkg"
85
+ fi
86
+ done
87
+ if [ -n "$MISSING_PKGS" ]; then
88
+ echo "Installing missing packages: $MISSING_PKGS"
89
+ sudo apt-get update -y
90
+ sudo apt-get install -y $MISSING_PKGS
91
+ else
92
+ echo "System packages already installed."
93
+ fi
94
+
95
+ # 2. Install Mise: Check for the binary
96
+ if [ ! -f "$HOME/.local/bin/mise" ]; then
97
+ echo "Installing mise..."
98
+ curl https://mise.run | sh
99
+ else
100
+ echo "mise already installed."
101
+ fi
102
+
103
+ # Set path for the duration of this script
104
+ export PATH="$HOME/.local/bin:$PATH"
105
+
106
+ # 3. Activate Mise: Always run this to ensure the current shell has access to tools
107
+ eval "$(mise activate bash --shims)"
108
+
109
+ # 4. Mise Tools: 'mise install' is generally smart, but we can skip if you want pure speed.
110
+ # However, keep it to ensure version compliance.
111
+ mise trust -a
112
+ mise install
113
+
114
+ # 5. Global Gems: Check if they exist
115
+ if ! gem list -i bundler >/dev/null 2>&1; then
116
+ gem install --quiet bundler
117
+ fi
118
+
119
+ if ! gem list -i rake >/dev/null 2>&1; then
120
+ gem install --quiet rake
121
+ fi
122
+
123
+ echo "Done with Ruby install!"
124
+
125
+ # 6. Bundle Install: Use 'bundle check' to skip 'bundle install'
126
+ if ! bundle check >/dev/null 2>&1; then
127
+ echo "Installing project dependencies..."
128
+ bundle install
129
+ else
130
+ echo "Bundle dependencies satisfied."
131
+ fi
132
+
133
+ echo
134
+ echo "Environment prepared!"
135
+ ```
136
+
137
+ ## Code Style Guidelines
138
+
139
+ ### Ruby Version
140
+ - Target Ruby 3.0+ (`required_ruby_version >= 3.0.0`)
141
+
142
+ ### RuboCop Configuration
143
+ Key settings from `.rubocop.yml`:
144
+ - **Line length**: Max 120 characters
145
+ - **Method length**: Max 20 lines
146
+ - **Class length**: Max 150 lines
147
+ - **ABC size**: Max 25
148
+ - **Cyclomatic complexity**: Max 10
149
+ - Documentation cop is disabled
150
+
151
+ ### Naming Conventions
152
+ - **Module**: `JulesRuby` (camelCase)
153
+ - **Gem name**: `jules-ruby` (hyphenated, matching file paths)
154
+ - **Files**: Hyphenated to match gem name (`jules-ruby/` directory)
155
+
156
+ ### Architecture Patterns
157
+
158
+ 1. **Models** (`lib/jules-ruby/models/`): Plain Ruby objects with:
159
+ - `initialize(attributes = {})` accepting a hash
160
+ - Attribute readers for all fields
161
+ - Convenience methods for state checking (e.g., `session.completed?`)
162
+ - `from_api_response(data)` class method for parsing API responses
163
+
164
+ 2. **Resources** (`lib/jules-ruby/resources/`): API endpoint wrappers extending `Base`:
165
+ - `list(params)` - Returns `{ resource_name: [], next_page_token: nil }`
166
+ - `find(id)` - Returns single model instance
167
+ - `all(params)` - Fetches all pages, returns array
168
+ - `create(params)` - For writable resources
169
+
170
+ 3. **Client** (`lib/jules-ruby/client.rb`): Entry point providing:
171
+ - `client.sources`, `client.sessions`, `client.activities` resource accessors
172
+ - Uses `async-http` for HTTP requests
173
+ - Handles authentication via `Authorization: Bearer` header
174
+
175
+ 4. **CLI** (`lib/jules-ruby/cli.rb`): Thor-based commands:
176
+ - Subcommands: `sources`, `sessions`, `activities`, `interactive`
177
+ - Output formats: `--format=table` (default) or `--format=json`
178
+
179
+ ### CLI Color Theme
180
+
181
+ The interactive CLI uses a custom purple color theme defined in `lib/jules-ruby/cli/prompts.rb`:
182
+
183
+ ```ruby
184
+ COLORS = {
185
+ purple: [147, 112, 219], # #9370DB - menu items, values, content
186
+ lavender: [196, 181, 253], # #C4B5FD - labels, prompts
187
+ muted: [139, 92, 246], # #8B5CF6 - dividers, decorations
188
+ dim: [107, 114, 128] # #6B7280 - hints like "Press any key..."
189
+ }.freeze
190
+ ```
191
+
192
+ **Color helpers** (in `Prompts` module):
193
+ - `rgb_color(text, :color_name)` - Apply true-color ANSI escape sequences
194
+ - `highlight(text)` - Apply lavender color
195
+ - `muted(text)` - Apply dim color
196
+ - `divider` - Return a colored divider line
197
+
198
+ **When modifying CLI output**, use these helpers instead of raw strings to maintain the theme. The banner uses a separate HSL-based gradient in `banner.rb`.
199
+
200
+ ## Dependencies
201
+
202
+ ### Runtime
203
+ - `async-http ~> 0.75` - Async HTTP client
204
+ - `dotenv ~> 3.0` - Environment variable loading
205
+ - `thor ~> 1.3` - CLI framework
206
+ - `tty-prompt ~> 0.23` - Interactive prompts
207
+ - `tty-spinner ~> 0.9` - Loading spinners
208
+ - `pastel ~> 0.8` - Terminal output styling
209
+
210
+ ### Development
211
+ - `rspec ~> 3.0` - Testing
212
+ - `webmock ~> 3.0` - HTTP request stubbing
213
+ - `rubocop ~> 1.0` - Linting
214
+ - `simplecov ~> 0.22` - Code coverage
215
+
216
+ ## Configuration
217
+
218
+ The gem uses `JULES_API_KEY` from environment or `.env` file:
219
+
220
+ ```ruby
221
+ # Option 1: Environment variable
222
+ ENV['JULES_API_KEY'] = 'your_key'
223
+
224
+ # Option 2: Block configuration
225
+ JulesRuby.configure do |config|
226
+ config.api_key = 'your_key'
227
+ config.timeout = 60
228
+ end
229
+
230
+ # Option 3: Per-client
231
+ client = JulesRuby::Client.new(api_key: 'your_key')
232
+ ```
233
+
234
+ ## Error Handling
235
+
236
+ Custom errors in `lib/jules-ruby/errors.rb`:
237
+ - `JulesRuby::Error` - Base error class
238
+ - `JulesRuby::AuthenticationError` - 401/403 responses
239
+ - `JulesRuby::NotFoundError` - 404 responses
240
+ - `JulesRuby::RateLimitError` - 429 responses
241
+ - `JulesRuby::ServerError` - 5xx responses
242
+
243
+ ## API Reference
244
+
245
+ The gem wraps the Jules API documented at: https://developers.google.com/jules/api
246
+
247
+ Main resources:
248
+ - **Sources**: Connected GitHub repositories
249
+ - **Sessions**: Coding task sessions (create, approve plans, send messages)
250
+ - **Activities**: Session events/history (messages, plans, progress updates)
data/CHANGELOG.md ADDED
@@ -0,0 +1,20 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [0.0.67] - 2025-12-17
9
+
10
+ ### Added
11
+ - CLI with commands for sources, sessions, and activities
12
+ - Interactive TUI mode (`jules-ruby interactive`)
13
+ - JSON output format (`--format=json`)
14
+ - Ruby client library for Jules API
15
+ - Session management (create, approve, message, delete)
16
+ - Activity monitoring with pagination
17
+ - Source repository listing
18
+
19
+ ### Changed
20
+ - Initial public release
data/CONTRIBUTING.md ADDED
@@ -0,0 +1,82 @@
1
+ # Contributing to Jules Ruby
2
+
3
+ Thank you for your interest in contributing to jules-ruby!
4
+
5
+ ## Development Setup
6
+
7
+ 1. Fork and clone the repository:
8
+ ```bash
9
+ git clone https://github.com/YOUR_USERNAME/jules-ruby.git
10
+ cd jules-ruby
11
+ ```
12
+
13
+ 2. Install dependencies:
14
+ ```bash
15
+ bundle install
16
+ ```
17
+
18
+ 3. Set up your API key for testing:
19
+ ```bash
20
+ cp .env.example .env
21
+ # Edit .env with your Jules API key
22
+ ```
23
+
24
+ ## Running Tests
25
+
26
+ ```bash
27
+ # Run the test suite
28
+ bundle exec rspec
29
+
30
+ # Run with coverage report
31
+ COVERAGE=true bundle exec rspec
32
+
33
+ # Run linter
34
+ bundle exec rubocop
35
+
36
+ # Auto-fix linting issues
37
+ bundle exec rubocop -a
38
+ ```
39
+
40
+ ## Making Changes
41
+
42
+ 1. Create a feature branch:
43
+ ```bash
44
+ git checkout -b feature/your-feature-name
45
+ ```
46
+
47
+ 2. Make your changes and ensure:
48
+ - All tests pass (`bundle exec rspec`)
49
+ - Code follows style guidelines (`bundle exec rubocop`)
50
+ - New code has test coverage
51
+
52
+ 3. Commit with a clear message:
53
+ ```bash
54
+ git commit -m "Add feature: brief description"
55
+ ```
56
+
57
+ 4. Push and open a Pull Request
58
+
59
+ ## Pull Request Guidelines
60
+
61
+ - Keep PRs focused on a single change
62
+ - Update documentation if adding new features
63
+ - Add tests for new functionality
64
+ - Update CHANGELOG.md under "Unreleased" section
65
+
66
+ ## Release Process (Maintainers)
67
+
68
+ 1. Update version in `jules-ruby.gemspec`
69
+ 2. Update `CHANGELOG.md` with release notes
70
+ 3. Commit: `git commit -am "Bump version to X.Y.Z"`
71
+ 4. Tag: `git tag vX.Y.Z`
72
+ 5. Push: `git push origin main --tags`
73
+
74
+ The GitHub Actions release workflow will automatically:
75
+ - Build the gem
76
+ - Generate checksums
77
+ - Publish to RubyGems.org
78
+ - Create a GitHub Release
79
+
80
+ ## Code of Conduct
81
+
82
+ Be kind and respectful. We're all here to learn and build together.
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Taylor Weibley
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.