genie_cli 0.1.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.
- checksums.yaml +7 -0
- data/LICENSE +21 -0
- data/README.md +107 -0
- data/Rakefile +8 -0
- data/bin/genie +8 -0
- data/lib/genie/cli.rb +20 -0
- data/lib/genie/sandboxed_file_tool.rb +22 -0
- data/lib/genie/session.rb +83 -0
- data/lib/genie/session_config.rb +110 -0
- data/lib/genie/version.rb +3 -0
- data/lib/genie.rb +69 -0
- data/lib/tools/append_to_file.rb +33 -0
- data/lib/tools/ask_for_help.rb +14 -0
- data/lib/tools/insert_into_file.rb +58 -0
- data/lib/tools/list_files.rb +61 -0
- data/lib/tools/read_file.rb +34 -0
- data/lib/tools/rename_file.rb +45 -0
- data/lib/tools/replace_lines_in_file.rb +58 -0
- data/lib/tools/run_tests.rb +38 -0
- data/lib/tools/take_a_note.rb +14 -0
- data/lib/tools/write_file.rb +38 -0
- data/test/data/sample_config.yml +5 -0
- data/test/data/sample_files/a_dir/two.txt +0 -0
- data/test/data/sample_files/one.txt +0 -0
- data/test/data/sample_files/read_file_test.txt +3 -0
- data/test/test_cli.rb +11 -0
- data/test/test_helper.rb +5 -0
- data/test/test_session.rb +13 -0
- data/test/test_session_config.rb +55 -0
- data/test/tools/test_append_to_file.rb +29 -0
- data/test/tools/test_insert_into_file.rb +97 -0
- data/test/tools/test_list_files.rb +31 -0
- data/test/tools/test_read_file.rb +26 -0
- data/test/tools/test_rename_file.rb +76 -0
- data/test/tools/test_replace_lines_in_file.rb +141 -0
- data/test/tools/test_run_tests.rb +9 -0
- data/test/tools/test_take_a_note.rb +11 -0
- data/test/tools/test_write_file.rb +17 -0
- metadata +179 -0
@@ -0,0 +1,141 @@
|
|
1
|
+
require "tmpdir"
|
2
|
+
|
3
|
+
class TestReplaceLinesInFile < TLDR
|
4
|
+
def test_replace_middle
|
5
|
+
Dir.mktmpdir do |dir|
|
6
|
+
file = "#{dir}/test.txt"
|
7
|
+
File.write(file, "A\nB\nC\nD\nE\n")
|
8
|
+
|
9
|
+
result = Genie::ReplaceLinesInFile.new(base_path: dir).execute(
|
10
|
+
filepath: file,
|
11
|
+
start_line: 1,
|
12
|
+
end_line: 3,
|
13
|
+
content: "X\nY\n"
|
14
|
+
)
|
15
|
+
assert_equal true, result[:success]
|
16
|
+
|
17
|
+
actual = File.read(file)
|
18
|
+
expected = "A\nX\nY\nE\n"
|
19
|
+
assert_equal expected, actual
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_replace_beginning
|
24
|
+
Dir.mktmpdir do |dir|
|
25
|
+
file = "#{dir}/test.txt"
|
26
|
+
File.write(file, "Line1\nLine2\nLine3\n")
|
27
|
+
|
28
|
+
result = Genie::ReplaceLinesInFile.new(base_path: dir).execute(
|
29
|
+
filepath: file,
|
30
|
+
start_line: 0,
|
31
|
+
end_line: 0,
|
32
|
+
content: "New1\n"
|
33
|
+
)
|
34
|
+
assert_equal true, result[:success]
|
35
|
+
|
36
|
+
actual = File.read(file)
|
37
|
+
expected = "New1\nLine2\nLine3\n"
|
38
|
+
assert_equal expected, actual
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def test_replace_end
|
43
|
+
Dir.mktmpdir do |dir|
|
44
|
+
file = "#{dir}/test.txt"
|
45
|
+
File.write(file, "1\n2\n3\n4\n")
|
46
|
+
|
47
|
+
result = Genie::ReplaceLinesInFile.new(base_path: dir).execute(
|
48
|
+
filepath: file,
|
49
|
+
start_line: 3,
|
50
|
+
end_line: 3,
|
51
|
+
content: "End\n"
|
52
|
+
)
|
53
|
+
assert_equal true, result[:success]
|
54
|
+
|
55
|
+
actual = File.read(file)
|
56
|
+
expected = "1\n2\n3\nEnd\n"
|
57
|
+
assert_equal expected, actual
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def test_replace_multiple_to_end
|
62
|
+
Dir.mktmpdir do |dir|
|
63
|
+
file = "#{dir}/test.txt"
|
64
|
+
File.write(file, "A\nB\nC\nD\n")
|
65
|
+
|
66
|
+
result = Genie::ReplaceLinesInFile.new(base_path: dir).execute(
|
67
|
+
filepath: file,
|
68
|
+
start_line: 2,
|
69
|
+
end_line: 3,
|
70
|
+
content: "X\n"
|
71
|
+
)
|
72
|
+
assert_equal true, result[:success]
|
73
|
+
|
74
|
+
actual = File.read(file)
|
75
|
+
expected = "A\nB\nX\n"
|
76
|
+
assert_equal expected, actual
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def test_error_for_invalid_indices
|
81
|
+
Dir.mktmpdir do |dir|
|
82
|
+
file = "#{dir}/test.txt"
|
83
|
+
File.write(file, "Only one line\n")
|
84
|
+
|
85
|
+
# negative start
|
86
|
+
result = Genie::ReplaceLinesInFile.new(base_path: dir).execute(
|
87
|
+
filepath: file,
|
88
|
+
start_line: -1,
|
89
|
+
end_line: 0,
|
90
|
+
content: "X\n"
|
91
|
+
)
|
92
|
+
assert result[:error]&.include?("Invalid line numbers"), "Expected error for negative start_line"
|
93
|
+
|
94
|
+
# start > end
|
95
|
+
result2 = Genie::ReplaceLinesInFile.new(base_path: dir).execute(
|
96
|
+
filepath: file,
|
97
|
+
start_line: 1,
|
98
|
+
end_line: 0,
|
99
|
+
content: "X\n"
|
100
|
+
)
|
101
|
+
assert result2[:error]&.include?("Invalid line numbers"), "Expected error for start_line > end_line"
|
102
|
+
|
103
|
+
# end beyond last index
|
104
|
+
result3 = Genie::ReplaceLinesInFile.new(base_path: dir).execute(
|
105
|
+
filepath: file,
|
106
|
+
start_line: 0,
|
107
|
+
end_line: 5,
|
108
|
+
content: "X\n"
|
109
|
+
)
|
110
|
+
assert result3[:error]&.include?("Invalid line numbers"), "Expected error for end_line beyond file"
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
def test_error_for_file_outside_base_path
|
115
|
+
Dir.mktmpdir do |dir|
|
116
|
+
outside = "#{dir}/../outside.txt"
|
117
|
+
|
118
|
+
result = Genie::ReplaceLinesInFile.new(base_path: dir).execute(
|
119
|
+
filepath: outside,
|
120
|
+
start_line: 0,
|
121
|
+
end_line: 1,
|
122
|
+
content: "data\n"
|
123
|
+
)
|
124
|
+
assert result[:error]&.include?("File not allowed"), "Expected error for file outside base path"
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
def test_error_for_nonexistent_file
|
129
|
+
Dir.mktmpdir do |dir|
|
130
|
+
file = "#{dir}/no_file.txt"
|
131
|
+
|
132
|
+
result = Genie::ReplaceLinesInFile.new(base_path: dir).execute(
|
133
|
+
filepath: file,
|
134
|
+
start_line: 0,
|
135
|
+
end_line: 0,
|
136
|
+
content: "data\n"
|
137
|
+
)
|
138
|
+
assert result[:error]&.include?("File not found"), "Expected error for nonexistent file"
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require "tmpdir"
|
2
|
+
|
3
|
+
require "tools/write_file"
|
4
|
+
|
5
|
+
class TestWriteFile < TLDR
|
6
|
+
def test_write_file
|
7
|
+
Dir.mktmpdir {|dir|
|
8
|
+
|
9
|
+
Genie::WriteFile.new(base_path: "#{dir}").execute(filepath: "#{dir}/test_file.txt", content: "Hello, World!")
|
10
|
+
|
11
|
+
actual = File.read("#{dir}/test_file.txt")
|
12
|
+
expected = "Hello, World!"
|
13
|
+
|
14
|
+
assert_equal expected, actual
|
15
|
+
}
|
16
|
+
end
|
17
|
+
end
|
metadata
ADDED
@@ -0,0 +1,179 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: genie_cli
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Jeff McFadden
|
8
|
+
bindir: bin
|
9
|
+
cert_chain: []
|
10
|
+
date: 2025-06-16 00:00:00.000000000 Z
|
11
|
+
dependencies:
|
12
|
+
- !ruby/object:Gem::Dependency
|
13
|
+
name: ruby_llm
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
15
|
+
requirements:
|
16
|
+
- - ">="
|
17
|
+
- !ruby/object:Gem::Version
|
18
|
+
version: '0'
|
19
|
+
type: :runtime
|
20
|
+
prerelease: false
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
22
|
+
requirements:
|
23
|
+
- - ">="
|
24
|
+
- !ruby/object:Gem::Version
|
25
|
+
version: '0'
|
26
|
+
- !ruby/object:Gem::Dependency
|
27
|
+
name: dotenv
|
28
|
+
requirement: !ruby/object:Gem::Requirement
|
29
|
+
requirements:
|
30
|
+
- - ">="
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '0'
|
33
|
+
type: :runtime
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - ">="
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '0'
|
40
|
+
- !ruby/object:Gem::Dependency
|
41
|
+
name: debug
|
42
|
+
requirement: !ruby/object:Gem::Requirement
|
43
|
+
requirements:
|
44
|
+
- - ">="
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: '0'
|
47
|
+
type: :runtime
|
48
|
+
prerelease: false
|
49
|
+
version_requirements: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - ">="
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
54
|
+
- !ruby/object:Gem::Dependency
|
55
|
+
name: tldr
|
56
|
+
requirement: !ruby/object:Gem::Requirement
|
57
|
+
requirements:
|
58
|
+
- - ">="
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: '0'
|
61
|
+
type: :runtime
|
62
|
+
prerelease: false
|
63
|
+
version_requirements: !ruby/object:Gem::Requirement
|
64
|
+
requirements:
|
65
|
+
- - ">="
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: '0'
|
68
|
+
- !ruby/object:Gem::Dependency
|
69
|
+
name: tty-command
|
70
|
+
requirement: !ruby/object:Gem::Requirement
|
71
|
+
requirements:
|
72
|
+
- - ">="
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
version: '0'
|
75
|
+
type: :runtime
|
76
|
+
prerelease: false
|
77
|
+
version_requirements: !ruby/object:Gem::Requirement
|
78
|
+
requirements:
|
79
|
+
- - ">="
|
80
|
+
- !ruby/object:Gem::Version
|
81
|
+
version: '0'
|
82
|
+
- !ruby/object:Gem::Dependency
|
83
|
+
name: tldr
|
84
|
+
requirement: !ruby/object:Gem::Requirement
|
85
|
+
requirements:
|
86
|
+
- - ">="
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
version: '1.0'
|
89
|
+
type: :development
|
90
|
+
prerelease: false
|
91
|
+
version_requirements: !ruby/object:Gem::Requirement
|
92
|
+
requirements:
|
93
|
+
- - ">="
|
94
|
+
- !ruby/object:Gem::Version
|
95
|
+
version: '1.0'
|
96
|
+
- !ruby/object:Gem::Dependency
|
97
|
+
name: ruby_llm
|
98
|
+
requirement: !ruby/object:Gem::Requirement
|
99
|
+
requirements:
|
100
|
+
- - ">="
|
101
|
+
- !ruby/object:Gem::Version
|
102
|
+
version: '0'
|
103
|
+
type: :development
|
104
|
+
prerelease: false
|
105
|
+
version_requirements: !ruby/object:Gem::Requirement
|
106
|
+
requirements:
|
107
|
+
- - ">="
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: '0'
|
110
|
+
description: Genie CLI is a command-line tool that brings Test Driven Development
|
111
|
+
(TDD) principles to life by integrating with a large language model (LLM) through
|
112
|
+
the ruby_llm library. It provides an interactive session to write tests, implement
|
113
|
+
code, and manage your codebase.
|
114
|
+
email:
|
115
|
+
- jeff@example.com
|
116
|
+
executables:
|
117
|
+
- genie
|
118
|
+
extensions: []
|
119
|
+
extra_rdoc_files: []
|
120
|
+
files:
|
121
|
+
- LICENSE
|
122
|
+
- README.md
|
123
|
+
- Rakefile
|
124
|
+
- bin/genie
|
125
|
+
- lib/genie.rb
|
126
|
+
- lib/genie/cli.rb
|
127
|
+
- lib/genie/sandboxed_file_tool.rb
|
128
|
+
- lib/genie/session.rb
|
129
|
+
- lib/genie/session_config.rb
|
130
|
+
- lib/genie/version.rb
|
131
|
+
- lib/tools/append_to_file.rb
|
132
|
+
- lib/tools/ask_for_help.rb
|
133
|
+
- lib/tools/insert_into_file.rb
|
134
|
+
- lib/tools/list_files.rb
|
135
|
+
- lib/tools/read_file.rb
|
136
|
+
- lib/tools/rename_file.rb
|
137
|
+
- lib/tools/replace_lines_in_file.rb
|
138
|
+
- lib/tools/run_tests.rb
|
139
|
+
- lib/tools/take_a_note.rb
|
140
|
+
- lib/tools/write_file.rb
|
141
|
+
- test/data/sample_config.yml
|
142
|
+
- test/data/sample_files/a_dir/two.txt
|
143
|
+
- test/data/sample_files/one.txt
|
144
|
+
- test/data/sample_files/read_file_test.txt
|
145
|
+
- test/test_cli.rb
|
146
|
+
- test/test_helper.rb
|
147
|
+
- test/test_session.rb
|
148
|
+
- test/test_session_config.rb
|
149
|
+
- test/tools/test_append_to_file.rb
|
150
|
+
- test/tools/test_insert_into_file.rb
|
151
|
+
- test/tools/test_list_files.rb
|
152
|
+
- test/tools/test_read_file.rb
|
153
|
+
- test/tools/test_rename_file.rb
|
154
|
+
- test/tools/test_replace_lines_in_file.rb
|
155
|
+
- test/tools/test_run_tests.rb
|
156
|
+
- test/tools/test_take_a_note.rb
|
157
|
+
- test/tools/test_write_file.rb
|
158
|
+
homepage: https://github.com/jeffmcfadden/genie_cli
|
159
|
+
licenses:
|
160
|
+
- MIT
|
161
|
+
metadata: {}
|
162
|
+
rdoc_options: []
|
163
|
+
require_paths:
|
164
|
+
- lib
|
165
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
166
|
+
requirements:
|
167
|
+
- - ">="
|
168
|
+
- !ruby/object:Gem::Version
|
169
|
+
version: '3.2'
|
170
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
171
|
+
requirements:
|
172
|
+
- - ">="
|
173
|
+
- !ruby/object:Gem::Version
|
174
|
+
version: '0'
|
175
|
+
requirements: []
|
176
|
+
rubygems_version: 3.6.2
|
177
|
+
specification_version: 4
|
178
|
+
summary: CLI Coding Agent written in Ruby.
|
179
|
+
test_files: []
|