ruby_coded 0.3.1 → 0.4.0
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 +4 -4
- data/CHANGELOG.md +20 -0
- data/README.md +113 -1
- data/lib/ruby_coded/chat/app.rb +35 -34
- data/lib/ruby_coded/chat/bridge_common/auto_switch.rb +45 -0
- data/lib/ruby_coded/chat/bridge_common/mode_transitions.rb +70 -0
- data/lib/ruby_coded/chat/bridge_common/tool_flow.rb +61 -0
- data/lib/ruby_coded/chat/bridge_common.rb +31 -0
- data/lib/ruby_coded/chat/bridge_factory.rb +61 -0
- data/lib/ruby_coded/chat/codex_bridge/error_handling.rb +1 -20
- data/lib/ruby_coded/chat/codex_bridge/request_builder.rb +3 -15
- data/lib/ruby_coded/chat/codex_bridge/tool_approval.rb +8 -32
- data/lib/ruby_coded/chat/codex_bridge/tool_handling.rb +3 -34
- data/lib/ruby_coded/chat/codex_bridge.rb +31 -46
- data/lib/ruby_coded/chat/command_handler/agent_commands.rb +3 -3
- data/lib/ruby_coded/chat/command_handler/plan_commands.rb +1 -1
- data/lib/ruby_coded/chat/command_handler/skill_commands.rb +87 -0
- data/lib/ruby_coded/chat/command_handler.rb +3 -0
- data/lib/ruby_coded/chat/llm_bridge/chat_configuration.rb +38 -0
- data/lib/ruby_coded/chat/llm_bridge/plan_mode.rb +3 -32
- data/lib/ruby_coded/chat/llm_bridge/tool_call_handling.rb +9 -50
- data/lib/ruby_coded/chat/llm_bridge.rb +31 -65
- data/lib/ruby_coded/chat/prompt_builder.rb +66 -0
- data/lib/ruby_coded/chat/renderer/chat_panel.rb +48 -62
- data/lib/ruby_coded/chat/renderer/chat_panel_cache.rb +35 -0
- data/lib/ruby_coded/chat/renderer/chat_panel_formatting.rb +72 -0
- data/lib/ruby_coded/chat/renderer/chat_panel_layout.rb +81 -0
- data/lib/ruby_coded/chat/renderer/chat_panel_sections.rb +93 -0
- data/lib/ruby_coded/chat/renderer/chat_panel_thinking.rb +20 -34
- data/lib/ruby_coded/chat/renderer/chat_panel_thinking_render.rb +49 -0
- data/lib/ruby_coded/chat/renderer/rich_text.rb +92 -0
- data/lib/ruby_coded/chat/renderer/rich_text_inline.rb +81 -0
- data/lib/ruby_coded/chat/renderer.rb +12 -0
- data/lib/ruby_coded/chat/runtime_mode.rb +97 -0
- data/lib/ruby_coded/commands/core_provider.rb +7 -0
- data/lib/ruby_coded/commands.rb +11 -0
- data/lib/ruby_coded/plugins.rb +10 -1
- data/lib/ruby_coded/skills/catalog.rb +103 -0
- data/lib/ruby_coded/skills/markdown_loader.rb +112 -0
- data/lib/ruby_coded/skills/prompt_formatter.rb +42 -0
- data/lib/ruby_coded/skills/skill_definition.rb +29 -0
- data/lib/ruby_coded/skills.rb +18 -0
- data/lib/ruby_coded/tools/base_tool.rb +14 -0
- data/lib/ruby_coded/tools/delete_path_tool.rb +5 -8
- data/lib/ruby_coded/tools/edit_file_tool.rb +6 -8
- data/lib/ruby_coded/tools/execution_pipeline.rb +60 -0
- data/lib/ruby_coded/tools/execution_policy.rb +89 -0
- data/lib/ruby_coded/tools/write_file_tool.rb +6 -9
- data/lib/ruby_coded/version.rb +1 -1
- data/lib/ruby_coded.rb +1 -0
- metadata +25 -2
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RubyCoded
|
|
4
|
+
module Skills
|
|
5
|
+
# Formats active skills for prompt injection.
|
|
6
|
+
module PromptFormatter
|
|
7
|
+
def self.append(base_instructions, skills)
|
|
8
|
+
skills = Array(skills)
|
|
9
|
+
return base_instructions if skills.empty?
|
|
10
|
+
|
|
11
|
+
<<~PROMPT
|
|
12
|
+
#{base_instructions}
|
|
13
|
+
|
|
14
|
+
## Active project skills
|
|
15
|
+
|
|
16
|
+
Apply the following project-local skills when relevant. If a skill conflicts with higher-priority system instructions or the user's explicit request, follow the higher-priority instruction.
|
|
17
|
+
|
|
18
|
+
#{format_skills(skills)}
|
|
19
|
+
PROMPT
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def self.format_skills(skills)
|
|
23
|
+
skills.map { |skill| format_skill(skill) }.join("\n\n")
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def self.format_skill(skill)
|
|
27
|
+
(["### #{skill.name}"] + skill_metadata_lines(skill) + ["", skill.content.to_s]).join("\n")
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def self.skill_metadata_lines(skill)
|
|
31
|
+
description = skill.description.to_s
|
|
32
|
+
trigger = skill.trigger.to_s
|
|
33
|
+
[
|
|
34
|
+
(description unless description.empty?),
|
|
35
|
+
"Modes: #{skill.modes.join(", ")}",
|
|
36
|
+
("Tags: #{skill.tags.join(", ")}" if skill.tags.any?),
|
|
37
|
+
("Trigger: #{trigger}" unless trigger.empty?)
|
|
38
|
+
].compact
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RubyCoded
|
|
4
|
+
module Skills
|
|
5
|
+
# Normalized project-local skill metadata.
|
|
6
|
+
class SkillDefinition
|
|
7
|
+
ATTRIBUTES = %i[name description modes content path priority tags trigger].freeze
|
|
8
|
+
|
|
9
|
+
attr_reader(*ATTRIBUTES)
|
|
10
|
+
|
|
11
|
+
def initialize(**attrs)
|
|
12
|
+
ATTRIBUTES.each { |attr| instance_variable_set(ivar(attr), attrs[attr]) }
|
|
13
|
+
@modes = Array(@modes).map(&:to_s)
|
|
14
|
+
@tags = Array(@tags).map(&:to_s)
|
|
15
|
+
@priority = (@priority || 0).to_i
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def applies_to_mode?(mode)
|
|
19
|
+
@modes.include?(mode.to_s)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
private
|
|
23
|
+
|
|
24
|
+
def ivar(name)
|
|
25
|
+
:"@#{name}"
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Skills are **automatic instruction overlays** applied to the
|
|
4
|
+
# system prompt for a given mode.
|
|
5
|
+
#
|
|
6
|
+
# The user does not invoke a skill directly; the PromptBuilder
|
|
7
|
+
# consults the Skills::Catalog for the active RuntimeMode and
|
|
8
|
+
# appends the relevant skills to the final instructions. Skills
|
|
9
|
+
# are defined as markdown files under `.rubycoded/skills`.
|
|
10
|
+
#
|
|
11
|
+
# See also:
|
|
12
|
+
# - RubyCoded::Commands — explicit user-invoked slash actions.
|
|
13
|
+
# - RubyCoded::Plugins — code-level behavioral extensions.
|
|
14
|
+
|
|
15
|
+
require_relative "skills/skill_definition"
|
|
16
|
+
require_relative "skills/markdown_loader"
|
|
17
|
+
require_relative "skills/catalog"
|
|
18
|
+
require_relative "skills/prompt_formatter"
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
require "ruby_llm"
|
|
4
4
|
require_relative "tool_rejected_error"
|
|
5
|
+
require_relative "execution_pipeline"
|
|
5
6
|
|
|
6
7
|
module RubyCoded
|
|
7
8
|
module Tools
|
|
@@ -28,6 +29,19 @@ module RubyCoded
|
|
|
28
29
|
|
|
29
30
|
private
|
|
30
31
|
|
|
32
|
+
# Runs the shared execution pipeline (path validation, project-root
|
|
33
|
+
# guard, filesystem error normalization) around the given block.
|
|
34
|
+
# Prefer this over calling validate_path! directly for tools that
|
|
35
|
+
# need the full pipeline; use validate_path! when only path
|
|
36
|
+
# resolution is required (e.g. read-only tools with custom flows).
|
|
37
|
+
def run_pipeline(path: nil, forbid_root: false, &)
|
|
38
|
+
pipeline.call(path: path, forbid_root: forbid_root, &)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def pipeline
|
|
42
|
+
@pipeline ||= ExecutionPipeline.new(project_root: @project_root)
|
|
43
|
+
end
|
|
44
|
+
|
|
31
45
|
def resolve_path(relative_path)
|
|
32
46
|
expanded = File.expand_path(relative_path, @project_root)
|
|
33
47
|
File.realpath(expanded)
|
|
@@ -15,14 +15,11 @@ module RubyCoded
|
|
|
15
15
|
end
|
|
16
16
|
|
|
17
17
|
def execute(path:)
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
perform_delete(path, full_path)
|
|
24
|
-
rescue SystemCallError => e
|
|
25
|
-
{ error: "Failed to delete #{path}: #{e.message}" }
|
|
18
|
+
run_pipeline(path: path, forbid_root: true) do |full_path|
|
|
19
|
+
next { error: "Path not found: #{path}" } unless File.exist?(full_path)
|
|
20
|
+
|
|
21
|
+
perform_delete(path, full_path)
|
|
22
|
+
end
|
|
26
23
|
end
|
|
27
24
|
|
|
28
25
|
private
|
|
@@ -16,14 +16,12 @@ module RubyCoded
|
|
|
16
16
|
end
|
|
17
17
|
|
|
18
18
|
def execute(path:, old_text:, new_text:)
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
rescue SystemCallError => e
|
|
26
|
-
{ error: "Failed to edit #{path}: #{e.message}" }
|
|
19
|
+
run_pipeline(path: path) do |full_path|
|
|
20
|
+
next { error: "File not found: #{path}" } unless File.exist?(full_path)
|
|
21
|
+
next { error: "Not a file: #{path}" } unless File.file?(full_path)
|
|
22
|
+
|
|
23
|
+
apply_edit(path, full_path, old_text, new_text)
|
|
24
|
+
end
|
|
27
25
|
end
|
|
28
26
|
|
|
29
27
|
private
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RubyCoded
|
|
4
|
+
module Tools
|
|
5
|
+
# Standardizes the internal execution flow shared by side-effecting tools:
|
|
6
|
+
# 1. validate input (project-relative path if given)
|
|
7
|
+
# 2. resolve to an absolute path inside the project root
|
|
8
|
+
# 3. optionally forbid operating on the project root itself
|
|
9
|
+
# 4. execute the tool's business logic (via block)
|
|
10
|
+
# 5. normalize filesystem errors into a structured response
|
|
11
|
+
#
|
|
12
|
+
# Policy, risk assessment and user approval intentionally live outside
|
|
13
|
+
# this pipeline: they are handled by Tools::ExecutionPolicy and by the
|
|
14
|
+
# bridges (BridgeCommon::ToolFlow), which sit above tool execution.
|
|
15
|
+
class ExecutionPipeline
|
|
16
|
+
def initialize(project_root:)
|
|
17
|
+
@project_root = File.realpath(project_root)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# Runs the pipeline. Yields the resolved full_path (or nil if `path`
|
|
21
|
+
# was not provided) to the caller-supplied block, which returns the
|
|
22
|
+
# tool result — either a success value (string/hash without :error)
|
|
23
|
+
# or an error hash of the form { error: "..." }.
|
|
24
|
+
#
|
|
25
|
+
# Any SystemCallError raised inside the block is normalized to an
|
|
26
|
+
# error hash.
|
|
27
|
+
def call(path: nil, forbid_root: false)
|
|
28
|
+
full_path = nil
|
|
29
|
+
if path
|
|
30
|
+
full_path = resolve_and_validate(path)
|
|
31
|
+
return full_path if full_path.is_a?(Hash)
|
|
32
|
+
return { error: "Cannot operate on the project root" } if forbid_root && full_path == @project_root
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
yield(full_path)
|
|
36
|
+
rescue SystemCallError => e
|
|
37
|
+
{ error: "Filesystem error: #{e.message}" }
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
private
|
|
41
|
+
|
|
42
|
+
def resolve_and_validate(relative_path)
|
|
43
|
+
expanded = File.expand_path(relative_path, @project_root)
|
|
44
|
+
full_path = begin
|
|
45
|
+
File.realpath(expanded)
|
|
46
|
+
rescue Errno::ENOENT
|
|
47
|
+
expanded
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
return full_path if inside_project?(full_path)
|
|
51
|
+
|
|
52
|
+
{ error: "Path is outside the project directory. Only paths within #{@project_root} are allowed." }
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def inside_project?(full_path)
|
|
56
|
+
full_path.start_with?(@project_root)
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "base_tool"
|
|
4
|
+
require_relative "agent_iteration_limit_error"
|
|
5
|
+
|
|
6
|
+
module RubyCoded
|
|
7
|
+
module Tools
|
|
8
|
+
# Centralizes runtime safety policy for tool execution:
|
|
9
|
+
#
|
|
10
|
+
# - risk lookup (delegated to the registry),
|
|
11
|
+
# - call budgeting (write vs total rounds, warning threshold),
|
|
12
|
+
# - confirmation requirement based on risk, mode, and auto-approve.
|
|
13
|
+
#
|
|
14
|
+
# Both LLMBridge and CodexBridge share a policy instance so
|
|
15
|
+
# limits and approval rules stay consistent across backends.
|
|
16
|
+
class ExecutionPolicy
|
|
17
|
+
MAX_WRITE_TOOL_ROUNDS = 50
|
|
18
|
+
MAX_TOTAL_TOOL_ROUNDS = 200
|
|
19
|
+
WARNING_THRESHOLD_RATIO = 0.8
|
|
20
|
+
|
|
21
|
+
def initialize(state:, registry:)
|
|
22
|
+
@state = state
|
|
23
|
+
@registry = registry
|
|
24
|
+
reset_counters!
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def reset_counters!
|
|
28
|
+
@tool_call_count = 0
|
|
29
|
+
@write_tool_call_count = 0
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def risk_for(tool_name)
|
|
33
|
+
@registry.risk_level_for(tool_name)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# Records the call, enforces hard limits, and returns the risk level.
|
|
37
|
+
# Raises AgentIterationLimitError when the total budget is exceeded.
|
|
38
|
+
def register_call!(tool_name)
|
|
39
|
+
risk = risk_for(tool_name)
|
|
40
|
+
@tool_call_count += 1
|
|
41
|
+
@write_tool_call_count += 1 unless risk == BaseTool::SAFE_RISK
|
|
42
|
+
enforce_limits!
|
|
43
|
+
risk
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def warn_if_approaching_limit!
|
|
47
|
+
threshold = warning_threshold
|
|
48
|
+
return unless @tool_call_count == threshold
|
|
49
|
+
|
|
50
|
+
remaining = MAX_TOTAL_TOOL_ROUNDS - threshold
|
|
51
|
+
@state.add_message(:system,
|
|
52
|
+
"Approaching total tool call limit: #{remaining} calls remaining. " \
|
|
53
|
+
"Prioritize completing the most important work.")
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
# True when the user must confirm this call before it runs.
|
|
57
|
+
def requires_confirmation?(risk, mode)
|
|
58
|
+
return false if risk == BaseTool::SAFE_RISK
|
|
59
|
+
return false if @state.auto_approve_tools?
|
|
60
|
+
|
|
61
|
+
mode.requires_confirmation?
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def risk_label_for(risk)
|
|
65
|
+
risk == BaseTool::DANGEROUS_RISK ? "DANGEROUS" : "WRITE"
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
private
|
|
69
|
+
|
|
70
|
+
def warning_threshold
|
|
71
|
+
(MAX_TOTAL_TOOL_ROUNDS * WARNING_THRESHOLD_RATIO).to_i
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def enforce_limits!
|
|
75
|
+
if @write_tool_call_count >= MAX_WRITE_TOOL_ROUNDS
|
|
76
|
+
@write_tool_call_count = 0
|
|
77
|
+
@state.add_message(:system,
|
|
78
|
+
"Write tool call budget (#{MAX_WRITE_TOOL_ROUNDS}) reached — auto-resetting counter.")
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
return unless @tool_call_count > MAX_TOTAL_TOOL_ROUNDS
|
|
82
|
+
|
|
83
|
+
raise AgentIterationLimitError,
|
|
84
|
+
"Reached maximum of #{MAX_TOTAL_TOOL_ROUNDS} total tool calls. " \
|
|
85
|
+
"Send a new message to continue, or use /agent on to reset counters."
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
end
|
|
@@ -15,16 +15,13 @@ module RubyCoded
|
|
|
15
15
|
end
|
|
16
16
|
|
|
17
17
|
def execute(path:, content:)
|
|
18
|
-
|
|
19
|
-
|
|
18
|
+
run_pipeline(path: path) do |full_path|
|
|
19
|
+
dir = File.dirname(full_path)
|
|
20
|
+
FileUtils.mkdir_p(dir) unless File.directory?(dir)
|
|
20
21
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
File.write(full_path, content)
|
|
25
|
-
"File written: #{path} (#{content.bytesize} bytes)"
|
|
26
|
-
rescue SystemCallError => e
|
|
27
|
-
{ error: "Failed to write #{path}: #{e.message}" }
|
|
22
|
+
File.write(full_path, content)
|
|
23
|
+
"File written: #{path} (#{content.bytesize} bytes)"
|
|
24
|
+
end
|
|
28
25
|
end
|
|
29
26
|
end
|
|
30
27
|
end
|
data/lib/ruby_coded/version.rb
CHANGED
data/lib/ruby_coded.rb
CHANGED
|
@@ -6,6 +6,7 @@ require_relative "ruby_coded/auth/auth_manager"
|
|
|
6
6
|
require_relative "ruby_coded/initializer"
|
|
7
7
|
require_relative "ruby_coded/plugins"
|
|
8
8
|
require_relative "ruby_coded/commands"
|
|
9
|
+
require_relative "ruby_coded/skills"
|
|
9
10
|
|
|
10
11
|
raise "This gem requires Ruby 3.3.0 or higher" if Gem::Version.new(RUBY_VERSION) < Gem::Version.new("3.3.0")
|
|
11
12
|
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: ruby_coded
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.4.0
|
|
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-
|
|
11
|
+
date: 2026-07-04 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: faraday
|
|
@@ -127,6 +127,11 @@ files:
|
|
|
127
127
|
- lib/ruby_coded/chat/app/event_dispatch.rb
|
|
128
128
|
- lib/ruby_coded/chat/app/login_handler.rb
|
|
129
129
|
- lib/ruby_coded/chat/app/oauth_handler.rb
|
|
130
|
+
- lib/ruby_coded/chat/bridge_common.rb
|
|
131
|
+
- lib/ruby_coded/chat/bridge_common/auto_switch.rb
|
|
132
|
+
- lib/ruby_coded/chat/bridge_common/mode_transitions.rb
|
|
133
|
+
- lib/ruby_coded/chat/bridge_common/tool_flow.rb
|
|
134
|
+
- lib/ruby_coded/chat/bridge_factory.rb
|
|
130
135
|
- lib/ruby_coded/chat/codex_bridge.rb
|
|
131
136
|
- lib/ruby_coded/chat/codex_bridge/error_handling.rb
|
|
132
137
|
- lib/ruby_coded/chat/codex_bridge/request_builder.rb
|
|
@@ -142,6 +147,7 @@ files:
|
|
|
142
147
|
- lib/ruby_coded/chat/command_handler/login_commands.rb
|
|
143
148
|
- lib/ruby_coded/chat/command_handler/model_commands.rb
|
|
144
149
|
- lib/ruby_coded/chat/command_handler/plan_commands.rb
|
|
150
|
+
- lib/ruby_coded/chat/command_handler/skill_commands.rb
|
|
145
151
|
- lib/ruby_coded/chat/command_handler/token_commands.rb
|
|
146
152
|
- lib/ruby_coded/chat/command_handler/token_formatting.rb
|
|
147
153
|
- lib/ruby_coded/chat/help.txt
|
|
@@ -150,21 +156,31 @@ files:
|
|
|
150
156
|
- lib/ruby_coded/chat/input_handler/modal_inputs.rb
|
|
151
157
|
- lib/ruby_coded/chat/input_handler/normal_mode_input.rb
|
|
152
158
|
- lib/ruby_coded/chat/llm_bridge.rb
|
|
159
|
+
- lib/ruby_coded/chat/llm_bridge/chat_configuration.rb
|
|
153
160
|
- lib/ruby_coded/chat/llm_bridge/plan_mode.rb
|
|
154
161
|
- lib/ruby_coded/chat/llm_bridge/streaming_retries.rb
|
|
155
162
|
- lib/ruby_coded/chat/llm_bridge/tool_call_handling.rb
|
|
156
163
|
- lib/ruby_coded/chat/model_filter.rb
|
|
157
164
|
- lib/ruby_coded/chat/plan_clarification_parser.rb
|
|
165
|
+
- lib/ruby_coded/chat/prompt_builder.rb
|
|
158
166
|
- lib/ruby_coded/chat/renderer.rb
|
|
159
167
|
- lib/ruby_coded/chat/renderer/chat_panel.rb
|
|
168
|
+
- lib/ruby_coded/chat/renderer/chat_panel_cache.rb
|
|
169
|
+
- lib/ruby_coded/chat/renderer/chat_panel_formatting.rb
|
|
160
170
|
- lib/ruby_coded/chat/renderer/chat_panel_input.rb
|
|
171
|
+
- lib/ruby_coded/chat/renderer/chat_panel_layout.rb
|
|
172
|
+
- lib/ruby_coded/chat/renderer/chat_panel_sections.rb
|
|
161
173
|
- lib/ruby_coded/chat/renderer/chat_panel_thinking.rb
|
|
174
|
+
- lib/ruby_coded/chat/renderer/chat_panel_thinking_render.rb
|
|
162
175
|
- lib/ruby_coded/chat/renderer/login_flow.rb
|
|
163
176
|
- lib/ruby_coded/chat/renderer/login_flow_layout.rb
|
|
164
177
|
- lib/ruby_coded/chat/renderer/model_selector.rb
|
|
165
178
|
- lib/ruby_coded/chat/renderer/plan_clarifier.rb
|
|
166
179
|
- lib/ruby_coded/chat/renderer/plan_clarifier_layout.rb
|
|
180
|
+
- lib/ruby_coded/chat/renderer/rich_text.rb
|
|
181
|
+
- lib/ruby_coded/chat/renderer/rich_text_inline.rb
|
|
167
182
|
- lib/ruby_coded/chat/renderer/status_bar.rb
|
|
183
|
+
- lib/ruby_coded/chat/runtime_mode.rb
|
|
168
184
|
- lib/ruby_coded/chat/state.rb
|
|
169
185
|
- lib/ruby_coded/chat/state/context_window.rb
|
|
170
186
|
- lib/ruby_coded/chat/state/login_flow.rb
|
|
@@ -195,6 +211,11 @@ files:
|
|
|
195
211
|
- lib/ruby_coded/plugins/command_completion/renderer_extension.rb
|
|
196
212
|
- lib/ruby_coded/plugins/command_completion/state_extension.rb
|
|
197
213
|
- lib/ruby_coded/plugins/registry.rb
|
|
214
|
+
- lib/ruby_coded/skills.rb
|
|
215
|
+
- lib/ruby_coded/skills/catalog.rb
|
|
216
|
+
- lib/ruby_coded/skills/markdown_loader.rb
|
|
217
|
+
- lib/ruby_coded/skills/prompt_formatter.rb
|
|
218
|
+
- lib/ruby_coded/skills/skill_definition.rb
|
|
198
219
|
- lib/ruby_coded/strategies/api_key_strategy.rb
|
|
199
220
|
- lib/ruby_coded/strategies/base.rb
|
|
200
221
|
- lib/ruby_coded/strategies/oauth_strategy.rb
|
|
@@ -204,6 +225,8 @@ files:
|
|
|
204
225
|
- lib/ruby_coded/tools/create_directory_tool.rb
|
|
205
226
|
- lib/ruby_coded/tools/delete_path_tool.rb
|
|
206
227
|
- lib/ruby_coded/tools/edit_file_tool.rb
|
|
228
|
+
- lib/ruby_coded/tools/execution_pipeline.rb
|
|
229
|
+
- lib/ruby_coded/tools/execution_policy.rb
|
|
207
230
|
- lib/ruby_coded/tools/git_add_tool.rb
|
|
208
231
|
- lib/ruby_coded/tools/git_base_tool.rb
|
|
209
232
|
- lib/ruby_coded/tools/git_commit_tool.rb
|