botiasloop 0.0.1 → 0.0.7

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: 6b2c58deeefe3094bad216a8dd08b0fa9df9ea5e79924a088f77723d88542a64
4
- data.tar.gz: 0d7bc8c46234f75313694d9c6adc1c35642ef012bf8cce15202d63bdadf52c93
3
+ metadata.gz: 19ce350bd375ddbae065af8ff880cfe1f4f01c1d53b0b865caec2d577119c7bc
4
+ data.tar.gz: 41021e8b39ce89d96b04000d2c9d6e23f78672915561d5c17ee81846faf87ed3
5
5
  SHA512:
6
- metadata.gz: 6f17a7416ca693846a9070b998a59355de00dd9bbf707461bf28d6ab6469dfb0e6544619f6097a809b86f11acec6e2de33371f1ec60499484ca0c7aaa09fb03c
7
- data.tar.gz: ff0d76df0c00904b848581c840fa1bae29c8f707a23e38da07698894e488482194c9368760a2c78fced02d0604f750cd3b1f1cae8e29256c240d4d8fbcf4ec7d
6
+ metadata.gz: d017fa894d1c47e03ef694b3f25a4144e84b5dc0a8b645add7e871062bf7cb754a65febf450ab5964c273196bebbbda7481a1da5f738fd125058b909ddb0b213
7
+ data.tar.gz: c848deadc5eb12e6aa07ffb539bd11a6cb3c2559a88a24285cb7768694c5818f7c9e6b21bffea5dbd6bffe862cfd3a800f130ef0543d6afa65fe77140be41d4f
data/LICENSE ADDED
@@ -0,0 +1,7 @@
1
+ Copyright (c) 2026 Tobias Feistmantl
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4
+
5
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6
+
7
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md CHANGED
@@ -1,62 +1,25 @@
1
- # BotiasLoop
2
-
3
- A minimal agentic AI application built on the ReAct (Reasoning + Acting) loop pattern. BotiasLoop provides an AI agent with shell access and web search capabilities via OpenRouter, designed for dedicated infrastructure following the Rails Doctrine.
1
+ # 🤖 BotiasLoop
4
2
 
5
3
  [![Ruby](https://img.shields.io/badge/ruby-3.4%2B-red.svg)](https://www.ruby-lang.org/)
4
+ [![Gem Version](https://img.shields.io/gem/v/botiasloop.svg)](https://rubygems.org/gems/botiasloop)
6
5
  [![License](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
7
6
  [![StandardRB](https://img.shields.io/badge/code_style-standard-success.svg)](https://github.com/standardrb/standard)
7
+ [![Tests](https://img.shields.io/badge/tests-rspec-brightgreen.svg)]()
8
8
 
9
- ## Philosophy
10
-
11
- **Sharp Knives**: BotiasLoop intentionally provides full shell access without restrictions. This is a feature, not a bug. It's designed for dedicated infrastructure where raw power is needed, not personal devices. The agent can execute any shell command, read any file, and make system changes.
12
-
13
- Following the Rails Doctrine:
14
- - **Optimize for programmer happiness**: Beautiful, readable Ruby code
15
- - **Convention over Configuration**: Sensible defaults, minimal setup required
16
- - **The menu is omakase**: Curated stack (ruby_llm, StandardRB, RSpec)
17
- - **No one paradigm**: Practical over pure - use what works
18
-
19
- ## Features
20
-
21
- ### Core
22
- - **ReAct Loop**: AI reasons, acts using tools, observes results, and repeats
23
- - **Shell Access**: Execute any shell command (full system access)
24
- - **Web Search**: Search the web via SearXNG
25
- - **Conversation Persistence**: SQLite-backed conversation storage with UUID tracking
26
- - **Token Tracking**: Monitor input/output tokens per conversation
27
-
28
- ### Channels
29
- - **CLI Mode**: Interactive REPL for local usage
30
- - **Telegram Bot**: Chat with the agent via Telegram
31
- - **Multi-Channel**: Run multiple channels simultaneously
32
- - **Boot Auto-Start**: systemd service with automatic startup on boot
33
-
34
- ### Commands
35
- Slash commands for conversation management:
36
- - `/new` - Start a new conversation
37
- - `/switch <label|uuid>` - Switch to a different conversation
38
- - `/label <name>` - Label the current conversation
39
- - `/conversations` - List all conversations
40
- - `/reset` - Clear current conversation history
41
- - `/compact` - Summarize and archive old messages
42
- - `/status` - Show current model, token usage
43
- - `/archive` - Archive old conversations
44
- - `/system_prompt` - Show current system prompt
45
- - `/help` - Show available commands
46
-
47
- ### Skills System
48
- Skills follow the [agentskills.io](https://agentskills.io) specification:
49
- - Load default skills from `data/skills/`
50
- - Load custom skills from `~/skills/`
51
- - Progressive disclosure: name/description in system prompt, full content on demand
52
- - Includes `skill-creator` skill for creating new skills
9
+ > **Think. Act. Repeat.**
10
+ >
11
+ > A minimal agentic AI application built on the ReAct (Reasoning + Acting) loop pattern.
53
12
 
54
- ## Installation
13
+ BotiasLoop gives your AI agent **full shell access** and **web search capabilities** via multiple LLM providers. Designed for dedicated infrastructure following the Rails Doctrine — beautiful code, sensible defaults, sharp knives.
14
+
15
+ ---
16
+
17
+ ## 🚀 Installation
55
18
 
56
19
  ### Prerequisites
57
20
 
58
21
  - Ruby 3.4 or higher
59
- - OpenRouter API key
22
+ - API key from your preferred LLM provider (see supported providers below)
60
23
  - (Optional) SearXNG instance for web search
61
24
 
62
25
  ### Via RubyGems
@@ -87,38 +50,115 @@ mise install
87
50
  mise exec ruby -- bundle install
88
51
  ```
89
52
 
90
- ## Configuration
53
+ ---
91
54
 
92
- Create `~/.config/botiasloop/config.yml`:
55
+ ## ⚡ Quick Start
93
56
 
94
- ```yaml
95
- # Required: OpenRouter configuration
96
- providers:
97
- openrouter:
98
- api_key: "your-openrouter-api-key" # Or set BOTIASLOOP_API_KEY env var
99
- model: "moonshotai/kimi-k2.5" # Any OpenRouter model
57
+ ```bash
58
+ # 1. Configure your API key
59
+ export BOTIASLOOP_API_KEY="your-api-key"
100
60
 
101
- # Optional: Web search configuration
102
- tools:
103
- web_search:
104
- searxng_url: "http://localhost:8080" # Your SearXNG instance
61
+ # 2. Start chatting
62
+ botiasloop cli
105
63
 
106
- # Optional: Maximum ReAct iterations (default: 20)
107
- max_iterations: 20
64
+ # 3. Ask anything!
65
+ You: What's the weather in Tokyo?
108
66
 
109
- # Optional: Telegram channel
110
- channels:
111
- telegram:
112
- bot_token: "your-telegram-bot-token"
113
- allowed_users: [] # Empty = allow all, or list specific user IDs
67
+ Agent: I'll search for the current weather in Tokyo for you.
68
+
69
+ [Tool] Executing web_search with arguments: {"query"=>"current weather Tokyo Japan"}
70
+
71
+ The weather in Tokyo is currently...
114
72
  ```
115
73
 
116
- ### Environment Variables
74
+ ---
75
+
76
+ ## ✨ Features
77
+
78
+ ### 🧠 Core Capabilities
79
+
80
+ - **ReAct Loop** — AI reasons, acts using tools, observes results, and repeats
81
+ - **12+ LLM Providers** — OpenRouter, OpenAI, Anthropic, Gemini, DeepSeek, Mistral, Perplexity, Ollama, and more
82
+ - **Shell Access** — Execute any shell command (full system access)
83
+ - **Web Search** — Search the web via SearXNG integration
84
+ - **Token Tracking** — Monitor input/output tokens per conversation
85
+
86
+ ### 💬 Channels & Interfaces
87
+
88
+ - **CLI Mode** — Interactive REPL for local usage
89
+ - **Telegram Bot** — Chat with your agent anywhere
90
+ - **Multi-Channel** — Run CLI + Telegram simultaneously
91
+ - **One-Shot Mode** — Single command execution
92
+
93
+ ### 🗄️ Conversation Management
94
+
95
+ - **Persistent Storage** — JSONL-backed conversation history
96
+ - **UUID Tracking** — Every conversation has a unique ID
97
+ - **Auto-Labeling** — Conversations get human-readable names
98
+ - **Conversation Switching** — Jump between active chats
99
+ - **Archiving** — Keep your workspace clean
100
+
101
+ ### 🛠️ Built-in Tools
102
+
103
+ | Tool | Description |
104
+ |------|-------------|
105
+ | 🔧 `shell` | Execute any shell command |
106
+ | 🔍 `web_search` | Search the web via SearXNG |
107
+
108
+ ### 📚 Skills System
109
+
110
+ Skills follow the [agentskills.io](https://agentskills.io) specification:
111
+
112
+ - Load default skills from `data/skills/`
113
+ - Load custom skills from `~/skills/`
114
+ - Progressive disclosure: name/description in system prompt, full content on demand
115
+ - Includes `skill-creator` skill for creating new skills
116
+
117
+ ### ⌨️ Slash Commands
118
+
119
+ Manage conversations with intuitive commands:
120
+
121
+ | Command | Description |
122
+ |---------|-------------|
123
+ | `/new` | Start a new conversation |
124
+ | `/switch <label\|uuid>` | Switch to a different conversation |
125
+ | `/label <name>` | Label the current conversation |
126
+ | `/conversations` | List all conversations |
127
+ | `/reset` | Clear current conversation history |
128
+ | `/compact` | Summarize and archive old messages |
129
+ | `/status` | Show current model, token usage |
130
+ | `/archive` | Archive old conversations |
131
+ | `/system_prompt` | Show current system prompt |
132
+ | `/verbose` | Toggle verbose mode (show tool calls) |
133
+ | `/help` | Show available commands |
134
+
135
+ ---
136
+
137
+ ## 🎨 Philosophy
138
+
139
+ ### Sharp Knives 🔪
140
+
141
+ BotiasLoop intentionally provides **full shell access without restrictions**. This is a feature, not a bug. It's designed for dedicated infrastructure where raw power is needed, not personal devices.
117
142
 
118
- - `BOTIASLOOP_API_KEY` - OpenRouter API key (overrides config file)
119
- - `BOTIASLOOP_SEARXNG_URL` - SearXNG URL (overrides config file)
143
+ The agent can:
144
+ - Execute any shell command
145
+ - Read, write, and delete any file
146
+ - Install software
147
+ - Modify system configuration
148
+ - Access network resources
149
+
150
+ ### Rails Doctrine 🚂
120
151
 
121
- ## Usage
152
+ Following the [Rails Doctrine](https://rubyonrails.org/doctrine):
153
+
154
+ - **Optimize for programmer happiness** — Beautiful, readable Ruby code
155
+ - **Convention over Configuration** — Sensible defaults, minimal setup required
156
+ - **The menu is omakase** — Curated stack (ruby_llm, StandardRB, RSpec)
157
+ - **No one paradigm** — Practical over pure - use what works
158
+
159
+ ---
160
+
161
+ ## 📖 Usage
122
162
 
123
163
  ### CLI Mode
124
164
 
@@ -130,6 +170,14 @@ botiasloop cli
130
170
 
131
171
  Exit with: `exit`, `quit`, `\q`, or Ctrl+C
132
172
 
173
+ ### One-Shot Mode
174
+
175
+ Send a single message:
176
+
177
+ ```bash
178
+ botiasloop "What's the weather in Tokyo?"
179
+ ```
180
+
133
181
  ### Gateway Mode (Telegram Bot)
134
182
 
135
183
  Start the gateway to enable Telegram and other channels:
@@ -143,17 +191,10 @@ botiasloop gateway enable # Install and enable boot auto-start
143
191
  botiasloop gateway start # Start the service now
144
192
  botiasloop gateway status # Check service status
145
193
  botiasloop gateway stop # Stop the service
194
+ botiasloop gateway logs # View service logs
146
195
  botiasloop gateway disable # Disable boot auto-start and uninstall
147
196
  ```
148
197
 
149
- ### One-Shot Mode
150
-
151
- Send a single message:
152
-
153
- ```bash
154
- botiasloop "What's the weather in Tokyo?"
155
- ```
156
-
157
198
  ### Example Session
158
199
 
159
200
  ```bash
@@ -182,12 +223,120 @@ You: /label my-project
182
223
 
183
224
  Agent: **Conversation labeled as `my-project`**
184
225
 
226
+ You: /verbose
227
+
228
+ Agent: **Verbose mode enabled** — You will now see reasoning and tool execution details.
229
+
185
230
  You: exit
186
231
 
187
232
  Goodbye!
188
233
  ```
189
234
 
190
- ## Development
235
+ ---
236
+
237
+ ## ⚙️ Configuration
238
+
239
+ Create `~/.config/botiasloop/config.yml`:
240
+
241
+ ### OpenRouter (Recommended)
242
+
243
+ ```yaml
244
+ providers:
245
+ openrouter:
246
+ api_key: "your-openrouter-api-key"
247
+ model: "moonshotai/kimi-k2.5"
248
+ ```
249
+
250
+ ### OpenAI
251
+
252
+ ```yaml
253
+ providers:
254
+ openai:
255
+ api_key: "your-openai-api-key"
256
+ model: "gpt-4o"
257
+ ```
258
+
259
+ ### Anthropic
260
+
261
+ ```yaml
262
+ providers:
263
+ anthropic:
264
+ api_key: "your-anthropic-api-key"
265
+ model: "claude-3-5-sonnet-20241022"
266
+ ```
267
+
268
+ ### Ollama (Local)
269
+
270
+ ```yaml
271
+ providers:
272
+ ollama:
273
+ api_base: "http://localhost:11434/v1"
274
+ model: "llama3.2"
275
+ ```
276
+
277
+ ### Full Configuration Example
278
+
279
+ ```yaml
280
+ # Required: Provider configuration
281
+ providers:
282
+ openrouter:
283
+ api_key: "your-api-key"
284
+ model: "moonshotai/kimi-k2.5"
285
+
286
+ # Optional: Web search configuration
287
+ tools:
288
+ web_search:
289
+ searxng_url: "http://localhost:8080"
290
+
291
+ # Optional: Maximum ReAct iterations (default: 20)
292
+ max_iterations: 20
293
+
294
+ # Optional: Telegram channel
295
+ channels:
296
+ telegram:
297
+ bot_token: "your-telegram-bot-token"
298
+ allowed_users: [] # Empty = allow all, or list specific user IDs
299
+
300
+ # Optional: Logging
301
+ logger:
302
+ level: "info" # debug, info, warn, error
303
+ destination: "stdout" # stdout, stderr, or path to log file
304
+ ```
305
+
306
+ ### Environment Variables
307
+
308
+ Environment variables override config file values:
309
+
310
+ | Variable | Description |
311
+ |----------|-------------|
312
+ | `BOTIASLOOP_API_KEY` | API key for the active provider |
313
+ | `BOTIASLOOP_SEARXNG_URL` | SearXNG URL for web search |
314
+ | `BOTIASLOOP_LOG_LEVEL` | Log level (debug, info, warn, error) |
315
+
316
+ ---
317
+
318
+ ## 🔒 Security
319
+
320
+ ⚠️ **IMPORTANT**: BotiasLoop provides **full shell access**. The AI agent can:
321
+ - Execute any shell command
322
+ - Read, write, and delete any file
323
+ - Install software
324
+ - Modify system configuration
325
+ - Access network resources
326
+
327
+ **Use only on dedicated infrastructure**, never on personal devices or production systems containing sensitive data.
328
+
329
+ ### Future Security Features (Roadmap)
330
+
331
+ - Sandboxed execution (Docker/Firejail)
332
+ - Command whitelist/blacklist
333
+ - Confirmation for destructive operations
334
+ - Read-only mode option
335
+ - Secret management integration
336
+
337
+ ---
338
+
339
+ ## 🛠️ Development
191
340
 
192
341
  ### Setup
193
342
 
@@ -237,7 +386,9 @@ bundle exec standardrb --fix
237
386
  bundle exec rake
238
387
  ```
239
388
 
240
- ## Architecture
389
+ ---
390
+
391
+ ## 📁 Architecture
241
392
 
242
393
  ```
243
394
  botiasloop/
@@ -249,7 +400,9 @@ botiasloop/
249
400
  │ ├── agent.rb # Main orchestrator
250
401
  │ ├── loop.rb # ReAct cycle implementation
251
402
  │ ├── config.rb # Configuration management
252
- │ ├── conversation.rb # Conversation persistence (SQLite)
403
+ │ ├── conversation.rb # Conversation persistence
404
+ │ ├── conversation_manager.rb # Multi-conversation management
405
+ │ ├── auto_label.rb # Auto-labeling conversations
253
406
  │ ├── tool.rb # Base tool class
254
407
  │ ├── tools/
255
408
  │ │ ├── registry.rb # Tool registration
@@ -267,45 +420,32 @@ botiasloop/
267
420
  │ │ ├── base.rb # Channel base class
268
421
  │ │ ├── cli.rb # CLI channel
269
422
  │ │ └── telegram.rb # Telegram bot
270
- └── channels_manager.rb # Multi-channel orchestration
423
+ ├── channels_manager.rb # Multi-channel orchestration
424
+ │ └── systemd_service.rb # Service management
271
425
  ├── data/
272
426
  │ └── skills/ # Default skills
273
427
  ├── spec/ # Test suite
274
428
  └── README.md # This file
275
429
  ```
276
430
 
277
- ## Security
278
-
279
- ⚠️ **IMPORTANT**: BotiasLoop provides full shell access. The AI agent can:
280
- - Execute any shell command
281
- - Read, write, and delete any file
282
- - Install software
283
- - Modify system configuration
284
- - Access network resources
285
-
286
- **Use only on dedicated infrastructure**, never on personal devices or production systems containing sensitive data.
431
+ ---
287
432
 
288
- ### Future Security Features (Roadmap)
289
- - Sandboxed execution (Docker/Firejail)
290
- - Command whitelist/blacklist
291
- - Confirmation for destructive operations
292
- - Read-only mode option
293
- - Secret management integration
433
+ ## 🗺️ Roadmap
294
434
 
295
- ## Roadmap
435
+ See [ROADMAP.md](ROADMAP.md) for detailed planned features:
296
436
 
297
- See [ROADMAP.md](ROADMAP.md) for detailed planned features including:
437
+ - **Persistent Memory** Vector database for semantic search
438
+ - **Custom Tools** — Load tools from `~/tools/`
439
+ - **Conversation Compaction** — Automatic summarization
440
+ - **Subagents** — Specialized agent instances
441
+ - **Streaming Responses** — Real-time token display
442
+ - **Multi-Modal** — Image analysis, audio transcription
443
+ - **Web Dashboard** — Browser-based management UI
444
+ - **Plugin System** — Load plugins from gems
298
445
 
299
- - **Persistent Memory**: Vector database for semantic search
300
- - **Custom Tools**: Load tools from `~/tools/`
301
- - **Conversation Compaction**: Automatic summarization
302
- - **Subagents**: Specialized agent instances
303
- - **Streaming Responses**: Real-time token display
304
- - **Multi-Modal**: Image analysis, audio transcription
305
- - **Web Dashboard**: Browser-based management UI
306
- - **Plugin System**: Load plugins from gems
446
+ ---
307
447
 
308
- ## Contributing
448
+ ## 🤝 Contributing
309
449
 
310
450
  1. Fork the repository
311
451
  2. Create a feature branch
@@ -319,24 +459,28 @@ See [ROADMAP.md](ROADMAP.md) for detailed planned features including:
319
459
 
320
460
  ### Development Principles
321
461
 
322
- - **Test-First**: All features built using TDD
323
- - **Sharp Knives**: Keep raw power, minimal restrictions
324
- - **Rails Doctrine**: Optimize for programmer happiness
325
- - **Privacy First**: Local-first, user-controlled data
326
- - **Unix Philosophy**: Do one thing well, compose with other tools
462
+ - **Test-First** All features built using TDD
463
+ - **Sharp Knives** Keep raw power, minimal restrictions
464
+ - **Rails Doctrine** Optimize for programmer happiness
465
+ - **Privacy First** Local-first, user-controlled data
466
+ - **Unix Philosophy** Do one thing well, compose with other tools
467
+
468
+ ---
327
469
 
328
- ## License
470
+ ## 📜 License
329
471
 
330
- MIT License - see [LICENSE](LICENSE) file for details.
472
+ MIT License see [LICENSE](LICENSE) file for details.
473
+
474
+ ---
331
475
 
332
- ## Credits
476
+ ## 🙏 Credits
333
477
 
334
478
  Built by [Tobias Feistmantl](https://github.com/0x7466) with inspiration from nanobot and the Ruby on Rails doctrine.
335
479
 
336
480
  Powered by:
337
- - [ruby_llm](https://github.com/crmne/ruby_llm) - Unified LLM API
338
- - [OpenRouter](https://openrouter.ai/) - Unified LLM API gateway
339
- - [SearXNG](https://docs.searxng.org/) - Privacy-respecting metasearch
481
+ - [ruby_llm](https://github.com/crmne/ruby_llm) Unified LLM API
482
+ - [OpenRouter](https://openrouter.ai/) Unified LLM API gateway
483
+ - [SearXNG](https://docs.searxng.org/) Privacy-respecting metasearch
340
484
 
341
485
  ---
342
486
 
data/bin/botiasloop CHANGED
@@ -3,6 +3,9 @@
3
3
 
4
4
  require_relative "../lib/botiasloop"
5
5
 
6
+ # Initialize global config instance
7
+ Botiasloop::Config.instance = Botiasloop::Config.new
8
+
6
9
  def print_help
7
10
  puts "botiasloop - Minimal agentic AI with ReAct loop"
8
11
  puts
@@ -22,11 +25,16 @@ def print_help
22
25
  puts " stop Stop the systemd service"
23
26
  puts " restart Restart the systemd service"
24
27
  puts " status Show systemd service status"
28
+ puts " logs Show service logs (journalctl)"
25
29
  puts " enable Install and enable systemd service (auto-start on login)"
26
30
  puts " disable Disable and uninstall systemd service"
31
+ puts
32
+ puts "Logs Options:"
33
+ puts " -f, --follow Follow log output in real-time"
34
+ puts " -n, --lines N Show last N lines (default: 50)"
27
35
  end
28
36
 
29
- def start_gateway(config)
37
+ def start_gateway
30
38
  # Check if any channels are configured (excluding CLI)
31
39
  available_channels = Botiasloop::Channels.registry.channels.except(:cli)
32
40
 
@@ -36,10 +44,10 @@ def start_gateway(config)
36
44
  exit 1
37
45
  end
38
46
 
39
- manager = Botiasloop::ChannelsManager.new(config)
47
+ manager = Botiasloop::ChannelsManager.new
40
48
 
41
49
  # Start all channels and wait
42
- manager.start_channels.wait
50
+ manager.start_listening.wait
43
51
  end
44
52
 
45
53
  if ARGV[0] == "-h" || ARGV[0] == "--help"
@@ -47,10 +55,8 @@ if ARGV[0] == "-h" || ARGV[0] == "--help"
47
55
  elsif ARGV[0] == "-v" || ARGV[0] == "--version"
48
56
  puts "botiasloop #{Botiasloop::VERSION}"
49
57
  elsif ARGV[0] == "gateway"
50
- config = Botiasloop::Config.new
51
-
52
58
  if ARGV[1] == "start"
53
- service = Botiasloop::SystemdService.new(config)
59
+ service = Botiasloop::SystemdService.new
54
60
  if service.systemd_available?
55
61
  begin
56
62
  service.start
@@ -64,7 +70,7 @@ elsif ARGV[0] == "gateway"
64
70
  exit 1
65
71
  end
66
72
  elsif ARGV[1] == "stop"
67
- service = Botiasloop::SystemdService.new(config)
73
+ service = Botiasloop::SystemdService.new
68
74
  if service.systemd_available?
69
75
  begin
70
76
  service.stop
@@ -78,7 +84,7 @@ elsif ARGV[0] == "gateway"
78
84
  exit 1
79
85
  end
80
86
  elsif ARGV[1] == "restart"
81
- service = Botiasloop::SystemdService.new(config)
87
+ service = Botiasloop::SystemdService.new
82
88
  if service.systemd_available?
83
89
  begin
84
90
  service.restart
@@ -92,7 +98,7 @@ elsif ARGV[0] == "gateway"
92
98
  exit 1
93
99
  end
94
100
  elsif ARGV[1] == "status"
95
- service = Botiasloop::SystemdService.new(config)
101
+ service = Botiasloop::SystemdService.new
96
102
  if service.systemd_available?
97
103
  status = service.status
98
104
  puts "Service status: #{status[:message]}"
@@ -101,8 +107,53 @@ elsif ARGV[0] == "gateway"
101
107
  puts "Error: systemd is not available on this system"
102
108
  exit 1
103
109
  end
110
+ elsif ARGV[1] == "logs"
111
+ service = Botiasloop::SystemdService.new
112
+ if service.systemd_available?
113
+ # Parse logs options
114
+ follow = false
115
+ lines = 50
116
+
117
+ # Parse arguments from ARGV[2..] to support both -n 100 and --lines 100 formats
118
+ i = 2
119
+ while i < ARGV.length
120
+ arg = ARGV[i]
121
+
122
+ if arg == "-f" || arg == "--follow"
123
+ follow = true
124
+ i += 1
125
+ elsif arg == "-n" || arg == "--lines"
126
+ if i + 1 >= ARGV.length
127
+ puts "Error: #{arg} requires a value"
128
+ exit 1
129
+ end
130
+
131
+ lines_str = ARGV[i + 1]
132
+ unless lines_str.match(/^\d+$/)
133
+ puts "Error: Invalid number of lines: #{lines_str}"
134
+ exit 1
135
+ end
136
+
137
+ lines = lines_str.to_i
138
+ i += 2
139
+ else
140
+ puts "Unknown option: #{arg}"
141
+ exit 1
142
+ end
143
+ end
144
+
145
+ begin
146
+ service.logs(follow: follow, lines: lines)
147
+ rescue Botiasloop::SystemdError => e
148
+ puts "Error: #{e.message}"
149
+ exit 1
150
+ end
151
+ else
152
+ puts "Error: systemd is not available on this system"
153
+ exit 1
154
+ end
104
155
  elsif ARGV[1] == "enable"
105
- service = Botiasloop::SystemdService.new(config)
156
+ service = Botiasloop::SystemdService.new
106
157
  if service.systemd_available?
107
158
  begin
108
159
  service.install unless service.installed?
@@ -118,7 +169,7 @@ elsif ARGV[0] == "gateway"
118
169
  exit 1
119
170
  end
120
171
  elsif ARGV[1] == "disable"
121
- service = Botiasloop::SystemdService.new(config)
172
+ service = Botiasloop::SystemdService.new
122
173
  if service.systemd_available?
123
174
  begin
124
175
  if service.installed?
@@ -136,13 +187,12 @@ elsif ARGV[0] == "gateway"
136
187
  exit 1
137
188
  end
138
189
  else
139
- start_gateway(config)
190
+ start_gateway
140
191
  end
141
192
  elsif ARGV[0] == "cli"
142
193
  # CLI interactive mode
143
- config = Botiasloop::Config.new
144
- cli_channel = Botiasloop::Channels::CLI.new(config)
145
- cli_channel.start
194
+ cli_channel = Botiasloop::Channels::CLI.new
195
+ cli_channel.start_listening
146
196
  elsif ARGV.empty? || ARGV[0] == "help"
147
197
  # Default to help when no args or explicit help command
148
198
  print_help