elelem 0.9.2 → 0.11.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/README.md +8 -118
- data/Rakefile +0 -11
- data/exe/elelem +8 -79
- data/lib/elelem/agent.rb +51 -142
- data/lib/elelem/cli.rb +76 -0
- data/lib/elelem/commands.rb +49 -0
- data/lib/elelem/config.rb +17 -0
- data/lib/elelem/conversation.rb +25 -0
- data/lib/elelem/input.rb +53 -0
- data/lib/elelem/null_input.rb +8 -0
- data/lib/elelem/null_output.rb +7 -0
- data/lib/elelem/null_tool.rb +18 -0
- data/lib/elelem/output.rb +57 -0
- data/lib/elelem/plugins.rb +10 -21
- data/lib/elelem/prompts/default.erb +3 -0
- data/lib/elelem/registration.rb +37 -0
- data/lib/elelem/registry.rb +69 -0
- data/lib/elelem/result.rb +26 -0
- data/lib/elelem/slash_command.rb +18 -0
- data/lib/elelem/stub_provider.rb +15 -0
- data/lib/elelem/system_prompt.rb +4 -42
- data/lib/elelem/tool.rb +6 -14
- data/lib/elelem/toolbox.rb +23 -23
- data/lib/elelem/version.rb +2 -2
- data/lib/elelem.rb +29 -27
- metadata +49 -65
- data/CHANGELOG.md +0 -280
- data/lib/elelem/mcp.rb +0 -96
- data/lib/elelem/net/claude.rb +0 -200
- data/lib/elelem/net/ollama.rb +0 -78
- data/lib/elelem/net/openai.rb +0 -86
- data/lib/elelem/net.rb +0 -16
- data/lib/elelem/plugins/confirm.rb +0 -12
- data/lib/elelem/plugins/edit.rb +0 -15
- data/lib/elelem/plugins/eval.rb +0 -20
- data/lib/elelem/plugins/execute.rb +0 -18
- data/lib/elelem/plugins/mcp.rb +0 -14
- data/lib/elelem/plugins/read.rb +0 -21
- data/lib/elelem/plugins/verify.rb +0 -47
- data/lib/elelem/plugins/write.rb +0 -23
- data/lib/elelem/templates/system_prompt.erb +0 -53
- data/lib/elelem/terminal.rb +0 -97
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: elelem
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.11.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- mo khan
|
|
@@ -10,173 +10,159 @@ cert_chain: []
|
|
|
10
10
|
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
11
|
dependencies:
|
|
12
12
|
- !ruby/object:Gem::Dependency
|
|
13
|
-
name:
|
|
13
|
+
name: erb
|
|
14
14
|
requirement: !ruby/object:Gem::Requirement
|
|
15
15
|
requirements:
|
|
16
16
|
- - "~>"
|
|
17
17
|
- !ruby/object:Gem::Version
|
|
18
|
-
version: '
|
|
18
|
+
version: '6.0'
|
|
19
19
|
type: :runtime
|
|
20
20
|
prerelease: false
|
|
21
21
|
version_requirements: !ruby/object:Gem::Requirement
|
|
22
22
|
requirements:
|
|
23
23
|
- - "~>"
|
|
24
24
|
- !ruby/object:Gem::Version
|
|
25
|
-
version: '
|
|
25
|
+
version: '6.0'
|
|
26
26
|
- !ruby/object:Gem::Dependency
|
|
27
|
-
name:
|
|
27
|
+
name: forwardable
|
|
28
28
|
requirement: !ruby/object:Gem::Requirement
|
|
29
29
|
requirements:
|
|
30
30
|
- - "~>"
|
|
31
31
|
- !ruby/object:Gem::Version
|
|
32
|
-
version: '
|
|
32
|
+
version: '1.4'
|
|
33
33
|
type: :runtime
|
|
34
34
|
prerelease: false
|
|
35
35
|
version_requirements: !ruby/object:Gem::Requirement
|
|
36
36
|
requirements:
|
|
37
37
|
- - "~>"
|
|
38
38
|
- !ruby/object:Gem::Version
|
|
39
|
-
version: '
|
|
39
|
+
version: '1.4'
|
|
40
40
|
- !ruby/object:Gem::Dependency
|
|
41
|
-
name:
|
|
41
|
+
name: io-console
|
|
42
42
|
requirement: !ruby/object:Gem::Requirement
|
|
43
43
|
requirements:
|
|
44
44
|
- - "~>"
|
|
45
45
|
- !ruby/object:Gem::Version
|
|
46
|
-
version: '
|
|
46
|
+
version: '0.9'
|
|
47
47
|
type: :runtime
|
|
48
48
|
prerelease: false
|
|
49
49
|
version_requirements: !ruby/object:Gem::Requirement
|
|
50
50
|
requirements:
|
|
51
51
|
- - "~>"
|
|
52
52
|
- !ruby/object:Gem::Version
|
|
53
|
-
version: '
|
|
53
|
+
version: '0.9'
|
|
54
54
|
- !ruby/object:Gem::Dependency
|
|
55
55
|
name: json
|
|
56
56
|
requirement: !ruby/object:Gem::Requirement
|
|
57
57
|
requirements:
|
|
58
58
|
- - "~>"
|
|
59
59
|
- !ruby/object:Gem::Version
|
|
60
|
-
version: '
|
|
60
|
+
version: '3.0'
|
|
61
61
|
type: :runtime
|
|
62
62
|
prerelease: false
|
|
63
63
|
version_requirements: !ruby/object:Gem::Requirement
|
|
64
64
|
requirements:
|
|
65
65
|
- - "~>"
|
|
66
66
|
- !ruby/object:Gem::Version
|
|
67
|
-
version: '
|
|
67
|
+
version: '3.0'
|
|
68
68
|
- !ruby/object:Gem::Dependency
|
|
69
69
|
name: json_schemer
|
|
70
70
|
requirement: !ruby/object:Gem::Requirement
|
|
71
71
|
requirements:
|
|
72
72
|
- - "~>"
|
|
73
73
|
- !ruby/object:Gem::Version
|
|
74
|
-
version: '2.
|
|
74
|
+
version: '2.5'
|
|
75
75
|
type: :runtime
|
|
76
76
|
prerelease: false
|
|
77
77
|
version_requirements: !ruby/object:Gem::Requirement
|
|
78
78
|
requirements:
|
|
79
79
|
- - "~>"
|
|
80
80
|
- !ruby/object:Gem::Version
|
|
81
|
-
version: '2.
|
|
81
|
+
version: '2.5'
|
|
82
82
|
- !ruby/object:Gem::Dependency
|
|
83
|
-
name:
|
|
83
|
+
name: logger
|
|
84
84
|
requirement: !ruby/object:Gem::Requirement
|
|
85
85
|
requirements:
|
|
86
86
|
- - "~>"
|
|
87
87
|
- !ruby/object:Gem::Version
|
|
88
|
-
version: '1.
|
|
88
|
+
version: '1.7'
|
|
89
89
|
type: :runtime
|
|
90
90
|
prerelease: false
|
|
91
91
|
version_requirements: !ruby/object:Gem::Requirement
|
|
92
92
|
requirements:
|
|
93
93
|
- - "~>"
|
|
94
94
|
- !ruby/object:Gem::Version
|
|
95
|
-
version: '1.
|
|
95
|
+
version: '1.7'
|
|
96
96
|
- !ruby/object:Gem::Dependency
|
|
97
97
|
name: open3
|
|
98
98
|
requirement: !ruby/object:Gem::Requirement
|
|
99
99
|
requirements:
|
|
100
100
|
- - "~>"
|
|
101
101
|
- !ruby/object:Gem::Version
|
|
102
|
-
version: '0.
|
|
102
|
+
version: '0.2'
|
|
103
103
|
type: :runtime
|
|
104
104
|
prerelease: false
|
|
105
105
|
version_requirements: !ruby/object:Gem::Requirement
|
|
106
106
|
requirements:
|
|
107
107
|
- - "~>"
|
|
108
108
|
- !ruby/object:Gem::Version
|
|
109
|
-
version: '0.
|
|
109
|
+
version: '0.2'
|
|
110
110
|
- !ruby/object:Gem::Dependency
|
|
111
111
|
name: optparse
|
|
112
112
|
requirement: !ruby/object:Gem::Requirement
|
|
113
113
|
requirements:
|
|
114
114
|
- - "~>"
|
|
115
115
|
- !ruby/object:Gem::Version
|
|
116
|
-
version: '0.
|
|
116
|
+
version: '0.8'
|
|
117
117
|
type: :runtime
|
|
118
118
|
prerelease: false
|
|
119
119
|
version_requirements: !ruby/object:Gem::Requirement
|
|
120
120
|
requirements:
|
|
121
121
|
- - "~>"
|
|
122
122
|
- !ruby/object:Gem::Version
|
|
123
|
-
version: '0.
|
|
123
|
+
version: '0.8'
|
|
124
124
|
- !ruby/object:Gem::Dependency
|
|
125
125
|
name: pathname
|
|
126
126
|
requirement: !ruby/object:Gem::Requirement
|
|
127
127
|
requirements:
|
|
128
128
|
- - "~>"
|
|
129
129
|
- !ruby/object:Gem::Version
|
|
130
|
-
version: '0.
|
|
130
|
+
version: '0.5'
|
|
131
131
|
type: :runtime
|
|
132
132
|
prerelease: false
|
|
133
133
|
version_requirements: !ruby/object:Gem::Requirement
|
|
134
134
|
requirements:
|
|
135
135
|
- - "~>"
|
|
136
136
|
- !ruby/object:Gem::Version
|
|
137
|
-
version: '0.
|
|
137
|
+
version: '0.5'
|
|
138
138
|
- !ruby/object:Gem::Dependency
|
|
139
139
|
name: reline
|
|
140
140
|
requirement: !ruby/object:Gem::Requirement
|
|
141
141
|
requirements:
|
|
142
142
|
- - "~>"
|
|
143
143
|
- !ruby/object:Gem::Version
|
|
144
|
-
version: '0.
|
|
144
|
+
version: '0.7'
|
|
145
145
|
type: :runtime
|
|
146
146
|
prerelease: false
|
|
147
147
|
version_requirements: !ruby/object:Gem::Requirement
|
|
148
148
|
requirements:
|
|
149
149
|
- - "~>"
|
|
150
150
|
- !ruby/object:Gem::Version
|
|
151
|
-
version: '0.
|
|
152
|
-
- !ruby/object:Gem::Dependency
|
|
153
|
-
name: stringio
|
|
154
|
-
requirement: !ruby/object:Gem::Requirement
|
|
155
|
-
requirements:
|
|
156
|
-
- - "~>"
|
|
157
|
-
- !ruby/object:Gem::Version
|
|
158
|
-
version: '3.0'
|
|
159
|
-
type: :runtime
|
|
160
|
-
prerelease: false
|
|
161
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
162
|
-
requirements:
|
|
163
|
-
- - "~>"
|
|
164
|
-
- !ruby/object:Gem::Version
|
|
165
|
-
version: '3.0'
|
|
151
|
+
version: '0.7'
|
|
166
152
|
- !ruby/object:Gem::Dependency
|
|
167
|
-
name:
|
|
153
|
+
name: shellwords
|
|
168
154
|
requirement: !ruby/object:Gem::Requirement
|
|
169
155
|
requirements:
|
|
170
156
|
- - "~>"
|
|
171
157
|
- !ruby/object:Gem::Version
|
|
172
|
-
version: '0.
|
|
158
|
+
version: '0.2'
|
|
173
159
|
type: :runtime
|
|
174
160
|
prerelease: false
|
|
175
161
|
version_requirements: !ruby/object:Gem::Requirement
|
|
176
162
|
requirements:
|
|
177
163
|
- - "~>"
|
|
178
164
|
- !ruby/object:Gem::Version
|
|
179
|
-
version: '0.
|
|
165
|
+
version: '0.2'
|
|
180
166
|
- !ruby/object:Gem::Dependency
|
|
181
167
|
name: uri
|
|
182
168
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -191,7 +177,7 @@ dependencies:
|
|
|
191
177
|
- - "~>"
|
|
192
178
|
- !ruby/object:Gem::Version
|
|
193
179
|
version: '1.0'
|
|
194
|
-
description: A minimal coding
|
|
180
|
+
description: A minimal coding harness.
|
|
195
181
|
email:
|
|
196
182
|
- mo@mokhan.ca
|
|
197
183
|
executables:
|
|
@@ -199,41 +185,39 @@ executables:
|
|
|
199
185
|
extensions: []
|
|
200
186
|
extra_rdoc_files: []
|
|
201
187
|
files:
|
|
202
|
-
- CHANGELOG.md
|
|
203
188
|
- LICENSE.txt
|
|
204
189
|
- README.md
|
|
205
190
|
- Rakefile
|
|
206
191
|
- exe/elelem
|
|
207
192
|
- lib/elelem.rb
|
|
208
193
|
- lib/elelem/agent.rb
|
|
209
|
-
- lib/elelem/
|
|
210
|
-
- lib/elelem/
|
|
211
|
-
- lib/elelem/
|
|
212
|
-
- lib/elelem/
|
|
213
|
-
- lib/elelem/
|
|
194
|
+
- lib/elelem/cli.rb
|
|
195
|
+
- lib/elelem/commands.rb
|
|
196
|
+
- lib/elelem/config.rb
|
|
197
|
+
- lib/elelem/conversation.rb
|
|
198
|
+
- lib/elelem/input.rb
|
|
199
|
+
- lib/elelem/null_input.rb
|
|
200
|
+
- lib/elelem/null_output.rb
|
|
201
|
+
- lib/elelem/null_tool.rb
|
|
202
|
+
- lib/elelem/output.rb
|
|
214
203
|
- lib/elelem/plugins.rb
|
|
215
|
-
- lib/elelem/
|
|
216
|
-
- lib/elelem/
|
|
217
|
-
- lib/elelem/
|
|
218
|
-
- lib/elelem/
|
|
219
|
-
- lib/elelem/
|
|
220
|
-
- lib/elelem/
|
|
221
|
-
- lib/elelem/plugins/verify.rb
|
|
222
|
-
- lib/elelem/plugins/write.rb
|
|
204
|
+
- lib/elelem/prompts/default.erb
|
|
205
|
+
- lib/elelem/registration.rb
|
|
206
|
+
- lib/elelem/registry.rb
|
|
207
|
+
- lib/elelem/result.rb
|
|
208
|
+
- lib/elelem/slash_command.rb
|
|
209
|
+
- lib/elelem/stub_provider.rb
|
|
223
210
|
- lib/elelem/system_prompt.rb
|
|
224
|
-
- lib/elelem/templates/system_prompt.erb
|
|
225
|
-
- lib/elelem/terminal.rb
|
|
226
211
|
- lib/elelem/tool.rb
|
|
227
212
|
- lib/elelem/toolbox.rb
|
|
228
213
|
- lib/elelem/version.rb
|
|
229
|
-
homepage: https://src.mokhan.ca/
|
|
214
|
+
homepage: https://src.mokhan.ca/elelem/elelem
|
|
230
215
|
licenses:
|
|
231
216
|
- MIT
|
|
232
217
|
metadata:
|
|
233
218
|
allowed_push_host: https://rubygems.org
|
|
234
|
-
homepage_uri: https://src.mokhan.ca/
|
|
235
|
-
source_code_uri: https://src.mokhan.ca/
|
|
236
|
-
changelog_uri: https://src.mokhan.ca/xlgmokha/elelem/blob/main/CHANGELOG.md.html
|
|
219
|
+
homepage_uri: https://src.mokhan.ca/elelem/elelem
|
|
220
|
+
source_code_uri: https://src.mokhan.ca/elelem/elelem
|
|
237
221
|
rdoc_options: []
|
|
238
222
|
require_paths:
|
|
239
223
|
- lib
|
|
@@ -248,7 +232,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
248
232
|
- !ruby/object:Gem::Version
|
|
249
233
|
version: 4.0.0
|
|
250
234
|
requirements: []
|
|
251
|
-
rubygems_version: 4.0.
|
|
235
|
+
rubygems_version: 4.0.20
|
|
252
236
|
specification_version: 4
|
|
253
|
-
summary: A minimal coding
|
|
237
|
+
summary: A minimal coding harness for LLMs.
|
|
254
238
|
test_files: []
|
data/CHANGELOG.md
DELETED
|
@@ -1,280 +0,0 @@
|
|
|
1
|
-
## [0.9.2] - 2026-01-22
|
|
2
|
-
|
|
3
|
-
### Fixed
|
|
4
|
-
- Suppress pathname gem constant redefinition warnings on Ruby 4.0
|
|
5
|
-
|
|
6
|
-
## [0.9.1] - 2026-01-22
|
|
7
|
-
|
|
8
|
-
### Fixed
|
|
9
|
-
- Use `next` instead of `return` to exit block in execute plugin after-hook
|
|
10
|
-
- Use `break` instead of `return` to exit `inject` block in verify plugin
|
|
11
|
-
|
|
12
|
-
## [0.9.0] - 2026-01-21
|
|
13
|
-
|
|
14
|
-
### Added
|
|
15
|
-
- **Plugin system** with support for custom tool definitions
|
|
16
|
-
- Load plugins from `lib/elelem/plugins/`, `~/.elelem/plugins/`, and `.elelem/plugins/`
|
|
17
|
-
- `Elelem::Plugins.register(name) { |toolbox| ... }` API
|
|
18
|
-
- Built-in plugins: `read`, `write`, `edit`, `execute`, `eval`, `verify`, `confirm`, `mcp`
|
|
19
|
-
- **MCP (Model Context Protocol)** server support via `.mcp.json` configuration
|
|
20
|
-
- **AGENTS.md** file support - searches up directory tree for project instructions
|
|
21
|
-
- **`/init` command** to generate an AGENTS.md file for the current project
|
|
22
|
-
- **`/shell` command** to drop into a shell session and capture the transcript to context
|
|
23
|
-
- **`/reload` command** to hot-reload source code without restarting the process
|
|
24
|
-
- **`task` tool** for delegating subtasks to focused sub-agents
|
|
25
|
-
- **`edit` tool** for replacing first occurrence of text in a file
|
|
26
|
-
- **`eval` tool** for executing Ruby code and dynamically registering new tools
|
|
27
|
-
- **`verify` tool** for syntax checking and running project tests
|
|
28
|
-
- **Pre/post tool hooks** (`toolbox.before`/`toolbox.after`) for extensibility
|
|
29
|
-
- **Confirmation prompt** before executing shell commands (when TTY)
|
|
30
|
-
- **Context compaction** for long conversations (summarizes old messages)
|
|
31
|
-
- **Repo map** via ctags included in system prompt
|
|
32
|
-
- **Markdown rendering** with [glow](https://github.com/charmbracelet/glow) for LLM responses
|
|
33
|
-
- **CLI improvements**: optparse-based interface with `-p`/`-m` flags
|
|
34
|
-
- `elelem chat` - Interactive REPL (default)
|
|
35
|
-
- `elelem ask <prompt>` - One-shot query (reads stdin if piped)
|
|
36
|
-
- `elelem files` - Output files as XML
|
|
37
|
-
- JSON Schema validation for tool call arguments (via `json_schemer`)
|
|
38
|
-
- Tool aliases support (e.g., `bash`, `sh`, `exec` → `execute`)
|
|
39
|
-
- **Dependencies documentation** in README with installation links
|
|
40
|
-
|
|
41
|
-
### Changed
|
|
42
|
-
- **Breaking**: Requires Ruby >= 4.0.0 (was 3.4.0)
|
|
43
|
-
- **Breaking**: Removed `net-llm` dependency - LLM clients now inline in `lib/elelem/net/`
|
|
44
|
-
- `Elelem::Net::Claude` (Anthropic and Vertex AI)
|
|
45
|
-
- `Elelem::Net::OpenAI`
|
|
46
|
-
- `Elelem::Net::Ollama`
|
|
47
|
-
- **Breaking**: Simplified LLM client `fetch` contract
|
|
48
|
-
- Yields `{content:, thinking:}` deltas
|
|
49
|
-
- Returns `tool_calls` array directly
|
|
50
|
-
- **Breaking**: Tool schema uses OpenAI format (`{type: "function", function: {...}}`)
|
|
51
|
-
- **Breaking**: Tool definitions use `description:` key (was `desc:`)
|
|
52
|
-
- **Breaking**: Removed modes and permissions system entirely
|
|
53
|
-
- **Breaking**: Removed slash commands (`/mode`, `/env`, `/provider`, `/model`)
|
|
54
|
-
- Remaining: `/clear`, `/context`, `/init`, `/reload`, `/shell`, `/exit`, `/help`
|
|
55
|
-
- **Breaking**: Removed many dependencies
|
|
56
|
-
- Removed: `thor`, `cli-ui`, `erb`, `cgi`, `set`, `timeout`, `logger`, `net-llm`, `json-schema`
|
|
57
|
-
- Added: `json_schemer`, `optparse`, `tempfile`, `stringio`, `uri`
|
|
58
|
-
- Consolidated multiple exe files into single `exe/elelem` entry point
|
|
59
|
-
- Tools are now defined via plugins instead of hardcoded in Toolbox
|
|
60
|
-
- System prompt includes hints for `rg`, `fd`, `sg` (ast-grep), `sed`, `patch`
|
|
61
|
-
- System prompt regenerated on each fetch (includes dynamic repo map)
|
|
62
|
-
- Default tool set: `read`, `write`, `edit`, `execute`, `eval`, `verify`, `task`
|
|
63
|
-
- System prompt encourages using `eval` to create tools for repetitive tasks
|
|
64
|
-
|
|
65
|
-
### Removed
|
|
66
|
-
- `lib/elelem/application.rb` - CLI now in `exe/elelem`
|
|
67
|
-
- `lib/elelem/conversation.rb` - simplified into Agent
|
|
68
|
-
- `lib/elelem/git_context.rb` - inlined into Agent
|
|
69
|
-
- `lib/elelem/system_prompt.erb` - now generated in Agent
|
|
70
|
-
- `web_fetch`, `web_search`, `fetch`, `search_engine` tools
|
|
71
|
-
- `patch` tool (use `edit` or `execute` with `sed`/`patch`)
|
|
72
|
-
- `grep`, `list` tools (use `execute` with `rg`, `fd`)
|
|
73
|
-
- Modes and permissions system
|
|
74
|
-
- Events module
|
|
75
|
-
- GitHub Actions CI workflow
|
|
76
|
-
|
|
77
|
-
### Fixed
|
|
78
|
-
- Handle missing args in Claude provider
|
|
79
|
-
- Tool alias resolution (use canonical tool name, not alias)
|
|
80
|
-
- Unknown tool error now suggests using `execute` and lists available tools
|
|
81
|
-
- Duplicate write operations in edit flow
|
|
82
|
-
|
|
83
|
-
## [0.8.0] - 2026-01-14
|
|
84
|
-
|
|
85
|
-
### Added
|
|
86
|
-
- `fetch` tool for HTTP GET requests (returns status and body)
|
|
87
|
-
- `search_engine` tool for DuckDuckGo Instant Answer API searches
|
|
88
|
-
- Tool aliases: `get`/`web` → `fetch`, `ddg`/`duckduckgo` → `search_engine`
|
|
89
|
-
- `net-hippie` and `cgi` dependencies for HTTP requests
|
|
90
|
-
|
|
91
|
-
## [0.7.0] - 2026-01-14
|
|
92
|
-
|
|
93
|
-
### Added
|
|
94
|
-
- ASCII spinner animation while waiting for LLM responses
|
|
95
|
-
- `Terminal#waiting` method with automatic cleanup on next output
|
|
96
|
-
- Decision-making principles in system prompt (prefer reversible actions, ask when uncertain)
|
|
97
|
-
- Mode enforcement tests
|
|
98
|
-
|
|
99
|
-
### Changed
|
|
100
|
-
- Renamed internal `mode` concept to `permissions` for clarity (read/write/execute are permissions, plan/build/verify are modes)
|
|
101
|
-
- Refactored `Toolbox#run_tool` to accept `permissions:` parameter
|
|
102
|
-
|
|
103
|
-
### Fixed
|
|
104
|
-
- **Security**: Mode restrictions now enforced at execution time, not just schema time
|
|
105
|
-
- Previously, LLMs could call tools outside their mode by guessing tool names
|
|
106
|
-
- Now `run_tool` validates the tool is allowed for the current permission set
|
|
107
|
-
|
|
108
|
-
## [0.6.0] - 2026-01-12
|
|
109
|
-
|
|
110
|
-
### Added
|
|
111
|
-
- `/env` slash command to capture environment variables for provider connections
|
|
112
|
-
- `/shell` slash command
|
|
113
|
-
- `/provider` and `/model` slash commands
|
|
114
|
-
- Tab completion for commands
|
|
115
|
-
- Help output for `/mode` and `/env` commands
|
|
116
|
-
|
|
117
|
-
### Changed
|
|
118
|
-
- Renamed `bash` tool to `exec`
|
|
119
|
-
- Tuned system prompt
|
|
120
|
-
- Changed thinking prompt to ellipsis
|
|
121
|
-
- Removed username from system prompt
|
|
122
|
-
- Use pessimistic constraint on net-llm dependency
|
|
123
|
-
- Extracted Terminal class for IO abstraction (enables E2E testing)
|
|
124
|
-
|
|
125
|
-
### Fixed
|
|
126
|
-
- Prevent infinite looping errors
|
|
127
|
-
- Provide function schema when tool is called with invalid arguments
|
|
128
|
-
- Tab completion for `pass` entries without requiring `show` subcommand
|
|
129
|
-
- Password store symlink support in tab completion
|
|
130
|
-
|
|
131
|
-
## [0.5.0] - 2026-01-07
|
|
132
|
-
|
|
133
|
-
### Added
|
|
134
|
-
- Multi-provider support: Ollama, Anthropic, OpenAI, and VertexAI
|
|
135
|
-
- `--provider` CLI option to select LLM provider (default: ollama)
|
|
136
|
-
- `--model` CLI option to override default model
|
|
137
|
-
- Tool aliases (`bash` also accepts `exec`, `shell`, `command`, `terminal`, `run`)
|
|
138
|
-
- Thinking text output for models that support extended thinking
|
|
139
|
-
|
|
140
|
-
### Changed
|
|
141
|
-
- Requires net-llm >= 0.5.0 with unified fetch interface
|
|
142
|
-
- Updated gem description to reflect multi-provider support
|
|
143
|
-
|
|
144
|
-
## [0.4.2] - 2025-12-01
|
|
145
|
-
|
|
146
|
-
### Changed
|
|
147
|
-
- Renamed `exec` tool to `bash` for clarity
|
|
148
|
-
- Improved system prompt with iterative refinements
|
|
149
|
-
- Added environment context variables to system prompt
|
|
150
|
-
|
|
151
|
-
## [0.4.1] - 2025-11-26
|
|
152
|
-
|
|
153
|
-
### Added
|
|
154
|
-
- `elelem files` subcommand: generates Claude‑compatible XML file listings.
|
|
155
|
-
- Rake task `files:prompt` to output a ready‑to‑copy list of files for prompts.
|
|
156
|
-
|
|
157
|
-
### Changed
|
|
158
|
-
- Refactor tool‑call formatting to a more compact JSON payload for better LLM parsing.
|
|
159
|
-
- Updated CI and documentation to use GitHub instead of previous hosting.
|
|
160
|
-
- Runtime validation of command‑line parameters against a JSON schema.
|
|
161
|
-
|
|
162
|
-
### Fixed
|
|
163
|
-
- Minor documentation and CI workflow adjustments.
|
|
164
|
-
|
|
165
|
-
## [0.4.0] - 2025-11-10
|
|
166
|
-
|
|
167
|
-
### Added
|
|
168
|
-
- **Eval Tool**: Meta-programming tool that allows the LLM to dynamically create and register new tools at runtime
|
|
169
|
-
- Eval tool has access to the toolbox for enhanced capabilities
|
|
170
|
-
- Comprehensive test coverage with RSpec
|
|
171
|
-
- Agent specs
|
|
172
|
-
- Conversation specs
|
|
173
|
-
- Toolbox specs
|
|
174
|
-
|
|
175
|
-
### Changed
|
|
176
|
-
- **Architecture Improvements**: Significant refactoring for better separation of concerns
|
|
177
|
-
- Extracted Tool class to separate file (`lib/elelem/tool.rb`)
|
|
178
|
-
- Extracted Toolbox class to separate file (`lib/elelem/toolbox.rb`)
|
|
179
|
-
- Extracted Shell class for command execution
|
|
180
|
-
- Improved tool registration through `#add_tool` method
|
|
181
|
-
- Tool constants moved to Toolbox for better organization
|
|
182
|
-
- Agent class simplified by delegating to Tool instances
|
|
183
|
-
|
|
184
|
-
### Fixed
|
|
185
|
-
- `/context` command now correctly accounts for the current mode
|
|
186
|
-
|
|
187
|
-
## [0.3.0] - 2025-11-05
|
|
188
|
-
|
|
189
|
-
### Added
|
|
190
|
-
- **Mode System**: Control agent capabilities with workflow modes
|
|
191
|
-
- `/mode plan` - Read-only mode (grep, list, read)
|
|
192
|
-
- `/mode build` - Read + Write mode (grep, list, read, patch, write)
|
|
193
|
-
- `/mode verify` - Read + Execute mode (grep, list, read, execute)
|
|
194
|
-
- `/mode auto` - All tools enabled
|
|
195
|
-
- Each mode adapts system prompt to guide appropriate behavior
|
|
196
|
-
- Improved output formatting
|
|
197
|
-
- Suppressed verbose thinking/reasoning output
|
|
198
|
-
- Clean tool call display (e.g., `date` instead of full JSON hash)
|
|
199
|
-
- Mode switch confirmation messages
|
|
200
|
-
- Clear command feedback
|
|
201
|
-
- Design philosophy documentation in README
|
|
202
|
-
- Mode system documentation
|
|
203
|
-
|
|
204
|
-
### Changed
|
|
205
|
-
- **BREAKING**: Removed `llm-ollama` and `llm-openai` standalone executables (use main `elelem chat` command)
|
|
206
|
-
- **BREAKING**: Simplified architecture - consolidated all logic into Agent class
|
|
207
|
-
- Removed Configuration class
|
|
208
|
-
- Removed Toolbox system
|
|
209
|
-
- Removed MCP client infrastructure
|
|
210
|
-
- Removed Tool and Tools classes
|
|
211
|
-
- Removed TUI abstraction layer (direct puts/Reline usage)
|
|
212
|
-
- Removed API wrapper class
|
|
213
|
-
- Removed state machine
|
|
214
|
-
- Improved execute tool description to guide LLM toward direct command execution
|
|
215
|
-
- Extracted tool definitions from long inline strings to readable private methods
|
|
216
|
-
- Updated README with clear philosophy and usage examples
|
|
217
|
-
- Reduced total codebase from 417 to 395 lines (-5%)
|
|
218
|
-
|
|
219
|
-
### Fixed
|
|
220
|
-
- Working directory handling for execute tool (handles empty string cwd)
|
|
221
|
-
- REPL EOF handling (graceful exit when input stream ends)
|
|
222
|
-
- Tool call formatting now shows clean, readable commands
|
|
223
|
-
|
|
224
|
-
### Removed
|
|
225
|
-
- `exe/llm-ollama` (359 lines)
|
|
226
|
-
- `exe/llm-openai` (340 lines)
|
|
227
|
-
- `lib/elelem/configuration.rb`
|
|
228
|
-
- `lib/elelem/toolbox.rb` and toolbox/* files
|
|
229
|
-
- `lib/elelem/mcp_client.rb`
|
|
230
|
-
- `lib/elelem/tool.rb` and `lib/elelem/tools.rb`
|
|
231
|
-
- `lib/elelem/tui.rb`
|
|
232
|
-
- `lib/elelem/api.rb`
|
|
233
|
-
- `lib/elelem/states/*` (state machine infrastructure)
|
|
234
|
-
- Removed ~750 lines of unused/redundant code
|
|
235
|
-
|
|
236
|
-
## [0.2.1] - 2025-10-15
|
|
237
|
-
|
|
238
|
-
### Fixed
|
|
239
|
-
- Added missing `exe/llm-ollama` and `exe/llm-openai` files to gemspec
|
|
240
|
-
- These executables were added in 0.2.0 but not included in the packaged gem
|
|
241
|
-
|
|
242
|
-
## [0.2.0] - 2025-10-15
|
|
243
|
-
|
|
244
|
-
### Added
|
|
245
|
-
- New `llm-ollama` executable - minimal coding agent with streaming support for Ollama
|
|
246
|
-
- New `llm-openai` executable - minimal coding agent for OpenAI/compatible APIs
|
|
247
|
-
- Memory feature for persistent context storage and retrieval
|
|
248
|
-
- Web fetch tool for retrieving and analyzing web content
|
|
249
|
-
- Streaming responses with real-time token display
|
|
250
|
-
- Visual "thinking" progress indicators with dots during reasoning phase
|
|
251
|
-
|
|
252
|
-
### Changed
|
|
253
|
-
- **BREAKING**: Migrated from custom Net::HTTP implementation to `net-llm` gem
|
|
254
|
-
- API client now uses `Net::Llm::Ollama` for better reliability and maintainability
|
|
255
|
-
- Removed direct dependencies on `net-http` and `uri` (now transitive through net-llm)
|
|
256
|
-
- Maps Ollama's `thinking` field to internal `reasoning` field
|
|
257
|
-
- Maps Ollama's `done_reason` to internal `finish_reason`
|
|
258
|
-
- Improved system prompt for better agent behavior
|
|
259
|
-
- Enhanced error handling and logging
|
|
260
|
-
|
|
261
|
-
### Fixed
|
|
262
|
-
- Response processing for Ollama's native message format
|
|
263
|
-
- Tool argument parsing to handle both string and object formats
|
|
264
|
-
- Safe navigation operator usage to prevent nil errors
|
|
265
|
-
|
|
266
|
-
## [0.1.2] - 2025-08-14
|
|
267
|
-
|
|
268
|
-
### Fixed
|
|
269
|
-
- Fixed critical bug where bash tool had nested parameters schema causing tool calls to fail with "no implicit conversion of nil into String" error
|
|
270
|
-
|
|
271
|
-
## [0.1.1] - 2025-08-12
|
|
272
|
-
|
|
273
|
-
### Fixed
|
|
274
|
-
- Fixed infinite loop bug after tool execution - loop now continues until assistant provides final response
|
|
275
|
-
- Fixed conversation history accumulating streaming chunks as separate entries - now properly combines same-role consecutive messages
|
|
276
|
-
- Improved state machine logging with better debug output
|
|
277
|
-
|
|
278
|
-
## [0.1.0] - 2025-08-08
|
|
279
|
-
|
|
280
|
-
- Initial release
|
data/lib/elelem/mcp.rb
DELETED
|
@@ -1,96 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Elelem
|
|
4
|
-
class MCP
|
|
5
|
-
def initialize(config_path = ".mcp.json")
|
|
6
|
-
@config = File.exist?(config_path) ? JSON.parse(IO.read(config_path)) : {}
|
|
7
|
-
@servers = {}
|
|
8
|
-
end
|
|
9
|
-
|
|
10
|
-
def tools
|
|
11
|
-
@config.fetch("mcpServers", {}).flat_map do |name, _|
|
|
12
|
-
server(name).tools.map do |tool|
|
|
13
|
-
[
|
|
14
|
-
"#{name}_#{tool["name"]}",
|
|
15
|
-
{
|
|
16
|
-
description: tool["description"],
|
|
17
|
-
params: tool.dig("inputSchema", "properties") || {},
|
|
18
|
-
required: tool.dig("inputSchema", "required") || [],
|
|
19
|
-
fn: ->(a) { server(name).call(tool["name"], a) }
|
|
20
|
-
}
|
|
21
|
-
]
|
|
22
|
-
end
|
|
23
|
-
end.to_h
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
def close
|
|
27
|
-
@servers.each_value(&:close)
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
private
|
|
31
|
-
|
|
32
|
-
def server(name)
|
|
33
|
-
@servers[name] ||= Server.new(**@config.dig("mcpServers", name).transform_keys(&:to_sym))
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
class Server
|
|
37
|
-
def initialize(command:, args: [], env: {})
|
|
38
|
-
resolved_env = env.transform_values { |v| v.gsub(/\$\{(\w+)\}/) { ENV[$1] } }
|
|
39
|
-
@stdin, @stdout, @stderr, @wait = Open3.popen3(resolved_env, command, *args)
|
|
40
|
-
@id = 0
|
|
41
|
-
initialize!
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
def tools
|
|
45
|
-
request("tools/list")["tools"]
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
def call(name, args)
|
|
49
|
-
result = request("tools/call", { name: name, arguments: args })
|
|
50
|
-
{ content: result["content"]&.map { |c| c["text"] }&.join("\n") }
|
|
51
|
-
end
|
|
52
|
-
|
|
53
|
-
def close
|
|
54
|
-
@stdin.close rescue nil
|
|
55
|
-
@stdout.close rescue nil
|
|
56
|
-
@stderr.close rescue nil
|
|
57
|
-
@wait.kill rescue nil
|
|
58
|
-
end
|
|
59
|
-
|
|
60
|
-
private
|
|
61
|
-
|
|
62
|
-
def initialize!
|
|
63
|
-
request("initialize", {
|
|
64
|
-
protocolVersion: "2024-11-05",
|
|
65
|
-
capabilities: {},
|
|
66
|
-
clientInfo: { name: "elelem", version: VERSION }
|
|
67
|
-
})
|
|
68
|
-
notify("notifications/initialized")
|
|
69
|
-
end
|
|
70
|
-
|
|
71
|
-
def request(method, params = {})
|
|
72
|
-
send_msg(id: @id += 1, method: method, params: params)
|
|
73
|
-
read_response(@id)
|
|
74
|
-
end
|
|
75
|
-
|
|
76
|
-
def notify(method, params = {})
|
|
77
|
-
send_msg(method: method, params: params)
|
|
78
|
-
end
|
|
79
|
-
|
|
80
|
-
def send_msg(msg)
|
|
81
|
-
@stdin.puts({ jsonrpc: "2.0", **msg }.to_json)
|
|
82
|
-
@stdin.flush
|
|
83
|
-
end
|
|
84
|
-
|
|
85
|
-
def read_response(id)
|
|
86
|
-
loop do
|
|
87
|
-
line = @stdout.gets
|
|
88
|
-
raise "Server closed" unless line
|
|
89
|
-
msg = JSON.parse(line)
|
|
90
|
-
return msg["result"] if msg["id"] == id
|
|
91
|
-
raise msg["error"]["message"] if msg["error"]
|
|
92
|
-
end
|
|
93
|
-
end
|
|
94
|
-
end
|
|
95
|
-
end
|
|
96
|
-
end
|