internator 0.1.6 → 0.1.8

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6f09125886d45ef7715beec21a71c377bfc87c0bbda9961b43672d6f14bf483f
4
- data.tar.gz: 8af709fed7f4efbb39c9047ad38e341c38934d50d2dc09ee07cc45345be28edc
3
+ metadata.gz: 1d33b4fb255d17e002241c8d049c7ddae3ae67a91bc5047775a3805ab0b98328
4
+ data.tar.gz: 2ddd4787eecc43049ea2f548832fa448f18f5939c52a807f93d5ae4968da6193
5
5
  SHA512:
6
- metadata.gz: 5a33350b6d1b501be5607a7d5b60bf0cbd3118c6cb1ddd7d9bd3a2eefd7d0c7dee4b37776f704abb04312460661e716d42a89f88d0c56787644adc04a22fc5cb
7
- data.tar.gz: e844ba9e21223c9f2b10a9e420f4b3cf448c6d95074ba023feaf9612b64602e0ab517caaf443c3b3f38984d093cc6eed5f9b3ff7e4415d61471e88a574bc559a
6
+ metadata.gz: 8820879243003de78152d85a10b5ec1ba3b3b9738074f45b35ec7f518c13815809ab2bda9c944662db25bc5de8245895e7d8b3f6b5e435a08aa6ed1e645887a5
7
+ data.tar.gz: a764e5adf9a315fc5eab5d3cba3b3447ad3217973308c5ff5419e3b1696c7b6b76b019fc31bd64da25561d88709454a184f5af82f1aabdfb3a2359ec157efe90
data/README.md CHANGED
@@ -7,7 +7,7 @@ Internator is a Ruby-based CLI tool that automates iterative pull request improv
7
7
  ## Requirements
8
8
 
9
9
  - Ruby (>= 2.5).
10
- - [Codex CLI](https://github.com/openai/codex) installed (>= 0.3.0).
10
+ - [Codex CLI](https://github.com/openai/codex) installed (v 0.30.0).
11
11
  - Environment variable `OPENAI_API_KEY` set to your OpenAI API key.
12
12
 
13
13
  ## Installation
@@ -17,15 +17,15 @@ gem install internator
17
17
  ```
18
18
 
19
19
  ## Usage
20
-
21
- Push to Github your new empty branch and run the `internator` command:
20
+ Create your new empty branch and run the `internator` command:
22
21
 
23
22
  ```bash
24
- internator "<PR Objectives>" [delay_mins]
23
+ internator "<PR Objectives>" [delay_mins] [parent_branch]
25
24
  ```
26
25
 
27
- - `<PR Objectives>`: Description of what the pull request should achieve.
28
- - `[delay_mins]`: (Optional) Minutes to wait between commits (default: 0).
26
+ - `<PR Objectives>`: Description of what the pull request should achieve.
27
+ - `[delay_mins]`: (Optional) Minutes to wait between commits (default: 0).
28
+ - `[parent_branch]`: (Optional) Branch name to diff against (default: detected repository default branch).
29
29
 
30
30
  Example:
31
31
  ```bash
@@ -59,16 +59,42 @@ module Internator
59
59
  abort "❌ OPENAI_API_KEY not set. Please set the environment variable."
60
60
  end
61
61
 
62
- if args.empty? || args.size > 2
63
- abort "❌ Usage: internator \"<PR Objectives>\" [delay_mins]"
62
+ # Parse arguments: objectives, optional delay (minutes), optional parent_branch
63
+ if args.empty? || args.size > 3
64
+ abort "❌ Usage: internator \"<PR Objectives>\" [delay_mins] [parent_branch]"
64
65
  end
65
66
 
66
67
  objectives = args[0]
67
- delay_mins = if args[1]
68
- Integer(args[1]) rescue abort("❌ Invalid delay_mins: must be an integer")
69
- else
70
- 0
71
- end
68
+ delay_mins = 0
69
+ parent_branch = nil
70
+ case args.size
71
+ when 2
72
+ # single extra arg: integer delay or parent branch
73
+ begin
74
+ delay_mins = Integer(args[1])
75
+ rescue ArgumentError
76
+ parent_branch = args[1]
77
+ end
78
+ when 3
79
+ delay_mins = Integer(args[1]) rescue abort("❌ Invalid delay_mins: must be an integer")
80
+ parent_branch = args[2]
81
+ end
82
+
83
+ remote, default_base = git_detect_default_base&.split("/", 2)
84
+ branch = git_current_branch
85
+
86
+ abort "❌ Git remote is not detected." unless remote
87
+ abort "❌ Git default branch is not detected." unless default_base
88
+
89
+ if branch == default_base
90
+ abort "❌ You are on the default branch '#{default_base}'. Please create a new branch before running Internator."
91
+ end
92
+
93
+ if parent_branch && !system("git rev-parse --verify --quiet #{parent_branch} > /dev/null 2>&1")
94
+ abort "❌ Specified parent branch '#{parent_branch}' does not exist."
95
+ end
96
+
97
+ git_upstream(remote, branch)
72
98
 
73
99
  iteration = 1
74
100
  Signal.trap("INT") do
@@ -79,15 +105,14 @@ module Internator
79
105
  begin
80
106
  loop do
81
107
  puts "\n🌀 Iteration ##{iteration} - #{Time.now.strftime("%Y-%m-%d %H:%M:%S")}"
82
- exit_code = codex_cycle(objectives, iteration)
108
+
109
+ exit_code = codex_cycle(objectives, iteration, remote, default_base, branch, parent_branch)
83
110
  if exit_code != 0
84
- puts "🚨 Codex process exited with code #{exit_code}. Stopping."
85
- break
111
+ abort "🚨 Codex process exited with code #{exit_code}. Stopping."
86
112
  end
87
113
 
88
114
  if `git status --porcelain`.strip.empty?
89
- puts "🎉 Objectives completed; no new changes. Exiting loop..."
90
- break
115
+ abort "🎉 Objectives completed; no new changes. Exiting loop..."
91
116
  end
92
117
 
93
118
  auto_commit
@@ -103,7 +128,7 @@ module Internator
103
128
  end
104
129
 
105
130
  # Detect the repository's default branch across remotes (e.g., main, master, develop)
106
- def self.detect_default_base
131
+ def self.git_detect_default_base
107
132
  remotes = `git remote`.split("\n").reject(&:empty?)
108
133
  remotes.unshift('origin') unless remotes.include?('origin')
109
134
  remotes.each do |remote|
@@ -119,23 +144,27 @@ module Internator
119
144
  nil
120
145
  end
121
146
 
122
- # Executes one Codex iteration by diffing against the appropriate base branch
123
- def self.codex_cycle(objectives, iteration)
124
- # Determine configured upstream and current branch name
147
+ def self.git_current_branch
148
+ `git rev-parse --abbrev-ref HEAD`.strip
149
+ end
150
+
151
+ def self.git_upstream(remote, branch)
125
152
  upstream = `git rev-parse --abbrev-ref --symbolic-full-name @{u} 2>/dev/null`.strip
126
- current_branch = `git rev-parse --abbrev-ref HEAD`.strip
127
- # Choose diff base:
128
- # 1) If upstream is tracking current branch, use remote default branch
129
- # 2) Else if upstream exists, diff against that
130
- # 3) Otherwise fallback to remote default branch or master
131
- if !upstream.empty? && upstream.split('/').last == current_branch
132
- base = detect_default_base || upstream
133
- elsif !upstream.empty?
134
- base = upstream
135
- else
136
- base = detect_default_base || 'master'
153
+
154
+ if upstream.empty?
155
+ # As upstream is not configured, push the current branch and set upstream to remote
156
+ puts "🔄 No upstream configured for branch '#{branch}'. Sending to #{remote}..."
157
+ system("git push -u #{remote} #{branch}")
158
+ upstream = `git rev-parse --abbrev-ref --symbolic-full-name @{u} 2>/dev/null`.strip
137
159
  end
138
- # Get the diff against the chosen base
160
+
161
+ upstream
162
+ end
163
+
164
+ # Executes one Codex iteration by diffing against the parent or default branch
165
+ def self.codex_cycle(objectives, iteration, remote, default_base, branch, parent_branch = nil)
166
+ # Determine base branch: user-specified parent or detected default
167
+ base = parent_branch || default_base
139
168
  current_diff = `git diff #{base} 2>/dev/null`
140
169
  current_diff = "No initial changes" if current_diff.strip.empty?
141
170
  prompt = <<~PROMPT
@@ -12,6 +12,8 @@ module Internator
12
12
  command = [
13
13
  "codex",
14
14
  "exec",
15
+ "-c",
16
+ "preferred_auth_method=apikey",
15
17
  "--full-auto",
16
18
  @instruction
17
19
  ]
@@ -1,3 +1,3 @@
1
1
  module Internator
2
- VERSION = "0.1.6"
2
+ VERSION = "0.1.8"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: internator
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.6
4
+ version: 0.1.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - AlexLarra