ruby_coded 0.1.1 → 0.2.1

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 (38) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop_todo.yml +3 -1
  3. data/CHANGELOG.md +29 -0
  4. data/README.md +15 -10
  5. data/lib/ruby_coded/auth/auth_manager.rb +20 -5
  6. data/lib/ruby_coded/auth/jwt_decoder.rb +29 -0
  7. data/lib/ruby_coded/auth/providers/openai.rb +19 -5
  8. data/lib/ruby_coded/chat/app/event_dispatch.rb +23 -3
  9. data/lib/ruby_coded/chat/app/login_handler.rb +79 -0
  10. data/lib/ruby_coded/chat/app/oauth_handler.rb +105 -0
  11. data/lib/ruby_coded/chat/app.rb +65 -6
  12. data/lib/ruby_coded/chat/codex_bridge/error_handling.rb +93 -0
  13. data/lib/ruby_coded/chat/codex_bridge/request_builder.rb +104 -0
  14. data/lib/ruby_coded/chat/codex_bridge/sse_parser.rb +136 -0
  15. data/lib/ruby_coded/chat/codex_bridge/token_manager.rb +45 -0
  16. data/lib/ruby_coded/chat/codex_bridge/tool_approval.rb +51 -0
  17. data/lib/ruby_coded/chat/codex_bridge/tool_handling.rb +128 -0
  18. data/lib/ruby_coded/chat/codex_bridge.rb +126 -0
  19. data/lib/ruby_coded/chat/codex_models.rb +41 -0
  20. data/lib/ruby_coded/chat/command_handler/login_commands.rb +33 -0
  21. data/lib/ruby_coded/chat/command_handler/model_commands.rb +19 -6
  22. data/lib/ruby_coded/chat/command_handler.rb +6 -2
  23. data/lib/ruby_coded/chat/help.txt +2 -0
  24. data/lib/ruby_coded/chat/input_handler/login_inputs.rb +66 -0
  25. data/lib/ruby_coded/chat/input_handler.rb +3 -0
  26. data/lib/ruby_coded/chat/renderer/chat_panel_input.rb +1 -1
  27. data/lib/ruby_coded/chat/renderer/login_flow.rb +105 -0
  28. data/lib/ruby_coded/chat/renderer/login_flow_layout.rb +65 -0
  29. data/lib/ruby_coded/chat/renderer/status_bar.rb +2 -1
  30. data/lib/ruby_coded/chat/renderer.rb +12 -3
  31. data/lib/ruby_coded/chat/state/login_flow.rb +117 -0
  32. data/lib/ruby_coded/chat/state/login_flow_steps.rb +69 -0
  33. data/lib/ruby_coded/chat/state.rb +25 -2
  34. data/lib/ruby_coded/initializer.rb +14 -3
  35. data/lib/ruby_coded/plugins/command_completion/state_extension.rb +1 -0
  36. data/lib/ruby_coded/strategies/oauth_strategy.rb +4 -3
  37. data/lib/ruby_coded/version.rb +1 -1
  38. metadata +33 -2
@@ -8,6 +8,7 @@ require_relative "state/scrollable"
8
8
  require_relative "state/tool_confirmation"
9
9
  require_relative "state/plan_tracking"
10
10
  require_relative "state/token_cost"
11
+ require_relative "state/login_flow"
11
12
 
12
13
  module RubyCoded
13
14
  module Chat
@@ -21,11 +22,12 @@ module RubyCoded
21
22
  include ToolConfirmation
22
23
  include PlanTracking
23
24
  include TokenCost
25
+ include LoginFlow
24
26
 
25
27
  attr_reader :input_buffer, :cursor_position, :input_scroll_offset, :messages, :scroll_offset,
26
28
  :mode, :model_list, :model_select_index, :model_select_filter,
27
- :streaming, :mutex
28
- attr_accessor :model, :should_quit
29
+ :streaming, :mutex, :tui_suspend_reason
30
+ attr_accessor :model, :should_quit, :codex_mode
29
31
 
30
32
  MIN_RENDER_INTERVAL = 0.05
31
33
 
@@ -39,6 +41,7 @@ module RubyCoded
39
41
  @streaming = false
40
42
  @should_quit = false
41
43
  @agentic_mode = false
44
+ @codex_mode = false
42
45
  @mutex = Mutex.new
43
46
  @dirty = true
44
47
  @last_render_at = 0.0
@@ -54,6 +57,7 @@ module RubyCoded
54
57
  init_tool_confirmation
55
58
  init_plan_tracking
56
59
  init_token_cost
60
+ init_login_flow
57
61
  init_plugin_state
58
62
  end
59
63
 
@@ -186,6 +190,25 @@ module RubyCoded
186
190
  input
187
191
  end
188
192
 
193
+ def request_tui_suspend!(reason, **metadata)
194
+ @tui_suspend_reason = reason
195
+ @tui_suspend_metadata = metadata
196
+ mark_dirty!
197
+ end
198
+
199
+ def tui_suspend_requested?
200
+ !@tui_suspend_reason.nil?
201
+ end
202
+
203
+ def tui_suspend_metadata
204
+ @tui_suspend_metadata || {}
205
+ end
206
+
207
+ def clear_tui_suspend!
208
+ @tui_suspend_reason = nil
209
+ @tui_suspend_metadata = nil
210
+ end
211
+
189
212
  private
190
213
 
191
214
  # Calls plugin state initializers (e.g. init_command_completion).
@@ -12,7 +12,7 @@ module RubyCoded
12
12
  # Initializer class for the RubyCoded gem (think of it as a main class)
13
13
  class Initializer
14
14
  PROVIDER_DEFAULT_MODELS = {
15
- openai: "gpt-5-codex",
15
+ openai: "gpt-5.4",
16
16
  anthropic: "claude-sonnet-4-6"
17
17
  }.freeze
18
18
 
@@ -20,6 +20,7 @@ module RubyCoded
20
20
  @user_cfg = UserConfig.new
21
21
  @prompt = TTY::Prompt.new
22
22
  @auth_manager = Auth::AuthManager.new
23
+ @fallback_from_model = nil
23
24
 
24
25
  ask_for_directory_permission unless @user_cfg.directory_trusted?
25
26
  @auth_manager.check_authentication
@@ -38,12 +39,22 @@ module RubyCoded
38
39
  end
39
40
 
40
41
  def start_chat
41
- Chat::App.new(model: resolved_chat_model, user_config: @user_cfg).run
42
+ model = resolved_chat_model
43
+ Chat::App.new(
44
+ model: model,
45
+ user_config: @user_cfg,
46
+ auth_manager: @auth_manager,
47
+ fallback_from_model: @fallback_from_model
48
+ ).run
42
49
  end
43
50
 
44
51
  def resolved_chat_model
45
52
  stored = @user_cfg.get_config("model")
46
- return stored.to_s if stored && !stored.to_s.strip.empty?
53
+ if stored && !stored.to_s.strip.empty?
54
+ return stored.to_s if @auth_manager.model_provider_authenticated?(stored.to_s)
55
+
56
+ @fallback_from_model = stored.to_s
57
+ end
47
58
 
48
59
  provider = @auth_manager.authenticated_provider_names.first
49
60
  PROVIDER_DEFAULT_MODELS.fetch(provider, RubyLLM.config.default_model).to_s
@@ -13,6 +13,7 @@ module RubyCoded
13
13
  "/tokens" => "Show detailed token usage and cost",
14
14
  "/agent" => "Toggle agent mode (on/off)",
15
15
  "/plan" => "Toggle plan mode (on/off/save)",
16
+ "/login" => "Authenticate with an AI provider",
16
17
  "/exit" => "Exit the chat",
17
18
  "/quit" => "Exit the chat"
18
19
  }.freeze
@@ -79,7 +79,7 @@ module RubyCoded
79
79
  end
80
80
 
81
81
  def build_auth_url(challenge, state)
82
- params = URI.encode_www_form(
82
+ params = {
83
83
  client_id: @provider.client_id,
84
84
  redirect_uri: @provider.redirect_uri,
85
85
  response_type: "code",
@@ -87,8 +87,9 @@ module RubyCoded
87
87
  code_challenge: challenge,
88
88
  code_challenge_method: "S256",
89
89
  state: state
90
- )
91
- "#{@provider.auth_url}?#{params}"
90
+ }
91
+ params.merge!(@provider.codex_auth_params) if @provider.respond_to?(:codex_auth_params)
92
+ "#{@provider.auth_url}?#{URI.encode_www_form(params)}"
92
93
  end
93
94
 
94
95
  def exchange_code(code, verifier)
@@ -2,7 +2,7 @@
2
2
 
3
3
  # This module contains the version of the RubyCoded gem
4
4
  module RubyCoded
5
- VERSION = "0.1.1"
5
+ VERSION = "0.2.1"
6
6
 
7
7
  def self.gem_version
8
8
  Gem::Version.new(VERSION).freeze
metadata CHANGED
@@ -1,15 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby_coded
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Cesar Rodriguez
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2026-04-15 00:00:00.000000000 Z
11
+ date: 2026-04-17 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: faraday
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '2.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '2.0'
13
27
  - !ruby/object:Gem::Dependency
14
28
  name: ratatui_ruby
15
29
  requirement: !ruby/object:Gem::Requirement
@@ -104,21 +118,34 @@ files:
104
118
  - lib/ruby_coded/auth/auth_manager.rb
105
119
  - lib/ruby_coded/auth/callback_servlet.rb
106
120
  - lib/ruby_coded/auth/credentials_store.rb
121
+ - lib/ruby_coded/auth/jwt_decoder.rb
107
122
  - lib/ruby_coded/auth/oauth_callback_server.rb
108
123
  - lib/ruby_coded/auth/pkce.rb
109
124
  - lib/ruby_coded/auth/providers/anthropic.rb
110
125
  - lib/ruby_coded/auth/providers/openai.rb
111
126
  - lib/ruby_coded/chat/app.rb
112
127
  - lib/ruby_coded/chat/app/event_dispatch.rb
128
+ - lib/ruby_coded/chat/app/login_handler.rb
129
+ - lib/ruby_coded/chat/app/oauth_handler.rb
130
+ - lib/ruby_coded/chat/codex_bridge.rb
131
+ - lib/ruby_coded/chat/codex_bridge/error_handling.rb
132
+ - lib/ruby_coded/chat/codex_bridge/request_builder.rb
133
+ - lib/ruby_coded/chat/codex_bridge/sse_parser.rb
134
+ - lib/ruby_coded/chat/codex_bridge/token_manager.rb
135
+ - lib/ruby_coded/chat/codex_bridge/tool_approval.rb
136
+ - lib/ruby_coded/chat/codex_bridge/tool_handling.rb
137
+ - lib/ruby_coded/chat/codex_models.rb
113
138
  - lib/ruby_coded/chat/command_handler.rb
114
139
  - lib/ruby_coded/chat/command_handler/agent_commands.rb
115
140
  - lib/ruby_coded/chat/command_handler/history_commands.rb
141
+ - lib/ruby_coded/chat/command_handler/login_commands.rb
116
142
  - lib/ruby_coded/chat/command_handler/model_commands.rb
117
143
  - lib/ruby_coded/chat/command_handler/plan_commands.rb
118
144
  - lib/ruby_coded/chat/command_handler/token_commands.rb
119
145
  - lib/ruby_coded/chat/command_handler/token_formatting.rb
120
146
  - lib/ruby_coded/chat/help.txt
121
147
  - lib/ruby_coded/chat/input_handler.rb
148
+ - lib/ruby_coded/chat/input_handler/login_inputs.rb
122
149
  - lib/ruby_coded/chat/input_handler/modal_inputs.rb
123
150
  - lib/ruby_coded/chat/input_handler/normal_mode_input.rb
124
151
  - lib/ruby_coded/chat/llm_bridge.rb
@@ -131,11 +158,15 @@ files:
131
158
  - lib/ruby_coded/chat/renderer/chat_panel.rb
132
159
  - lib/ruby_coded/chat/renderer/chat_panel_input.rb
133
160
  - lib/ruby_coded/chat/renderer/chat_panel_thinking.rb
161
+ - lib/ruby_coded/chat/renderer/login_flow.rb
162
+ - lib/ruby_coded/chat/renderer/login_flow_layout.rb
134
163
  - lib/ruby_coded/chat/renderer/model_selector.rb
135
164
  - lib/ruby_coded/chat/renderer/plan_clarifier.rb
136
165
  - lib/ruby_coded/chat/renderer/plan_clarifier_layout.rb
137
166
  - lib/ruby_coded/chat/renderer/status_bar.rb
138
167
  - lib/ruby_coded/chat/state.rb
168
+ - lib/ruby_coded/chat/state/login_flow.rb
169
+ - lib/ruby_coded/chat/state/login_flow_steps.rb
139
170
  - lib/ruby_coded/chat/state/message_assistant.rb
140
171
  - lib/ruby_coded/chat/state/message_token_tracking.rb
141
172
  - lib/ruby_coded/chat/state/messages.rb